diff options
| author | Thomas Voss <mail@thomasvoss.com> | 2024-06-09 11:26:21 +0200 | 
|---|---|---|
| committer | Thomas Voss <mail@thomasvoss.com> | 2024-06-09 11:26:21 +0200 | 
| commit | 11e13e9ee23554a452ae348f6551250152b87638 (patch) | |
| tree | 8977b6cb355f6c05280599e240127a857155cbc6 | |
| parent | ca812456b590d349f4c15a972ecc444d5b27c5ec (diff) | |
Start working on documentation
| -rw-r--r-- | README.md | 250 | 
1 files changed, 196 insertions, 54 deletions
@@ -68,32 +68,32 @@ static char *cflags[] = {"-Wall", "-Wextra", "-Werror", "-O3"};  int  main(int argc, char **argv)  { -    /* Initialize the library, and rebuild this script if needed */ -    cbsinit(argc, argv); -    rebuild(); - -    /* If the compiled binary isn’t outdated, do nothing */ -    if (!foutdatedl("my-file", "my-file.c")) -        return EXIT_SUCCESS; - -    /* Append ‘cc’ and our cflags to the command, but allow the user to use the -       $CC and $CFLAGS environment variables to override them */ -    struct strs cmd = {0}; -    strspushenvl(&cmd, "CC", "cc"); -    strspushenv(&cmd, "CFLAGS", cflags, lengthof(cflags)); - -    /* Call pkg-config with the --libs and --cflags options for the library -      ‘liblux’, appending the result to our command.  If it fails then we -      fallback to using -llux */ -    if (!pcquery(&cmd, "liblux", PC_LIBS | PC_CFLAGS)) -        strspushl(&cmd, "-llux"); - -    /* Push the final arguments to our command */ -    strspushl(&cmd, "-o", "my-file", "-c", "my-file.c"); - -    /* Print our command to stdout, and execute it */ -    cmdput(cmd); -    return cmdexec(cmd); +	/* Initialize the library, and rebuild this script if needed */ +	cbsinit(argc, argv); +	rebuild(); + +	/* If the compiled binary isn’t outdated, do nothing */ +	if (!foutdatedl("my-file", "my-file.c")) +		return EXIT_SUCCESS; + +	/* Append ‘cc’ and our cflags to the command, but allow the user to use the +	   $CC and $CFLAGS environment variables to override them */ +	struct strs cmd = {0}; +	strspushenvl(&cmd, "CC", "cc"); +	strspushenv(&cmd, "CFLAGS", cflags, lengthof(cflags)); + +	/* Call pkg-config with the --libs and --cflags options for the library +	  ‘liblux’, appending the result to our command.  If it fails then we +	  fallback to using -llux */ +	if (!pcquery(&cmd, "liblux", PC_LIBS | PC_CFLAGS)) +		strspushl(&cmd, "-llux"); + +	/* Push the final arguments to our command */ +	strspushl(&cmd, "-o", "my-file", "-c", "my-file.c"); + +	/* Print our command to stdout, and execute it */ +	cmdput(cmd); +	return cmdexec(cmd);  }  ``` @@ -121,61 +121,203 @@ main(int argc, char **argv)  	if (!foutdated("my-file", sources, lengthof(sources)))  		return EXIT_SUCCESS; -    /* Get the number of CPUs available.  If this fails we fallback to 8. */ -    int cpus = nproc(); +	/* Get the number of CPUs available.  If this fails we fallback to 8. */ +	int cpus = nproc();  	if (cpus == -1)  		cpus = 8; -    /* Create a thread pool, with one thread per CPU */ -    tpool tp; +	/* Create a thread pool, with one thread per CPU */ +	tpool tp;  	tpinit(&tp, cpus); -    /* For each of our source files, add a task to the thread pool to build -       the file ‘sources[i]’ with the function ‘build’ */ +	/* For each of our source files, add a task to the thread pool to build +	   the file ‘sources[i]’ with the function ‘build’ */  	for (size_t i = 0; i < lengthof(sources); i++)  		tpenq(&tp, build, sources[i], NULL); -    /* Wait for all the tasks to complete and free the thread pool */ +	/* Wait for all the tasks to complete and free the thread pool */  	tpwait(&tp);  	tpfree(&tp); -    struct strs cmd = {0}; -    strspushenvl(&cmd, "CC", "cc"); -    strspushl(&cmd, "-o", "my-file"); +	struct strs cmd = {0}; +	strspushenvl(&cmd, "CC", "cc"); +	strspushl(&cmd, "-o", "my-file"); -    for (size_t i = 0; i < lengthof(sources); i++) -        strspushl(&cmd, swpext(sources[i], "o")); +	for (size_t i = 0; i < lengthof(sources); i++) +		strspushl(&cmd, swpext(sources[i], "o"));  	cmdput(cmd); -    return cmdexec(cmd); +	return cmdexec(cmd);  }  void  build(void *arg)  { -    /* This function will be called by the thread pool with ‘arg’ set to a -       filename such as ‘foo.c’ */ +	/* This function will be called by the thread pool with ‘arg’ set to a +	   filename such as ‘foo.c’ */ -    struct strs cmd = {0}; +	struct strs cmd = {0}; -    strspushenvl(&cmd, "CC", "cc"); -    strspushenv(&cmd, "CFLAGS", cflags, lengthof(cflags)); +	strspushenvl(&cmd, "CC", "cc"); +	strspushenv(&cmd, "CFLAGS", cflags, lengthof(cflags)); -    /* Allocate a copy of the string ‘arg’, with the file extension replaced. -       This will for example return ‘foo.o’ when given ‘foo.c’ */ -    char *object = swpext(arg, "o"); +	/* Allocate a copy of the string ‘arg’, with the file extension replaced. +	   This will for example return ‘foo.o’ when given ‘foo.c’ */ +	char *object = swpext(arg, "o"); -    strspushl(&cmd, "-o", object, "-c", arg); +	strspushl(&cmd, "-o", object, "-c", arg); -    cmdput(cmd); -    if (cmdexec(cmd) != EXIT_SUCCESS) -        exit(EXIT_FAILURE); -    free(object); -    strsfree(&cmd); +	cmdput(cmd); +	if (cmdexec(cmd) != EXIT_SUCCESS) +		exit(EXIT_FAILURE); +	free(object); +	strsfree(&cmd);  }  ```  ## Documentation -Coming soon! +### Macros + +```c +#define CBS_NO_THREADS +``` + +If this macro is defined before including `cbs.h`, then support for thread pools +won’t be included meaning you don’t need to link with `-lpthread` when +bootstrapping the build script. + +--- + +```c +#define lengthof(xs) /* … */ +``` + +Return the number of elements in the static array `xs`. + +### Startup Functions + +These two functions should be called at the very beginning of your `main()` +function in the order in which they are documented here for everything to work +properly. + +--- + +```c +void cbsinit(int argc, char **argv) +``` + +Should be the first function called in `main()` and passed the same parameters +received from `main()`.  It initializes some internal data, but it also changes +the current working directory so that the running process is in the same +directory as the location of the process.  For example if your build script is +called `make` and you call it as `./build/make`, this function will change your +working directory to `./build`. + +--- + +```c +#define rebuild() /* … */ +``` + +Should be called right after `cbsinit()`.  This function-like macro checks to +see if the build script is outdated compared to its source file.  If it finds +that the build script is outdated it rebuilds it before executing the new build +script. + +### String Array Types and Functions + +The following types and functions all work on dynamically-allocated arrays of +string, which make gradually composing a complete command that can be executed +very simple. + +--- + +```c +struct strs { +	char **buf; +	size_t len, cap; +}; +``` + +A type representing a dynamic array of strings.  The `len` and `cap` fields hold +the length and capacity of the string array respectively, and the `buf` field is +the actual array itself.  Despite being a sized array, `buf` is also guaranteed +by all the functions that act on this structure to always be null-terminated. + +There is no initialization function for the `strs` structure.  To initialize the +structure simply zero-initialize it: + +```c +int +main(int argc, char **argv) +{ +	/* … */ +	struct strs cmd = {0}; +	strspush(&cmd, "cc"); +	/* … */ +} +``` + +--- + +```c +void strsfree(struct strs *xs) +``` + +Deallocates all memory associated with the string array `xs`.  Note that this +does **not** deallocate memory associated with the individual elements in the +string array — that must still be done manually. + +This function also zeros `xs` after freeing memory, so that the same structure +can be safely reused afterwards. + +--- + +```c +void strszero(struct strs *xs) +``` + +Zeros the string array `xs` **without** deallocating any memory used by the +string array.  This allows you to reuse the same structure for a different +purpose without needing to reallocate a fresh new array, instead reusing the old +one. + +--- + +```c +void strspush(struct strs *xs, char **ys, size_t n) +``` + +Append `n` strings from the string array `ys` to the end of `xs`. + +--- + +```c +#define strspushl(xs, ...) /* … */ +``` + +Append the strings specified by the provided variable-arguments to the end of +`xs`. + +--- + +```c +void strspushenv(struct strs *xs, const char *ev, char **ys, size_t n) +``` + +Append the value of the environment variable `ev` to the end of `xs`.  If the +provided environment variable doesn’t exist or has the value of the empty +string, then fallback to appending `n` strings from `ys` to the end of `xs`. + +--- + +```c +#define strspushenvl(xs, ev, ...) +``` + +Append the value of the environment variable `ev` to the end of `xs`.  If the +provided environment variable doesn’t exist or has the value of the empty +string, then fallback to appending the strings specified by the provided +variable-arguments to the end of `xs`.  |