From: compudj Date: Wed, 9 Nov 2005 01:22:47 +0000 (+0000) Subject: progress X-Git-Tag: v0.12.20~2178 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=2d2d14a73451144b1f67fb64191a6cef99b90a26;p=lttv.git progress git-svn-id: http://ltt.polymtl.ca/svn@1311 04897980-b3bd-0310-b5e0-8ef037075253 --- diff --git a/genevent-new/Makefile b/genevent-new/Makefile index d106fb0f..44030d89 100644 --- a/genevent-new/Makefile +++ b/genevent-new/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/sh CC = gcc -CFLAGS = -Wall -g +CFLAGS = -std=c99 -Wall -g -DDEBUG all: genevent diff --git a/genevent-new/genevent.c b/genevent-new/genevent.c index 7b141a57..92342a66 100644 --- a/genevent-new/genevent.c +++ b/genevent-new/genevent.c @@ -55,6 +55,9 @@ * to know the structure's alignment. */ +#define _GNU_SOURCE +#include +#include #include #include #include @@ -62,7 +65,7 @@ #include #include #include -#include +#include #include "genevent.h" #include "parser.h" @@ -71,9 +74,29 @@ #define TRUE 1 #define FALSE (!TRUE) +/* Debugging printf */ +#ifdef DEBUG +#define dprintf(...) \ + do {\ + printf(__FILE__ ",%u,%s: ",\ + __LINE__, __func__);\ + printf(__VA_ARGS__);\ + } while(0) +#else +#define dprintf(...) +#endif + + /* Code printing */ +void print_tabs(unsigned int tabs, FILE *fd) +{ + for(unsigned int i = 0; itype_name != NULL) { + strncpy(basename, td->type_name, PATH_MAX); + basename_len = strlen(basename); + } else { + /* For a unnamed type, there must be a field name */ + if(basename_len != 0) { + strncat(basename, "_", PATH_MAX - basename_len); + basename_len = strlen(basename); + } + strncat(basename, field_name, PATH_MAX - basename_len); + } + + switch(td->type) { + case INT_FIXED: + fprintf(fd, "%s", intOutputTypes[getSizeindex(td->size)]); + break; + case UINT_FIXED: + fprintf(fd, "%s", uintOutputTypes[getSizeindex(td->size)]); + break; + case CHAR: + fprintf(fd, "signed char"); + break; + case UCHAR: + fprintf(fd, "unsigned char"); + break; + case SHORT: + fprintf(fd, "short"); + break; + case USHORT: + fprintf(fd, "unsigned short"); + break; + case INT: + fprintf(fd, "int"); + break; + case UINT: + fprintf(fd, "unsigned int"); + break; + case FLOAT: + fprintf(fd, "%s", floatOutputTypes[getSizeindex(td->size)]); + break; + case POINTER: + fprintf(fd, "void *"); + break; + case LONG: + fprintf(fd, "long"); + break; + case ULONG: + fprintf(fd, "unsigned long"); + break; + case SIZE_T: + fprintf(fd, "size_t"); + break; + case SSIZE_T: + fprintf(fd, "ssize_t"); + break; + case OFF_T: + fprintf(fd, "off_t"); + break; + case STRING: + fprintf(fd, "char *"); + break; + case ENUM: + fprintf(fd, "enum lttng_%s", basename); + break; + case ARRAY: + fprintf(fd, "lttng_array_%s", basename); + break; + case SEQUENCE: + fprintf(fd, "lttng_sequence_%s", basename); + break; + case STRUCT: + fprintf(fd, "struct lttng_%s", basename); + break; + case UNION: + fprintf(fd, "union lttng_%s", basename); + break; + default: + printf("print_type : unknown type\n"); + return 1; + } + + return 0; +} + +/* print type declaration. + * + * Copied from construct_types_and_fields in LTTV facility.c */ + +int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs, + char *nest_name, char *field_name) +{ + char basename[PATH_MAX]; + unsigned int basename_len = 0; + + strcpy(basename, nest_name); + basename_len = strlen(basename); + + /* For a named type, we use the type_name directly */ + if(td->type_name != NULL) { + strncpy(basename, td->type_name, PATH_MAX); + basename_len = strlen(basename); + } else { + /* For a unnamed type, there must be a field name */ + if(basename_len != 0) { + strncat(basename, "_", PATH_MAX - basename_len); + basename_len = strlen(basename); + } + strncat(basename, field_name, PATH_MAX - basename_len); + dprintf("%s\n", field_name); + } + + switch(td->type) { + case ENUM: + fprintf(fd, "enum lttng_%s", basename); + fprintf(fd, " {\n"); + for(unsigned int i=0;ilabels.position;i++){ + print_tabs(1, fd); + fprintf(fd, "LTTNG_%s", ((char*)(td->labels.array[i]))); + fprintf(fd, ",\n"); + } + fprintf(fd, "};\n"); + fprintf(fd, "\n"); + break; + + case ARRAY: + assert(td->size >= 0); + if(td->nested_type->type_name == NULL) { + /* Not a named nested type : we must print its declaration first */ + if(print_type_declaration(td->nested_type, + fd, 0, basename, "")) return 1; + } + fprintf(fd, "#define LTTNG_ARRAY_SIZE_%s %llu\n", basename, + td->size); + print_type(td->nested_type, fd, tabs, basename, ""); + fprintf(fd, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename, + basename); + fprintf(fd, "\n"); + break; + case SEQUENCE: + if(td->nested_type->type_name == NULL) { + /* Not a named nested type : we must print its declaration first */ + if(print_type_declaration(td->nested_type, + fd, 0, basename, "")) return 1; + } + fprintf(fd, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n", + basename, + basename); + fprintf(fd, "struct lttng_sequence_%s", basename); + fprintf(fd, " {\n"); + print_tabs(1, fd); + fprintf(fd, "unsigned int len;\n"); + print_tabs(1, fd); + print_type(td->nested_type, fd, tabs, basename, ""); + fprintf(fd, " *array;\n"); + fprintf(fd, "};\n"); + fprintf(fd, "\n"); + break; + + case STRUCT: + for(unsigned int i=0;ifields.position;i++){ + field_t *field = (field_t*)(td->fields.array[i]); + type_descriptor_t *type = field->type; + if(type->type_name == NULL) { + /* Not a named nested type : we must print its declaration first */ + if(print_type_declaration(type, + fd, 0, basename, field->name)) return 1; + } + } + fprintf(fd, "struct lttng_%s", basename); + fprintf(fd, " {\n"); + for(unsigned int i=0;ifields.position;i++){ + field_t *field = (field_t*)(td->fields.array[i]); + type_descriptor_t *type = field->type; + print_tabs(1, fd); + print_type(type, fd, tabs, basename, field->name); + fprintf(fd, " "); + fprintf(fd, "%s", field->name); + fprintf(fd, ";\n"); + } + fprintf(fd, "};\n"); + fprintf(fd, "\n"); + break; + case UNION: + /* TODO : Do not allow variable length fields in a union */ + for(unsigned int i=0;ifields.position;i++){ + field_t *field = (field_t*)(td->fields.array[i]); + type_descriptor_t *type = field->type; + if(type->type_name == NULL) { + /* Not a named nested type : we must print its declaration first */ + //if(print_type_declaration(type, + // fd, 0, basename, field->name)) return 1; + } + } + fprintf(fd, "union lttng_%s", basename); + fprintf(fd, " {\n"); + for(unsigned i=0;ifields.position;i++){ + field_t *field = (field_t*)(td->fields.array[i]); + type_descriptor_t *type = field->type; + print_tabs(1, fd); + print_type(type, fd, tabs, basename, field->name); + fprintf(fd, " "); + fprintf(fd, "%s", field->name); + fprintf(fd, ";\n"); + } + fprintf(fd, "};\n"); + fprintf(fd, "\n"); + break; + default: + dprintf("print_type_declaration : unknown type or nothing to declare.\n"); + break; + } + + return 0; +} + + + + +/* ltt-facility-name.h : main logging header. + * log_header */ + +void print_log_header_head(facility_t *fac, FILE *fd) +{ + fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname); + fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname); +} + + + + +int print_log_header_types(facility_t *fac, FILE *fd) +{ + sequence_t *types = &fac->named_types.values; + fprintf(fd, "/* Named types */\n"); + fprintf(fd, "\n"); + + for(unsigned int i = 0; i < types->position; i++) { + /* For each named type, print the definition */ + if((print_type_declaration(types->array[i], fd, + 0, "", ""))) return 1; + } + return 0; +} + +int print_log_header_events(facility_t *fac, FILE *fd) +{ + + return 0; +} + + +void print_log_header_tail(facility_t *fac, FILE *fd) +{ + fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname); +} + +int print_log_header(facility_t *fac) +{ + char filename[PATH_MAX]; + unsigned int filename_size = 0; + FILE *fd; + dprintf("%s\n", fac->name); + + strcpy(filename, "ltt-facility-"); + filename_size = strlen(filename); + + strncat(filename, fac->name, PATH_MAX - filename_size); + filename_size = strlen(filename); + + strncat(filename, ".h", PATH_MAX - filename_size); + filename_size = strlen(filename); + + + fd = fopen(filename, "w"); + if(fd == NULL) { + printf("Error opening file %s for writing : %s\n", + filename, strerror(errno)); + return errno; + } + + /* Print file head */ + print_log_header_head(fac, fd); + + /* print named types in declaration order */ + if(print_log_header_types(fac, fd)) return 1; + + /* Print events */ + if(print_log_header_events(fac, fd)) return 1; + + /* Print file tail */ + print_log_header_tail(fac, fd); + + + fclose(fd); + + return 0; +} + + +/* ltt-facility-id-name.h : facility id. + * log_id_header */ +int print_id_header(facility_t *fac) +{ + char filename[PATH_MAX]; + unsigned int filename_size = 0; + FILE *fd; + dprintf("%s\n", fac->name); + + strcpy(filename, "ltt-facility-id-"); + filename_size = strlen(filename); + + strncat(filename, fac->name, PATH_MAX - filename_size); + filename_size = strlen(filename); + + strncat(filename, ".h", PATH_MAX - filename_size); + filename_size = strlen(filename); + + + fd = fopen(filename, "w"); + if(fd == NULL) { + printf("Error opening file %s for writing : %s\n", + filename, strerror(errno)); + return errno; + } + + fclose(fd); + + return 0; +} + + +/* ltt-facility-loader-name.h : facility specific loader info. + * loader_header */ +int print_loader_header(facility_t *fac) +{ + char filename[PATH_MAX]; + unsigned int filename_size = 0; + FILE *fd; + dprintf("%s\n", fac->name); + + strcpy(filename, "ltt-facility-loader-"); + filename_size = strlen(filename); + + strncat(filename, fac->name, PATH_MAX - filename_size); + filename_size = strlen(filename); + + strncat(filename, ".h", PATH_MAX - filename_size); + filename_size = strlen(filename); + + + fd = fopen(filename, "w"); + if(fd == NULL) { + printf("Error opening file %s for writing : %s\n", + filename, strerror(errno)); + return errno; + } + + fclose(fd); + + return 0; +} + +/* ltt-facility-loader-name.c : generic faciilty loader + * loader_c */ +int print_loader_c(facility_t *fac) +{ + char filename[PATH_MAX]; + unsigned int filename_size = 0; + FILE *fd; + dprintf("%s\n", fac->name); + + strcpy(filename, "ltt-facility-loader-"); + filename_size = strlen(filename); + + strncat(filename, fac->name, PATH_MAX - filename_size); + filename_size = strlen(filename); + + strncat(filename, ".c", PATH_MAX - filename_size); + filename_size = strlen(filename); + + + fd = fopen(filename, "w"); + if(fd == NULL) { + printf("Error opening file %s for writing : %s\n", + filename, strerror(errno)); + return errno; + } + + + fclose(fd); + + return 0; +} + + + /* open facility */ /* code taken from ltt_facility_open in ltt/facility.c in lttv */ @@ -241,17 +674,25 @@ int main(int argc, char **argv) /* generate the output C files */ - /* ltt-facility-name.h : main logging header */ - + /* ltt-facility-name.h : main logging header. + * log_header */ + err = print_log_header(fac); + if(err) return err; - /* ltt-facility-id-name.h : facility id. */ + /* ltt-facility-id-name.h : facility id. + * log_id_header */ + err = print_id_header(fac); + if(err) return err; - - /* ltt-facility-loader-name.h : facility specific loader info. */ - - /* ltt-facility-loader-name.c : generic faciilty loader */ - - + /* ltt-facility-loader-name.h : facility specific loader info. + * loader_header */ + err = print_loader_header(fac); + if(err) return err; + + /* ltt-facility-loader-name.c : generic faciilty loader + * loader_c */ + err = print_loader_c(fac); + if(err) return err; /* close the facility */ ltt_facility_close(fac); diff --git a/genevent-new/parser.c b/genevent-new/parser.c index 795b3f96..638aa5ab 100644 --- a/genevent-new/parser.c +++ b/genevent-new/parser.c @@ -43,15 +43,14 @@ This program is distributed in the hope that it will be useful, #include "parser.h" -static char *intOutputTypes[] = { - "int8_t", "int16_t", "int32_t", "int64_t", "short int", "int", "long int" }; +char *intOutputTypes[] = { + "int8_t", "int16_t", "int32_t", "int64_t" }; -static char *uintOutputTypes[] = { - "uint8_t", "uint16_t", "uint32_t", "uint64_t", "unsigned short int", - "unsigned int", "unsigned long int" }; +char *uintOutputTypes[] = { + "uint8_t", "uint16_t", "uint32_t", "uint64_t" }; -static char *floatOutputTypes[] = { - "undef", "undef", "float", "double", "undef", "float", "double" }; +char *floatOutputTypes[] = { + "undef", "undef", "float", "double" }; @@ -68,7 +67,7 @@ void strupper(char *string) } -int getSizeindex(int value) +int getSizeindex(unsigned int value) { switch(value) { case 1: @@ -94,21 +93,13 @@ int getSizeindex(int value) * size *****************************************************************************/ -int getSize(parse_file_t *in) +unsigned long long int getSize(parse_file_t *in) { char *token; token = getToken(in); if(in->type == NUMBER) { - if(strcmp(token,"1") == 0) return 0; - else if(strcmp(token,"2") == 0) return 1; - else if(strcmp(token,"4") == 0) return 2; - else if(strcmp(token,"8") == 0) return 3; - } - else if(in->type == NAME) { - if(strcmp(token,"short") == 0) return 4; - else if(strcmp(token,"medium") == 0) return 5; - else if(strcmp(token,"long") == 0) return 6; + return strtoull(token, NULL, 0); } in->error(in,"incorrect size specification"); return -1; @@ -188,7 +179,7 @@ void getTypeAttributes(parse_file_t *in, type_descriptor_t *t) char * token; t->fmt = NULL; - t->size = -1; + t->size = 0; t->alignment = 0; while(1) { @@ -207,7 +198,7 @@ void getTypeAttributes(parse_file_t *in, type_descriptor_t *t) // 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)) { + } else if(!strcmp("size",token) || !strcmp("lengthsize", token)) { getEqual(in); t->size = getSize(in); } else if(!strcmp("align",token)) { @@ -608,8 +599,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, else if(strcmp(token,"union") == 0) { t->type = UNION; getTypeAttributes(in, t); - if(t->size == -1) in->error(in, "Union has empty size"); - getRAnglebracket(in); // + getRAnglebracket(in); // getLAnglebracket(in); // token = getToken(in); @@ -630,7 +620,8 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, else if(strcmp(token,"array") == 0) { t->type = ARRAY; getTypeAttributes(in, t); - if(t->size == -1) in->error(in, "Array has empty size"); + if(t->size == 0) in->error(in, "Array has empty size"); + getForwardslash(in); getRAnglebracket(in); // getLAnglebracket(in); // @@ -645,8 +636,9 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, else if(strcmp(token,"sequence") == 0) { t->type = SEQUENCE; getTypeAttributes(in, t); - if(t->size == -1) in->error(in, "Sequence has empty size"); - getRAnglebracket(in); // + if(t->size == 0) in->error(in, "Sequence has empty lengthsize"); + getForwardslash(in); + getRAnglebracket(in); // getLAnglebracket(in); // t->nested_type = parseType(in,NULL, unnamed_types, named_types); @@ -664,7 +656,11 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, sequence_init(&(t->labels_description)); t->already_printed = 0; getTypeAttributes(in, t); - if(t->size == -1) in->error(in, "Sequence has empty size"); + //if(t->size == 0) in->error(in, "Sequence has empty size"); + //Mathieu : we fix enum size to 4 bytes. GCC is always like this. + //fox copy optimisation. + if(t->size != 0) in->error(in, "Enum has fixed size of 4."); + t->size = 4; getRAnglebracket(in); // } + else if(strcmp(token,"int_fixed") == 0) { + t->type = INT_FIXED; + getTypeAttributes(in, t); + if(t->size == 0) in->error(in, "int has empty size"); + getForwardslash(in); + getRAnglebracket(in); + } + else if(strcmp(token,"uint_fixed") == 0) { + t->type = UINT_FIXED; + getTypeAttributes(in, t); + if(t->size == 0) in->error(in, "uint has empty size"); + getForwardslash(in); + getRAnglebracket(in); + } + else if(strcmp(token,"char") == 0) { + t->type = CHAR; + getTypeAttributes(in, t); + getForwardslash(in); + getRAnglebracket(in); + } + else if(strcmp(token,"uchar") == 0) { + t->type = UCHAR; + getTypeAttributes(in, t); + getForwardslash(in); + getRAnglebracket(in); + } + else if(strcmp(token,"short") == 0) { + t->type = SHORT; + getTypeAttributes(in, t); + getForwardslash(in); + getRAnglebracket(in); + } + else if(strcmp(token,"ushort") == 0) { + t->type = USHORT; + getTypeAttributes(in, t); + getForwardslash(in); + getRAnglebracket(in); + } else if(strcmp(token,"int") == 0) { t->type = INT; 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; 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); @@ -877,7 +910,10 @@ char *getForwardslash(parse_file_t * in) char *token; token = getToken(in); - if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected"); + //if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected"); + /* Mathieu : final / is optional now. */ + if(in->type != FORWARDSLASH) ungetToken(in); + return token; } @@ -1157,16 +1193,40 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type) field_t * fld; switch(type->type){ - case INT: - str = intOutputTypes[type->size]; + case INT_FIXED: + str = intOutputTypes[getSizeindex(type->size)]; break; - case UINT: - str = uintOutputTypes[type->size]; + case UINT_FIXED: + str = uintOutputTypes[getSizeindex(type->size)]; break; case POINTER: str = allocAndCopy("void *"); flag = 1; break; + case CHAR: + str = allocAndCopy("signed char"); + flag = 1; + break; + case UCHAR: + str = allocAndCopy("unsigned char"); + flag = 1; + break; + case SHORT: + str = allocAndCopy("short"); + flag = 1; + break; + case USHORT: + str = allocAndCopy("unsigned short"); + flag = 1; + break; + case INT: + str = allocAndCopy("int"); + flag = 1; + break; + case UINT: + str = allocAndCopy("uint"); + flag = 1; + break; case LONG: str = allocAndCopy("long"); flag = 1; @@ -1188,23 +1248,24 @@ unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type) flag = 1; break; case FLOAT: - str = floatOutputTypes[type->size]; + str = floatOutputTypes[getSizeindex(type->size)]; break; case STRING: str = allocAndCopy("string"); flag = 1; break; case ENUM: - str = appendString("enum ", uintOutputTypes[type->size]); + //str = appendString("enum ", uintOutputTypes[getSizeindex(type->size)]); + str = allocAndCopy("enum"); flag = 1; break; case ARRAY: - sprintf(buf,"%d",type->size); + sprintf(buf,"%llu", type->size); str = appendString("array ",buf); flag = 1; break; case SEQUENCE: - sprintf(buf,"%d",type->size); + sprintf(buf,"%llu", type->size); str = appendString("sequence ",buf); flag = 1; break; diff --git a/genevent-new/parser.h b/genevent-new/parser.h index c846697b..482e16d0 100644 --- a/genevent-new/parser.h +++ b/genevent-new/parser.h @@ -77,9 +77,15 @@ static const int BUFFER_SIZE = 1024; /* Events data types */ typedef enum _data_type { + INT_FIXED, + UINT_FIXED, + POINTER, + CHAR, + UCHAR, + SHORT, + USHORT, INT, UINT, - POINTER, LONG, ULONG, SIZE_T, @@ -101,7 +107,7 @@ typedef struct _type_descriptor { char * type_name; //used for named type data_type_t type; char *fmt; - int size; + unsigned long long size; sequence_t labels; // for enumeration sequence_t labels_description; int already_printed; @@ -139,7 +145,8 @@ typedef struct _facility { table_t named_types; } facility_t; -int getSize(parse_file_t *in); +int getSizeindex(unsigned int value); +unsigned long long int getSize(parse_file_t *in); unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type); void parseFacility(parse_file_t *in, facility_t * fac); @@ -206,4 +213,13 @@ crc32(const char *s) } +extern char *intOutputTypes[]; + +extern char *uintOutputTypes[]; + +extern char *floatOutputTypes[]; + + + + #endif // PARSER_H