ff6b8f438a6fc1b798b69756bbc388b4342b0e10
[tpg/acess2.git] / Tools / udibuild / src / main.c
1 /*
2  * udibuild - UDI Compilation Utility
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - Core
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>     // getopt
11 #include <getopt.h>
12 #include <string.h>     // strrchr
13 #include <assert.h>
14 #include "include/common.h"
15 #include "include/build.h"
16 #include "include/inifile.h"
17 #include "include/udiprops.h"
18
19 #define CONFIG_FILENAME "udibuild.ini"
20 #ifdef __ACESS__
21 #define RUNTIME_DIR     "/Acess/Conf/UDI"
22 #else
23 #define RUNTIME_DIR     "/etc/udi"
24 #endif
25
26 // === PROTOTYPES ===
27  int    main(int argc, char *argv[]);
28  int    ParseArguments(int argc, char *argv[]);
29 void    Usage(const char *progname);
30
31 // === GLOBALS ===
32 const char *gsRuntimeDir = RUNTIME_DIR;
33 const char *gsOpt_ConfigFile;
34 const char *gsOpt_WorkingDir;
35 const char *gsOpt_UdipropsFile;
36 const char *gsOpt_ABIName = "ia32";
37 tIniFile        *gpOptions;
38 tUdiprops       *gpUdipropsBuild;
39
40 // === CODE ===
41 int main(int argc, char *argv[])
42 {
43         if( ParseArguments(argc, argv) ) {
44                 return 1;
45         }
46
47         // Locate udibuild.ini
48         // 1. Check CWD
49         if( !gsOpt_ConfigFile ) {
50                 //if( file_exists("./udibuild.ini") )
51                 //{
52                 //      gsOpt_ConfigFile = "udibuild.ini";
53                 //}
54         }
55         // 2. Check program dir (if not invoked from PATH)
56         if( !gsOpt_ConfigFile && (argv[0][0] == '.' || argv[0][0] == '/') ) {
57                 char *last_slash = strrchr(argv[0], '/');
58                 if( last_slash ) {
59                         gsOpt_ConfigFile = mkstr("%.*s/%s",
60                                 last_slash-argv[0], argv[0], CONFIG_FILENAME);
61                 }
62                 //if( !file_exists(gsOpt_ConfigFile) ) {
63                 //      free(gsOpt_ConfigFile);
64                 //      gsOpt_ConfigFile = NULL;
65                 //}
66         }
67         // 3. Check ~/.config/udi/udibuild.ini
68         // 4. Check RUNTIME_DIR/udibuild.ini
69
70         // #. Oh well   
71         if( !gsOpt_ConfigFile ) {
72                 fprintf(stderr, "Can't locate "CONFIG_FILENAME" file, please specify using '-c'\n");
73                 exit(2);
74         }
75         
76         // Load udibuild.ini
77         gpOptions = IniFile_Load(gsOpt_ConfigFile);
78         assert(gpOptions);
79
80         // Change to working directory (-C <dir>)
81         if( gsOpt_WorkingDir )
82         {
83                 chdir(gsOpt_WorkingDir);
84         }
85
86         // Load udiprops
87         gpUdipropsBuild = Udiprops_LoadBuild( gsOpt_UdipropsFile ? gsOpt_UdipropsFile : "udiprops.txt" );
88         assert(gpUdipropsBuild);
89         assert(gpUdipropsBuild->SourceFiles);
90
91         // Do build
92         for( int i = 0; i < gpUdipropsBuild->nSourceFiles; i ++ )
93         {
94                 int rv = Build_CompileFile(gpOptions, gsOpt_ABIName, gpUdipropsBuild,
95                         gpUdipropsBuild->SourceFiles[i]);
96                 if( rv ) {
97                         fprintf(stderr, "*** Exit status: %i\n", rv);
98                         return rv;
99                 }
100         }
101         Build_LinkObjects(gpOptions, gsOpt_ABIName, gpUdipropsBuild);
102
103         return 0;
104 }
105
106 int ParseArguments(int argc, char *argv[])
107 {
108          int    opt;
109         while( (opt = getopt(argc, argv, "hC:c:f:a:")) != -1 )
110         {
111                 switch(opt)
112                 {
113                 case 'h':
114                         Usage(argv[0]);
115                         exit(0);
116                 case 'C':
117                         gsOpt_WorkingDir = optarg;
118                         break;
119                 case 'c':
120                         gsOpt_ConfigFile = optarg;
121                         break;
122                 case 'f':
123                         gsOpt_UdipropsFile = optarg;
124                         break;
125                 case 'a':
126                         gsOpt_ABIName = optarg;
127                         break;
128                 case '?':
129                         Usage(argv[0]);
130                         return 1;
131                 default:
132                         fprintf(stderr, "BUG: Unhandled optarg %i '%c'\n", opt, opt);
133                         break;
134                 }
135         }
136         return 0;
137 }
138
139 void Usage(const char *progname)
140 {
141         fprintf(stderr, "Usage: %s [-C workingdir] [-c udibuild.ini] [-f udiprops.txt] [-a abiname]\n",
142                 progname);
143         fprintf(stderr, "\n"
144                 "-C workingdir   : Change to the specified directory before looking for udiprops.txt\n"
145                 "-c udibuild.ini : Override the default udibuild config file\n"
146                 "-f udiprops.txt : Override the default udiprops file\n"
147                 "-a abiname      : Select a different ABI\n"
148                 "\n");
149 }
150
151 char *mkstr(const char *fmt, ...)
152 {
153         va_list args;
154         va_start(args, fmt);
155         size_t len = vsnprintf(NULL, 0, fmt, args);
156         va_end(args);
157         va_start(args, fmt);
158         char *ret = malloc(len+1);
159         vsnprintf(ret, len+1, fmt, args);
160         va_end(args);
161         return ret;
162 }
163

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