summaryrefslogtreecommitdiff
path: root/generate_uudmap.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2011-05-15 13:21:09 +0100
committerNicholas Clark <nick@ccl4.org>2011-06-11 10:39:59 +0200
commit6f83ef0e5a45c465f83de3304c5818ba44492250 (patch)
tree6b5a754cde4ee86baf633e6415f18b5fd8e721ff /generate_uudmap.c
parent546efe9fbd6c3c651c39b369e97d0835230a0f9f (diff)
downloadperl-6f83ef0e5a45c465f83de3304c5818ba44492250.tar.gz
Create a lookup table for magic vtables from magic type, PL_magic_data.
Use it to eliminate the large switch statement in Perl_sv_magic(). As the table needs to be keyed on magic type, which is expressed as C character constants, the order depends on the compiler's character set. Frustratingly, EBCDIC variants don't agree on the code points for '~' and ']', which we use here. Instead of having (at least) 4 tables, get the local runtime to sort the table for us. Hence the regen script writes out the (unsorted) mg_raw.h, which generate_uudmap sorts to generate mg_data.h
Diffstat (limited to 'generate_uudmap.c')
-rw-r--r--generate_uudmap.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/generate_uudmap.c b/generate_uudmap.c
index 6159259add..b6307c09cf 100644
--- a/generate_uudmap.c
+++ b/generate_uudmap.c
@@ -12,6 +12,46 @@
"hello world" won't port easily to it. */
#include <errno.h>
+struct mg_data_raw_t {
+ unsigned char type;
+ const char *value;
+ const char *comment;
+};
+
+static struct mg_data_raw_t mg_data_raw[] = {
+#ifdef WIN32
+# include "..\mg_raw.h"
+#else
+# include "mg_raw.h"
+#endif
+ {0, 0, 0}
+};
+
+struct mg_data_t {
+ const char *value;
+ const char *comment;
+};
+
+static struct mg_data_t mg_data[256];
+
+static void
+format_mg_data(FILE *out, const void *thing, size_t count) {
+ const struct mg_data_t *p = (const struct mg_data_t *)thing;
+
+ while (1) {
+ if (p->value) {
+ fprintf(out, " %s\n %s", p->comment, p->value);
+ } else {
+ fputs(" 0", out);
+ }
+ ++p;
+ if (!--count)
+ break;
+ fputs(",\n", out);
+ }
+ fputc('\n', out);
+}
+
static void
format_char_block(FILE *out, const void *thing, size_t count) {
const char *block = (const char *)thing;
@@ -66,9 +106,11 @@ static char PL_bitcount[256];
int main(int argc, char **argv) {
size_t i;
int bits;
+ struct mg_data_raw_t *p = mg_data_raw;
- if (argc < 3 || argv[1][0] == '\0' || argv[2][0] == '\0') {
- fprintf(stderr, "Usage: %s uudemap.h bitcount.h\n", argv[0]);
+ if (argc < 4 || argv[1][0] == '\0' || argv[2][0] == '\0'
+ || argv[3][0] == '\0') {
+ fprintf(stderr, "Usage: %s uudemap.h bitcount.h mg_data.h\n", argv[0]);
return 1;
}
@@ -97,5 +139,14 @@ int main(int argc, char **argv) {
output_to_file(argv[0], argv[2], &format_char_block,
(const void *)PL_bitcount, sizeof(PL_bitcount));
+ while (p->value) {
+ mg_data[p->type].value = p->value;
+ mg_data[p->type].comment = p->comment;
+ ++p;
+ }
+
+ output_to_file(argv[0], argv[3], &format_mg_data,
+ (const void *)mg_data, sizeof(mg_data)/sizeof(mg_data[0]));
+
return 0;
}