Add new XML parser from genevent
[lttv.git] / ltt / branches / poly / ltt / parser.c
index e4917ce5d2166ab3a9e6acd4ddee5626c4257c49..b4bd088b5c8fb8e22859d7e20dc6fe0c43b03a96 100644 (file)
@@ -36,13 +36,42 @@ This program is distributed in the hope that it will be useful,
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
-#include <ctype.h>
 #include <linux/errno.h>  
+#include <assert.h>
 
 
 #include "parser.h"
 
 
+/* helper function  */
+void strupper(char *string)
+{
+  char *ptr = string;
+  
+  while(*ptr != '\0') {
+    *ptr = toupper(*ptr);
+               ptr++;
+  }
+}
+
+
+int getSizeindex(int value)
+{ 
+  switch(value) {
+    case 1:
+      return 0;
+    case 2:
+      return 1;
+    case 4:
+      return 2;
+    case 8:
+      return 3;
+    default:
+      printf("Error : unknown value size %d\n", value);
+      exit(-1);
+  }
+}
+
 /*****************************************************************************
  *Function name
  *    getSize    : translate from string to integer
@@ -86,6 +115,7 @@ void error_callback(parse_file *in, char *msg)
     printf("Error in file %s, line %d: %s\n", in->name, in->lineno, msg);
   else
     printf("%s\n",msg);
+  assert(0);
   exit(1);
 }
 
@@ -130,69 +160,195 @@ char *allocAndCopy(char *str)
 
 /**************************************************************************
  * Function :
- *    getNameAttribute,getFormatAttribute,getSizeAttribute,getValueAttribute 
- *    getValueStrAttribute
+ *    getTypeAttributes
  * Description :
  *    Read the attribute from the input file.
  *
  * Parameters :
  *    in , input file handle.
- *
- * Return values :
- *    address of the attribute.
+ *    t , the type descriptor to fill.
  *
  **************************************************************************/
 
-char * getNameAttribute(parse_file *in)
+void getTypeAttributes(parse_file *in, type_descriptor *t)
 {
-  char * token, car;
-  token = getName(in);
-  if(strcmp("name",token))in->error(in,"name was expected");
-  getEqual(in);
+  char * token;
+  char car;
+
+  t->fmt = NULL;
+  t->size = -1;
+  t->alignment = 0;
   
-  car = seekNextChar(in);
-  if(car == EOF)in->error(in,"name was expected");
-  else if(car == '\"')token = getQuotedString(in);
-  else token = getName(in);
-  return token;
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+    
+    if(!strcmp("format",token)) {
+      getEqual(in);
+      t->fmt = allocAndCopy(getQuotedString(in));
+    //} else if(!strcmp("name",token)) {
+     // getEqual(in);
+     // car = seekNextChar(in);
+     // if(car == EOF) in->error(in,"name was expected");
+     // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
+     // else t->type_name = allocAndCopy(getName(in));
+    } else if(!strcmp("size",token)) {
+      getEqual(in);
+      t->size = getSize(in);
+    } else if(!strcmp("align",token)) {
+      getEqual(in);
+      t->alignment = getNumber(in);
+    }
+  }
 }
 
-char * getFormatAttribute(parse_file *in)
+/**************************************************************************
+ * Function :
+ *    getEventAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    ev , the event to fill.
+ *
+ **************************************************************************/
+
+void getEventAttributes(parse_file *in, event *ev)
 {
   char * token;
+  char car;
+  
+  ev->name = NULL;
+  ev->per_trace = 0;
+  ev->per_tracefile = 0;
+
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') ev->name = allocAndCopy(getQuotedString(in));
+      else ev->name = allocAndCopy(getName(in));
+    } else if(!strcmp("per_trace", token)) {
+      ev->per_trace = 1;
+    } else if(!strcmp("per_tracefile", token)) {
+      ev->per_tracefile = 1;
+    }
 
-  //format is an option
-  token = getToken(in); 
-  if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
-    ungetToken(in);
-    return NULL;
   }
+}
 
-  if(strcmp("format",token))in->error(in,"format was expected");
-  getEqual(in);
-  token = getQuotedString(in);
-  return token;
+/**************************************************************************
+ * Function :
+ *    getFacilityAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    fac , the facility to fill.
+ *
+ **************************************************************************/
+
+void getFacilityAttributes(parse_file *in, facility *fac)
+{
+  char * token;
+  char car;
+  
+  fac->name = NULL;
+
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') fac->name = allocAndCopy(getQuotedString(in));
+      else fac->name = allocAndCopy(getName(in));
+    }
+  }
 }
 
