Date: Mon, 24 Jul 2006 21:32:37 GMT From: Spencer Whitman <swhitman@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 102315 for review Message-ID: <200607242132.k6OLWbnQ044355@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102315 Change 102315 by swhitman@swhitman_joethecat on 2006/07/24 21:32:04 More work on implementing #defines. Each #define structure has a list of arguments. Each argument has a list of offsets which indicate this argument's position in the macro value. Affected files ... .. //depot/projects/soc2006/swhitman-K_Kernel_Meta-Language/k/cpp.c#14 edit Differences ... ==== //depot/projects/soc2006/swhitman-K_Kernel_Meta-Language/k/cpp.c#14 (text+ko) ==== @@ -44,27 +44,34 @@ struct ref *r; }; -/* XXX This should prob be optimized to a tree or hash table but should work for now */ +/* XXX These should be optimized, but work for now */ + +/* Each argument has a list of indexes of where it appears in the macro string */ +struct arg_ind { + int offset; + TAILQ_ENTRY(arg_ind) list; +}; + struct macro_arg { const char *name; /* Argument name */ + TAILQ_HEAD(,arg_ind) offsets; /* Offset list */ TAILQ_ENTRY(macro_arg) list; /* Entry into the argument list */ }; -TAILQ_HEAD(args_list_head, macro_arg); /* Macro argument list head */ - #define OBJ_MAC_TYPE 0/* For object like macros (no paraens, no arguments) */ #define FUNC_MAC_TYPE 1/* For function like macros (paraens and arguments) */ #define NONE_MAC_TYPE -1/* Inital value. Indecates type was not set */ struct define { const char *name; /* Name of the macro */ int mac_type; /* Object or function like macro */ - struct args_list_head *args; /* Head of argument list */ + TAILQ_HEAD(,macro_arg) args; /* Head of argument list */ const char *value; /* Value of the macro */ TAILQ_ENTRY(define) list; /* Link to list of macros */ }; - -#define INIT_DEF_ARG(def) *((def)->args) = { NULL, ((def)->args).tqh_first } //TAILQ_HEAD_INITIALIZER((def)->args) +/* XXX Implement this */ +#define FREE_LIST(HEAD,TYPE) do { \ +}while(0) static TAILQ_HEAD(,iarg) iarg = TAILQ_HEAD_INITIALIZER(iarg); static TAILQ_HEAD(,define) define = TAILQ_HEAD_INITIALIZER(define); @@ -168,17 +175,26 @@ fprintf(stderr, "PRAGMA: <%V>\n", String(b, e)); } +#if 0 +static const char * +expand_macro(struct define * mac, struct arg_ind * head) { + +} +#endif + /* -------------------------------------------------------------------*/ static void cpp_expand(struct cppfilestate *cfs, struct ref *rr __unused, const char *s, const char *e) { - assert(s != NULL); assert(e != NULL); if (s == e) return; + + /* Expand any macro expansions before passing this to the lexer */ + D(0x10, "expand <%V>\n", String(s, e)); Lexer(cfs->h->tokens, s, e); } @@ -188,20 +204,20 @@ static struct sourcefile * cpp_include_path(const char *filename) { - struct iarg *ap; - struct sourcefile *sf; - char *q; - - sf = NULL; - TAILQ_FOREACH(ap, &iarg, list) { - asprintf(&q, "%s/%s", ap->dir, filename); - assert(q != NULL); - sf = LoadFile(q); - free(q); - if (sf != NULL) - break; - } - return (sf); + struct iarg *ap; + struct sourcefile *sf; + char *q; + + sf = NULL; + TAILQ_FOREACH(ap, &iarg, list) { + asprintf(&q, "%s/%s", ap->dir, filename); + assert(q != NULL); + sf = LoadFile(q); + free(q); + if (sf != NULL) + break; + } + return (sf); } /* @@ -254,15 +270,45 @@ cppfile(cfs->h, r); } +static void +calculate_offsets(struct macro_arg *arg, struct define * mac __unused) +{ + TAILQ_INIT(&arg->offsets); + /* XXX Use strstr to find substrings of arg in mac */ +} + -/* Pass this function a string to expand any and all macros */ -/*static void -cpp_macro_expand(const char *b __unused, const char *e __unused) +static void +add_macro_arg(const char *b, const char * e, struct define * mac) { + struct macro_arg * new_arg; + struct macro_arg * tmp; - -}*/ + new_arg = calloc(sizeof(*new_arg),1); + assert(new_arg != NULL); + + new_arg->name = String(b,e); + + printf("adding macro arg: %V\n",new_arg->name); + + TAILQ_FOREACH(tmp, &mac->args, list) { + if(tmp == NULL) { + printf("tmp == null; inserting into tail\n"); + TAILQ_INSERT_TAIL(&mac->args,new_arg,list); + } + + if(tmp->name == new_arg->name) { + free(new_arg); + errx(1, "duplicate macro parameter \"%V\"",tmp->name); + } + } + + calculate_offsets(new_arg,mac); + + printf("added argument named: <%V> to macro named <%V>\n",new_arg->name, + mac->name); +} /* * This function attempts to add a define specified by b and e to the define @@ -273,7 +319,7 @@ * are both optional. */ static void -cpp_add_define(const char *b, const char *e) +cpp_add_define(struct cppfilestate *cfs, const char *b, const char *e) { struct define *mac; struct define *tmp; @@ -327,25 +373,34 @@ break; case FUNC_MAC_TYPE: - - /* Make sure function macro is wellformed (has a matching ')', arguments - * are correct, etc.) Add arguments to mac. - */ - //INIT_DEF_ARG(mac); - //*(mac->args) = TAILQ_HEAD_INITIALIZER(*(mac->args)); - //TAILQ_INIT(mac->args); - /* do { - printf("here\n"); - ((mac->args))->tqh_first = NULL; - printf("1\n"); - (mac->args)->tqh_last = &TAILQ_FIRST((mac->args)); - printf("2\n"); - QMD_TRACE_HEAD(mac->args); - printf("3\n"); - } while (0);*/ + { + const char * arg_beg = skipspace(cfs,name_e+1,e); + + TAILQ_INIT(&mac->args); + + /* Insert each argument name. Error if list does not end with a ')' */ + /* XXX Should this detect empty arguments and non-ID like arguments? */ + for(p = arg_beg; p < e; p++) { + if (*p == ')') { + add_macro_arg(arg_beg,p,mac); + break; + } + if(*p == ',') { + add_macro_arg(arg_beg,p,mac); + p = skipspace(cfs,p+1,e); + arg_beg = p-1; + } + } + /* Macro was ill-formed. Free everything and exit with error */ + if(*p != ')') { + /* XXX Free everything */ + free(mac); + errx(1, "Function macro has no ending \')\'"); + } + mac->value = String(p,e); + } break; - default: break; } @@ -396,7 +451,7 @@ printf("#define of %V\n",String(b,e)); /* The first token is the macro name */ - cpp_add_define(skipspace(cfs, b, e),e); + cpp_add_define(cfs,skipspace(cfs, b, e),e); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607242132.k6OLWbnQ044355>