diff --git a/Makefile b/Makefile index 82e64b3..f62105f 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ dist: $(LN) . $(PACKAGE)-$(VERSION) @$(TAR) $(PACKAGE)-$(VERSION).tar.gz \ $(PACKAGE)-$(VERSION)/src/c99.c \ + $(PACKAGE)-$(VERSION)/src/main.c \ $(PACKAGE)-$(VERSION)/src/tokenset.c \ $(PACKAGE)-$(VERSION)/src/c99.h \ $(PACKAGE)-$(VERSION)/src/tokenset.h \ diff --git a/src/Makefile b/src/Makefile index fc28350..69cbd61 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,7 +14,7 @@ INSTALL = install all: $(TARGETS) -c99_OBJS = c99.o tokenset.o +c99_OBJS = c99.o main.o tokenset.o c99_CFLAGS = $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) c99: $(c99_OBJS) @@ -23,6 +23,9 @@ c99: $(c99_OBJS) c99.o: c99.c c99.h tokenset.h $(CC) $(c99_CFLAGS) -c c99.c +main.o: main.c c99.h + $(CC) $(c99_CFLAGS) -c main.c + tokenset.o: tokenset.c c99.h tokenset.h $(CC) $(c99_CFLAGS) -c tokenset.c diff --git a/src/c99.c b/src/c99.c index 31e4df0..814124b 100644 --- a/src/c99.c +++ b/src/c99.c @@ -13,8 +13,6 @@ * You should have received a copy of the Creative Commons Attribution- * NonCommercial-ShareAlike 3.0 along with c99; if not, browse to * http://creativecommons.org/licenses/by-nc-sa/3.0/ */ -/* FIXME: - * - place main() in main.c? */ @@ -25,27 +23,18 @@ #include #include "tokenset.h" #include "c99.h" -#include "../config.h" /* private */ /* types */ -typedef struct _Prefs +struct _C99 { - int flags; - char const * outfile; - const char ** paths; - size_t paths_cnt; - char ** defines; - size_t defines_cnt; - const char ** undefines; - size_t undefines_cnt; + int flags; /* FIXME get rid of it */ + FILE * outfp; + Cpp * cpp; + char * outfile; int optlevel; -} Prefs; -#define PREFS_c 0x1 -#define PREFS_E 0x2 -#define PREFS_g 0x4 -#define PREFS_s 0x8 +}; typedef struct _C99Operator { @@ -54,10 +43,6 @@ typedef struct _C99Operator } C99Operator; -/* prototypes */ -static int _c99(Prefs * prefs, int filec, char * filev[]); - - /* variables */ static C99Operator _operators[] = { @@ -102,105 +87,122 @@ static C99Operator _operators[] = static size_t _operators_cnt = sizeof(_operators) / sizeof(*_operators); +/* public */ /* functions */ -/* c99 */ -static int _c99_do(Prefs * prefs, FILE * outfp, char const * infile); +/* c99_new */ +static char * _new_outfile(int flags, char const * outfile, + char const * pathname); -static int _c99(Prefs * prefs, int filec, char * filev[]) +C99 * c99_new(C99Prefs * prefs, char const * pathname) { - FILE * fp = stdout; - int ret = 0; - int i; - - if(prefs->outfile != NULL && (fp = fopen(prefs->outfile, "w")) == NULL) - return error_set_print(PACKAGE, 1, "%s: %s", prefs->outfile, - strerror(errno)); - for(i = 0; i < filec; i++) - ret |= _c99_do(prefs, fp, filev[i]); - if(fp != NULL && fclose(fp) != 0) - return error_set_print(PACKAGE, 1, "%s: %s", prefs->outfile, - strerror(errno)); - if(ret != 0) - error_print(PACKAGE); - return ret; -} - -static int _c99_do_c(Prefs * prefs, FILE * outfp, char const * infile); -static int _c99_do_E(Prefs * prefs, FILE * outfp, char const * infile); -static int _c99_do_o(Prefs * prefs, FILE * outfp, char const * infile); -static int _c99_do(Prefs * prefs, FILE * outfp, char const * infile) -{ - if(prefs->flags & PREFS_c) - return _c99_do_c(prefs, outfp, infile); - else if(prefs->flags & PREFS_E) - return _c99_do_E(prefs, outfp, infile); - else - return _c99_do_o(prefs, outfp, infile); -} - -static int _c99_do_c(Prefs * prefs, FILE * outfp, char const * infile) -{ - int ret = 0; - size_t len; - char * o = NULL; - Cpp * cpp; - - if(prefs->outfile == NULL) - { - if((len = strlen(infile)) < 3 || infile[len - 2] != '.' - || infile[len - 1] != 'c') - return error_set_code(1, "%s", strerror(EINVAL)); - if((o = strdup(infile)) == NULL) - return error_set_code(1, "%s", strerror(errno)); - o[len - 1] = 'o'; - if((outfp = fopen(o, "w")) == NULL) - { - error_set_code(1, "%s: %s", o, strerror(errno)); - free(o); - return 1; - } - } - if((cpp = cpp_new(infile, CPP_FILTER_TRIGRAPH)) == NULL) - ret = 1; - else - ret = c99_parse(cpp, C99_PARSER_MODE_OBJECT); - if(o != NULL) - { - if(fclose(outfp) != 0) - ret = error_set_code(1, "%s: %s", o, strerror(errno)); - free(o); - } - return ret; -} - -static int _c99_do_E(Prefs * prefs, FILE * outfp, char const * infile) -{ - int ret; - Cpp * cpp; + C99 * c99; size_t i; size_t j; size_t k; + + if((c99 = object_new(sizeof(*c99))) == NULL) + return NULL; + c99->flags = prefs->flags; + if((c99->cpp = cpp_new(pathname, CPP_FILTER_TRIGRAPH)) == NULL) + { + object_delete(c99); + return NULL; + } + for(i = 0; i < prefs->paths_cnt; i++) + if(cpp_path_add(c99->cpp, prefs->paths[i]) != 0) + break; + for(j = 0; j < prefs->defines_cnt; j++) + if(cpp_define_add(c99->cpp, prefs->defines[j], NULL) != 0) + break; + for(k = 0; k < prefs->undefines_cnt; k++) + if(cpp_define_remove(c99->cpp, prefs->undefines[k]) != 0) + break; + c99->outfile = _new_outfile(prefs->flags, prefs->outfile, pathname); + if(c99->outfile != NULL) + c99->outfp = (c99->outfile[0] == '\0') ? stdout + : fopen(c99->outfile, "w"); + else + c99->outfp = NULL; + c99->optlevel = prefs->optlevel; + if(c99->outfile == NULL + || c99->outfp == NULL + || i != prefs->paths_cnt + || j != prefs->defines_cnt + || k != prefs->undefines_cnt) + { + c99_delete(c99); + return NULL; + } + return c99; +} + +static char * _new_outfile(int flags, char const * outfile, + char const * pathname) +{ + char * ret; + size_t len; + + if(flags & C99PREFS_c && pathname != NULL) + { + if((len = strlen(pathname)) < 3 || pathname[len - 2] != '.' + || pathname[len - 1] != 'c') + { + error_set_code(1, "%s", strerror(EINVAL)); + return NULL; + } + if((ret = strdup(pathname)) == NULL) + { + error_set_code(1, "%s", strerror(errno)); + return NULL; + } + ret[len - 1] = 'o'; + return ret; + } + if(flags & C99PREFS_E && outfile == NULL) + outfile = ""; + if((ret = strdup(outfile != NULL ? outfile : "a.out")) == NULL) + { + error_set_code(1, "%s", strerror(errno)); + return NULL; + } + return ret; +} + + +/* c99_delete */ +int c99_delete(C99 * c99) +{ + int ret = 0; + + cpp_delete(c99->cpp); + if(c99->outfp != NULL && fclose(c99->outfp) != 0) + ret = error_set_code(1, "%s: %s", c99->outfile, + strerror(errno)); + free(c99->outfile); + object_delete(c99); + return ret; +} + + +/* useful */ +/* c99_parse */ +static int _parse_E(C99 * c99); + +int c99_parse(C99 * c99) +{ + if(c99->flags & C99PREFS_E) + return _parse_E(c99); + /* FIXME implement */ + return error_set_code(1, "%s", strerror(ENOSYS)); +} + +static int _parse_E(C99 * c99) +{ + int ret; Token * token; int code; - if((cpp = cpp_new(infile, CPP_FILTER_TRIGRAPH)) == NULL) - return 1; - for(i = 0; i < prefs->paths_cnt; i++) - if(cpp_path_add(cpp, prefs->paths[i]) != 0) - break; - for(j = 0; j < prefs->defines_cnt; j++) - if(cpp_define_add(cpp, prefs->defines[j], NULL) != 0) - break; - for(k = 0; k < prefs->undefines_cnt; k++) - if(cpp_define_remove(cpp, prefs->undefines[k]) != 0) - break; - if(i != prefs->paths_cnt || j != prefs->defines_cnt - || k != prefs->undefines_cnt) - { - cpp_delete(cpp); - return 1; - } - while((ret = cpp_scan(cpp, &token)) == 0 + while((ret = cpp_scan(c99->cpp, &token)) == 0 && token != NULL) { if((code = token_get_code(token)) == CPP_CODE_META_ERROR @@ -213,34 +215,14 @@ static int _c99_do_E(Prefs * prefs, FILE * outfp, char const * infile) token_get_string(token)); else if(code >= CPP_CODE_META_FIRST && code <= CPP_CODE_META_LAST) - fprintf(outfp, "%s\n", token_get_string(token)); + fprintf(c99->outfp, "%s\n", token_get_string(token)); else - fputs(token_get_string(token), outfp); + fputs(token_get_string(token), c99->outfp); + token_delete(token); } - cpp_delete(cpp); return ret; } -static int _c99_do_o(Prefs * prefs, FILE * outfp, char const * infile) -{ - int ret; - Cpp * cpp; - - if((cpp = cpp_new(infile, CPP_FILTER_TRIGRAPH)) == NULL) - ret = 1; - else - ret = c99_parse(cpp, C99_PARSER_MODE_OBJECT); - return ret; -} - - -/* useful */ -/* c99_parse */ -int c99_parse(C99 * c99, C99ParserMode mode) -{ - return error_set_code(1, "%s", strerror(ENOSYS)); -} - /* c99_scan */ int c99_scan(C99 * c99, Token ** token) @@ -249,7 +231,7 @@ int c99_scan(C99 * c99, Token ** token) char const * string; size_t i; - if((ret = cpp_scan(c99, token)) != 0) + if((ret = cpp_scan(c99->cpp, token)) != 0) return ret; if(token == NULL) return 0; @@ -265,115 +247,3 @@ int c99_scan(C99 * c99, Token ** token) } return 0; } - - -/* usage */ -static int _usage(void) -{ - fputs("Usage: c99 [-c][-D name[=value]]...[-E][-g][-I directory]" -"[-L directory][-o outfile][-Ooptlevel][-s][-U name]... operand ...\n", stderr); - return 1; -} - - -/* public */ -/* main */ -static int _main_add_define(Prefs * prefs, char * define); -static int _main_add_path(Prefs * prefs, char const * path); -static int _main_add_undefine(Prefs * prefs, char const * undefine); - -int main(int argc, char * argv[]) -{ - Prefs prefs; - int o; - - memset(&prefs, 0, sizeof(prefs)); - while((o = getopt(argc, argv, "cD:EgI:L:o:O123sU:")) != -1) - switch(o) - { - case 'c': - prefs.flags |= PREFS_c; - break; - case 'D': - if(_main_add_define(&prefs, optarg) != 0) - return 2; - break; - case 'E': - prefs.flags |= PREFS_E; - break; - case 'I': - if(_main_add_path(&prefs, optarg) != 0) - return 2; - break; - case 'g': - prefs.flags |= PREFS_g; - break; - case 'o': - prefs.outfile = optarg; - break; - case 'O': - prefs.optlevel++; - break; - case 's': - prefs.flags |= PREFS_s; - break; - case 'U': - if(_main_add_undefine(&prefs, optarg) != 0) - return 2; - break; - case '1': - case '2': - case '3': - prefs.optlevel = o - '0'; - break; - default: - return _usage(); - } - if(optind == argc) - return _usage(); - if(prefs.flags & PREFS_c && prefs.outfile != NULL && optind + 1 != argc) - return _usage(); - return _c99(&prefs, argc - optind, &argv[optind]) == 0 ? 0 : 2; -} - -static int _main_add_define(Prefs * prefs, char * define) -{ - char ** p; - char * value; - - if(strlen(define) == 0) - return 1; - value = strtok(define, "="); - if((p = realloc(prefs->defines, sizeof(*p) * (prefs->defines_cnt + 1))) - == NULL) - return error_set_print(PACKAGE, 1, "%s", strerror(errno)); - prefs->defines = p; - prefs->defines[prefs->defines_cnt++] = define; - return 0; -} - -static int _main_add_path(Prefs * prefs, char const * path) -{ - const char ** p; - - if((p = realloc(prefs->paths, sizeof(*p) * (prefs->paths_cnt + 1))) - == NULL) - return error_set_print(PACKAGE, 1, "%s", strerror(errno)); - prefs->paths = p; - prefs->paths[prefs->paths_cnt++] = path; - return 0; -} - -static int _main_add_undefine(Prefs * prefs, char const * undefine) -{ - const char ** p; - - if(strlen(undefine) == 0) - return 1; - if((p = realloc(prefs->undefines, sizeof(*p) - * (prefs->undefines_cnt + 1))) == NULL) - return error_set_print(PACKAGE, 1, "%s", strerror(errno)); - prefs->undefines = p; - prefs->undefines[prefs->undefines_cnt++] = undefine; - return 0; -} diff --git a/src/c99.h b/src/c99.h index 14a6218..1d96b3c 100644 --- a/src/c99.h +++ b/src/c99.h @@ -19,13 +19,14 @@ #ifndef C99_C99_H # define C99_C99_H +# include # include /* C99 */ /* protected */ /* types */ -typedef Cpp C99; +typedef struct _C99 C99; typedef enum _C99Code { @@ -137,14 +138,30 @@ typedef enum _C99Code C99_CODE_KEYWORD__IMAGINARY } C99Code; -typedef enum _C99ParserMode { - C99_PARSER_MODE_OBJECT, C99_PARSER_MODE_EXECUTABLE -} C99ParserMode; +typedef struct _C99Prefs +{ + int flags; + char const * outfile; + const char ** paths; + size_t paths_cnt; + char ** defines; + size_t defines_cnt; + const char ** undefines; + size_t undefines_cnt; + int optlevel; +} C99Prefs; +# define C99PREFS_c 0x1 +# define C99PREFS_E 0x2 +# define C99PREFS_g 0x4 +# define C99PREFS_s 0x8 /* functions */ +C99 * c99_new(C99Prefs * prefs, char const * pathname); +int c99_delete(C99 * c99); + /* useful */ -int c99_parse(C99 * c99, C99ParserMode mode); +int c99_parse(C99 * c99); int c99_scan(C99 * c99, Token ** token); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..7aebc13 --- /dev/null +++ b/src/main.c @@ -0,0 +1,162 @@ +/* $Id$ */ +/* Copyright (c) 2008 Pierre Pronchery */ +/* This file is part of DeforaOS Devel c99 */ +/* c99 is not free software; you can redistribute it and/or modify it under the + * terms of the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 + * Unported as published by the Creative Commons organization. + * + * c99 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 Creative Commons Attribution-NonCommercial- + * ShareAlike 3.0 Unported license for more details. + * + * You should have received a copy of the Creative Commons Attribution- + * NonCommercial-ShareAlike 3.0 along with c99; if not, browse to + * http://creativecommons.org/licenses/by-nc-sa/3.0/ */ + + + +#include +#include +#include +#include +#include +#include "c99.h" +#include "../config.h" + + +/* c99 */ +static int _c99(C99Prefs * prefs, int filec, char * filev[]) +{ + int ret = 0; + int i; + C99 * c99; + + if(filec == 1) + { + if((c99 = c99_new(prefs, filev[0])) == NULL) + return error_print(PACKAGE); + ret = c99_parse(c99); + c99_delete(c99); + return ret; + } + for(i = 0; i < filec; i++) + { + /* FIXME implement (link edition) */ + } + return ret; +} + + +/* usage */ +static int _usage(void) +{ + fputs("Usage: c99 [-c][-D name[=value]]...[-E][-g][-I directory]" +"[-L directory][-o outfile][-Ooptlevel][-s][-U name]... operand ...\n", stderr); + return 1; +} + + +/* public */ +/* main */ +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); + +int main(int argc, char * argv[]) +{ + C99Prefs prefs; + int o; + + memset(&prefs, 0, sizeof(prefs)); + while((o = getopt(argc, argv, "cD:EgI:L:o:O123sU:")) != -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 '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 '1': + case '2': + case '3': + prefs.optlevel = o - '0'; + break; + default: + return _usage(); + } + if(optind == argc) + return _usage(); + if(prefs.flags & C99PREFS_c + && prefs.outfile != NULL + && optind + 1 != argc) + return _usage(); + return _c99(&prefs, argc - optind, &argv[optind]) == 0 ? 0 : 2; +} + +static int _main_add_define(C99Prefs * prefs, char * define) +{ + char ** p; + char * value; + + if(strlen(define) == 0) + return 1; + value = strtok(define, "="); + if((p = realloc(prefs->defines, sizeof(*p) * (prefs->defines_cnt + 1))) + == NULL) + return error_set_print(PACKAGE, 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; + + if((p = realloc(prefs->paths, sizeof(*p) * (prefs->paths_cnt + 1))) + == NULL) + return error_set_print(PACKAGE, 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; + + if(strlen(undefine) == 0) + return 1; + if((p = realloc(prefs->undefines, sizeof(*p) + * (prefs->undefines_cnt + 1))) == NULL) + return error_set_print(PACKAGE, 1, "%s", strerror(errno)); + prefs->undefines = p; + prefs->undefines[prefs->undefines_cnt++] = undefine; + return 0; +} diff --git a/src/project.conf b/src/project.conf index 32f6d24..9fc2acf 100644 --- a/src/project.conf +++ b/src/project.conf @@ -6,10 +6,13 @@ dist=c99.h,tokenset.h [c99] type=binary -sources=c99.c,tokenset.c +sources=c99.c,main.c,tokenset.c [c99.c] depends=c99.h,tokenset.h +[main.c] +depends=c99.h + [tokenset.c] depends=c99.h,tokenset.h