+
+void construct_fields(LttFacility *fac,
+ LttField *field,
+ field_t *fld)
+{
+ char *fmt_type;//gaby
+ guint len;
+ type_descriptor_t *td;
+ LttType *type;
+
+ if(fld->name)
+ field->name = g_quark_from_string(fld->name);
+ else
+ fld->name = 0;
+
+ if(fld->description) {
+ len = strlen(fld->description);
+ field->description = g_new(gchar, len+1);
+ strcpy(field->description, fld->description);
+ }
+ field->dynamic_offsets = NULL;
+ type = &field->field_type;
+ td = fld->type;
+
+ type->enum_map = NULL;
+ type->fields = NULL;
+ type->fields_by_name = NULL;
+ type->network = td->network;
+
+ switch(td->type) {
+ case INT_FIXED:
+ type->type_class = LTT_INT_FIXED;
+ type->size = td->size;
+ break;
+ case UINT_FIXED:
+ type->type_class = LTT_UINT_FIXED;
+ type->size = td->size;
+ break;
+ case POINTER:
+ type->type_class = LTT_POINTER;
+ type->size = fac->pointer_size;
+ break;
+ case CHAR:
+ type->type_class = LTT_CHAR;
+ type->size = td->size;
+ break;
+ case UCHAR:
+ type->type_class = LTT_UCHAR;
+ type->size = td->size;
+ g_assert(type->size != 0);
+ break;
+ case SHORT:
+ type->type_class = LTT_SHORT;
+ type->size = td->size;
+ break;
+ case USHORT:
+ type->type_class = LTT_USHORT;
+ type->size = td->size;
+ break;
+ case INT:
+ type->type_class = LTT_INT;
+ type->size = fac->int_size;
+ break;
+ case UINT:
+ type->type_class = LTT_UINT;
+ type->size = fac->int_size;
+ g_assert(type->size != 0);
+ break;
+ case LONG:
+ type->type_class = LTT_LONG;
+ type->size = fac->long_size;
+ break;
+ case ULONG:
+ type->type_class = LTT_ULONG;
+ type->size = fac->long_size;
+ break;
+ case SIZE_T:
+ type->type_class = LTT_SIZE_T;
+ type->size = fac->size_t_size;
+ break;
+ case SSIZE_T:
+ type->type_class = LTT_SSIZE_T;
+ type->size = fac->size_t_size;
+ break;
+ case OFF_T:
+ type->type_class = LTT_OFF_T;
+ type->size = fac->size_t_size;
+ break;
+ case FLOAT:
+ type->type_class = LTT_FLOAT;
+ type->size = td->size;
+ break;
+ case STRING:
+ type->type_class = LTT_STRING;
+ type->size = 0;
+ break;
+ case ENUM:
+ type->type_class = LTT_ENUM;
+ type->size = fac->int_size;
+ {
+ guint i;
+ type->enum_map = g_hash_table_new(g_direct_hash, g_direct_equal);
+ type->lowest_value = G_MAXINT32;
+ type->highest_value = G_MININT32;
+ for(i=0; i<td->labels.position; i++) {
+ GQuark value = g_quark_from_string((char*)td->labels.array[i]);
+ gint key = *(int*)td->labels_values.array[i];
+ g_hash_table_insert(type->enum_map, (gpointer)key, (gpointer)value);
+ type->highest_value = max(key, type->highest_value);
+ type->lowest_value = min(key, type->lowest_value);
+ }
+ }
+ g_assert(type->size != 0);
+ break;
+ case ARRAY:
+ type->type_class = LTT_ARRAY;
+ type->size = td->size;
+ type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
+ td->fields.position);
+ type->fields = g_array_set_size(type->fields, td->fields.position);
+ {
+ guint i;
+
+ for(i=0; i<td->fields.position; i++) {
+ field_t *schild = (field_t*)td->fields.array[i];
+ LttField *dchild = &g_array_index(type->fields, LttField, i);
+
+ construct_fields(fac, dchild, schild);
+ }
+ }
+ break;
+ case SEQUENCE:
+ type->type_class = LTT_SEQUENCE;
+ type->size = 0;
+ type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
+ td->fields.position);
+ type->fields = g_array_set_size(type->fields, td->fields.position);
+ {
+ guint i;
+
+ for(i=0; i<td->fields.position; i++) {
+ field_t *schild = (field_t*)td->fields.array[i];
+ LttField *dchild = &g_array_index(type->fields, LttField, i);
+
+ construct_fields(fac, dchild, schild);
+ }
+ }
+ break;
+ case STRUCT:
+ type->type_class = LTT_STRUCT;
+ type->size = 0; // Size not calculated by the parser.
+ type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
+ td->fields.position);
+ type->fields = g_array_set_size(type->fields, td->fields.position);
+ g_datalist_init(&type->fields_by_name);
+ {
+ guint i;
+
+ for(i=0; i<td->fields.position; i++) {
+ field_t *schild = (field_t*)td->fields.array[i];
+ LttField *dchild = &g_array_index(type->fields, LttField, i);
+
+ construct_fields(fac, dchild, schild);
+ g_datalist_id_set_data(&type->fields_by_name,
+ dchild->name,
+ dchild);
+ }
+ }
+ break;
+ case UNION:
+ type->type_class = LTT_UNION;
+ type->size = 0; // Size not calculated by the parser.
+ type->fields = g_array_sized_new(FALSE, TRUE, sizeof(LttField),
+ td->fields.position);
+ type->fields = g_array_set_size(type->fields, td->fields.position);
+ g_datalist_init(&type->fields_by_name);
+ {
+ guint i;
+
+ for(i=0; i<td->fields.position; i++) {
+ field_t *schild = (field_t*)td->fields.array[i];
+ LttField *dchild = &g_array_index(type->fields, LttField, i);
+
+ construct_fields(fac, dchild, schild);
+ g_datalist_id_set_data(&type->fields_by_name,
+ dchild->name,
+ dchild);
+ }
+ }
+ break;
+ case NONE:
+ default:
+ g_error("construct_fields : unknown type");
+ }
+
+ field->field_size = type->size;
+
+ /* Put the fields as "variable" offset to root first. Then,
+ * the offset precomputation will only have to set the FIELD_FIXED until
+ * it reaches the first variable length field, then stop.
+ */
+ field->fixed_root = FIELD_VARIABLE;
+
+ if(td->fmt) {
+ len = strlen(td->fmt);
+ type->fmt = g_new(gchar, len+1);
+ strcpy(type->fmt, td->fmt);
+ }
+ //here I should verify syntax based on type.
+ //if type is array or sequence or enum, parse_fmt.
+ //if type is basic, verify syntax, and allow or not the type format.
+ //the code can be integrated in the above code (after testing)
+
+
+
+ switch (type->type_class){
+ case LTT_ARRAY:
+ case LTT_UNION:
+ case LTT_STRUCT:
+ case LTT_SEQUENCE:
+ if(type->fmt==NULL)
+ {
+ //Assign a default format for these complex types
+ //type->fmt = malloc(11*sizeof(char));
+ type->fmt = g_new(gchar, 11);
+ type->fmt = g_strdup("{ %S, %S }");//set a default value for fmt. can directly set header and footer, but kept this way on purpose.
+ }
+ //Parse the fmt string in order to extract header, separator and footer
+ parse_fmt(type->fmt,&(type->header),&(type->separator),&(type->footer));
+
+ break;
+ case LTT_SHORT:
+ case LTT_INT:
+ case LTT_LONG:
+ case LTT_SSIZE_T:
+ case LTT_INT_FIXED:
+
+ if(type->fmt == NULL)
+ {
+ //Assign a default format string
+ //type->fmt = malloc(5*sizeof(char));
+ type->fmt = g_new(gchar, 5);
+ type->fmt=g_strdup("%lld");
+ break;
+ }
+ else
+ if(verify_fmt_syntax((type->fmt),&fmt_type)>0)
+ switch(fmt_type[0]){
+ case 'd':
+ case 'i':
+ case 'x':
+ case 'X':
+ append_ll(&(type->fmt),&fmt_type);//append 'll' to fmt
+ break;
+ default:
+ g_error("Format type '%c' not supported\n",fmt_type[0]);
+ break;
+ }
+ break;
+
+ case LTT_USHORT:
+ case LTT_UINT:
+ case LTT_ULONG:
+ case LTT_SIZE_T:
+ case LTT_OFF_T:
+ case LTT_UINT_FIXED:
+ if(type->fmt == NULL)
+ {
+ //Assign a default format string
+ //type->fmt= malloc(5*sizeof(char));
+ type->fmt = g_new(gchar, 5);
+ type->fmt=g_strdup("%lld");
+ break;
+ }
+ else
+ if(verify_fmt_syntax((type->fmt),&fmt_type)>0)
+ switch(fmt_type[0]){
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ append_ll(&(type->fmt),&fmt_type);
+ break;
+ default:
+ g_error("Format type '%c' not supported\n",fmt_type[0]);
+ }
+ break;
+
+ case LTT_CHAR:
+ case LTT_UCHAR:
+ if(type->fmt == NULL)
+ {
+ //Assign a default format string
+ //type->fmt = malloc(3*sizeof(char));
+ type->fmt = g_new(gchar, 3);
+ type->fmt = g_strdup("%c");
+ break;
+ }
+ else
+ if(verify_fmt_syntax((type->fmt),&fmt_type)>1)
+ switch(fmt_type[0]){
+ case 'c':
+ case 'd':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'o':
+ break;
+ default:
+ g_error("Format type '%c' not supported\n",fmt_type[0]);
+ }
+ break;
+
+ case LTT_FLOAT:
+ if(type->fmt == NULL)
+ {
+ //Assign a default format string
+ //type->fmt = malloc(3*sizeof(char));
+ type->fmt = g_new(gchar, 3);
+ type->fmt = g_strdup("%g");
+ break;
+ }
+ else
+ if(verify_fmt_syntax((type->fmt),&fmt_type)>0)
+ switch(fmt_type[0]){
+ case 'f':
+ case 'g':
+ case 'G':
+ case 'e':
+ case 'E':
+ break;
+ default:
+ g_error("Format type '%c' not supported\n",fmt_type[0]);
+ }
+ break;
+
+ case LTT_POINTER:
+ if(type->fmt == NULL)
+ {
+ //Assign a default format string
+ //type->fmt = malloc(7*sizeof(char));
+ type->fmt = g_new(gchar, 7);
+ type->fmt = g_strdup("0x%llx");
+ break;
+ }
+ else
+ if(verify_fmt_syntax((type->fmt),&fmt_type)>0)
+ switch(fmt_type[0]){
+ case 'p':
+ //type->fmt = malloc(7*sizeof(char));
+ type->fmt = g_new(gchar, 7);
+ type->fmt = g_strdup("0x%llx");
+ break;
+ case 'x':
+ case 'X':
+ case 'd':
+ append_ll(&(type->fmt),&fmt_type);
+ break;
+ default:
+ g_error("Format type '%c' not supported\n",fmt_type[0]);
+ }
+ break;
+
+ case LTT_STRING:
+ if(type->fmt == NULL)
+ {
+ //type->fmt = malloc(7*sizeof(char));
+ type->fmt = g_new(gchar, 5);
+ type->fmt = g_strdup("\"%s\"");//default value for fmt.
+ break;
+ }
+ else
+ if(verify_fmt_syntax((type->fmt),&fmt_type)>0)
+ switch(fmt_type[0]){
+ case 's':
+ break;
+ default:
+ g_error("Format type '%c' not supported\n", fmt_type[0]);
+ }
+ break;
+
+ default:
+ //missing enum
+ break;
+ }
+
+
+}
+
+#if 0
+void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td,