ckiss

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 18dcad30113c5e0579f17215d2158e4dd1cf8cfb
parent 934bb3f405fd968f99fc3395d6fed1844ea3c0ce
Author: aabacchus <ben@bvnf.space>
Date:   Fri, 21 Apr 2023 22:05:50 +0100

start search (no glob)

Diffstat:
MREADME | 2+-
Msrc/Makefile | 3++-
Msrc/kiss.h | 6++++--
Msrc/libkiss.c | 37++++++++++++++++++++++++++++++-------
Msrc/main.c | 6+++++-
Asrc/search.c | 16++++++++++++++++
6 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/README b/README @@ -11,7 +11,7 @@ An implementation of the kiss package manager in C. [ ] install [x] list [ ] remove -[ ] search +[.] search [ ] update [ ] upgrade [ ] version diff --git a/src/Makefile b/src/Makefile @@ -2,7 +2,7 @@ XCFLAGS = $(CFLAGS) -Wall -Wextra -Wshadow -pedantic -D_XOPEN_SOURCE=700 -Og -g -OBJS = main.o list.o +OBJS = main.o list.o search.o all: kiss @@ -29,4 +29,5 @@ clean: libkiss.o: kiss.h test.o: kiss.h list.o: kiss.h +search.o: kiss.h main.o: kiss.h diff --git a/src/kiss.h b/src/kiss.h @@ -56,8 +56,9 @@ char **split(char *s, char *sep); /* Goes through the path array looking for a file in each directory with the * given name. Returns the first one. The returned string must be freed by the - * caller. */ -char *find_in_path(char *name, char **path); + * caller. If limit is true, only return the first result found in path, + * otherwise return an array of all results found in path. */ +char **find_in_path(char *name, char **path, bool limit); /* Checks for the first cmd which may be found in path. Returns the index of the * cmd (0, 1, 2, ...). Arg list must be terminated with a NULL */ @@ -71,3 +72,4 @@ void destroy_env(struct env *e); int list(int argc, char **argv, struct env *e); +int search(int argc, char **argv, struct env *e); diff --git a/src/libkiss.c b/src/libkiss.c @@ -120,31 +120,54 @@ split(char *s, char *sep) { return res; } -char * -find_in_path(char *name, char **path) { +char ** +find_in_path(char *name, char **path, bool limit) { + char **s = NULL, **tmp; + int n = 0; for (int i = 0; path[i] != NULL; i++) { char *file = concat(path[i], "/", name, NULL); if (access(file, R_OK) == 0) { - return file; + tmp = realloc(s, sizeof(char *) * ++n); + if (tmp == NULL) { + free(file); + free(s); + die_perror("realloc"); + } + s = tmp; + s[n - 1] = file; + if (limit) + return s; + } else { + free(file); + } + } + if (s != NULL) { + /* add terminating NULL */ + tmp = realloc(s, sizeof(char *) * (n+1)); + if (tmp == NULL) { + free(s); + die_perror("realloc"); } - free(file); + s = tmp; + s[n] = NULL; } - return NULL; + return s; } int available_cmd(char **path, char *cmd, ...) { - char *s; va_list ap; int n = 0; va_start(ap, cmd); while (cmd != NULL) { - s = find_in_path(cmd, path); + char **s = find_in_path(cmd, path, true); if (s != NULL) { + free(*s); free(s); va_end(ap); return n; } + free(*s); free(s); n++; cmd = va_arg(ap, char *); diff --git a/src/main.c b/src/main.c @@ -5,8 +5,9 @@ char *c1, *c2, *c3; noreturn void usage(int r) { - mylog("kiss [l] [pkg]..."); + mylog("kiss [l|s] [pkg]..."); mylog("list List installed packages"); + mylog("search Search for packages"); exit(r); } @@ -34,6 +35,9 @@ main(int argc, char **argv) { case 'l': list(argc - 1, argv + 1, e); break; + case 's': + search(argc - 1, argv + 1, e); + break; default: /* TODO: external tools */ usage(1); diff --git a/src/search.c b/src/search.c @@ -0,0 +1,16 @@ +#include <stdio.h> +#include <stdlib.h> +#include "kiss.h" + +int +search(int argc, char **argv, struct env *e) { + char **s = find_in_path(argv[1], e->kiss_path, false); + if (s == NULL) + die2(argv[1], "not found"); + for (int i = 0; s[i] != NULL; i++) { + printf("%s\n", s[i]); + free(s[i]); + } + free(s); + return 0; +}