version update
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bootstrap.c
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 // Bootstrap for themes.
7
8 // By default, concatenates all the resources and a table of contents
9 // into an object file with objcopy.
10
11 // Run nm <object> to get the symbols created by bootstrap.
12
13 // The user must make extern variable declarations like
14 // extern unsigned char _binary_myobject_data_start[];
15 // and link the object to get at the symbols.
16
17 // Pass the symbol like
18 // _binary_destname_o_start
19 // to BC_Theme::set_data to set an image table for a theme.
20
21
22 // Because of the need for runtime compilation of source files for OpenGL,
23 // it now supports loading a single resource and omitting the table of contents.
24
25
26
27
28 // Usage: bootstrap <dest object> <resource> * n
29
30
31
32
33 void append_contents(char *path,
34         int data_offset,
35         char *buffer,
36         int *buffer_size)
37 {
38         char string[1024];
39         int i, j = 0;
40
41         for(i = strlen(path) - 1;
42                 i > 0 && path[i] && path[i] != '/';
43                 i--)
44                 ;
45
46         if(path[i] == '/') i++;
47
48         for(j = 0; path[i] != 0; i++, j++)
49                 string[j] = path[i];
50
51         string[j] = 0;
52
53         strcpy(buffer + *buffer_size, string);
54
55         *buffer_size += strlen(string) + 1;
56
57         *(int*)(buffer + *buffer_size) = data_offset;
58         *buffer_size += sizeof(int);
59 }
60
61 int main(int argc, char *argv[])
62 {
63         FILE *dest;
64         FILE *src;
65         int i;
66         char *contents_buffer;
67         int contents_size = 0;
68         char *data_buffer;
69         int data_size = 0;
70         int data_offset = 0;
71         char temp_path[1024];
72         char out_path[1024];
73         char *ptr;
74 // TODO 2100 to get rid of compiler warning, but better solution needed:
75 // temp_path and out_path parsing have potential buffer overflow.
76         char system_command[2100];   
77         int current_arg = 1;
78         int binary_mode = 0;
79         int string_mode = 0;
80
81         if(argc < 3)
82         {
83                 fprintf(stderr, "Usage: bootstrap [-b] <dest object> <resource> * n\n");
84                 fprintf(stderr, "-b - omit table of contents just store resource.\n");
85                 fprintf(stderr, "-s - omit table of contents but append 0 to resource.\n");
86                 exit(1);
87         }
88
89         if(!strcmp(argv[current_arg], "-b"))
90         {
91                 binary_mode = 1;
92                 current_arg++;
93         }
94
95         if(!strcmp(argv[current_arg], "-s"))
96         {
97                 string_mode = 1;
98                 current_arg++;
99         }
100
101 // Make object filename
102         strcpy(temp_path, argv[current_arg]);
103         strcpy(out_path, argv[current_arg++]);
104         ptr = strchr(temp_path, '.');
105         if(ptr)
106         {
107                 *ptr = 0;
108         }
109         else
110         {
111                 fprintf(stderr, "Dest path must end in .o\n");
112                 exit(1);
113         }
114
115         if(!(dest = fopen(temp_path, "w")))
116         {
117                 fprintf(stderr, "Couldn't open dest file %s. %s\n",
118                         temp_path,
119                         strerror(errno));
120                 exit(1);
121         }
122
123         if(!(data_buffer = malloc(0x1000000)))
124         {
125                 fprintf(stderr, "Not enough memory to allocate data buffer.\n");
126                 exit(1);
127         }
128
129         if(!(contents_buffer = malloc(0x100000)))
130         {
131                 fprintf(stderr, "Not enough memory to allocate contents buffer.\n");
132                 exit(1);
133         }
134
135 // Leave space for offset to data
136         contents_size = sizeof(int);
137
138 // Read through all the resources, concatenate to dest file,
139 // and record the contents.
140         while(current_arg < argc)
141         {
142                 char *path = argv[current_arg++];
143                 if(!(src = fopen(path, "r")))
144                 {
145                         fprintf(stderr, "%s while opening %s\n", strerror(errno), path);
146                 }
147                 else
148                 {
149                         int size;
150                         fseek(src, 0, SEEK_END);
151                         size = ftell(src);
152                         fseek(src, 0, SEEK_SET);
153
154                         data_offset = data_size;
155
156                         if(!binary_mode && !string_mode)
157                         {
158 // Write size of image in data buffer
159                                 *(data_buffer + data_size) = (size & 0xff000000) >> 24;
160                                 data_size++;
161                                 *(data_buffer + data_size) = (size & 0xff0000) >> 16;
162                                 data_size++;
163                                 *(data_buffer + data_size) = (size & 0xff00) >> 8;
164                                 data_size++;
165                                 *(data_buffer + data_size) = size & 0xff;
166                                 data_size++;
167                         }
168
169                         int temp = fread(data_buffer + data_size, 1, size, src);
170                         data_size += size;
171 // Terminate string
172                         if(string_mode) data_buffer[data_size++] = 0;
173                         fclose(src);
174
175                         if(!binary_mode && !string_mode)
176                         {
177 // Create contents
178                                 append_contents(path,
179                                         data_offset,
180                                         contents_buffer,
181                                         &contents_size);
182                         }
183                 }
184         }
185
186         if(!binary_mode && !string_mode)
187         {
188 // Finish off size of contents
189                 *(int*)(contents_buffer) = contents_size;
190 // Write contents
191                 fwrite(contents_buffer, 1, contents_size, dest);
192         }
193
194 // Write data
195         fwrite(data_buffer, 1, data_size, dest);
196         fclose(dest);
197
198 // Run system command on it
199         sprintf(system_command, "%s %s %s", BOOTSTRAP, temp_path, out_path);
200         int temp = system(system_command);
201         return 0;
202 }
203
204