tranche-make draft
authorThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Fri, 29 Mar 2019 21:14:24 +0000 (22:14 +0100)
committerThomas Walker Lynch <thomas.lynch@reasoningtechnology.com>
Fri, 29 Mar 2019 21:14:24 +0000 (22:14 +0100)
module/da/src/da.lib.c
module/da/src/da.lib.h
module/share/include/da.h
module/share/lib/libda.a
module/tranche/src/tranche-make.c [deleted file]
module/tranche/src/tranche-make.cli.c [new file with mode: 0644]
module/tranche/src/tranche.lib.c
module/tranche/src/tranche.lib.h

index 47558e0..7fa384a 100644 (file)
@@ -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;
index d480d8c..189ee50 100644 (file)
@@ -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);
index 6d3c43b..189ee50 100644 (file)
@@ -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
index ba48a6e..49ece65 100644 (file)
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 (file)
index 2f84d0f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-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;
-}
diff --git a/module/tranche/src/tranche-make.cli.c b/module/tranche/src/tranche-make.cli.c
new file mode 100644 (file)
index 0000000..5286e3c
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+
+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;
+  }
+}
index 276fa95..455c6d7 100644 (file)
@@ -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;
+}
index 4c1d2f3..4ef4840 100644 (file)
@@ -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