commit 18dcad30113c5e0579f17215d2158e4dd1cf8cfb
parent 934bb3f405fd968f99fc3395d6fed1844ea3c0ce
Author: aabacchus <ben@bvnf.space>
Date: Fri, 21 Apr 2023 22:05:50 +0100
start search (no glob)
Diffstat:
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;
+}