This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update IO-Compress to CPAN version 2.061
[perl5.git] / generate_uudmap.c
1 /* Originally this program just generated uudmap.h
2    However, when we later wanted to generate bitcount.h, it was easier to
3    refactor it and keep the same name, than either alternative - rename it,
4    or duplicate all of the Makefile logic for a second program.  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 /* If it turns out that we need to make this conditional on config.sh derived
9    values, it might be easier just to rip out the use of strerrer().  */
10 #include <string.h>
11 /* If a platform doesn't support errno.h, it's probably so strange that
12    "hello world" won't port easily to it.  */
13 #include <errno.h>
14
15 struct mg_data_raw_t {
16     unsigned char type;
17     const char *value;
18     const char *comment;
19 };
20
21 static struct mg_data_raw_t mg_data_raw[] = {
22 #ifdef WIN32
23 #  include "..\mg_raw.h"
24 #else
25 #  include "mg_raw.h"
26 #endif
27     {0, 0, 0}
28 };
29
30 struct mg_data_t {
31     const char *value;
32     const char *comment;
33 };
34
35 static struct mg_data_t mg_data[256];
36
37 static void
38 format_mg_data(FILE *out, const void *thing, size_t count) {
39   const struct mg_data_t *p = (const struct mg_data_t *)thing;
40
41   while (1) {
42       if (p->value) {
43           fprintf(out, "    %s\n    %s", p->comment, p->value);
44       } else {
45           fputs("    0", out);
46       }
47       ++p;
48       if (!--count)
49           break;
50       fputs(",\n", out);
51   }
52   fputc('\n', out);
53 }
54
55 static void
56 format_char_block(FILE *out, const void *thing, size_t count) {
57   const char *block = (const char *)thing;
58
59   fputs("    ", out);
60   while (count--) {
61     fprintf(out, "%d", *block);
62     block++;
63     if (count) {
64       fputs(", ", out);
65       if (!(count & 15)) {
66         fputs("\n    ", out);
67       }
68     }
69   }
70   fputc('\n', out);
71 }
72
73 static void
74 output_to_file(const char *progname, const char *filename,
75                void (format_function)(FILE *out, const void *thing, size_t count),
76                const void *thing, size_t count) {
77   FILE *const out = fopen(filename, "w");
78
79   if (!out) {
80     fprintf(stderr, "%s: Could not open '%s': %s\n", progname, filename,
81             strerror(errno));
82     exit(1);
83   }
84
85   fputs("{\n", out);
86   format_function(out, thing, count);
87   fputs("}\n", out);
88
89   if (fclose(out)) {
90     fprintf(stderr, "%s: Could not close '%s': %s\n", progname, filename,
91             strerror(errno));
92     exit(1);
93   }
94 }
95
96
97 static const char PL_uuemap[]
98 = "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
99
100 typedef unsigned char U8;
101
102 /* This will ensure it is all zeros.  */
103 static char PL_uudmap[256];
104 static char PL_bitcount[256];
105
106 int main(int argc, char **argv) {
107   size_t i;
108   int bits;
109   struct mg_data_raw_t *p = mg_data_raw;
110
111   if (argc < 4 || argv[1][0] == '\0' || argv[2][0] == '\0'
112       || argv[3][0] == '\0') {
113     fprintf(stderr, "Usage: %s uudemap.h bitcount.h mg_data.h\n", argv[0]);
114     return 1;
115   }
116
117   for (i = 0; i < sizeof(PL_uuemap) - 1; ++i)
118     PL_uudmap[(U8)PL_uuemap[i]] = (char)i;
119   /*
120    * Because ' ' and '`' map to the same value,
121    * we need to decode them both the same.
122    */
123   PL_uudmap[(U8)' '] = 0;
124
125   output_to_file(argv[0], argv[1], &format_char_block,
126                  (const void *)PL_uudmap, sizeof(PL_uudmap));
127
128   for (bits = 1; bits < 256; bits++) {
129     if (bits & 1)       PL_bitcount[bits]++;
130     if (bits & 2)       PL_bitcount[bits]++;
131     if (bits & 4)       PL_bitcount[bits]++;
132     if (bits & 8)       PL_bitcount[bits]++;
133     if (bits & 16)      PL_bitcount[bits]++;
134     if (bits & 32)      PL_bitcount[bits]++;
135     if (bits & 64)      PL_bitcount[bits]++;
136     if (bits & 128)     PL_bitcount[bits]++;
137   }
138
139   output_to_file(argv[0], argv[2], &format_char_block,
140                  (const void *)PL_bitcount, sizeof(PL_bitcount));
141
142   while (p->value) {
143       mg_data[p->type].value = p->value;
144       mg_data[p->type].comment = p->comment;
145       ++p;
146   }
147       
148   output_to_file(argv[0], argv[3], &format_mg_data,
149                  (const void *)mg_data, sizeof(mg_data)/sizeof(mg_data[0]));
150
151   return 0;
152 }