diff --git a/src/tools/rc/compile.h b/src/tools/rc/compile.h
index 9ba0026dd4..0e544eb988 100644
--- a/src/tools/rc/compile.h
+++ b/src/tools/rc/compile.h
@@ -63,9 +63,10 @@ struct data_t
// Describes a data field in a user-defined type.
struct field_t
{
- type_t type; // data type
- char* name; // name of this field
- data_t data; // default value
+ type_t type; // data type
+ char* name; // name of this field
+ size_t resize; // if not 0, data will be resized
+ data_t data; // default value
};
// Describes an array of data_t or field_t objects.
diff --git a/src/tools/rc/docs/grammar.html b/src/tools/rc/docs/grammar.html
index d66000bce6..53794855a0 100644
--- a/src/tools/rc/docs/grammar.html
+++ b/src/tools/rc/docs/grammar.html
@@ -61,8 +61,8 @@ number, hex number, or four character code. Examples: #200, #0x00C8,
The following are treated as keywords and special symbols:
-enum resource array message archive type { } ( ) , ; = -
-
+enum resource array message archive type import
+{ } ( ) , ; = -
The lexer also deals with #include statements, which look like: #include
"filename"\n. When you #include a file, the lexer expects it to contain valid
@@ -113,7 +113,7 @@ BNF, so the actual bison source file may look a little different. Legend:
| typedef | TYPE [id] [TYPECODE] IDENT '{' fielddef {',' fieldef}
'}' ';' |
-| fielddef | datatype IDENT ['=' data] |
+| fielddef | datatype IDENT ['[' INTEGER ']'] ['=' data] |
| resource | RESOURCE [id] [typecode] data ';' |
@@ -132,7 +132,8 @@ BNF, so the actual bison source file may look a little different. Legend:
| float | ['-'] FLOAT |
-| array | ARRAY ['{' [data {',' data}] '}'] |
+| array | ARRAY ['{' [data {',' data}] '}'] | [ARRAY] IMPORT
+STRING |
| message | MESSAGE ['(' integer ')'] ['{' [msgfield {','
msgfield}] '}'] |
@@ -371,9 +372,11 @@ resource(1) vector { 1, 3, x = 2 };
Note: if a user-defined type contains string, raw, or message fields, the
size of the type depends on the data that the user puts into it, because these
-fields have a variable size. In a future version we will add "constraints" that
-let you force the size of a field to a fixed number of bytes. (And possibly
-other constraints as well, such as a valid data range.)
+fields have a variable size. However, the user may specify a fixed size for a
+field (number of bytes, enclosed in square brackets following the field name).
+In this case, data that is too long will be truncated and data that is too
+short will be padded with zeroes. You can do this for all types, but it really
+only makes sense for strings and raw data.
A type definition may also contain a default resource ID and name. The
default ID of built-in types is usually 1 and the name is empty (NULL). For
diff --git a/src/tools/rc/docs/history.html b/src/tools/rc/docs/history.html
index e5d41ff1ba..d036353c74 100644
--- a/src/tools/rc/docs/history.html
+++ b/src/tools/rc/docs/history.html
@@ -8,6 +8,18 @@
This is the change history of the rc resource compiler and librdef.
+Version 1.1 (not released yet):
+
+
+- You can now import the contents of external files (such as pictures) into
+array resources or fields. This does away with the need to convert (large)
+binary files into text form.
+- You can now give type fields a fixed size, which can be handy for certain
+kinds of string or raw data resources (for example, app_version).
+- Line number counter was not reset properly when compiling multiple rdef
+files in one go.
+
+
Version 1.0 (February 16, 2003):
diff --git a/src/tools/rc/docs/rc.html b/src/tools/rc/docs/rc.html
index c64aebeb33..f73dd0fea0 100644
--- a/src/tools/rc/docs/rc.html
+++ b/src/tools/rc/docs/rc.html
@@ -334,6 +334,31 @@ also be specified as:
resource myint 123;
+Most data types have a fixed size; a uint16 is always 2 bytes long, a float
+always comprises 4 bytes, and so on. But the sizes of string and raw data
+resources depend on what you put in them. Sometimes you may want to force
+these kinds of resources to have a fixed size as well. You can do this as
+follows:
+
+type fixed { string s[64] };
+
+Any resources with type "fixed" will always contain a 64-byte string, no
+matter how many characters you actually specify. Too much data will be
+truncated; too little data will be padded with zeroes. Note that string
+resources are always terminated with a null character, so string "s" in the
+above type only allows for 63 real characters. The number between the square
+brackets always indicates bytes (unlike C/C++ arrays which use a similar
+notation).
+
+If you have (large) binary files that you want to include in the resources,
+such as pictures of Buffy, you don't need to convert the binary data to text
+form first. You can simply "import" the file:
+
+resource(22) #'PNG ' import "buffy.png";
+
+Imported resources are always arrays (raw data), and you can specify the
+import statement everywhere that array data is valid.
+
@@ -439,8 +464,9 @@ them.
The rc resource compiler and its companion library librdef were written by
Matthijs Hollemans for the
-OpenBeOS project. Comments, bug reports,
-suggestions, and patches are welcome!
+OpenBeOS project. Thanks to Ingo Weinhold
+for the Jamfile and the Jam rules. Comments, bug reports, suggestions, and
+patches are welcome!
diff --git a/src/tools/rc/docs/todo.html b/src/tools/rc/docs/todo.html
index 875c8bd7fd..e143beb07f 100644
--- a/src/tools/rc/docs/todo.html
+++ b/src/tools/rc/docs/todo.html
@@ -11,14 +11,7 @@
Simple integer expressions + - * / | & ~ ()
Make user-defined types more powerful. Some ideas: bitmask fields (for
-app_flags), choice fields (for app_version), specify boolean fields as "name"
-(true) or "!name" (false), conditional constructs, fixed-size strings and
-arrays.
-
-Importing files. Right now, you must specify the resource data in the
-rdef script, which is messy for (large) binary files. The "import" feature lets
-you copy the contents of such files (pictures, icons, etc.) straight into your
-resources.
+app_flags), choice fields (for app_version), conditional constructs.
Attributes, so you can also use rdef scripts to add attributes to your
files instead of (or in addition to) resources.
@@ -30,10 +23,10 @@ statement. This can also happen when multiple input files have conflicting
resource IDs.
Support for the built-in types point, rect, and rgb_color is hardcoded
-into the decompiler. The other types, app_flags etc, are not supported at all.
-It would be better to use the type symbol table for this as well. Then the
-decompiler can also support user-defined types (although these type definitions
-must be provided to the decompiler somehow.)
+into the decompiler. The other built-in types--app_flags, mini_icon, etc--are
+not supported at all. It would be better to use the type symbol table for this
+as well. Then the decompiler can also support user-defined types (although these
+type definitions must be provided to the decompiler somehow.)
Right now, archives are treated as messages. Maybe we should give them
their own type, B_ARCHIVED_OBJECT (type code 'ARCV').
diff --git a/src/tools/rc/lexer.l b/src/tools/rc/lexer.l
index f5aaebce76..ded03aec1a 100644
--- a/src/tools/rc/lexer.l
+++ b/src/tools/rc/lexer.l
@@ -90,6 +90,7 @@ array return ARRAY;
message return MESSAGE;
archive return ARCHIVE;
type return TYPE;
+import return IMPORT;
false yylval.b = false; return BOOL;
true yylval.b = true; return BOOL;
@@ -219,12 +220,9 @@ void open_include()
{
yytext[yyleng - 1] = '\0'; // remove trailing " quote
- for (ptr_iter_t i = include_dirs.begin(); i != include_dirs.end(); ++i)
+ char tmpname[B_PATH_NAME_LENGTH];
+ if (open_file_from_include_dir(yytext, tmpname))
{
- char tmpname[B_PATH_NAME_LENGTH];
- strcpy(tmpname, (char*) *i);
- strcat(tmpname, yytext);
-
yyin = fopen(tmpname, "r");
if (yyin != NULL)
{
diff --git a/src/tools/rc/parser.y b/src/tools/rc/parser.y
index 9995aa315a..965c0b26a8 100644
--- a/src/tools/rc/parser.y
+++ b/src/tools/rc/parser.y
@@ -67,6 +67,9 @@ static data_t make_bool(bool);
static data_t make_int(uint64);
static data_t make_float(double);
+static data_t import_data(char*);
+static data_t resize_data(data_t, size_t);
+
static BMessage* make_msg(list_t);
static data_t flatten_msg(BMessage*);
@@ -102,7 +105,7 @@ static void add_resource(id_t, type_code, data_t);
type_t T;
}
-%token ENUM RESOURCE ARCHIVE ARRAY MESSAGE TYPE
+%token ENUM RESOURCE ARCHIVE ARRAY MESSAGE TYPE IMPORT
%token BOOL
%token INTEGER
@@ -176,15 +179,31 @@ typedeffields
typedeffield
: datatype IDENT
{
- $$.type = $1;
- $$.name = $2;
- $$.data = make_default($1);
+ $$.type = $1;
+ $$.name = $2;
+ $$.resize = 0;
+ $$.data = make_default($1);
}
| datatype IDENT '=' data
{
- $$.type = $1;
- $$.name = $2;
- $$.data = cast($1, $4);
+ $$.type = $1;
+ $$.name = $2;
+ $$.resize = 0;
+ $$.data = cast($1, $4);
+ }
+ | datatype IDENT '[' INTEGER ']'
+ {
+ $$.type = $1;
+ $$.name = $2;
+ $$.resize = (size_t) $4;
+ $$.data = resize_data(make_default($1), $$.resize);
+ }
+ | datatype IDENT '[' INTEGER ']' '=' data
+ {
+ $$.type = $1;
+ $$.name = $2;
+ $$.resize = (size_t) $4;
+ $$.data = resize_data(cast($1, $7), $$.resize);
}
;
@@ -253,6 +272,8 @@ array
: ARRAY '{' arrayfields '}' { $$ = $3; }
| ARRAY '{' '}' { $$ = make_data(0, get_type("raw")); }
| ARRAY { $$ = make_data(0, get_type("raw")); }
+ | ARRAY IMPORT STRING { $$ = import_data((char*) $3.ptr); }
+ | IMPORT STRING { $$ = import_data((char*) $2.ptr); }
;
arrayfields
@@ -576,6 +597,67 @@ data_t make_float(double f)
//------------------------------------------------------------------------------
+data_t import_data(char* filename)
+{
+ data_t out;
+ out.type = get_type("raw");
+ out.name = NULL;
+
+ char tmpname[B_PATH_NAME_LENGTH];
+ if (open_file_from_include_dir(filename, tmpname))
+ {
+ BFile file(tmpname, B_READ_ONLY);
+ if (file.InitCheck() == B_OK)
+ {
+ off_t size;
+ if (file.GetSize(&size) == B_OK)
+ {
+ out.size = (size_t) size;
+ out.ptr = alloc_mem(size);
+
+ if (file.Read(out.ptr, out.size) == (ssize_t) out.size)
+ {
+ free_mem(filename);
+ return out;
+ }
+ }
+ }
+ }
+
+ abort_compile(RDEF_COMPILE_ERR, "cannot import %s", filename);
+ return out;
+}
+
+//------------------------------------------------------------------------------
+
+data_t resize_data(data_t data, size_t new_size)
+{
+ if (new_size == 0)
+ {
+ abort_compile(RDEF_COMPILE_ERR, "invalid size %lu", new_size);
+ }
+ else if (data.size != new_size)
+ {
+ void* new_ptr = alloc_mem(new_size);
+
+ memset(new_ptr, 0, new_size);
+ memcpy(new_ptr, data.ptr, min(data.size, new_size));
+
+ if (data.type.code == B_STRING_TYPE)
+ {
+ ((char*) new_ptr)[new_size - 1] = '\0';
+ }
+
+ free_mem(data.ptr);
+ data.ptr = new_ptr;
+ data.size = new_size;
+ }
+
+ return data;
+}
+
+//------------------------------------------------------------------------------
+
BMessage* make_msg(list_t list)
{
BMessage* msg = new BMessage;
@@ -669,8 +751,13 @@ data_t make_default(type_t type)
break;
}
}
- else // user-defined type
+ else
{
+ // For user-defined types, we copy the default values of the fields
+ // into a new data_t object. There is no need to call resize_data()
+ // here, because the default values were already resized to their
+ // proper length when we added them to the type.
+
size_t size = 0;
for (int32 t = 0; t < type.count; ++t)
{
@@ -756,10 +843,14 @@ static data_t convert_slots(type_t type, data_t* slots)
size_t size = 0;
for (int32 k = 0; k < type.count; ++k)
{
- if (slots[k].ptr == NULL)
+ if (slots[k].ptr == NULL) // default value
{
size += type.fields[k].data.size;
}
+ else if (type.fields[k].resize != 0)
+ {
+ size += type.fields[k].resize;
+ }
else
{
size += slots[k].size;
@@ -771,11 +862,18 @@ static data_t convert_slots(type_t type, data_t* slots)
for (int32 k = 0; k < type.count; ++k)
{
- if (slots[k].ptr == NULL)
+ if (slots[k].ptr == NULL) // default value
{
memcpy(ptr, type.fields[k].data.ptr, type.fields[k].data.size);
ptr += type.fields[k].data.size;
}
+ else if (type.fields[k].resize != 0)
+ {
+ data_t temp = resize_data(slots[k], type.fields[k].resize);
+ memcpy(ptr, temp.ptr, temp.size);
+ ptr += temp.size;
+ free_mem(temp.ptr);
+ }
else
{
memcpy(ptr, slots[k].ptr, slots[k].size);
@@ -1190,13 +1288,15 @@ void add_resource(id_t id, type_code code, data_t data)
static void add_point_type()
{
- field_t* fields = (field_t*) alloc_mem(2 * sizeof(field_t));
- fields[0].type = get_type("float");
- fields[0].name = "x";
- fields[0].data = make_default(fields[0].type);
- fields[1].type = get_type("float");
- fields[1].name = "y";
- fields[1].data = make_default(fields[1].type);
+ field_t* fields = (field_t*) alloc_mem(2 * sizeof(field_t));
+ fields[0].type = get_type("float");
+ fields[0].name = "x";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
+ fields[1].type = get_type("float");
+ fields[1].name = "y";
+ fields[1].resize = 0;
+ fields[1].data = make_default(fields[1].type);
type_t type;
type.code = B_POINT_TYPE;
@@ -1213,19 +1313,23 @@ static void add_point_type()
static void add_rect_type()
{
- field_t* fields = (field_t*) alloc_mem(4 * sizeof(field_t));
- fields[0].type = get_type("float");
- fields[0].name = "left";
- fields[0].data = make_default(fields[0].type);
- fields[1].type = get_type("float");
- fields[1].name = "top";
- fields[1].data = make_default(fields[1].type);
- fields[2].type = get_type("float");
- fields[2].name = "right";
- fields[2].data = make_default(fields[2].type);
- fields[3].type = get_type("float");
- fields[3].name = "bottom";
- fields[3].data = make_default(fields[3].type);
+ field_t* fields = (field_t*) alloc_mem(4 * sizeof(field_t));
+ fields[0].type = get_type("float");
+ fields[0].name = "left";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
+ fields[1].type = get_type("float");
+ fields[1].name = "top";
+ fields[1].resize = 0;
+ fields[1].data = make_default(fields[1].type);
+ fields[2].type = get_type("float");
+ fields[2].name = "right";
+ fields[2].resize = 0;
+ fields[2].data = make_default(fields[2].type);
+ fields[3].type = get_type("float");
+ fields[3].name = "bottom";
+ fields[3].resize = 0;
+ fields[3].data = make_default(fields[3].type);
type_t type;
type.code = B_RECT_TYPE;
@@ -1242,19 +1346,24 @@ static void add_rect_type()
static void add_rgb_color_type()
{
- field_t* fields = (field_t*) alloc_mem(4 * sizeof(field_t));
- fields[0].type = get_type("uint8");
- fields[0].name = "red";
- fields[0].data = make_default(fields[0].type);
- fields[1].type = get_type("uint8");
- fields[1].name = "green";
- fields[1].data = make_default(fields[1].type);
- fields[2].type = get_type("uint8");
- fields[2].name = "blue";
- fields[2].data = make_default(fields[2].type);
- fields[3].type = get_type("uint8");
- fields[3].name = "alpha";
- fields[3].data = make_default(fields[3].type);
+ field_t* fields = (field_t*) alloc_mem(4 * sizeof(field_t));
+ fields[0].type = get_type("uint8");
+ fields[0].name = "red";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
+ fields[1].type = get_type("uint8");
+ fields[1].name = "green";
+ fields[1].resize = 0;
+ fields[1].data = make_default(fields[1].type);
+ fields[2].type = get_type("uint8");
+ fields[2].name = "blue";
+ fields[2].resize = 0;
+ fields[2].data = make_default(fields[2].type);
+ fields[3].type = get_type("uint8");
+ fields[3].name = "alpha";
+ fields[3].resize = 0;
+ fields[3].data = make_default(fields[3].type);
+
*((uint8*) fields[3].data.ptr) = 255;
type_t type;
@@ -1272,10 +1381,11 @@ static void add_rgb_color_type()
static void add_app_signature_type()
{
- field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
- fields[0].type = get_type("string");
- fields[0].name = "signature";
- fields[0].data = make_default(fields[0].type);
+ field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
+ fields[0].type = get_type("string");
+ fields[0].name = "signature";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
type_t type;
type.code = 'MIMS';
@@ -1292,10 +1402,11 @@ static void add_app_signature_type()
static void add_app_flags()
{
- field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
- fields[0].type = get_type("uint32");
- fields[0].name = "flags";
- fields[0].data = make_default(fields[0].type);
+ field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
+ fields[0].type = get_type("uint32");
+ fields[0].name = "flags";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
type_t type;
type.code = 'APPF';
@@ -1312,29 +1423,37 @@ static void add_app_flags()
static void add_app_version()
{
- field_t* fields = (field_t*) alloc_mem(7 * sizeof(field_t));
- fields[0].type = get_type("uint32");
- fields[0].name = "major";
- fields[0].data = make_default(fields[0].type);
- fields[1].type = get_type("uint32");
- fields[1].name = "middle";
- fields[1].data = make_default(fields[1].type);
- fields[2].type = get_type("uint32");
- fields[2].name = "minor";
- fields[2].data = make_default(fields[2].type);
- fields[3].type = get_type("uint32");
- fields[3].name = "variety";
- fields[3].data = make_default(fields[3].type);
- fields[4].type = get_type("uint32");
- fields[4].name = "internal";
- fields[4].data = make_default(fields[4].type);
- fields[5].type = get_type("string");
- fields[5].name = "short_info";
- fields[5].data = make_data(64, fields[5].type);
+ field_t* fields = (field_t*) alloc_mem(7 * sizeof(field_t));
+ fields[0].type = get_type("uint32");
+ fields[0].name = "major";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
+ fields[1].type = get_type("uint32");
+ fields[1].name = "middle";
+ fields[1].resize = 0;
+ fields[1].data = make_default(fields[1].type);
+ fields[2].type = get_type("uint32");
+ fields[2].name = "minor";
+ fields[2].resize = 0;
+ fields[2].data = make_default(fields[2].type);
+ fields[3].type = get_type("uint32");
+ fields[3].name = "variety";
+ fields[3].resize = 0;
+ fields[3].data = make_default(fields[3].type);
+ fields[4].type = get_type("uint32");
+ fields[4].name = "internal";
+ fields[4].resize = 0;
+ fields[4].data = make_default(fields[4].type);
+ fields[5].type = get_type("string");
+ fields[5].name = "short_info";
+ fields[5].resize = 64;
+ fields[5].data = make_data(fields[5].resize, fields[5].type);
+ fields[6].type = get_type("string");
+ fields[6].name = "long_info";
+ fields[6].resize = 256;
+ fields[6].data = make_data(fields[6].resize, fields[6].type);
+
memset(fields[5].data.ptr, '\0', fields[5].data.size);
- fields[6].type = get_type("string");
- fields[6].name = "long_info";
- fields[6].data = make_data(256, fields[6].type);
memset(fields[6].data.ptr, '\0', fields[6].data.size);
type_t type;
@@ -1352,10 +1471,11 @@ static void add_app_version()
static void add_large_icon()
{
- field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
- fields[0].type = get_type("raw");
- fields[0].name = "icon";
- fields[0].data = make_default(fields[0].type);
+ field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
+ fields[0].type = get_type("raw");
+ fields[0].name = "icon";
+ fields[0].resize = 1024;
+ fields[0].data = make_data(fields[0].resize, fields[0].type);
type_t type;
type.code = 'ICON';
@@ -1372,10 +1492,11 @@ static void add_large_icon()
static void add_mini_icon()
{
- field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
- fields[0].type = get_type("raw");
- fields[0].name = "icon";
- fields[0].data = make_default(fields[0].type);
+ field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
+ fields[0].type = get_type("raw");
+ fields[0].name = "icon";
+ fields[0].resize = 256;
+ fields[0].data = make_data(fields[0].resize, fields[0].type);
type_t type;
type.code = 'MICN';
@@ -1392,10 +1513,11 @@ static void add_mini_icon()
static void add_file_types()
{
- field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
- fields[0].type = get_type("message");
- fields[0].name = "types";
- fields[0].data = make_default(fields[0].type);
+ field_t* fields = (field_t*) alloc_mem(1 * sizeof(field_t));
+ fields[0].type = get_type("message");
+ fields[0].name = "types";
+ fields[0].resize = 0;
+ fields[0].data = make_default(fields[0].type);
type_t type;
type.code = 'MSGG';
diff --git a/src/tools/rc/private.h b/src/tools/rc/private.h
index 55867dbed9..4b3622a6d1 100644
--- a/src/tools/rc/private.h
+++ b/src/tools/rc/private.h
@@ -24,6 +24,7 @@
#define PRIVATE_H
#include
+#include
typedef std::list ptr_list_t;
typedef ptr_list_t::iterator ptr_iter_t;
@@ -43,4 +44,7 @@ void free_ptr_list(ptr_list_t& list);
// Resets the rdef_err_* variables.
void clear_error();
+// Scans all include dirs for the specified file.
+bool open_file_from_include_dir(const char* filename, char* outname);
+
#endif // PRIVATE_H
diff --git a/src/tools/rc/rc.cpp b/src/tools/rc/rc.cpp
index 018f719d81..4ad886c7be 100644
--- a/src/tools/rc/rc.cpp
+++ b/src/tools/rc/rc.cpp
@@ -27,7 +27,7 @@
#include "rdef.h"
-#define TITLE "OpenBeOS Resource Compiler 1.0"
+#define TITLE "OpenBeOS Resource Compiler 1.1"
#define DEFAULT_OUT_RSRC "out.rsrc"
#define DEFAULT_OUT_RDEF "out.rdef"
diff --git a/src/tools/rc/rdef.cpp b/src/tools/rc/rdef.cpp
index ed9697825e..87329ae77c 100644
--- a/src/tools/rc/rdef.cpp
+++ b/src/tools/rc/rdef.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include "rdef.h"
#include "private.h"
@@ -132,3 +133,23 @@ void clear_error()
}
//------------------------------------------------------------------------------
+
+bool open_file_from_include_dir(const char* filename, char* outname)
+{
+ for (ptr_iter_t i = include_dirs.begin(); i != include_dirs.end(); ++i)
+ {
+ char tmpname[B_PATH_NAME_LENGTH];
+ strcpy(tmpname, (char*) *i);
+ strcat(tmpname, filename);
+
+ if (access(tmpname, R_OK) == 0)
+ {
+ strcpy(outname, tmpname);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------------------
diff --git a/src/tools/rc/tests/array.rdef b/src/tools/rc/tests/array.rdef
index dae4c7bd10..778cb34faa 100644
--- a/src/tools/rc/tests/array.rdef
+++ b/src/tools/rc/tests/array.rdef
@@ -125,3 +125,28 @@ resource(1) #'MICN' array {
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
};
+
+resource(350) #'CSTR' import "import.txt";
+resource(351) #'CSTR' array import "import.txt";
+
+resource(352) #'CSTR' array
+{
+ array import "import.txt", array import "import.txt"
+};
+
+resource(353) #'CSTR' array
+{
+ import "import.txt"
+};
+
+type #'CSTR' import_t
+{
+ array field1 = array import "import.txt",
+ array field2
+};
+
+resource(354) import_t;
+resource(355) import_t { field1 = array { "a" }, field2 = array { "b" } };
+resource(356) import_t { field2 = array { "-booh" } };
+
+//resource(359) #'CSTR' array import "does-not-exist.txt";
diff --git a/src/tools/rc/tests/builtin.rdef b/src/tools/rc/tests/builtin.rdef
index 485a1225ff..e77bf3916b 100644
--- a/src/tools/rc/tests/builtin.rdef
+++ b/src/tools/rc/tests/builtin.rdef
@@ -60,26 +60,20 @@ type(1, "BEOS:APP_VERSION") #'APPV' app_version
uint32 internal,
- string short_info = // must be exactly 64 bytes (including null)
- " ",
-
- string long_info = // must be exactly 256 bytes (including null)
- " "
- " "
- " "
- " "
+ string short_info[64],
+ string long_info[256]
};
/* Large (32x32, 8-bit) application icon. */
type(101, "BEOS:L:STD_ICON") #'ICON' large_icon
{
- array icon // 1024 bytes
+ array icon[1024]
};
/* Small (16x16, 8-bit) application icon. */
type(101, "BEOS:M:STD_ICON") #'MICN' mini_icon
{
- array icon // 256 bytes
+ array icon[256]
};
/* Supported file types. */
diff --git a/src/tools/rc/tests/import.txt b/src/tools/rc/tests/import.txt
new file mode 100644
index 0000000000..510edc452d
--- /dev/null
+++ b/src/tools/rc/tests/import.txt
@@ -0,0 +1 @@
+a text file
\ No newline at end of file
diff --git a/src/tools/rc/tests/type.rdef b/src/tools/rc/tests/type.rdef
index d1bdae3481..5fdbf3b518 100644
--- a/src/tools/rc/tests/type.rdef
+++ b/src/tools/rc/tests/type.rdef
@@ -140,6 +140,8 @@ resource(871) ye_olde_raw 64;
//resource(890) myraw { 123 }; // invalid cast
//resource(890) (myrect) { 123 }; // invalid cast
+//------------------------------------------------------------------------------
+
enum {
R_Point = 100,
R_Rect = 100,
@@ -159,65 +161,83 @@ resource app_signature "application/x-vnd.vendor.appname";
resource app_flags;
resource app_version;
-
-resource large_icon array
-{
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-};
-
-resource mini_icon array
-{
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-};
+resource large_icon;
+resource mini_icon;
resource file_types message
{
"types" = "text/plain",
"types" = "text/x-source-code"
};
+
+//------------------------------------------------------------------------------
+
+type #'CSTR' notfixed1 { string s };
+resource(901) notfixed1; // empty string
+resource(902) notfixed1 "hi"; // "hi"
+resource(903) notfixed1 "hellotherepeeps"; // "hellotherepeeps"
+
+type #'CSTR' notfixed2 { string s = "hello" };
+resource(904) notfixed2; // "hello"
+resource(905) notfixed2 "hi"; // "hi"
+resource(906) notfixed2 "hellotherepeeps"; // "hellotherepeeps"
+
+type notfixed3 { array a };
+resource(907) notfixed3; // 0 bytes
+resource(908) notfixed3 array { // 3 bytes
+ (uint8) 0x01, (uint8) 0x02, (uint8) 0x03 };
+
+type #'CSTR' fixed1 { string s[10] };
+resource(910) fixed1; // 10 null bytes
+resource(911) fixed1 "hello"; // 5 chars, 5 nulls
+resource(912) fixed1 "hellotherepeeps"; // 9 chars, 1 null
+
+type #'CSTR' fixed2 { string s[10] = "hello" };
+resource(913) fixed2; // 5 chars, 5 nulls
+resource(914) fixed2 "hi"; // 2 chars, 8 nulls
+resource(915) fixed2 "hellotherepeeps"; // 9 chars, 1 null
+
+type #'CSTR' fixed3 { string s[2] = "hello" };
+resource(916) fixed3; // 1 char, 1 null
+resource(917) fixed3 "woot"; // 1 char, 1 null
+
+type #'BYTE' fixed4 { int32 i[1] = 1026 };
+resource(921) fixed4; // one byte with value 2
+resource(922) fixed4 1027; // one byte with value 3
+
+type #'BYTE' fixed5 { int32 i[1] };
+resource(923) fixed5; // one byte with value 0
+resource(924) fixed5 1026; // one byte with value 2
+
+type fixed6 { int32 i[8] };
+resource(925) fixed6; // eight bytes with value 0
+resource(926) fixed6 0xDEADBEEF; // EFBEADDE00000000
+
+type fixed7 { int32 i[4] }; // int32 is already 4 bytes,
+resource(927) fixed7; // so the [4] is ignored
+resource(928) fixed7 1234;
+
+type fixed8 { array a[3] };
+resource(930) fixed8; // 000000
+resource(931) fixed8 array { // 112200
+ (uint8) 0x11, (uint8) 0x22 };
+resource(932) fixed8 array { // 112233
+ (uint8) 0x11, (uint8) 0x22,
+ (uint8) 0x33, (uint8) 0x44 };
+
+type fixed9 { array a[3] = array {
+ (uint8) 0x11, (uint8) 0x22, (uint8) 0x33 } };
+resource(933) fixed9; // 112233
+resource(934) fixed9 array { // 778800
+ (uint8) 0x77, (uint8) 0x88 };
+resource(935) fixed9 array { // 667788
+ (uint8) 0x66, (uint8) 0x77,
+ (uint8) 0x88, (uint8) 0x99 };
+
+type fixed10 { message msg[2] };
+resource(936) fixed10;
+
+type fixed11 { fixed10 f[1] };
+resource(937) fixed11;
+
+//type fixed0 { string s[0] }; // invalid size