-int getSizeAttribute(parse_file *in)
+/**************************************************************************
+ * Function :
+ *    getFieldAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    f , the field to fill.
+ *
+ **************************************************************************/
+
+void getFieldAttributes(parse_file *in, field *f)
 {
-  /* skip name and equal */
-  getName(in);
-  getEqual(in);
+  char * token;
+  char car;
 
-  return getSize(in);
+  f->name = NULL;
+
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') f->name = allocAndCopy(getQuotedString(in));
+      else f->name = allocAndCopy(getName(in));
+    }
+  }
 }
 
-int getValueAttribute(parse_file *in)
+char *getNameAttribute(parse_file *in)
 {
-  /* skip name and equal */
-  getName(in);
-  getEqual(in);
+  char * token;
+  char *name = NULL;
+  char car;
+  
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') name = allocAndCopy(getQuotedString(in));
+      else name = allocAndCopy(getName(in));
+    }
+  }
+  if(name == NULL) in->error(in, "Name was expected");
+  return name;
   
-  return getNumber(in);
 }
 
-//for <label name=label_name value=n/>, value is an option
+
+
+//for <label name=label_name value=n format="..."/>, value is an option
 char * getValueStrAttribute(parse_file *in)
 {
   char * token;
@@ -256,12 +412,16 @@ char * getDescription(parse_file *in)
  *    fac           : facility filled with event list
  ****************************************************************************/
 
-void parseFacility(parse_file *in, facility_t * fac)
+void parseFacility(parse_file *in, facility * fac)
 {
   char * token;
-  event_t *ev;
+  event *ev;
   
-  fac->name = allocAndCopy(getNameAttribute(in));    
+  getFacilityAttributes(in, fac);
+  if(fac->name == NULL) in->error(in, "Attribute not named");
+
+  fac->capname = allocAndCopy(fac->name);
+       strupper(fac->capname);
   getRAnglebracket(in);    
   
   fac->description = getDescription(in);
@@ -274,7 +434,7 @@ void parseFacility(parse_file *in, facility_t * fac)
       in->error(in,"the definition of the facility is not finished");
 
     if(strcmp("event",token) == 0){
-      ev = (event_t*) memAlloc(sizeof(event_t));
+      ev = (event*) memAlloc(sizeof(event));
       sequence_push(&(fac->events),ev);
       parseEvent(in,ev, &(fac->unnamed_types), &(fac->named_types));    
     }else if(strcmp("type",token) == 0){
@@ -301,13 +461,15 @@ void parseFacility(parse_file *in, facility_t * fac)
  *    ev            : new event (parameters are passed to it)   
  ****************************************************************************/
 
-void parseEvent(parse_file *in, event_t * ev, sequence * unnamed_types, 
+void parseEvent(parse_file *in, event * ev, sequence * unnamed_types, 
                table * named_types) 
 {
   char *token;
+  type_descriptor *t;
 
   //<event name=eventtype_name>
-  ev->name = allocAndCopy(getNameAttribute(in));
+  getEventAttributes(in, ev);
+  if(ev->name == NULL) in->error(in, "Event not named");
   getRAnglebracket(in);  
 
   //<description>...</descriptio>
@@ -350,13 +512,14 @@ void parseFields(parse_file *in, type_descriptor *t, sequence * unnamed_types,
                 table * named_types) 
 {
   char * token;
-  type_fields *f;
+  field *f;
 
-  f = (type_fields *)memAlloc(sizeof(type_fields));
+  f = (field *)memAlloc(sizeof(field));
   sequence_push(&(t->fields),f);
 
   //<field name=field_name> <description> <type> </field>
-  f->name = allocAndCopy(getNameAttribute(in)); 
+  getFieldAttributes(in, f);
+  if(f->name == NULL) in->error(in, "Field not named");
   getRAnglebracket(in);
 
   f->description = getDescription(in);
@@ -412,6 +575,7 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
 
   if(strcmp(token,"struct") == 0) {
     t->type = STRUCT;
+    getTypeAttributes(in, t);
     getRAnglebracket(in); //<struct>
     getLAnglebracket(in); //<field name=..>
     token = getToken(in);
@@ -431,7 +595,8 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
   }
   else if(strcmp(token,"union") == 0) {
     t->type = UNION;
-    t->size = getSizeAttribute(in);
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Union has empty size");
     getRAnglebracket(in); //<union typecodesize=isize>
 
     getLAnglebracket(in); //<field name=..>
@@ -452,11 +617,12 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
   }
   else if(strcmp(token,"array") == 0) {
     t->type = ARRAY;
-    t->size = getValueAttribute(in);
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Array has empty size");
     getRAnglebracket(in); //<array size=n>
 
     getLAnglebracket(in); //<type struct> 
-    t->nested_type = parseType(in,NULL, unnamed_types, named_types);
+    t->nested_type = parseType(in, NULL, unnamed_types, named_types);
 
     getLAnglebracket(in); //</array>
     getForwardslash(in);
@@ -466,7 +632,8 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
   }
   else if(strcmp(token,"sequence") == 0) {
     t->type = SEQUENCE;
-    t->size = getSizeAttribute(in);
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Sequence has empty size");
     getRAnglebracket(in); //<array lengthsize=isize>
 
     getLAnglebracket(in); //<type struct> 
@@ -482,8 +649,10 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
     char * str, *str1;
     t->type = ENUM;
     sequence_init(&(t->labels));
-    t->size = getSizeAttribute(in);
-    t->fmt = allocAndCopy(getFormatAttribute(in));
+    sequence_init(&(t->labels_description));
+               t->already_printed = 0;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Sequence has empty size");
     getRAnglebracket(in);
 
     //<label name=label1 value=n/>
@@ -493,17 +662,22 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
       str   = allocAndCopy(getNameAttribute(in));      
       token = getValueStrAttribute(in);
       if(token){
-       str1 = appendString(str,"=");
-       free(str);
-       str = appendString(str1,token);
-       free(str1);
-       sequence_push(&(t->labels),str);
-      }else
-       sequence_push(&(t->labels),str);
+       str1 = appendString(str,"=");
+       free(str);
+       str = appendString(str1,token);
+       free(str1);
+       sequence_push(&(t->labels),str);
+      }
+      else
+       sequence_push(&(t->labels),str);
 
       getForwardslash(in);
       getRAnglebracket(in);
       
+      //read description if any. May be NULL.
+      str = allocAndCopy(getDescription(in));
+                       sequence_push(&(t->labels_description),str);
+                             
       //next label definition
       getLAnglebracket(in);
       token = getToken(in); //"label" or "/"      
@@ -511,32 +685,67 @@ type_descriptor *parseType(parse_file *in, type_descriptor *inType,
     if(strcmp("/",token))in->error(in, "not a valid enum definition");
     token = getName(in);
     if(strcmp("enum",token))in->error(in, "not a valid enum definition");
-    getRAnglebracket(in); //</label>
+      getRAnglebracket(in); //</label>
   }
   else if(strcmp(token,"int") == 0) {
     t->type = INT;
-    t->size = getSizeAttribute(in);
-    t->fmt  = allocAndCopy(getFormatAttribute(in));
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "int has empty size");
     getForwardslash(in);
     getRAnglebracket(in); 
   }
   else if(strcmp(token,"uint") == 0) {
     t->type = UINT;
-    t->size = getSizeAttribute(in);
-    t->fmt  = allocAndCopy(getFormatAttribute(in));
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "uint has empty size");
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"pointer") == 0) {
+    t->type = POINTER;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"long") == 0) {
+    t->type = LONG;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"ulong") == 0) {
+    t->type = ULONG;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"size_t") == 0) {
+    t->type = SIZE_T;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"ssize_t") == 0) {
+    t->type = SSIZE_T;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"off_t") == 0) {
+    t->type = OFF_T;
+    getTypeAttributes(in, t);
     getForwardslash(in);
     getRAnglebracket(in); 
   }
   else if(strcmp(token,"float") == 0) {
     t->type = FLOAT;
-    t->size = getSizeAttribute(in);
-    t->fmt  = allocAndCopy(getFormatAttribute(in));
+    getTypeAttributes(in, t);
     getForwardslash(in);
     getRAnglebracket(in); 
   }
   else if(strcmp(token,"string") == 0) {
     t->type = STRING;
-    t->fmt  = allocAndCopy(getFormatAttribute(in));
+    getTypeAttributes(in, t);
     getForwardslash(in);
     getRAnglebracket(in); 
   }
