Make UEFI boot-platform build again
[haiku.git] / src / bin / rc / parser.y
blob639c8931a1b148f43c899d007e1749a8446c6aa0
1 /*
2 * Copyright (c) 2003 Matthijs Hollemans
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
25 #include <Message.h>
27 #include <map>
28 #include <string.h>
29 #include <stdio.h>
30 #include <stdlib.h>
32 #include "rdef.h"
33 #include "compile.h"
34 #include "private.h"
36 using namespace std;
38 #define YYERROR_VERBOSE
40 static void yyerror(const char*);
42 struct ident_compare_t { // allows the maps to compare identifier names
43 bool
44 operator()(const char* s1, const char* s2) const
46 return strcmp(s1, s2) < 0;
50 typedef std::map<const char*, int32, ident_compare_t> sym_tab_t;
51 typedef sym_tab_t::iterator sym_iter_t;
53 typedef std::map<const char*, type_t, ident_compare_t> type_tab_t;
54 typedef type_tab_t::iterator type_iter_t;
56 typedef std::map<const char*, define_t, ident_compare_t> define_tab_t;
57 typedef define_tab_t::iterator define_iter_t;
60 static sym_tab_t symbol_table; // symbol table for enums
61 static int32 enum_cnt; // counter for enum symbols without id
62 static type_tab_t type_table; // symbol table for data types
63 static define_tab_t define_table; // symbol table for defines
66 static void add_user_type(res_id_t, type_code, const char*, list_t);
67 static void add_symbol(const char*, int32);
68 static int32 get_symbol(const char*);
70 static bool is_type(const char* name);
71 static define_t get_define(const char* name);
73 static data_t make_data(size_t, type_t);
74 static data_t make_bool(bool);
75 static data_t make_int(uint64);
76 static data_t make_float(double);
78 static data_t import_data(char*);
79 static data_t resize_data(data_t, size_t);
81 static BMessage* make_msg(list_t);
82 static data_t flatten_msg(BMessage*);
84 static data_t make_default(type_t);
85 static data_t make_type(char* name, list_t);
87 static list_t make_field_list(field_t);
88 static list_t concat_field_list(list_t, field_t);
89 static list_t make_data_list(data_t);
90 static list_t concat_data_list(list_t, data_t);
91 static data_t concat_data(data_t, data_t);
93 static data_t cast(type_t, data_t);
95 static data_t unary_expr(data_t, char);
96 static data_t binary_expr(data_t, data_t, char);
98 static void add_resource(res_id_t, type_code, data_t);
101 //------------------------------------------------------------------------------
104 %expect 15
106 %union {
107 bool b;
108 uint64 i;
109 double f;
110 char* I;
111 type_code t;
112 res_id_t id;
113 data_t d;
114 list_t l;
115 field_t F;
116 type_t T;
119 %token ENUM RESOURCE ARCHIVE ARRAY MESSAGE RTYPE IMPORT
121 %token <b> BOOL
122 %token <i> INTEGER
123 %token <f> FLOAT
124 %token <d> STRING RAW
125 %token <I> IDENT
126 %token <t> TYPECODE
128 %type <i> integer
129 %type <f> float
130 %type <id> id
131 %type <d> archive array arrayfields data expr message msgfield
132 %type <d> type typefield type_or_define
133 %type <l> msgfields typefields typedeffields
134 %type <F> typedeffield
135 %type <T> datatype typecast
137 %left '|'
138 %left '^'
139 %left '&'
140 %left '+' '-'
141 %left '*' '/' '%'
142 %right FLIP
146 script
147 : /* empty */
148 | script enum
149 | script typedef
150 | script resource
153 enum
154 : enumstart '{' '}' ';'
155 | enumstart '{' symbols '}' ';'
156 | enumstart '{' symbols ',' '}' ';'
159 enumstart
160 : ENUM { enum_cnt = 0; }
163 symbols
164 : symbols ',' symboldef
165 | symboldef
168 symboldef
169 : IDENT
171 add_symbol($1, enum_cnt);
172 ++enum_cnt;
174 | IDENT '=' integer
176 int32 id = (int32) $3;
177 add_symbol($1, id);
178 enum_cnt = id + 1;
182 typedef
183 : RTYPE id TYPECODE IDENT '{' typedeffields '}' ';'
185 add_user_type($2, $3, $4, $6);
187 | RTYPE id IDENT '{' typedeffields '}' ';'
189 add_user_type($2, B_RAW_TYPE, $3, $5);
193 typedeffields
194 : typedeffields ',' typedeffield { $$ = concat_field_list($1, $3); }
195 | typedeffield { $$ = make_field_list($1); }
198 typedeffield
199 : datatype IDENT
201 $$.type = $1;
202 $$.name = $2;
203 $$.resize = 0;
204 $$.data = make_default($1);
206 | datatype IDENT '=' expr
208 $$.type = $1;
209 $$.name = $2;
210 $$.resize = 0;
211 $$.data = cast($1, $4);
213 | datatype IDENT '[' INTEGER ']'
215 $$.type = $1;
216 $$.name = $2;
217 $$.resize = (size_t) $4;
218 $$.data = resize_data(make_default($1), $$.resize);
220 | datatype IDENT '[' INTEGER ']' '=' expr
222 $$.type = $1;
223 $$.name = $2;
224 $$.resize = (size_t) $4;
225 $$.data = resize_data(cast($1, $7), $$.resize);
229 resource
230 : RESOURCE id expr ';'
232 add_resource($2, $3.type.code, $3);
234 | RESOURCE id TYPECODE expr ';'
236 add_resource($2, $3, $4);
238 | RESOURCE id '(' TYPECODE ')' expr ';'
240 add_resource($2, $4, $6);
245 : /* empty */
247 $$.has_id = false; $$.has_name = false; $$.name = NULL;
249 | '(' ')'
251 $$.has_id = false; $$.has_name = false; $$.name = NULL;
253 | '(' integer ')'
255 $$.has_id = true; $$.id = (int32) $2;
256 $$.has_name = false; $$.name = NULL;
258 | '(' integer ',' STRING ')'
260 $$.has_id = true; $$.id = (int32) $2;
261 $$.has_name = true; $$.name = (char*) $4.ptr;
263 | '(' IDENT ')'
265 $$.has_id = true; $$.id = get_symbol($2);
267 if (flags & RDEF_AUTO_NAMES)
269 $$.has_name = true; $$.name = $2;
271 else
273 $$.has_name = false; $$.name = NULL;
274 free_mem($2);
277 | '(' IDENT ',' STRING ')'
279 $$.has_id = true; $$.id = get_symbol($2);
280 $$.has_name = true; $$.name = (char*) $4.ptr;
281 free_mem($2);
283 | '(' STRING ')'
285 $$.has_id = false;
286 $$.has_name = true; $$.name = (char*) $2.ptr;
290 array
291 : ARRAY '{' arrayfields '}' { $$ = $3; }
292 | ARRAY '{' '}' { $$ = make_data(0, get_type("raw")); }
293 | ARRAY { $$ = make_data(0, get_type("raw")); }
294 | ARRAY IMPORT STRING { $$ = import_data((char*) $3.ptr); }
295 | IMPORT STRING { $$ = import_data((char*) $2.ptr); }
298 arrayfields
299 : arrayfields ',' expr { $$ = concat_data($1, $3); }
300 | expr { $$ = $1; $$.type = get_type("raw"); }
303 message
304 : MESSAGE '(' integer ')' '{' msgfields '}'
306 BMessage* msg = make_msg($6);
307 msg->what = (int32) $3;
308 $$ = flatten_msg(msg);
310 | MESSAGE '(' integer ')' '{' '}'
312 BMessage* msg = new BMessage;
313 msg->what = (int32) $3;
314 $$ = flatten_msg(msg);
316 | MESSAGE '(' integer ')'
318 BMessage* msg = new BMessage;
319 msg->what = (int32) $3;
320 $$ = flatten_msg(msg);
322 | MESSAGE '{' msgfields '}' { $$ = flatten_msg(make_msg($3)); }
323 | MESSAGE '{' '}' { $$ = flatten_msg(new BMessage); }
324 | MESSAGE { $$ = flatten_msg(new BMessage); }
327 msgfields
328 : msgfields ',' msgfield { $$ = concat_data_list($1, $3); }
329 | msgfield { $$ = make_data_list($1); }
332 msgfield
333 : STRING '=' expr
335 $$ = $3;
336 $$.name = (char*) $1.ptr;
338 | datatype STRING '=' expr
340 $$ = cast($1, $4);
341 $$.name = (char*) $2.ptr;
343 | TYPECODE STRING '=' expr
345 $$ = $4;
346 $$.type.code = $1;
347 $$.name = (char*) $2.ptr;
349 | TYPECODE datatype STRING '=' expr
351 $$ = cast($2, $5);
352 $$.type.code = $1;
353 $$.name = (char*) $3.ptr;
357 archive
358 : ARCHIVE IDENT '{' msgfields '}'
360 BMessage* msg = make_msg($4);
361 msg->AddString("class", $2);
362 free_mem($2);
363 $$ = flatten_msg(msg);
365 | ARCHIVE '(' STRING ')' IDENT '{' msgfields '}'
367 BMessage* msg = make_msg($7);
368 msg->AddString("class", $5);
369 msg->AddString("add_on", (char*) $3.ptr);
370 free_mem($5);
371 free_mem($3.ptr);
372 $$ = flatten_msg(msg);
374 | ARCHIVE '(' ',' integer ')' IDENT '{' msgfields '}'
376 BMessage* msg = make_msg($8);
377 msg->what = (int32) $4;
378 msg->AddString("class", $6);
379 free_mem($6);
380 $$ = flatten_msg(msg);
382 | ARCHIVE '(' STRING ',' integer ')' IDENT '{' msgfields '}'
384 BMessage* msg = make_msg($9);
385 msg->what = (int32) $5;
386 msg->AddString("class", $7);
387 msg->AddString("add_on", (char*) $3.ptr);
388 free_mem($7);
389 free_mem($3.ptr);
390 $$ = flatten_msg(msg);
394 type
395 : IDENT '{' typefields '}' { $$ = make_type($1, $3); }
396 | IDENT '{' '}'
398 list_t list; list.count = 0; list.items = NULL;
399 $$ = make_type($1, list);
401 | IDENT expr
403 $$ = make_type($1, make_data_list($2));
405 | type_or_define { $$ = $1; }
408 type_or_define
409 : IDENT
411 if (is_type($1))
413 list_t list; list.count = 0; list.items = NULL;
414 $$ = make_type($1, list);
416 else
418 define_t define = get_define($1);
419 $$ = cast(get_type("int32"), make_int(define.value));
420 free_mem($1);
425 typefields
426 : typefields ',' typefield { $$ = concat_data_list($1, $3); }
427 | typefield { $$ = make_data_list($1); }
430 typefield
431 : IDENT '=' expr { $$ = $3; $$.name = $1; }
432 | expr { $$ = $1; }
435 expr
436 : expr '+' expr { $$ = binary_expr($1, $3, '+'); }
437 | expr '-' expr { $$ = binary_expr($1, $3, '-'); }
438 | expr '*' expr { $$ = binary_expr($1, $3, '*'); }
439 | expr '/' expr { $$ = binary_expr($1, $3, '/'); }
440 | expr '%' expr { $$ = binary_expr($1, $3, '%'); }
441 | expr '|' expr { $$ = binary_expr($1, $3, '|'); }
442 | expr '^' expr { $$ = binary_expr($1, $3, '^'); }
443 | expr '&' expr { $$ = binary_expr($1, $3, '&'); }
444 | '~' expr %prec FLIP { $$ = unary_expr($2, '~'); }
445 | data { $$ = $1; }
448 data
449 : BOOL { $$ = cast(get_type("bool"), make_bool($1)); }
450 | integer { $$ = cast(get_type("int32"), make_int($1)); }
451 | float { $$ = cast(get_type("float"), make_float($1)); }
452 | STRING { $$ = cast($1.type, $1); }
453 | RAW { $$ = cast($1.type, $1); }
454 | array { $$ = cast($1.type, $1); }
455 | message { $$ = cast($1.type, $1); }
456 | archive { $$ = cast($1.type, $1); }
457 | type { $$ = cast($1.type, $1); }
458 | '(' expr ')' { $$ = $2; }
459 | typecast BOOL { $$ = cast($1, make_bool($2)); }
460 | typecast integer { $$ = cast($1, make_int($2)); }
461 | typecast float { $$ = cast($1, make_float($2)); }
462 | typecast STRING { $$ = cast($1, $2); }
463 | typecast RAW { $$ = cast($1, $2); }
464 | typecast array { $$ = cast($1, $2); }
465 | typecast message { $$ = cast($1, $2); }
466 | typecast archive { $$ = cast($1, $2); }
467 | typecast type { $$ = cast($1, $2); }
468 | typecast '(' expr ')' { $$ = cast($1, $3); }
471 typecast
472 : '(' ARRAY ')' { $$ = get_type("raw"); }
473 | '(' MESSAGE ')' { $$ = get_type("message"); }
474 | '(' ARCHIVE IDENT ')' { $$ = get_type("message"); free_mem($3); }
475 | '(' IDENT ')' { $$ = get_type($2); free_mem($2); }
478 datatype
479 : ARRAY { $$ = get_type("raw"); }
480 | MESSAGE { $$ = get_type("message"); }
481 | ARCHIVE IDENT { $$ = get_type("message"); free_mem($2); }
482 | IDENT { $$ = get_type($1); free_mem($1); }
485 integer
486 : INTEGER { $$ = $1; }
487 | '-' INTEGER { $$ = -($2); }
490 float
491 : FLOAT { $$ = $1; }
492 | '-' FLOAT { $$ = -($2); }
496 //------------------------------------------------------------------------------
499 void
500 yyerror(const char* msg)
502 // This function is called by the parser when it encounters
503 // an error, after which it aborts parsing and returns from
504 // yyparse(). We never call yyerror() directly.
506 rdef_err = RDEF_COMPILE_ERR;
507 rdef_err_line = yylineno;
508 strcpy(rdef_err_file, lexfile);
509 strcpy(rdef_err_msg, msg);
513 void
514 add_symbol(const char* name, int32 id)
516 if (symbol_table.find(name) != symbol_table.end())
517 abort_compile(RDEF_COMPILE_ERR, "duplicate symbol %s", name);
519 symbol_table.insert(make_pair(name, id));
523 int32
524 get_symbol(const char* name)
526 sym_iter_t i = symbol_table.find(name);
528 if (i == symbol_table.end())
529 abort_compile(RDEF_COMPILE_ERR, "unknown symbol %s", name);
531 return i->second;
535 static void
536 add_builtin_type(type_code code, const char* name)
538 type_t type;
539 type.code = code;
540 type.name = name;
541 type.count = 0;
542 type.fields = NULL;
543 type.def_id = 1;
544 type.def_name = NULL;
546 type_table.insert(make_pair(name, type));
550 void
551 add_user_type(res_id_t id, type_code code, const char* name, list_t list)
553 if (type_table.find(name) != type_table.end())
554 abort_compile(RDEF_COMPILE_ERR, "duplicate type %s", name);
556 type_t type;
557 type.code = code;
558 type.name = name;
559 type.count = list.count;
560 type.fields = (field_t*) list.items;
561 type.def_id = 1;
562 type.def_name = NULL;
564 if (id.has_id)
565 type.def_id = id.id;
567 if (id.has_name)
568 type.def_name = id.name;
570 type_table.insert(make_pair(name, type));
574 static bool
575 is_builtin_type(type_t type)
577 return type.count == 0;
581 static bool
582 same_type(type_t type1, type_t type2)
584 return type1.name == type2.name; // no need for strcmp
588 type_t
589 get_type(const char* name)
591 type_iter_t i = type_table.find(name);
593 if (i == type_table.end())
594 abort_compile(RDEF_COMPILE_ERR, "unknown type %s", name);
596 return i->second;
600 bool
601 is_type(const char* name)
603 return type_table.find(name) != type_table.end();
607 define_t
608 get_define(const char* name)
610 define_iter_t i = define_table.find(name);
612 if (i == define_table.end())
613 abort_compile(RDEF_COMPILE_ERR, "unknown define %s", name);
615 return i->second;
619 data_t
620 make_data(size_t size, type_t type)
622 data_t out;
623 out.type = type;
624 out.name = NULL;
625 out.size = size;
626 out.ptr = alloc_mem(size);
627 return out;
631 data_t
632 make_bool(bool b)
634 data_t out = make_data(sizeof(bool), get_type("bool"));
635 *((bool*)out.ptr) = b;
636 return out;
640 data_t
641 make_int(uint64 i)
643 data_t out = make_data(sizeof(uint64), get_type("uint64"));
644 *((uint64*)out.ptr) = i;
645 return out;
649 data_t
650 make_float(double f)
652 data_t out = make_data(sizeof(double), get_type("double"));
653 *((double*)out.ptr) = f;
654 return out;
658 data_t
659 import_data(char* filename)
661 data_t out;
662 out.type = get_type("raw");
663 out.name = NULL;
665 char tmpname[B_PATH_NAME_LENGTH];
666 if (open_file_from_include_dir(filename, tmpname)) {
667 BFile file(tmpname, B_READ_ONLY);
668 if (file.InitCheck() == B_OK) {
669 off_t size;
670 if (file.GetSize(&size) == B_OK) {
671 out.size = (size_t) size;
672 out.ptr = alloc_mem(size);
674 if (file.Read(out.ptr, out.size) == (ssize_t) out.size) {
675 free_mem(filename);
676 return out;
682 abort_compile(RDEF_COMPILE_ERR, "cannot import %s", filename);
683 return out;
687 data_t
688 resize_data(data_t data, size_t newSize)
690 if (newSize == 0) {
691 abort_compile(RDEF_COMPILE_ERR, "invalid size %lu", newSize);
692 } else if (data.size != newSize) {
693 void* newBuffer = alloc_mem(newSize);
695 memset(newBuffer, 0, newSize);
696 memcpy(newBuffer, data.ptr, min(data.size, newSize));
698 if (data.type.code == B_STRING_TYPE)
699 ((char*)newBuffer)[newSize - 1] = '\0';
701 free_mem(data.ptr);
702 data.ptr = newBuffer;
703 data.size = newSize;
706 return data;
710 BMessage*
711 make_msg(list_t list)
713 BMessage* msg = new BMessage;
715 for (int32 t = 0; t < list.count; ++t) {
716 data_t data = ((data_t*)list.items)[t];
717 msg->AddData(data.name, data.type.code, data.ptr, data.size, false);
718 free_mem(data.name);
719 free_mem(data.ptr);
722 free_mem(list.items);
723 return msg;
727 data_t
728 flatten_msg(BMessage* msg)
730 #ifndef B_BEOS_VERSION_DANO
731 data_t out = make_data(msg->FlattenedSize(), get_type("message"));
732 msg->Flatten((char*)out.ptr, out.size);
733 #else
734 data_t out = make_data(msg->FlattenedSize(B_MESSAGE_VERSION_1),
735 get_type("message"));
736 msg->Flatten(B_MESSAGE_VERSION_1, (char*)out.ptr, out.size);
737 #endif
738 delete msg;
739 return out;
743 data_t
744 make_default(type_t type)
746 data_t out;
748 if (is_builtin_type(type)) {
749 switch (type.code) {
750 case B_BOOL_TYPE:
751 out = make_data(sizeof(bool), type);
752 *((bool*)out.ptr) = false;
753 break;
755 case B_INT8_TYPE:
756 case B_UINT8_TYPE:
757 out = make_data(sizeof(uint8), type);
758 *((uint8*)out.ptr) = 0;
759 break;
761 case B_INT16_TYPE:
762 case B_UINT16_TYPE:
763 out = make_data(sizeof(uint16), type);
764 *((uint16*)out.ptr) = 0;
765 break;
767 case B_INT32_TYPE:
768 case B_UINT32_TYPE:
769 case B_SIZE_T_TYPE:
770 case B_SSIZE_T_TYPE:
771 case B_TIME_TYPE:
772 out = make_data(sizeof(uint32), type);
773 *((uint32*)out.ptr) = 0;
774 break;
776 case B_INT64_TYPE:
777 case B_UINT64_TYPE:
778 case B_OFF_T_TYPE:
779 out = make_data(sizeof(uint64), type);
780 *((uint64*)out.ptr) = 0;
781 break;
783 case B_FLOAT_TYPE:
784 out = make_data(sizeof(float), type);
785 *((float*)out.ptr) = 0.0f;
786 break;
788 case B_DOUBLE_TYPE:
789 out = make_data(sizeof(double), type);
790 *((double*)out.ptr) = 0.0;
791 break;
793 case B_STRING_TYPE:
794 out = make_data(sizeof(char), type);
795 *((char*)out.ptr) = '\0';
796 break;
798 case B_RAW_TYPE:
799 out = make_data(0, type);
800 break;
802 case B_MESSAGE_TYPE:
803 out = flatten_msg(new BMessage);
804 break;
806 } else {
807 // For user-defined types, we copy the default values of the fields
808 // into a new data_t object. There is no need to call resize_data()
809 // here, because the default values were already resized to their
810 // proper length when we added them to the type.
812 size_t size = 0;
813 for (int32 t = 0; t < type.count; ++t) {
814 size += type.fields[t].data.size;
817 out = make_data(size, type);
819 uint8* ptr = (uint8*) out.ptr;
820 for (int32 t = 0; t < type.count; ++t) {
821 data_t field_data = type.fields[t].data;
822 memcpy(ptr, field_data.ptr, field_data.size);
823 ptr += field_data.size;
827 return out;
831 static data_t*
832 fill_slots(type_t type, list_t list)
834 data_t* slots = (data_t*)alloc_mem(type.count * sizeof(data_t));
835 memset(slots, 0, type.count * sizeof(data_t));
837 for (int32 t = 0; t < list.count; ++t) {
838 data_t data = ((data_t*)list.items)[t];
840 if (data.name == NULL) {
841 bool found = false;
842 for (int32 k = 0; k < type.count; ++k) {
843 if (slots[k].ptr == NULL) {
844 slots[k] = cast(type.fields[k].type, data);
845 found = true;
846 break;
850 if (!found)
851 abort_compile(RDEF_COMPILE_ERR, "too many fields");
852 } else {
853 // named field
854 bool found = false;
855 for (int32 k = 0; k < type.count; ++k) {
856 if (strcmp(type.fields[k].name, data.name) == 0) {
857 if (slots[k].ptr != NULL)
858 free_mem(slots[k].ptr);
860 slots[k] = cast(type.fields[k].type, data);
861 free_mem(data.name);
862 found = true;
863 break;
867 if (!found)
868 abort_compile(RDEF_COMPILE_ERR, "unknown field %s", data.name);
872 return slots;
876 static data_t
877 convert_slots(type_t type, data_t* slots)
879 size_t size = 0;
880 for (int32 k = 0; k < type.count; ++k) {
881 if (slots[k].ptr == NULL) {
882 // default value
883 size += type.fields[k].data.size;
884 } else if (type.fields[k].resize != 0)
885 size += type.fields[k].resize;
886 else
887 size += slots[k].size;
890 data_t out = make_data(size, type);
891 uint8* ptr = (uint8*) out.ptr;
893 for (int32 k = 0; k < type.count; ++k) {
894 if (slots[k].ptr == NULL) {
895 // default value
896 memcpy(ptr, type.fields[k].data.ptr, type.fields[k].data.size);
897 ptr += type.fields[k].data.size;
898 } else if (type.fields[k].resize != 0) {
899 data_t temp = resize_data(slots[k], type.fields[k].resize);
900 memcpy(ptr, temp.ptr, temp.size);
901 ptr += temp.size;
902 free_mem(temp.ptr);
903 } else {
904 memcpy(ptr, slots[k].ptr, slots[k].size);
905 ptr += slots[k].size;
906 free_mem(slots[k].ptr);
910 free_mem(slots);
911 return out;
915 data_t
916 make_type(char* name, list_t list)
918 // Some explanation is in order. The "list" contains zero or more data_t
919 // items. Each of these items corresponds to a data field that the user
920 // specified, but not necessarily to a field from the type definition.
921 // So here we have to figure out which data item goes where. It is fairly
922 // obvious where names items should go, but for items without a name we
923 // simply use the first available slot. For any fields that the user did
924 // not fill in we use the default value from the type definition. This
925 // algorithm allows for variable size fields, such as strings and arrays.
927 type_t type = get_type(name);
929 data_t* slots = fill_slots(type, list);
930 data_t out = convert_slots(type, slots);
932 free_mem(name);
933 free_mem(list.items);
934 return out;
938 list_t
939 make_field_list(field_t field)
941 list_t out;
942 out.count = 1;
943 out.items = alloc_mem(sizeof(field_t));
944 *((field_t*)out.items) = field;
945 return out;
949 list_t
950 concat_field_list(list_t list, field_t field)
952 list_t out;
953 out.count = list.count + 1;
954 out.items = alloc_mem(out.count * sizeof(field_t));
956 memcpy(out.items, list.items, list.count * sizeof(field_t));
957 memcpy((field_t*)out.items + list.count, &field, sizeof(field_t));
959 free_mem(list.items);
960 return out;
964 list_t
965 make_data_list(data_t data)
967 list_t out;
968 out.count = 1;
969 out.items = alloc_mem(sizeof(data_t));
970 *((data_t*)out.items) = data;
971 return out;
975 list_t
976 concat_data_list(list_t list, data_t data)
978 list_t out;
979 out.count = list.count + 1;
980 out.items = (data_t*)alloc_mem(out.count * sizeof(data_t));
982 memcpy(out.items, list.items, list.count * sizeof(data_t));
983 memcpy((data_t*)out.items + list.count, &data, sizeof(data_t));
985 free_mem(list.items);
986 return out;
990 data_t
991 concat_data(data_t data1, data_t data2)
993 data_t out = make_data(data1.size + data2.size, get_type("raw"));
995 memcpy(out.ptr, data1.ptr, data1.size);
996 memcpy((uint8*)out.ptr + data1.size, data2.ptr, data2.size);
998 free_mem(data1.ptr);
999 free_mem(data2.ptr);
1000 return out;
1004 static data_t
1005 cast_to_uint8(type_t new_type, data_t data)
1007 data_t out = make_data(sizeof(uint8), new_type);
1009 switch (data.type.code) {
1010 case B_INT8_TYPE:
1011 case B_UINT8_TYPE:
1012 *((uint8*)out.ptr) = *(uint8*)data.ptr;
1013 break;
1015 case B_INT16_TYPE:
1016 case B_UINT16_TYPE:
1017 *((uint8*)out.ptr) = (uint8)*(uint16*)data.ptr;
1018 break;
1020 case B_INT32_TYPE:
1021 case B_UINT32_TYPE:
1022 case B_SIZE_T_TYPE:
1023 case B_SSIZE_T_TYPE:
1024 case B_TIME_TYPE:
1025 *((uint8*)out.ptr) = (uint8)*(uint32*)data.ptr;
1026 break;
1028 case B_INT64_TYPE:
1029 case B_UINT64_TYPE:
1030 case B_OFF_T_TYPE:
1031 *((uint8*)out.ptr) = (uint8)*(uint64*)data.ptr;
1032 break;
1034 default:
1035 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1038 free_mem(data.ptr);
1039 return out;
1043 static data_t
1044 cast_to_uint16(type_t new_type, data_t data)
1046 data_t out = make_data(sizeof(uint16), new_type);
1048 switch (data.type.code) {
1049 case B_INT8_TYPE:
1050 case B_UINT8_TYPE:
1051 *((uint16*)out.ptr) = (uint16)*(uint8*)data.ptr;
1052 break;
1054 case B_INT16_TYPE:
1055 case B_UINT16_TYPE:
1056 *((uint16*)out.ptr) = *(uint16*)data.ptr;
1057 break;
1059 case B_INT32_TYPE:
1060 case B_UINT32_TYPE:
1061 case B_SIZE_T_TYPE:
1062 case B_SSIZE_T_TYPE:
1063 case B_TIME_TYPE:
1064 *((uint16*)out.ptr) = (uint16)*(uint32*)data.ptr;
1065 break;
1067 case B_INT64_TYPE:
1068 case B_UINT64_TYPE:
1069 case B_OFF_T_TYPE:
1070 *((uint16*)out.ptr) = (uint16)*(uint64*)data.ptr;
1071 break;
1073 default:
1074 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1077 free_mem(data.ptr);
1078 return out;
1082 static data_t
1083 cast_to_uint32(type_t new_type, data_t data)
1085 data_t out = make_data(sizeof(uint32), new_type);
1087 switch (data.type.code) {
1088 case B_INT8_TYPE:
1089 case B_UINT8_TYPE:
1090 *((uint32*)out.ptr) = (uint32)*(uint8*)data.ptr;
1091 break;
1093 case B_INT16_TYPE:
1094 case B_UINT16_TYPE:
1095 *((uint32*)out.ptr) = (uint32)*(uint16*)data.ptr;
1096 break;
1098 case B_INT32_TYPE:
1099 case B_UINT32_TYPE:
1100 case B_SIZE_T_TYPE:
1101 case B_SSIZE_T_TYPE:
1102 case B_TIME_TYPE:
1103 *((uint32*)out.ptr) = *(uint32*)data.ptr;
1104 break;
1106 case B_INT64_TYPE:
1107 case B_UINT64_TYPE:
1108 case B_OFF_T_TYPE:
1109 *((uint32*)out.ptr) = (uint32)*(uint64*)data.ptr;
1110 break;
1112 default:
1113 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1116 free_mem(data.ptr);
1117 return out;
1121 static data_t
1122 cast_to_uint64(type_t new_type, data_t data)
1124 data_t out = make_data(sizeof(uint64), new_type);
1126 switch (data.type.code) {
1127 case B_INT8_TYPE:
1128 case B_UINT8_TYPE:
1129 *((uint64*)out.ptr) = (uint64)*(uint8*)data.ptr;
1130 break;
1132 case B_INT16_TYPE:
1133 case B_UINT16_TYPE:
1134 *((uint64*)out.ptr) = (uint64)*(uint16*)data.ptr;
1135 break;
1137 case B_INT32_TYPE:
1138 case B_UINT32_TYPE:
1139 case B_SIZE_T_TYPE:
1140 case B_SSIZE_T_TYPE:
1141 case B_TIME_TYPE:
1142 *((uint64*)out.ptr) = (uint64)*(uint32*)data.ptr;
1143 break;
1145 case B_INT64_TYPE:
1146 case B_UINT64_TYPE:
1147 case B_OFF_T_TYPE:
1148 *((uint64*)out.ptr) = *(uint64*)data.ptr;
1149 break;
1151 default:
1152 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1155 free_mem(data.ptr);
1156 return out;
1160 static data_t
1161 cast_to_float(type_t new_type, data_t data)
1163 data_t out = make_data(sizeof(float), new_type);
1165 switch (data.type.code) {
1166 case B_INT8_TYPE:
1167 case B_UINT8_TYPE:
1168 *((float*)out.ptr) = (float)*((uint8*)data.ptr);
1169 break;
1171 case B_INT16_TYPE:
1172 case B_UINT16_TYPE:
1173 *((float*)out.ptr) = (float)*((uint16*)data.ptr);
1174 break;
1176 case B_INT32_TYPE:
1177 case B_UINT32_TYPE:
1178 case B_SIZE_T_TYPE:
1179 case B_SSIZE_T_TYPE:
1180 case B_TIME_TYPE:
1181 *((float*)out.ptr) = (float)*((uint32*)data.ptr);
1182 break;
1184 case B_INT64_TYPE:
1185 case B_UINT64_TYPE:
1186 case B_OFF_T_TYPE:
1187 *((float*)out.ptr) = (float)*((uint64*)data.ptr);
1188 break;
1190 case B_DOUBLE_TYPE:
1191 *((float*)out.ptr) = (float)*((double*)data.ptr);
1192 break;
1194 default:
1195 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1198 free_mem(data.ptr);
1199 return out;
1203 static data_t
1204 cast_to_double(type_t new_type, data_t data)
1206 data_t out = make_data(sizeof(double), new_type);
1208 switch (data.type.code) {
1209 case B_INT8_TYPE:
1210 case B_UINT8_TYPE:
1211 *((double*)out.ptr) = (double)*((uint8*)data.ptr);
1212 break;
1214 case B_INT16_TYPE:
1215 case B_UINT16_TYPE:
1216 *((double*)out.ptr) = (double)*((uint16*)data.ptr);
1217 break;
1219 case B_INT32_TYPE:
1220 case B_UINT32_TYPE:
1221 case B_SIZE_T_TYPE:
1222 case B_SSIZE_T_TYPE:
1223 case B_TIME_TYPE:
1224 *((double*)out.ptr) = (double)*((uint32*)data.ptr);
1225 break;
1227 case B_INT64_TYPE:
1228 case B_UINT64_TYPE:
1229 case B_OFF_T_TYPE:
1230 *((double*)out.ptr) = (double)*((uint64*)data.ptr);
1231 break;
1233 case B_FLOAT_TYPE:
1234 *((double*)out.ptr) = (double)*((float*)data.ptr);
1235 break;
1237 default:
1238 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1241 free_mem(data.ptr);
1242 return out;
1246 data_t
1247 cast(type_t newType, data_t data)
1249 if (same_type(newType, data.type)) {
1250 // you can't cast bool, string,
1251 // message, or user-defined type
1252 // to another type, only to same
1253 return data;
1256 if (is_builtin_type(newType)) {
1257 switch (newType.code) {
1258 case B_INT8_TYPE:
1259 case B_UINT8_TYPE:
1260 return cast_to_uint8(newType, data);
1262 case B_INT16_TYPE:
1263 case B_UINT16_TYPE:
1264 return cast_to_uint16(newType, data);
1266 case B_INT32_TYPE:
1267 case B_UINT32_TYPE:
1268 case B_SIZE_T_TYPE:
1269 case B_SSIZE_T_TYPE:
1270 case B_TIME_TYPE:
1271 return cast_to_uint32(newType, data);
1273 case B_INT64_TYPE:
1274 case B_UINT64_TYPE:
1275 case B_OFF_T_TYPE:
1276 return cast_to_uint64(newType, data);
1278 case B_FLOAT_TYPE:
1279 return cast_to_float(newType, data);
1281 case B_DOUBLE_TYPE:
1282 return cast_to_double(newType, data);
1284 case B_RAW_TYPE:
1285 // you can always cast anything to raw
1286 data.type = newType;
1287 return data;
1291 abort_compile(RDEF_COMPILE_ERR, "cannot cast to this type");
1292 return data;
1296 data_t
1297 unary_expr(data_t data, char oper)
1299 data_t op = cast_to_uint32(get_type("int32"), data);
1300 int32 i = *((int32*)op.ptr);
1301 data_t out;
1303 switch (oper) {
1304 case '~':
1305 out = make_int(~i);
1306 break;
1309 free_mem(op.ptr);
1311 return cast(get_type("int32"), out);
1315 data_t
1316 binary_expr(data_t data1, data_t data2, char oper)
1318 data_t op1 = cast_to_uint32(get_type("int32"), data1);
1319 data_t op2 = cast_to_uint32(get_type("int32"), data2);
1320 int32 i1 = *((int32*) op1.ptr);
1321 int32 i2 = *((int32*) op2.ptr);
1322 data_t out;
1324 switch (oper) {
1325 case '+':
1326 out = make_int(i1 + i2);
1327 break;
1328 case '-':
1329 out = make_int(i1 - i2);
1330 break;
1331 case '*':
1332 out = make_int(i1 * i2);
1333 break;
1335 case '/':
1336 if (i2 == 0)
1337 abort_compile(RDEF_COMPILE_ERR, "division by zero");
1338 else
1339 out = make_int(i1 / i2);
1340 break;
1342 case '%':
1343 if (i2 == 0)
1344 abort_compile(RDEF_COMPILE_ERR, "division by zero");
1345 else
1346 out = make_int(i1 % i2);
1347 break;
1349 case '|':
1350 out = make_int(i1 | i2);
1351 break;
1352 case '^':
1353 out = make_int(i1 ^ i2);
1354 break;
1355 case '&':
1356 out = make_int(i1 & i2);
1357 break;
1360 free_mem(op1.ptr);
1361 free_mem(op2.ptr);
1363 return cast(get_type("int32"), out);
1367 void
1368 add_resource(res_id_t id, type_code code, data_t data)
1370 if (!id.has_id)
1371 id.id = data.type.def_id;
1373 if (!id.has_name)
1374 id.name = (char*)data.type.def_name;
1376 if (!(flags & RDEF_MERGE_RESOURCES) && rsrc.HasResource(code, id.id))
1377 abort_compile(RDEF_COMPILE_ERR, "duplicate resource");
1379 status_t err = rsrc.AddResource(code, id.id, data.ptr, data.size, id.name);
1380 if (err != B_OK) {
1381 rdef_err = RDEF_WRITE_ERR;
1382 rdef_err_line = 0;
1383 strcpy(rdef_err_file, rsrc_file);
1384 sprintf(rdef_err_msg, "cannot add resource (%s)", strerror(err));
1385 abort_compile();
1388 if (id.has_name)
1389 free_mem(id.name);
1391 free_mem(data.ptr);
1395 static void
1396 add_point_type()
1398 field_t* fields = (field_t*)alloc_mem(2 * sizeof(field_t));
1399 fields[0].type = get_type("float");
1400 fields[0].name = "x";
1401 fields[0].resize = 0;
1402 fields[0].data = make_default(fields[0].type);
1403 fields[1].type = get_type("float");
1404 fields[1].name = "y";
1405 fields[1].resize = 0;
1406 fields[1].data = make_default(fields[1].type);
1408 type_t type;
1409 type.code = B_POINT_TYPE;
1410 type.name = "point";
1411 type.fields = fields;
1412 type.count = 2;
1413 type.def_id = 1;
1414 type.def_name = NULL;
1416 type_table.insert(make_pair(type.name, type));
1420 static void
1421 add_rect_type()
1423 field_t* fields = (field_t*)alloc_mem(4 * sizeof(field_t));
1424 fields[0].type = get_type("float");
1425 fields[0].name = "left";
1426 fields[0].resize = 0;
1427 fields[0].data = make_default(fields[0].type);
1428 fields[1].type = get_type("float");
1429 fields[1].name = "top";
1430 fields[1].resize = 0;
1431 fields[1].data = make_default(fields[1].type);
1432 fields[2].type = get_type("float");
1433 fields[2].name = "right";
1434 fields[2].resize = 0;
1435 fields[2].data = make_default(fields[2].type);
1436 fields[3].type = get_type("float");
1437 fields[3].name = "bottom";
1438 fields[3].resize = 0;
1439 fields[3].data = make_default(fields[3].type);
1441 type_t type;
1442 type.code = B_RECT_TYPE;
1443 type.name = "rect";
1444 type.fields = fields;
1445 type.count = 4;
1446 type.def_id = 1;
1447 type.def_name = NULL;
1449 type_table.insert(make_pair(type.name, type));
1453 static void
1454 add_rgb_color_type()
1456 field_t* fields = (field_t*)alloc_mem(4 * sizeof(field_t));
1457 fields[0].type = get_type("uint8");
1458 fields[0].name = "red";
1459 fields[0].resize = 0;
1460 fields[0].data = make_default(fields[0].type);
1461 fields[1].type = get_type("uint8");
1462 fields[1].name = "green";
1463 fields[1].resize = 0;
1464 fields[1].data = make_default(fields[1].type);
1465 fields[2].type = get_type("uint8");
1466 fields[2].name = "blue";
1467 fields[2].resize = 0;
1468 fields[2].data = make_default(fields[2].type);
1469 fields[3].type = get_type("uint8");
1470 fields[3].name = "alpha";
1471 fields[3].resize = 0;
1472 fields[3].data = make_default(fields[3].type);
1474 *((uint8*)fields[3].data.ptr) = 255;
1476 type_t type;
1477 type.code = B_RGB_COLOR_TYPE;
1478 type.name = "rgb_color";
1479 type.fields = fields;
1480 type.count = 4;
1481 type.def_id = 1;
1482 type.def_name = NULL;
1484 type_table.insert(make_pair(type.name, type));
1488 static void
1489 add_app_signature_type()
1491 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1492 fields[0].type = get_type("string");
1493 fields[0].name = "signature";
1494 fields[0].resize = 0;
1495 fields[0].data = make_default(fields[0].type);
1497 type_t type;
1498 type.code = 'MIMS';
1499 type.name = "app_signature";
1500 type.fields = fields;
1501 type.count = 1;
1502 type.def_id = 1;
1503 type.def_name = "BEOS:APP_SIG";
1505 type_table.insert(make_pair(type.name, type));
1509 static void
1510 add_app_name_catalog_entry()
1512 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1513 fields[0].type = get_type("string");
1514 fields[0].name = "catalog_entry";
1515 fields[0].resize = 0;
1516 fields[0].data = make_default(fields[0].type);
1518 type_t type;
1519 type.code = B_STRING_TYPE;
1520 type.name = "app_name_catalog_entry";
1521 type.fields = fields;
1522 type.count = 1;
1523 type.def_id = 1;
1524 type.def_name = "SYS:NAME";
1526 type_table.insert(make_pair(type.name, type));
1530 static void
1531 add_app_flags()
1533 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1534 fields[0].type = get_type("uint32");
1535 fields[0].name = "flags";
1536 fields[0].resize = 0;
1537 fields[0].data = make_default(fields[0].type);
1539 type_t type;
1540 type.code = 'APPF';
1541 type.name = "app_flags";
1542 type.fields = fields;
1543 type.count = 1;
1544 type.def_id = 1;
1545 type.def_name = "BEOS:APP_FLAGS";
1547 type_table.insert(make_pair(type.name, type));
1551 static void
1552 add_app_version()
1554 field_t* fields = (field_t*)alloc_mem(7 * sizeof(field_t));
1555 fields[0].type = get_type("uint32");
1556 fields[0].name = "major";
1557 fields[0].resize = 0;
1558 fields[0].data = make_default(fields[0].type);
1559 fields[1].type = get_type("uint32");
1560 fields[1].name = "middle";
1561 fields[1].resize = 0;
1562 fields[1].data = make_default(fields[1].type);
1563 fields[2].type = get_type("uint32");
1564 fields[2].name = "minor";
1565 fields[2].resize = 0;
1566 fields[2].data = make_default(fields[2].type);
1567 fields[3].type = get_type("uint32");
1568 fields[3].name = "variety";
1569 fields[3].resize = 0;
1570 fields[3].data = make_default(fields[3].type);
1571 fields[4].type = get_type("uint32");
1572 fields[4].name = "internal";
1573 fields[4].resize = 0;
1574 fields[4].data = make_default(fields[4].type);
1575 fields[5].type = get_type("string");
1576 fields[5].name = "short_info";
1577 fields[5].resize = 64;
1578 fields[5].data = make_data(fields[5].resize, fields[5].type);
1579 fields[6].type = get_type("string");
1580 fields[6].name = "long_info";
1581 fields[6].resize = 256;
1582 fields[6].data = make_data(fields[6].resize, fields[6].type);
1584 memset(fields[5].data.ptr, '\0', fields[5].data.size);
1585 memset(fields[6].data.ptr, '\0', fields[6].data.size);
1587 type_t type;
1588 type.code = 'APPV';
1589 type.name = "app_version";
1590 type.fields = fields;
1591 type.count = 7;
1592 type.def_id = 1;
1593 type.def_name = "BEOS:APP_VERSION";
1595 type_table.insert(make_pair(type.name, type));
1599 static void
1600 add_png_icon()
1602 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1603 fields[0].type = get_type("raw");
1604 fields[0].name = "icon";
1605 fields[0].resize = 0;
1606 fields[0].data = make_data(fields[0].resize, fields[0].type);
1608 type_t type;
1609 type.code = 'PNG ';
1610 type.name = "png_icon";
1611 type.fields = fields;
1612 type.count = 1;
1613 type.def_id = 101;
1614 type.def_name = "BEOS:ICON";
1616 type_table.insert(make_pair(type.name, type));
1620 static void
1621 add_vector_icon()
1623 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1624 fields[0].type = get_type("raw");
1625 fields[0].name = "icon";
1626 fields[0].resize = 0;
1627 fields[0].data = make_data(fields[0].resize, fields[0].type);
1629 type_t type;
1630 type.code = 'VICN';
1631 type.name = "vector_icon";
1632 type.fields = fields;
1633 type.count = 1;
1634 type.def_id = 101;
1635 type.def_name = "BEOS:ICON";
1637 type_table.insert(make_pair(type.name, type));
1641 static void
1642 add_large_icon()
1644 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1645 fields[0].type = get_type("raw");
1646 fields[0].name = "icon";
1647 fields[0].resize = 1024;
1648 fields[0].data = make_data(fields[0].resize, fields[0].type);
1650 type_t type;
1651 type.code = 'ICON';
1652 type.name = "large_icon";
1653 type.fields = fields;
1654 type.count = 1;
1655 type.def_id = 101;
1656 type.def_name = "BEOS:L:STD_ICON";
1658 type_table.insert(make_pair(type.name, type));
1662 static void
1663 add_mini_icon()
1665 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1666 fields[0].type = get_type("raw");
1667 fields[0].name = "icon";
1668 fields[0].resize = 256;
1669 fields[0].data = make_data(fields[0].resize, fields[0].type);
1671 type_t type;
1672 type.code = 'MICN';
1673 type.name = "mini_icon";
1674 type.fields = fields;
1675 type.count = 1;
1676 type.def_id = 101;
1677 type.def_name = "BEOS:M:STD_ICON";
1679 type_table.insert(make_pair(type.name, type));
1683 static void
1684 add_file_types()
1686 field_t* fields = (field_t*)alloc_mem(1 * sizeof(field_t));
1687 fields[0].type = get_type("message");
1688 fields[0].name = "types";
1689 fields[0].resize = 0;
1690 fields[0].data = make_default(fields[0].type);
1692 type_t type;
1693 type.code = 'MSGG';
1694 type.name = "file_types";
1695 type.fields = fields;
1696 type.count = 1;
1697 type.def_id = 1;
1698 type.def_name = "BEOS:FILE_TYPES";
1700 type_table.insert(make_pair(type.name, type));
1704 static void
1705 add_define(const char* name, int32 value)
1707 define_t define;
1708 define.name = name;
1709 define.value = value;
1711 define_table.insert(make_pair(define.name, define));
1715 void
1716 init_parser()
1718 add_builtin_type(B_BOOL_TYPE, "bool");
1719 add_builtin_type(B_INT8_TYPE, "int8");
1720 add_builtin_type(B_UINT8_TYPE, "uint8");
1721 add_builtin_type(B_INT16_TYPE, "int16");
1722 add_builtin_type(B_UINT16_TYPE, "uint16");
1723 add_builtin_type(B_INT32_TYPE, "int32");
1724 add_builtin_type(B_UINT32_TYPE, "uint32");
1725 add_builtin_type(B_SIZE_T_TYPE, "size_t");
1726 add_builtin_type(B_SSIZE_T_TYPE, "ssize_t");
1727 add_builtin_type(B_TIME_TYPE, "time_t");
1728 add_builtin_type(B_INT64_TYPE, "int64");
1729 add_builtin_type(B_UINT64_TYPE, "uint64");
1730 add_builtin_type(B_OFF_T_TYPE, "off_t");
1731 add_builtin_type(B_FLOAT_TYPE, "float");
1732 add_builtin_type(B_DOUBLE_TYPE, "double");
1733 add_builtin_type(B_STRING_TYPE, "string");
1734 add_builtin_type(B_RAW_TYPE, "raw");
1735 add_builtin_type(B_RAW_TYPE, "buffer");
1736 add_builtin_type(B_MESSAGE_TYPE, "message");
1738 add_point_type();
1739 add_rect_type();
1740 add_rgb_color_type();
1741 add_app_signature_type();
1742 add_app_name_catalog_entry();
1743 add_app_flags();
1744 add_app_version();
1745 add_large_icon();
1746 add_mini_icon();
1747 add_vector_icon();
1748 add_png_icon();
1749 add_file_types();
1751 add_define("B_SINGLE_LAUNCH", 0x0);
1752 add_define("B_MULTIPLE_LAUNCH", 0x1);
1753 add_define("B_EXCLUSIVE_LAUNCH", 0x2);
1754 add_define("B_BACKGROUND_APP", 0x4);
1755 add_define("B_ARGV_ONLY", 0x8);
1757 add_define("B_APPV_DEVELOPMENT", 0x0);
1758 add_define("B_APPV_ALPHA", 0x1);
1759 add_define("B_APPV_BETA", 0x2);
1760 add_define("B_APPV_GAMMA", 0x3);
1761 add_define("B_APPV_GOLDEN_MASTER", 0x4);
1762 add_define("B_APPV_FINAL", 0x5);
1766 void
1767 clean_up_parser()
1769 // The symbol table entries have several malloc'ed objects associated
1770 // with them (such as their name). They were allocated with alloc_mem(),
1771 // so we don't need to free them here; compile.cpp already does that
1772 // when it cleans up. However, we do need to remove the entries from
1773 // the tables, otherwise they will still be around the next time we are
1774 // asked to compile something.
1776 #ifdef DEBUG
1777 // Note that in DEBUG mode, we _do_ free these items, so they don't show
1778 // up in the mem leak statistics. The names etc of builtin items are not
1779 // alloc_mem()'d but we still free_mem() them. Not entirely correct, but
1780 // it doesn't seem to hurt, and we only do it in DEBUG mode anyway.
1782 for (sym_iter_t i = symbol_table.begin(); i != symbol_table.end(); ++i) {
1783 free_mem((void*) i->first);
1786 for (type_iter_t i = type_table.begin(); i != type_table.end(); ++i) {
1787 free_mem((void*) i->first);
1788 type_t type = i->second;
1790 for (int32 t = 0; t < type.count; ++t) {
1791 free_mem((void*) type.fields[t].name);
1792 free_mem((void*) type.fields[t].data.ptr);
1794 free_mem((void*) type.fields);
1795 free_mem((void*) type.name);
1796 free_mem((void*) type.def_name);
1798 #endif
1800 symbol_table.clear();
1801 type_table.clear();
1802 define_table.clear();