UDI/Tools - Moved udi* tools to UDI/ tree
[tpg/acess2.git] / UDI / Tools / src / udiprops.c
diff --git a/UDI/Tools/src/udiprops.c b/UDI/Tools/src/udiprops.c
new file mode 100644 (file)
index 0000000..f6a9bfc
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * udibuild - UDI Compilation Utility
+ * - By John Hodge (thePowersGang)
+ *
+ * udiprops.c
+ * - udiprops.txt parsing (for udibuild only)
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "include/udiprops.h"
+
+// === CODE ===
+static int _get_token_sym(const char *str, const char **outstr, ...)
+{
+       va_list args;
+       va_start(args, outstr);
+       const char *sym;
+       for( int idx = 0; (sym = va_arg(args, const char *)); idx ++ )
+       {
+               size_t len = strlen(sym);
+               if( memcmp(str, sym, len) != 0 )
+                       continue ;
+               if( str[len] && !isspace(str[len]) )
+                       continue ;
+               
+               // Found it!
+               *outstr = str + len;
+               while( isspace(**outstr) )
+                       (*outstr) ++;
+               return idx;
+       }
+       va_end(args);
+
+       const char *end = str;
+       while( !isspace(*end) )
+               end ++;
+//     fprintf(stderr, "udiprops: Unknown token '%.*s'\n", end-str, str);
+
+       *outstr = NULL;
+       return -1;
+}
+
+static void rtrim(char *str)
+{
+       char *pos = str;
+       while( *pos )
+               pos ++;
+       while( pos != str && isspace(pos[-1]) )
+               *--pos = '\0';
+}
+
+static char *my_strdup(const char *str)
+{
+       char *ret = malloc(strlen(str)+1);
+       return strcpy(ret, str);
+}
+
+tUdiprops *Udiprops_LoadBuild(const char *Filename)
+{
+       FILE *fp = fopen(Filename, "r");
+       if( !fp ) {
+               perror("Udiprops_LoadBuild");
+               return NULL;
+       }
+
+       char    *current_compile_opts = NULL;   
+        int    n_srcfiles = 0;
+       tUdiprops *ret = calloc( 1, sizeof(tUdiprops) );
+
+       char buf[512];
+       while( fgets(buf, sizeof(buf)-1, fp) )
+       {
+               char *str = buf;
+               {
+                       char *hash = strchr(str, '#');
+                       if( hash )      *hash = '\0';
+               }
+               rtrim(str);
+               if( !str[0] )   continue ;
+               
+               ret->nLines ++;
+               ret->Lines = realloc(ret->Lines, ret->nLines*sizeof(void*));
+               ret->Lines[ret->nLines-1] = my_strdup(str);
+               
+               int sym = _get_token_sym(str, (const char**)&str,
+                       "source_files", "compile_options", "source_requires",
+                       "module",
+                       NULL);
+               switch(sym)
+               {
+               case 0: // source_files
+                       for(char *file = strtok(str, " \t"); file; file = strtok(NULL, " \t") )
+                       {
+                               tUdiprops_Srcfile *srcfile = malloc(sizeof(tUdiprops_Srcfile)+strlen(file)+1);
+                               srcfile->CompileOpts = current_compile_opts;
+                               srcfile->Filename = (void*)(srcfile+1);
+                               strcpy((char*)srcfile->Filename, file);
+                               
+                               n_srcfiles ++;
+                               ret->SourceFiles = realloc(ret->SourceFiles, n_srcfiles*sizeof(void*));
+                               ret->SourceFiles[n_srcfiles-1] = srcfile;
+                       }
+                       break;
+               case 1: // compile_options
+                       current_compile_opts = my_strdup(str);
+                       break;
+               case 2: // source_requires
+                       // TODO: Use source_requires
+                       break;
+               case 3: // module
+                       ret->ModuleName = my_strdup(str);
+                       break;
+               }
+       }
+       
+       ret->nSourceFiles = n_srcfiles;
+       
+       // "Intentional" memory leak
+       // - current_compile_opts not freed, and shared between srcfiles
+       // - If two compile_options statements appear in a row, one is definitely leaked
+
+       fclose(fp);
+       return ret;
+}
+

UCC git Repository :: git.ucc.asn.au