@@ -600,13 +809,14 @@ void parseTypeDefinition(parse_file * in, sequence * unnamed_types,
   type_descriptor *t;
 
   token = getNameAttribute(in);
+  if(token == NULL) in->error(in, "Type has empty name");
   t = find_named_type(token, named_types);
 
   if(t->type != NONE) in->error(in,"redefinition of named type");
   getRAnglebracket(in); //<type name=type_name>
-  getLAnglebracket(in); //<struct>
+  getLAnglebracket(in); //<
   token = getName(in);
-  if(strcmp("struct",token))in->error(in,"not a valid type definition");
+  //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
   ungetToken(in);
   parseType(in,t, unnamed_types, named_types);
   
@@ -820,7 +1030,7 @@ char *getToken(parse_file * in)
         in->buffer[0] = car;
         pos = 1;
         while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
-          if(!isalnum(car)) {
+          if(!(isalnum(car) || car == '_')) {
             ungetc(car,fp);
             break;
           }
@@ -898,12 +1108,12 @@ void generateChecksum( char* facName, unsigned long * checksum, sequence * event
 {
   unsigned long crc ;
   int pos;
-  event_t * ev;
+  event * ev;
   char str[256];
 
   crc = crc32(facName);
   for(pos = 0; pos < events->position; pos++){
-    ev = (event_t *)(events->array[pos]);
+    ev = (event *)(events->array[pos]);
     crc = partial_crc32(ev->name,crc);    
     if(!ev->type) continue; //event without type
     if(ev->type->type != STRUCT){
@@ -930,7 +1140,7 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
   unsigned long crc = aCrc;
   char * str = NULL, buf[16];
   int flag = 0, pos;
-  type_fields * fld;
+  field * fld;
 
   switch(type->type){
     case INT:
@@ -939,6 +1149,30 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
     case UINT:
       str = uintOutputTypes[type->size];
       break;
+    case POINTER:
+      str = allocAndCopy("void *");
+                       flag = 1;
+      break;
+    case LONG:
+      str = allocAndCopy("long");
+                       flag = 1;
+      break;
+    case ULONG:
+      str = allocAndCopy("unsigned long");
+                       flag = 1;
+      break;
+    case SIZE_T:
+      str = allocAndCopy("size_t");
+                       flag = 1;
+      break;
+    case SSIZE_T:
+      str = allocAndCopy("ssize_t");
+                       flag = 1;
+      break;
+    case OFF_T:
+      str = allocAndCopy("off_t");
+                       flag = 1;
+      break;
     case FLOAT:
       str = floatOutputTypes[type->size];
       break;
@@ -951,12 +1185,12 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
       flag = 1;
       break;
     case ARRAY:
-      sprintf(buf,"%d",type->size);
+      sprintf(buf,"%d\0",type->size);
       str = appendString("array ",buf);
       flag = 1;
       break;
     case SEQUENCE:
-      sprintf(buf,"%d",type->size);
+      sprintf(buf,"%d\0",type->size);
       str = appendString("sequence ",buf);
       flag = 1;
       break;
@@ -982,7 +1216,7 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
     crc = getTypeChecksum(crc,type->nested_type);
   }else if(type->type == STRUCT || type->type == UNION){
     for(pos =0; pos < type->fields.position; pos++){
-      fld = (type_fields *) type->fields.array[pos];
+      fld = (field *) type->fields.array[pos];
       crc = partial_crc32(fld->name,crc);
       crc = getTypeChecksum(crc, fld->type);
     }    
@@ -999,7 +1233,7 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor * type)
 void freeType(type_descriptor * tp)
 {
   int pos2;
-  type_fields *f;
+  field *f;
 
   if(tp->fmt != NULL) free(tp->fmt);
   if(tp->type == ENUM) {
@@ -1010,7 +1244,7 @@ void freeType(type_descriptor * tp)
   }
   if(tp->type == STRUCT) {
     for(pos2 = 0; pos2 < tp->fields.position; pos2++) {
-      f = (type_fields *) tp->fields.array[pos2];
+      f = (field *) tp->fields.array[pos2];
       free(f->name);
       free(f->description);
       free(f);
@@ -1034,8 +1268,9 @@ void freeNamedType(table * t)
 
 void freeTypes(sequence *t) 
 {
-  int pos;
+  int pos, pos2;
   type_descriptor *tp;
+  field *f;
 
   for(pos = 0 ; pos < t->position; pos++) {
     tp = (type_descriptor *)t->array[pos];
@@ -1047,10 +1282,10 @@ void freeTypes(sequence *t)
 void freeEvents(sequence *t) 
 {
   int pos;
-  event_t *ev;
+  event *ev;
 
   for(pos = 0 ; pos < t->position; pos++) {
-    ev = (event_t *) t->array[pos];
+    ev = (event *) t->array[pos];
     free(ev->name);
     free(ev->description);
     free(ev);
This page took 0.032452 seconds and 4 git commands to generate.