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.
38 #define YYERROR_VERBOSE
40 static void yyerror(const char*);
42 struct ident_compare_t
{ // allows the maps to compare identifier names
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 //------------------------------------------------------------------------------
119 %token ENUM RESOURCE ARCHIVE ARRAY MESSAGE RTYPE IMPORT
124 %token
<d
> STRING RAW
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
154 : enumstart
'{' '}' ';'
155 | enumstart
'{' symbols
'}' ';'
156 | enumstart
'{' symbols
',' '}' ';'
160 : ENUM
{ enum_cnt
= 0; }
164 : symbols
',' symboldef
171 add_symbol
($1, enum_cnt
);
176 int32 id
= (int32
) $3;
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);
194 : typedeffields
',' typedeffield
{ $$
= concat_field_list
($1, $3); }
195 | typedeffield
{ $$
= make_field_list
($1); }
204 $$.data
= make_default
($1);
206 | datatype IDENT
'=' expr
211 $$.data
= cast
($1, $4);
213 | datatype IDENT
'[' INTEGER
']'
217 $$.resize
= (size_t) $4;
218 $$.data
= resize_data
(make_default
($1), $$.resize
);
220 | datatype IDENT
'[' INTEGER
']' '=' expr
224 $$.resize
= (size_t) $4;
225 $$.data
= resize_data
(cast
($1, $7), $$.resize
);
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);
247 $$.has_id
= false
; $$.has_name
= false
; $$.name
= NULL
;
251 $$.has_id
= false
; $$.has_name
= false
; $$.name
= NULL
;
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
;
265 $$.has_id
= true
; $$.id
= get_symbol
($2);
267 if
(flags
& RDEF_AUTO_NAMES
)
269 $$.has_name
= true
; $$.name
= $2;
273 $$.has_name
= false
; $$.name
= NULL
;
277 |
'(' IDENT
',' STRING
')'
279 $$.has_id
= true
; $$.id
= get_symbol
($2);
280 $$.has_name
= true
; $$.name
= (char*) $4.ptr
;
286 $$.has_name
= true
; $$.name
= (char*) $2.ptr
;
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
); }
299 : arrayfields
',' expr
{ $$
= concat_data
($1, $3); }
300 | expr
{ $$
= $1; $$.type
= get_type
("raw"); }
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
); }
328 : msgfields
',' msgfield
{ $$
= concat_data_list
($1, $3); }
329 | msgfield
{ $$
= make_data_list
($1); }
336 $$.name
= (char*) $1.ptr
;
338 | datatype STRING
'=' expr
341 $$.name
= (char*) $2.ptr
;
343 | TYPECODE STRING
'=' expr
347 $$.name
= (char*) $2.ptr
;
349 | TYPECODE datatype STRING
'=' expr
353 $$.name
= (char*) $3.ptr
;
358 : ARCHIVE IDENT
'{' msgfields
'}'
360 BMessage
* msg
= make_msg
($4);
361 msg
->AddString
("class", $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
);
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);
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
);
390 $$
= flatten_msg
(msg
);
395 : IDENT
'{' typefields
'}' { $$
= make_type
($1, $3); }
398 list_t list
; list.count
= 0; list.items
= NULL
;
399 $$
= make_type
($1, list
);
403 $$
= make_type
($1, make_data_list
($2));
405 | type_or_define
{ $$
= $1; }
413 list_t list
; list.count
= 0; list.items
= NULL
;
414 $$
= make_type
($1, list
);
418 define_t define
= get_define
($1);
419 $$
= cast
(get_type
("int32"), make_int
(define.value
));
426 : typefields
',' typefield
{ $$
= concat_data_list
($1, $3); }
427 | typefield
{ $$
= make_data_list
($1); }
431 : IDENT
'=' expr
{ $$
= $3; $$.name
= $1; }
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, '~'); }
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); }
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); }
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); }
486 : INTEGER
{ $$
= $1; }
487 |
'-' INTEGER
{ $$
= -($2); }
492 |
'-' FLOAT
{ $$
= -($2); }
496 //------------------------------------------------------------------------------
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
);
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
));
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
);
536 add_builtin_type
(type_code code
, const char* name
)
544 type.def_name
= NULL
;
546 type_table.insert
(make_pair
(name
, type
));
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
);
559 type.count
= list.count
;
560 type.fields
= (field_t
*) list.items
;
562 type.def_name
= NULL
;
568 type.def_name
= id.name
;
570 type_table.insert
(make_pair
(name
, type
));
575 is_builtin_type
(type_t type
)
577 return type.count
== 0;
582 same_type
(type_t type1
, type_t type2
)
584 return type1.name
== type2.name
; // no need for strcmp
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
);
601 is_type
(const char* name
)
603 return type_table.find
(name
) != type_table.end
();
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
);
620 make_data
(size_t size
, type_t type
)
626 out.ptr
= alloc_mem
(size
);
634 data_t out
= make_data
(sizeof
(bool), get_type
("bool"));
635 *((bool*)out.ptr
) = b
;
643 data_t out
= make_data
(sizeof
(uint64
), get_type
("uint64"));
644 *((uint64
*)out.ptr
) = i
;
652 data_t out
= make_data
(sizeof
(double), get_type
("double"));
653 *((double*)out.ptr
) = f
;
659 import_data
(char* filename
)
662 out.type
= get_type
("raw");
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
) {
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
) {
682 abort_compile
(RDEF_COMPILE_ERR
, "cannot import %s", filename
);
688 resize_data
(data_t data
, size_t newSize
)
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';
702 data.ptr
= newBuffer
;
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
);
722 free_mem
(list.items
);
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
);
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
);
744 make_default
(type_t type
)
748 if
(is_builtin_type
(type
)) {
751 out
= make_data
(sizeof
(bool), type
);
752 *((bool*)out.ptr
) = false
;
757 out
= make_data
(sizeof
(uint8
), type
);
758 *((uint8
*)out.ptr
) = 0;
763 out
= make_data
(sizeof
(uint16
), type
);
764 *((uint16
*)out.ptr
) = 0;
772 out
= make_data
(sizeof
(uint32
), type
);
773 *((uint32
*)out.ptr
) = 0;
779 out
= make_data
(sizeof
(uint64
), type
);
780 *((uint64
*)out.ptr
) = 0;
784 out
= make_data
(sizeof
(float), type
);
785 *((float*)out.ptr
) = 0.0f
;
789 out
= make_data
(sizeof
(double), type
);
790 *((double*)out.ptr
) = 0.0;
794 out
= make_data
(sizeof
(char), type
);
795 *((char*)out.ptr
) = '\0';
799 out
= make_data
(0, type
);
803 out
= flatten_msg
(new BMessage
);
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.
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
;
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
) {
842 for
(int32 k
= 0; k
< type.count
; ++k
) {
843 if
(slots
[k
].ptr
== NULL
) {
844 slots
[k
] = cast
(type.fields
[k
].type
, data
);
851 abort_compile
(RDEF_COMPILE_ERR
, "too many fields");
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
);
868 abort_compile
(RDEF_COMPILE_ERR
, "unknown field %s", data.name
);
877 convert_slots
(type_t type
, data_t
* slots
)
880 for
(int32 k
= 0; k
< type.count
; ++k
) {
881 if
(slots
[k
].ptr
== NULL
) {
883 size
+= type.fields
[k
].data.size
;
884 } else if
(type.fields
[k
].resize
!= 0)
885 size
+= type.fields
[k
].resize
;
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
) {
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
);
904 memcpy
(ptr
, slots
[k
].ptr
, slots
[k
].size
);
905 ptr
+= slots
[k
].size
;
906 free_mem
(slots
[k
].ptr
);
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
);
933 free_mem
(list.items
);
939 make_field_list
(field_t field
)
943 out.items
= alloc_mem
(sizeof
(field_t
));
944 *((field_t
*)out.items
) = field
;
950 concat_field_list
(list_t list
, field_t field
)
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
);
965 make_data_list
(data_t data
)
969 out.items
= alloc_mem
(sizeof
(data_t
));
970 *((data_t
*)out.items
) = data
;
976 concat_data_list
(list_t list
, data_t data
)
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
);
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
);
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
) {
1012 *((uint8
*)out.ptr
) = *(uint8
*)data.ptr
;
1017 *((uint8
*)out.ptr
) = (uint8
)*(uint16
*)data.ptr
;
1023 case B_SSIZE_T_TYPE
:
1025 *((uint8
*)out.ptr
) = (uint8
)*(uint32
*)data.ptr
;
1031 *((uint8
*)out.ptr
) = (uint8
)*(uint64
*)data.ptr
;
1035 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
) {
1051 *((uint16
*)out.ptr
) = (uint16
)*(uint8
*)data.ptr
;
1056 *((uint16
*)out.ptr
) = *(uint16
*)data.ptr
;
1062 case B_SSIZE_T_TYPE
:
1064 *((uint16
*)out.ptr
) = (uint16
)*(uint32
*)data.ptr
;
1070 *((uint16
*)out.ptr
) = (uint16
)*(uint64
*)data.ptr
;
1074 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
) {
1090 *((uint32
*)out.ptr
) = (uint32
)*(uint8
*)data.ptr
;
1095 *((uint32
*)out.ptr
) = (uint32
)*(uint16
*)data.ptr
;
1101 case B_SSIZE_T_TYPE
:
1103 *((uint32
*)out.ptr
) = *(uint32
*)data.ptr
;
1109 *((uint32
*)out.ptr
) = (uint32
)*(uint64
*)data.ptr
;
1113 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
) {
1129 *((uint64
*)out.ptr
) = (uint64
)*(uint8
*)data.ptr
;
1134 *((uint64
*)out.ptr
) = (uint64
)*(uint16
*)data.ptr
;
1140 case B_SSIZE_T_TYPE
:
1142 *((uint64
*)out.ptr
) = (uint64
)*(uint32
*)data.ptr
;
1148 *((uint64
*)out.ptr
) = *(uint64
*)data.ptr
;
1152 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
) {
1168 *((float*)out.ptr
) = (float)*((uint8
*)data.ptr
);
1173 *((float*)out.ptr
) = (float)*((uint16
*)data.ptr
);
1179 case B_SSIZE_T_TYPE
:
1181 *((float*)out.ptr
) = (float)*((uint32
*)data.ptr
);
1187 *((float*)out.ptr
) = (float)*((uint64
*)data.ptr
);
1191 *((float*)out.ptr
) = (float)*((double*)data.ptr
);
1195 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
) {
1211 *((double*)out.ptr
) = (double)*((uint8
*)data.ptr
);
1216 *((double*)out.ptr
) = (double)*((uint16
*)data.ptr
);
1222 case B_SSIZE_T_TYPE
:
1224 *((double*)out.ptr
) = (double)*((uint32
*)data.ptr
);
1230 *((double*)out.ptr
) = (double)*((uint64
*)data.ptr
);
1234 *((double*)out.ptr
) = (double)*((float*)data.ptr
);
1238 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
1256 if
(is_builtin_type
(newType
)) {
1257 switch
(newType.code
) {
1260 return cast_to_uint8
(newType
, data
);
1264 return cast_to_uint16
(newType
, data
);
1269 case B_SSIZE_T_TYPE
:
1271 return cast_to_uint32
(newType
, data
);
1276 return cast_to_uint64
(newType
, data
);
1279 return cast_to_float
(newType
, data
);
1282 return cast_to_double
(newType
, data
);
1285 // you can always cast anything to raw
1286 data.type
= newType
;
1291 abort_compile
(RDEF_COMPILE_ERR
, "cannot cast to this type");
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
);
1311 return cast
(get_type
("int32"), out
);
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
);
1326 out
= make_int
(i1
+ i2
);
1329 out
= make_int
(i1
- i2
);
1332 out
= make_int
(i1
* i2
);
1337 abort_compile
(RDEF_COMPILE_ERR
, "division by zero");
1339 out
= make_int
(i1
/ i2
);
1344 abort_compile
(RDEF_COMPILE_ERR
, "division by zero");
1346 out
= make_int
(i1 % i2
);
1350 out
= make_int
(i1 | i2
);
1353 out
= make_int
(i1 ^ i2
);
1356 out
= make_int
(i1
& i2
);
1363 return cast
(get_type
("int32"), out
);
1368 add_resource
(res_id_t id
, type_code code
, data_t data
)
1371 id.id
= data.type.def_id
;
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
);
1381 rdef_err
= RDEF_WRITE_ERR
;
1383 strcpy
(rdef_err_file
, rsrc_file
);
1384 sprintf
(rdef_err_msg
, "cannot add resource (%s)", strerror
(err
));
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
);
1409 type.code
= B_POINT_TYPE
;
1410 type.name
= "point";
1411 type.fields
= fields
;
1414 type.def_name
= NULL
;
1416 type_table.insert
(make_pair
(type.name
, 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
);
1442 type.code
= B_RECT_TYPE
;
1444 type.fields
= fields
;
1447 type.def_name
= NULL
;
1449 type_table.insert
(make_pair
(type.name
, type
));
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;
1477 type.code
= B_RGB_COLOR_TYPE
;
1478 type.name
= "rgb_color";
1479 type.fields
= fields
;
1482 type.def_name
= NULL
;
1484 type_table.insert
(make_pair
(type.name
, type
));
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
);
1499 type.name
= "app_signature";
1500 type.fields
= fields
;
1503 type.def_name
= "BEOS:APP_SIG";
1505 type_table.insert
(make_pair
(type.name
, type
));
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
);
1519 type.code
= B_STRING_TYPE
;
1520 type.name
= "app_name_catalog_entry";
1521 type.fields
= fields
;
1524 type.def_name
= "SYS:NAME";
1526 type_table.insert
(make_pair
(type.name
, type
));
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
);
1541 type.name
= "app_flags";
1542 type.fields
= fields
;
1545 type.def_name
= "BEOS:APP_FLAGS";
1547 type_table.insert
(make_pair
(type.name
, type
));
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
);
1589 type.name
= "app_version";
1590 type.fields
= fields
;
1593 type.def_name
= "BEOS:APP_VERSION";
1595 type_table.insert
(make_pair
(type.name
, type
));
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
);
1610 type.name
= "png_icon";
1611 type.fields
= fields
;
1614 type.def_name
= "BEOS:ICON";
1616 type_table.insert
(make_pair
(type.name
, type
));
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
);
1631 type.name
= "vector_icon";
1632 type.fields
= fields
;
1635 type.def_name
= "BEOS:ICON";
1637 type_table.insert
(make_pair
(type.name
, type
));
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
);
1652 type.name
= "large_icon";
1653 type.fields
= fields
;
1656 type.def_name
= "BEOS:L:STD_ICON";
1658 type_table.insert
(make_pair
(type.name
, type
));
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
);
1673 type.name
= "mini_icon";
1674 type.fields
= fields
;
1677 type.def_name
= "BEOS:M:STD_ICON";
1679 type_table.insert
(make_pair
(type.name
, type
));
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
);
1694 type.name
= "file_types";
1695 type.fields
= fields
;
1698 type.def_name
= "BEOS:FILE_TYPES";
1700 type_table.insert
(make_pair
(type.name
, type
));
1705 add_define
(const char* name
, int32 value
)
1709 define.value
= value
;
1711 define_table.insert
(make_pair
(define.name
, define
));
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");
1740 add_rgb_color_type
();
1741 add_app_signature_type
();
1742 add_app_name_catalog_entry
();
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);
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.
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
);
1800 symbol_table.clear
();
1802 define_table.clear
();