From: Thomas Walker Lynch Date: Fri, 29 Mar 2019 21:14:24 +0000 (+0100) Subject: tranche-make draft X-Git-Url: https://git.reasoningtechnology.com/style/static/gitweb.css?a=commitdiff_plain;h=617b32ecf9744cc0612e7c695ab33ab46e8b6eda;p=subu tranche-make draft --- diff --git a/module/da/src/da.lib.c b/module/da/src/da.lib.c index 47558e0..7fa384a 100644 --- a/module/da/src/da.lib.c +++ b/module/da/src/da.lib.c @@ -28,10 +28,15 @@ void da_rewind(Da *dap){ dap->end = dap->base; } -bool da_empty(Da *dap){ +bool da_emptyq(Da *dap){ return dap->end == dap->base; } +size_t da_length(Da *dap){ + return dap->end - dap->base; +} + + void da_rebase(Da *dap, char *old_base, void *pta){ char **pt = (char **)pta; size_t offset = *pt - old_base; @@ -129,7 +134,7 @@ void da_free_elements(Da *dap){ // for the case of an array of strings void da_strings_puts(Da *dap){ - char *pt = dap->base; + char *pt = dap->base; // char * because it points to a byte in the array while( pt < dap->end ){ puts(*(char **)pt); pt += dap->element_size; diff --git a/module/da/src/da.lib.h b/module/da/src/da.lib.h index d480d8c..189ee50 100644 --- a/module/da/src/da.lib.h +++ b/module/da/src/da.lib.h @@ -17,6 +17,8 @@ typedef struct Da{ void da_alloc(Da *dap, size_t element_size); void da_free(Da *dap); void da_rewind(Da *dap); +bool da_emptyq(Da *dap); +size_t da_length(Da *dap); char *da_expand(Da *dap); void da_rebase(Da *dap, char *old_base, void *pta); bool da_endq(Da *dap, void *pt); diff --git a/module/share/include/da.h b/module/share/include/da.h index 6d3c43b..189ee50 100644 --- a/module/share/include/da.h +++ b/module/share/include/da.h @@ -17,16 +17,20 @@ typedef struct Da{ void da_alloc(Da *dap, size_t element_size); void da_free(Da *dap); void da_rewind(Da *dap); +bool da_emptyq(Da *dap); +size_t da_length(Da *dap); char *da_expand(Da *dap); void da_rebase(Da *dap, char *old_base, void *pta); bool da_endq(Da *dap, void *pt); bool da_boundq(Da *dap); void da_push(Da *dap, void *element); bool da_pop(Da *dap, void *element); +void da_cat(Da *dap_base, Da *dap_cat); char *da_index(Da *dap, size_t i); void da_map(Da *dap, void f(void *, void *), void *closure); void da_free_elements(Da *dap); void da_strings_puts(Da *dap); +void da_ints_print(Da *dap); char *da_fgets(Da *dap, FILE *fd); #endif diff --git a/module/share/lib/libda.a b/module/share/lib/libda.a index ba48a6e..49ece65 100644 Binary files a/module/share/lib/libda.a and b/module/share/lib/libda.a differ diff --git a/module/tranche/src/tranche-make.c b/module/tranche/src/tranche-make.c deleted file mode 100644 index 2f84d0f..0000000 --- a/module/tranche/src/tranche-make.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -Scans a tranche file and outputs a make rule for makefile-deps, of the form: - -... : - tranche $@ - - file is opened for append. If the depfile is not present stdout is used. - -If the given source file name has a directory prefix, the targets in -the dep line are given the same prefix. -*/ - -#include -#include -#include -#include "tranche.lib.h" - -#define ERR_ARGC 1 -#define ERR_SRC_OPEN 2 -#define ERR_DEP_OPEN 4 - - -int main(int argc, char **argv, char **envp){ - if(argc < 2 || argc > 3){ - fprintf(stderr, "usage: %s []\n",argv[0]); - return ERR_ARGC; - } - char *src_file_name = argv[1]; - char *dep_file_name = argv[2]; - - int dep_fd; - FILE *src_file = fopen(src_file_name, "r"); - if(argc < 3) - dep_fd = 1; - else{ - dep_fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT, 0666); - } - unsigned int err = 0; - if(!src_file){ - fprintf(stderr,"could not open tranche source file %s\n", src_file_name); - err+= ERR_SRC_OPEN; - } - if(dep_fd == -1){ - fprintf(stderr, "Could not open the dep file %s\n", dep_file_name); - err+= ERR_DEP_OPEN; - } - if(err) return err; - - tranche_deps(src_file, dep_fd); - fclose(file); - close(dep_fd); - return 0; -} diff --git a/module/tranche/src/tranche-make.cli.c b/module/tranche/src/tranche-make.cli.c new file mode 100644 index 0000000..5286e3c --- /dev/null +++ b/module/tranche/src/tranche-make.cli.c @@ -0,0 +1,155 @@ +/* + +usage: + argv[0] [] [-sname ] [-sdir ] [-tdir ] [-mfile ] + +gets the names of all the targets from the source file, then appends +to the mfile a couple of lines of the form: + +... : + tranche $@ + +Our makefile is typically run in the directory above where the sources are +located. + +options + the trc file to be read +-sdir prepend to in the makefile deps line that is printed +-tdir prepend to each " +-mfile where to send the output, defaults to stdout +-sname replaces sourcename as the name to write as the source - useful for pipes + +If is not provided stdin is used. +If -mfile is not provided, stdout is used. +If -sdir is not provided, the directory part of the is used. If the +user does not want this behavior, give a value of "." for -sdir. + +*/ + +#include +#include +#include +#include "tranche.lib.h" + +int main(int argc, char **argv, char **envp){ + + char *source_file_path = 0; + char *sname = 0; + char *sdir = 0; + char *tdir = 0; + char *mfile_path = 0; + + { // argument parse + Da args; // we will queue the non option args here + Da *argsp = &args; + da_alloc(argsp, sizeof(char *)); + int args_cnt = 0; + + int err_cnt = 0; + char **pt = argv; + char *option; + char *value; // currently all our tranche options have exactly one value + while(*pt){ + if( **pt == '-' ){ + option = *pt + 1; + if(!*option){ + fprintf(stderr, "Currently there is no lone '-' option.\n"); + err_cnt++; + continue; + } + pt++; if(!*pt || **pt == '-'){ + fprintf(stderr, "Missing value for option %s.\n", option); + err_cnt++; + if(!*pt) break; + continue; + } + value = *pt; + if( !strcmp(option, "mfile") ){ + mfile_path = value; + continue; + } + if( !strcmp(option, "sdir") ){ + sdir = value; + continue; + } + if( !strcmp(option, "tdir") ){ + tdir = value; + continue; + } + if( !strcmp(option, "sname") ){ + sname = value; + continue; + } + fprintf(stderr, "Unrecognized option %s.", option); + err_cnt++; + continue; + } + da_push(argsp, pt); + arg_cnt++; + pt++; + } + if(!da_emptyq(argsp)) src_file_path = da_index(args, 0); + + // arg contracts + if(da_length(argsp) > 1){ + fprintf(stderr, "too many args/n"); + err_cnt++; + } + if(!src_file_name && !sname){ + fprintf(stderr, "must specify at least one eof a source_file_path or an sname/n"); + err_cnt++; + } + if(err_cnt > 0){ + fprintf(stderr, "usage: %s [] [-sname ] [-sdir ] [-tdir ] [-mfile ]\n", argv[0]); + return TRANCHE_ERR_ARG_PARSE; + } + + }// end of argument parse + + FILE *src_file; + int mfile_fd; + { //source and mfile open + if(!src_file_path) + src_file = stdin; + else + src_file = fopen(src_file_path, "r"); + + if(mfile_path == "") + mfile_fd = STDOUT_FILENO; + else + mfile_fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT, 0666); + + int err = 0; + if(!src_file){ + fprintf(stderr,"could not open tranche source file %s\n", src_file_path); + err+= ERR_SRC_OPEN; + } + if(mfile_fd == -1){ + fprintf(stderr, "Could not open the dep file %s\n", mfile_path); + err+= ERR_DST_OPEN; + } + if(err) return err; + } + + char *file_name_part; + if(src_file_path){ + // we are guaranteed a filename part, otherwise the fopen above would have failed + file_name_part = path_chop(src_file_path); + if(!sname) sname = file_name_part; + if(!sdir && file_name_part != src_file_path) sdir = src_file_path; // note the file name has been chopped from src_file_path + } + tranche_make(src_file, sname, mfile_fd, sdir, tdir); + + { // deallocate resources instead of just existing, so as to catch any errors + da_free(argsp); + int err_cnt = 0; + if(src_file != stdin) + if( !fclose(src_file) ){perror(); err_cnt++;} + if(mfile_fd != STDOUT_FILENO) + if( close(mfile_fd) == -1 ){perror(); err_cnt++;} + if( err_cnt ) + return TRANCHE_ERR_CLOSE; + else + return 0; + } +} diff --git a/module/tranche/src/tranche.lib.c b/module/tranche/src/tranche.lib.c index 276fa95..455c6d7 100644 --- a/module/tranche/src/tranche.lib.c +++ b/module/tranche/src/tranche.lib.c @@ -163,6 +163,7 @@ static void combine(Da *string_arrp, Da *proffered_string_arrp){ return; } +// make a list of the unique tranche target files found in src int tranche_target(FILE *src, Da *target_arrp){ char *pt; Da line; // buffer holding the characters from a line @@ -185,3 +186,84 @@ int tranche_target(FILE *src, Da *target_arrp){ da_free(&file_name_arr); return 0; } + +// Inserts a zero to chop off the filename similar to the old basename. +// Returns a pointer to the first character after the inserted zero, i.e. to the filename. +char *path_chop(char *path){ + file = path + strlen(path); + if(file == path) return file; + file--; + if(file == path){ + if(*file == '.') file++; // lone '.' case + return file; + } + file--; + if(file == path){ + if(*file == '.' && *(file+1)=='.') file+=2; // lone '..' case + return file; + } + do{ + file--; + }while(file != path && *file != '/'); + if( *file == '/' ){ + *file = 0; + file++; + } + return file; +} + +// write a make file rule for making the tranche targets +void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *sdir, char *tdir){ + + // target list + Da tarr; + Da *tarrp; // target array pointer + da_alloc(tarrp, sizeof(char *)); + tranche_target(src_file, tarrp); + + char sp = ' '; + char colon = ':'; + char slash = '/'; + char newline = '\n'; + char tab = '\t'; + char terminator = 0; + + // output the dependency line ---------------------------------------- + Da dlarr; + Da *dlarrp; // dependency line array pointer + da_alloc(dlarrp, sizeof(char)); + char *pt = tarrp->base; // char * because it points to a byte in the array + while( pt < tarrp->end ){ + if(tdir){ + da_push_string(dlarrp, tdir); + da_push(dlarrp, &slash); + } + da_push_string(dlarrp, *(char **)pt); + da_push(dlarrp, &sp); + pt += dap->element_size; + } + da_push(dlarrp, &colon); + da_push(dlarrp, &sp); + if(sdir){ + da_push_string(dlarrp, sdir); + da_push(dlarrp, &slash); + } + da_push_string(dlarrp, src_name); + da_push(dlarrp, &newline); + da_push(dlarrp, &terminator); + write(mfile_fd, dlarrp->base, dlarrp->end - dlarrp->base); + da_free_elements(tarrp); + da_free(tarrp); + + // output acction line ---------------------------------------- + da_rewind(dlarrp); // reuse the line buffer + da_push(dlarrp, &tab); + da_push_string(dlarrp, "tranche $<"); + da_push(dlarrp, &newline); + da_push(dlarrp, &newline); + da_push(dlarrp, &terminator); + write(mfile_fd, dlarrp->base, dlarrp->end - dlarrp->base); + da_free(dlarrp); + + return; +} diff --git a/module/tranche/src/tranche.lib.h b/module/tranche/src/tranche.lib.h index 4c1d2f3..4ef4840 100644 --- a/module/tranche/src/tranche.lib.h +++ b/module/tranche/src/tranche.lib.h @@ -1,12 +1,14 @@ #ifndef TRANCHE_LIB_H #define TRANCHE_LIB_H -#define TRANCHE_ERR_ARGC 1 +#define TRANCHE_ERR_ARG_PARSE 1 #define TRANCHE_ERR_SRC_OPEN 2 -#define TRANCHE_ERR_DEP_OPEN 4 +#define TRANCHE_ERR_DST_OPEN 4 +#define TRANCHE_ERR_FCLOSE 8 +char *path_chop(char *path); int tranche_send(FILE *src, Da *arg_fds); int tranche_target(FILE *src, Da *targets); - +void tranche_make(FILE *src_file, char *src_file_name, int mfile_fd, char *sdir, char *tdir); #endif