PERFORCE change 102315 for review
Spencer Whitman
swhitman at FreeBSD.org
Mon Jul 24 21:32:38 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=102315
Change 102315 by swhitman at 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);
}
More information about the p4-projects
mailing list