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