modify ptr_to_globals trick so that we do not violate type safety (well, sort of ;))
No binary (build failed)
—
(log yok)
| @@ -235,7 +235,7 @@ enum { | |
| }; | |
| - | struct global1 { |
| + | struct globals { |
| lng block_start; | |
| @@ -343,7 +343,6 @@ struct global1 { | |
| uint32_t crc; /* shift register contents */ | |
| }; | |
| - | extern struct global1 *ptr_to_globals; |
| #define G1 (*(ptr_to_globals - 1)) | |
| @@ -869,7 +868,7 @@ typedef struct tree_desc { | |
| int max_code; /* largest code with non zero frequency */ | |
| } tree_desc; | |
| - | struct global2 { |
| + | struct globals2 { |
| ush heap[HEAP_SIZE]; /* heap used to build the Huffman trees */ | |
| int heap_len; /* number of elements in the heap */ | |
| @@ -956,7 +955,7 @@ struct global2 { | |
| ulg compressed_len; /* total bit length of compressed file */ | |
| }; | |
| - | #define G2ptr ((struct global2*)(ptr_to_globals)) |
| + | #define G2ptr ((struct globals2*)(ptr_to_globals)) |
| #define G2 (*G2ptr) | |
| @@ -2048,7 +2047,7 @@ int gzip_main(int argc, char **argv) | |
| } | |
| #endif | |
| - | ptr_to_globals = xzalloc(sizeof(struct global1) + sizeof(struct global2)); |
| + | ptr_to_globals = xzalloc(sizeof(struct globals) + sizeof(struct globals2)); |
| ptr_to_globals++; | |
| G2.l_desc.dyn_tree = G2.dyn_ltree; | |
| G2.l_desc.static_tree = G2.static_ltree; | |
| @@ -59,30 +59,33 @@ archival/libunarchive/decompress_unzip.c: | |
| This example completely eliminates globals in that module. | |
| Required memory is allocated in inflate_gunzip() [its main module] | |
| - | and then passed down to all subroutines which need to access globals |
| + | and then passed down to all subroutines which need to access 'globals' |
| as a parameter. | |
| Example 2 | |
| In case you don't want to pass this additional parameter everywhere, | |
| take a look at archival/gzip.c. Here all global data is replaced by | |
| - | singe global pointer (ptr_to_globals) to allocated storage. |
| + | single global pointer (ptr_to_globals) to allocated storage. |
| In order to not duplicate ptr_to_globals in every applet, you can | |
| reuse single common one. It is defined in libbb/messages.c | |
| - | as void *ptr_to_globals, but is NOT declared in libbb.h. |
| - | You first define a struct: |
| + | as struct globals *ptr_to_globals, but the struct globals is |
| + | NOT defined in libbb.h. You first define your own struct: |
| - | struct my_globals { int a; char buf[1000]; }; |
| + | struct globals { int a; char buf[1000]; }; |
| and then declare that ptr_to_globals is a pointer to it: | |
| - | extern struct my_globals *ptr_to_globals; |
| #define G (*ptr_to_globals) | |
| - | Linker magic enures that these two merge into single pointer object. |
| + | Linker magic ensures that these two merge into single pointer object. |
| Now initialize it in <applet>_main(): | |
| ptr_to_globals = xzalloc(sizeof(G)); | |
| and you can reference "globals" by G.a, G.buf and so on, in any function. | |
| + | |
| + | The drawback is that now you have to initialize it by hand. xzalloc() |
| + | can be helpful in clearing allocated storage to 0, but anything more |
| + | must be done by hand. |
| @@ -806,6 +806,10 @@ extern const int const_int_1; | |
| #define BUFSIZ 4096 | |
| #endif | |
| extern char bb_common_bufsiz1[BUFSIZ+1]; | |
| + | /* This struct is deliberately not defined. */ |
| + | /* See docs/keep_data_small.txt */ |
| + | struct globals; |
| + | extern struct globals *ptr_to_globals; |
| /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, | |
| * use bb_default_login_shell and following defines. | |
| @@ -56,4 +56,5 @@ WTMP_FILE; | |
| char bb_common_bufsiz1[BUFSIZ+1]; | |
| - | void *ptr_to_globals; |
| + | struct globals; |
| + | struct globals *ptr_to_globals; |