/* $Id$ */ /* Copyright (c) 2008-2014 Pierre Pronchery */ /* This file is part of DeforaOS Devel c99 */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include "../include/C99/c99.h" /* constants */ #ifndef PROGNAME # define PROGNAME "c99" #endif /* c99 */ /* private */ /* prototypes */ static int _c99(C99Prefs * prefs, int filec, char * filev[]); static int _usage(void); /* functions */ /* c99 */ static int _c99(C99Prefs * prefs, int filec, char * filev[]) { int ret = 0; size_t len; int i; C99 * c99; if(filec == 1 && (len = strlen(filev[0])) > 2 && filev[0][len - 2] == '.' && filev[0][len - 1] == 'c') { if((c99 = c99_new(prefs, filev[0])) == NULL) return error_print(PROGNAME); ret = c99_parse(c99); c99_delete(c99); return ret; } /* link time */ for(i = 0; i < filec; i++) { /* FIXME implement */ } return ret; } /* usage */ static int _usage(void) { fputs("Usage: " PROGNAME " [-D name[=value]]... [-E][-g]" "[-I directory][-L directory]\n" " [-m name[=value]]... [-o outfile][-Ooptlevel][-s][-U name]...\n" " filename...\n" " " PROGNAME " -c [-D name[=value]]... [-E][-g]" "[-I directory][-L directory]\n" " [-m name[=value]]... [-o outfile][-Ooptlevel][-s][-U name]...\n" " filename...\n", stderr); return 1; } /* public */ /* main */ static int _main_default_paths(C99Prefs * prefs); static int _main_add_define(C99Prefs * prefs, char * define); static int _main_add_path(C99Prefs * prefs, char const * path); static int _main_add_undefine(C99Prefs * prefs, char const * undefine); static int _main_add_option(C99Prefs * prefs, char const * option); int main(int argc, char * argv[]) { int ret; C99Prefs prefs; int o; memset(&prefs, 0, sizeof(prefs)); if(_main_default_paths(&prefs) != 0) return 2; while((o = getopt(argc, argv, "cD:EgI:L:m:M:o:O123sU:W")) != -1) switch(o) { case 'c': prefs.flags |= C99PREFS_c; break; case 'D': if(_main_add_define(&prefs, optarg) != 0) return 2; break; case 'E': prefs.flags |= C99PREFS_E; break; case 'I': if(_main_add_path(&prefs, optarg) != 0) return 2; break; case 'g': prefs.flags |= C99PREFS_g; break; case 'm': if(_main_add_option(&prefs, optarg) != 0) return 2; break; case 'M': prefs.target = optarg; break; case 'o': prefs.outfile = optarg; break; case 'O': prefs.optlevel++; break; case 's': prefs.flags |= C99PREFS_s; break; case 'U': if(_main_add_undefine(&prefs, optarg) != 0) return 2; break; case 'W': prefs.warn = 1; break; case '1': case '2': case '3': prefs.optlevel = o - '0'; break; default: return _usage(); } if(optind == argc) ret = _usage(); else if(prefs.flags & C99PREFS_c && prefs.outfile != NULL && optind + 1 != argc) ret = _usage(); else { ret = _c99(&prefs, argc - optind, &argv[optind]); ret = (ret == 0) ? 0 : 2; } free(prefs.paths); free(prefs.defines); free(prefs.undefines); return ret; } static int _main_default_paths(C99Prefs * prefs) { char * paths[] = { "/usr/include" }; size_t i; char * cpath; for(i = 0; i < (sizeof(paths) / sizeof(*paths)); i++) if(_main_add_path(prefs, paths[i]) != 0) return 2; if((cpath = getenv("CPATH")) == NULL) return 0; while((cpath = strtok(cpath, ":")) != NULL) if(_main_add_path(prefs, cpath) != 0) return 2; else cpath = NULL; return 0; } static int _main_add_define(C99Prefs * prefs, char * define) { char ** p; char * value; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, define); #endif if(strlen(define) == 0) return _usage(); value = strtok(define, "="); if((p = realloc(prefs->defines, sizeof(*p) * (prefs->defines_cnt + 1))) == NULL) return error_set_print(PROGNAME, 1, "%s", strerror(errno)); prefs->defines = p; prefs->defines[prefs->defines_cnt++] = define; return 0; } static int _main_add_path(C99Prefs * prefs, char const * path) { const char ** p; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, path); #endif if((p = realloc(prefs->paths, sizeof(*p) * (prefs->paths_cnt + 1))) == NULL) return error_set_print(PROGNAME, 1, "%s", strerror(errno)); prefs->paths = p; prefs->paths[prefs->paths_cnt++] = path; return 0; } static int _main_add_undefine(C99Prefs * prefs, char const * undefine) { const char ** p; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, undefine); #endif if(strlen(undefine) == 0) return 1; if((p = realloc(prefs->undefines, sizeof(*p) * (prefs->undefines_cnt + 1))) == NULL) return error_set_print(PROGNAME, 1, "%s", strerror(errno)); prefs->undefines = p; prefs->undefines[prefs->undefines_cnt++] = undefine; return 0; } static int _main_add_option(C99Prefs * prefs, char const * option) { C99Option * p; char * q; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, option); #endif if(strlen(option) == 0) return 1; if((p = realloc(prefs->options, sizeof(*p) * (prefs->options_cnt + 1))) == NULL) return error_set_print(PROGNAME, 1, "%s", strerror(errno)); prefs->options = p; p = &prefs->options[prefs->options_cnt]; if((p->name = string_new(option)) == NULL) return 1; p->value = NULL; if((q = strstr(p->name, "=")) != NULL) { *q = '\0'; p->value = q + 1; } prefs->options_cnt++; return 0; }