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;
// 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;
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);
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
+++ /dev/null
-/*
-Scans a tranche file and outputs a make rule for makefile-deps, of the form:
-
-<target>... : <src>
- 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 <stdio.h>
-#include <unistd.h>
-#include <da.h>
-#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 <source> [<dep-file>]\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;
-}
--- /dev/null
+/*
+
+usage:
+ argv[0] [<source_file_path>] [-sname <sname>] [-sdir <dir>] [-tdir <dir>] [-mfile <mfile_path>]
+
+gets the names of all the targets from the source file, then appends
+to the mfile a couple of lines of the form:
+
+<target>... : <src>
+ tranche $@
+
+Our makefile is typically run in the directory above where the sources are
+located.
+
+options
+<source_file_path> the trc file to be read
+-sdir <sdir> prepend <sdir> to <src> in the makefile deps line that is printed
+-tdir <tdir> prepend <tdir> to each <target> "
+-mfile <mfile_path> where to send the output, defaults to stdout
+-sname <sname> replaces sourcename as the name to write as the source - useful for pipes
+
+If <source_file_path> is not provided stdin is used.
+If -mfile is not provided, stdout is used.
+If -sdir is not provided, the directory part of the <source_file_path> is used. If the
+user does not want this behavior, give a value of "." for -sdir.
+
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <da.h>
+#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 [<source_file_path>] [-sname <sname>] [-sdir <dir>] [-tdir <dir>] [-mfile <mfile_path>]\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;
+ }
+}
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
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;
+}
#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