]> Trent Huber's Code - cbs.git/commitdiff
Added NONE macro
authorTrent Huber <trentmhuber@gmail.com>
Wed, 23 Jul 2025 01:49:19 +0000 (21:49 -0400)
committerTrent Huber <trentmhuber@gmail.com>
Wed, 23 Jul 2025 01:49:19 +0000 (21:49 -0400)
README.md
cbs.c

index 17f8f0faecd4e522ac4414a0a69bba8e98ed4c5e..d1b92ea0a9fe5306735d33dda800bb42f4a71561 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,8 +14,10 @@ To build a project, you first need to make a file called `build.c` which describ
 int main(void) {
     build("./");
 
+    cflags = NONE;
     compile("main");
 
+    lflags = NONE;
     load('x', "main", LIST("main"));
 
     return EXIT_SUCCESS;
@@ -44,7 +46,7 @@ cc -o main main.o
 ```
 
 ## Detailed usage
-cbs tries to be as simple as possible, while still remaining powerful. Its simplicity is rooted in its intentionally limited scope to just build C projects. Thus, cbs just needs to worry about compiling and linking C code, and calling other build executables.
+cbs tries to be as simple as possible, while still remaining powerful. Its simplicity is rooted in its intentionally limited scope of only building C projects. Thus, cbs only needs to compile and link C code, as well as call other build executables.
 
 ### Compiling source files
 
@@ -54,7 +56,7 @@ void compile(char *src);
 
 The `compile()` function is given a single source file to compile and will generate an object file with the same name. In general, file extensions are unnecessary in your build files as they can usually be inferred based on the function being called. This has the added benefit of being able to reuse lists of file names in both compiling and linking.
 
-To define flags for the compiler to use, you can set the global `cflags` variable to a list of strings of flags. This list is expected to be NULL-terminated, an easy thing to forget, so a simple C macro has been defined to avoid the issue altogether.
+Before you run `compile()`, the global `cflags` variable has to be initialized with a list of flags to pass to the compiler. If no flags are needed, than the `NONE` macro should be used; otherwise the `LIST()` macro can be used.
 
 ```c
 cflags = LIST("-Wall", "-O3");
@@ -82,14 +84,14 @@ The second argument is the name of the target file. To aid portability, the file
 
 The third and final argument is a list of object files and libraries that will be linked to create the target file. Here, file extensions *are* required for libraries since they're mixed in with object files. The `LIST()` macro can also be used for this list since it too is expected to be NULL-terminated.
 
-Similar to the global `cflags` variable, there is a global `lflags` variable used by the linker.
+Similar to `cflags`, there is a global `lflags` variable used by the linker.
 
 ```c
 lflags = LIST("-lm");
 load('s', "main", LIST("first" DYEXT, "second", "third.a"));
 ```
 
-`DYEXT` is another macro defined as the platform-specific file extension for dynamic libraries, this time to aid the portability of build files.
+`DYEXT` is macro defined to be the platform-specific file extension for dynamic libraries, to aid the portability of build files.
 
 ### Recursive builds
 
diff --git a/cbs.c b/cbs.c
index 2ae59c4b2ad01377b60080e4b7ea9634b7a36432..fa4b22ecb4e98eef690f979915036531ce5ffc70 100644 (file)
--- a/cbs.c
+++ b/cbs.c
@@ -14,6 +14,7 @@
 #define DYEXT ".so"
 #endif
 
+#define NONE (char *[]){NULL}
 #define LIST(...) (char *[]){__VA_ARGS__, NULL}
 
 extern char **environ;
@@ -32,9 +33,7 @@ char *extend(char *path, char *ext) {
    char *dp, *bp, *e, *r;
    size_t d, b, l;
 
-   if (!(dp = path)) return NULL;
-
-   bp = (bp = strrchr(dp, '/')) ? bp + 1 : dp;
+   bp = (bp = strrchr(dp = path, '/')) ? bp + 1 : dp;
    d = bp - dp;
    b = (e = strrchr(bp, '.')) ? e - bp : (e = ext, strlen(bp));
    if (*ext == '!') e = ++ext;
@@ -63,10 +62,11 @@ char *extend(char *path, char *ext) {
 void run(char *file, char **args, char *what, char *who) {
    size_t i;
 
-   if (*args) for (i = 0; args[i]; ++i) {
+   if (*file == '!') ++file;
+   else for (i = 0; args[i]; ++i) {
        fputs(args[i], stdout);
        putchar(args[i + 1] ? ' ' : '\n');
-   } else ++args;
+   }
 
    if (execve(file, args, environ) == -1)
        err(EXIT_FAILURE, "Unable to %s `%s'", what, who);
@@ -83,24 +83,24 @@ void await(pid_t cpid, char *what, char *who) {
 
 void compile(char *src) {
    size_t f;
-   char **args, **p;
+   char **args, **p, *obj;
    pid_t cpid;
 
-   f = 0;
-   if (cflags) while (cflags[f]) ++f;
+   for (f = 0; cflags[f]; ++f);
    p = args = allocate((2 + f + 3 + 1) * sizeof*args);
 
    *p++ = "cc";
    *p++ = "-c";
-   if (cflags) for (f = 0; cflags[f]; *p++ = cflags[f++]);
+   for (f = 0; cflags[f]; *p++ = cflags[f++]);
    *p++ = "-o";
-   *p++ = extend(src, "!.o");
+   *p++ = obj = extend(src, "!.o");
    *p++ = src = extend(src, ".c");
 
    if ((cpid = fork()) == -1) err(EXIT_FAILURE, "Unable to fork");
    else if (!cpid) run("/usr/bin/cc", args, "compile", src);
    await(cpid, "compile", src);
 
+   free(obj);
    free(src);
    free(args);
 }
@@ -110,9 +110,8 @@ void load(char type, char *target, char **objs) {
    char **args, **p, **a, **fp, *path;
    pid_t cpid;
 
-   f = o = 0;
-   while (objs[o]) ++o;
-   if (lflags) while (lflags[f]) ++f;
+   for (o = 0; objs[o]; ++o);
+   for (f = 0; lflags[f]; ++f);
    args = allocate((3 + o + 1 + f + 1) * sizeof*args);
    fp = (a = (p = args) + 3) + o;
 
@@ -137,9 +136,8 @@ void load(char type, char *target, char **objs) {
        errx(EXIT_FAILURE, "Unknown target type `%c'", type);
    }
    *p++ = target;
-   f = o = 0;
-   while (objs[o]) *p++ = extend(objs[o++], ".o");
-   if (lflags) while (lflags[f]) *fp++ = lflags[f++];
+   for (o = 0; objs[o]; *p++ = extend(objs[o++], ".o"));
+   for (f = 0; lflags[f]; *fp++ = lflags[f++]);
 
    if ((cpid = fork()) == -1) err(EXIT_FAILURE, "Unable to fork");
    else if (!cpid) run(path, args, "link", target);
@@ -196,14 +194,16 @@ void build(char *path) {
    if (self || !exists) {
        c = cflags;
        l = lflags;
-       lflags = cflags = NULL;
 
+       cflags = NONE;
        compile("build");
+
+       lflags = NONE;
        load('x', "build", LIST("build"));
 
        cflags = c;
        lflags = l;
    }
 
-   run("build", LIST(NULL, "build"), "run", "build");
+   run("!build", LIST("build"), "run", "build");
 }