UDI/Tools - Moved udi* tools to UDI/ tree
[tpg/acess2.git] / UDI / Tools / src / udiprops.c
1 /*
2  * udibuild - UDI Compilation Utility
3  * - By John Hodge (thePowersGang)
4  *
5  * udiprops.c
6  * - udiprops.txt parsing (for udibuild only)
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <stdarg.h>
13 #include <ctype.h>
14 #include "include/udiprops.h"
15
16 // === CODE ===
17 static int _get_token_sym(const char *str, const char **outstr, ...)
18 {
19         va_list args;
20         va_start(args, outstr);
21         const char *sym;
22         for( int idx = 0; (sym = va_arg(args, const char *)); idx ++ )
23         {
24                 size_t len = strlen(sym);
25                 if( memcmp(str, sym, len) != 0 )
26                         continue ;
27                 if( str[len] && !isspace(str[len]) )
28                         continue ;
29                 
30                 // Found it!
31                 *outstr = str + len;
32                 while( isspace(**outstr) )
33                         (*outstr) ++;
34                 return idx;
35         }
36         va_end(args);
37
38         const char *end = str;
39         while( !isspace(*end) )
40                 end ++;
41 //      fprintf(stderr, "udiprops: Unknown token '%.*s'\n", end-str, str);
42
43         *outstr = NULL;
44         return -1;
45 }
46
47 static void rtrim(char *str)
48 {
49         char *pos = str;
50         while( *pos )
51                 pos ++;
52         while( pos != str && isspace(pos[-1]) )
53                 *--pos = '\0';
54 }
55
56 static char *my_strdup(const char *str)
57 {
58         char *ret = malloc(strlen(str)+1);
59         return strcpy(ret, str);
60 }
61
62 tUdiprops *Udiprops_LoadBuild(const char *Filename)
63 {
64         FILE *fp = fopen(Filename, "r");
65         if( !fp ) {
66                 perror("Udiprops_LoadBuild");
67                 return NULL;
68         }
69
70         char    *current_compile_opts = NULL;   
71          int    n_srcfiles = 0;
72         tUdiprops *ret = calloc( 1, sizeof(tUdiprops) );
73
74         char buf[512];
75         while( fgets(buf, sizeof(buf)-1, fp) )
76         {
77                 char *str = buf;
78                 {
79                         char *hash = strchr(str, '#');
80                         if( hash )      *hash = '\0';
81                 }
82                 rtrim(str);
83                 if( !str[0] )   continue ;
84                 
85                 ret->nLines ++;
86                 ret->Lines = realloc(ret->Lines, ret->nLines*sizeof(void*));
87                 ret->Lines[ret->nLines-1] = my_strdup(str);
88                 
89                 int sym = _get_token_sym(str, (const char**)&str,
90                         "source_files", "compile_options", "source_requires",
91                         "module",
92                         NULL);
93                 switch(sym)
94                 {
95                 case 0: // source_files
96                         for(char *file = strtok(str, " \t"); file; file = strtok(NULL, " \t") )
97                         {
98                                 tUdiprops_Srcfile *srcfile = malloc(sizeof(tUdiprops_Srcfile)+strlen(file)+1);
99                                 srcfile->CompileOpts = current_compile_opts;
100                                 srcfile->Filename = (void*)(srcfile+1);
101                                 strcpy((char*)srcfile->Filename, file);
102                                 
103                                 n_srcfiles ++;
104                                 ret->SourceFiles = realloc(ret->SourceFiles, n_srcfiles*sizeof(void*));
105                                 ret->SourceFiles[n_srcfiles-1] = srcfile;
106                         }
107                         break;
108                 case 1: // compile_options
109                         current_compile_opts = my_strdup(str);
110                         break;
111                 case 2: // source_requires
112                         // TODO: Use source_requires
113                         break;
114                 case 3: // module
115                         ret->ModuleName = my_strdup(str);
116                         break;
117                 }
118         }
119         
120         ret->nSourceFiles = n_srcfiles;
121         
122         // "Intentional" memory leak
123         // - current_compile_opts not freed, and shared between srcfiles
124         // - If two compile_options statements appear in a row, one is definitely leaked
125
126         fclose(fp);
127         return ret;
128 }
129

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