This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perlop - Invocant only needs to be an object or class name for method calls
[perl5.git] / generate_uudmap.c
CommitLineData
51ecf1ac
DM
1/* generate_uudmap.c:
2
3 Create three .h files, whose names are specified as argv[1..3],
4 but are usually uudmap.h, bitcount.h and mg_data.h.
5
6 It uses mg_raw.h as input, plus it relies on the C compiler knowing
7 the ord value of character literals under EBCDIC, to generate output
8 tables on an order which are platform-specific.
9
10 The outputs are:
11
12 uudmap.h:
13 The values which will populate PL_uumap[], as used by
14 unpack('u').
15
16 bitcount.h
17 The values which will populate PL_bitcount[]:
18 this is a count of bits for each U8 value 0..255.
19 (I'm not sure why this has to be generated - surely it's
20 platform-independent - DAPM.)
21
22 mg_data.h
23 Takes the input from mg_raw.h and sorts by it magic char;
24 the values will populate PL_magic_data[]: this is an array of
25 per-magic U8 values containing an index into PL_magic_vtables[]
26 plus two flags:
27 PERL_MAGIC_READONLY_ACCEPTABLE
28 PERL_MAGIC_VALUE_MAGIC
29
30 Originally this program just generated uudmap.h
efa50c51
NC
31 However, when we later wanted to generate bitcount.h, it was easier to
32 refactor it and keep the same name, than either alternative - rename it,
51ecf1ac
DM
33 or duplicate all of the Makefile logic for a second program.
34 Ditto when mg_data.h was added.
35*/
efa50c51 36
6d62b57d
NC
37#include <stdio.h>
38#include <stdlib.h>
2b1d1392
NC
39/* If it turns out that we need to make this conditional on config.sh derived
40 values, it might be easier just to rip out the use of strerrer(). */
41#include <string.h>
42/* If a platform doesn't support errno.h, it's probably so strange that
43 "hello world" won't port easily to it. */
44#include <errno.h>
6d62b57d 45
6f83ef0e
NC
46struct mg_data_raw_t {
47 unsigned char type;
48 const char *value;
49 const char *comment;
50};
51
52static struct mg_data_raw_t mg_data_raw[] = {
53#ifdef WIN32
54# include "..\mg_raw.h"
55#else
56# include "mg_raw.h"
57#endif
58 {0, 0, 0}
59};
60
61struct mg_data_t {
62 const char *value;
63 const char *comment;
64};
65
66static struct mg_data_t mg_data[256];
67
68static void
69format_mg_data(FILE *out, const void *thing, size_t count) {
70 const struct mg_data_t *p = (const struct mg_data_t *)thing;
71
72 while (1) {
73 if (p->value) {
1604cfb0 74 fprintf(out, " %s\n %s", p->comment, p->value);
6f83ef0e 75 } else {
1604cfb0 76 fputs(" 0", out);
6f83ef0e
NC
77 }
78 ++p;
79 if (!--count)
1604cfb0 80 break;
6f83ef0e
NC
81 fputs(",\n", out);
82 }
83 fputc('\n', out);
84}
85
546efe9f
NC
86static void
87format_char_block(FILE *out, const void *thing, size_t count) {
88 const char *block = (const char *)thing;
869053c8 89
546efe9f 90 fputs(" ", out);
869053c8
NC
91 while (count--) {
92 fprintf(out, "%d", *block);
93 block++;
94 if (count) {
95 fputs(", ", out);
96 if (!(count & 15)) {
1604cfb0 97 fputs("\n ", out);
869053c8
NC
98 }
99 }
100 }
546efe9f
NC
101 fputc('\n', out);
102}
103
104static void
105output_to_file(const char *progname, const char *filename,
1604cfb0
MS
106 void (format_function)(FILE *out, const void *thing, size_t count),
107 const void *thing, size_t count,
51ecf1ac
DM
108 const char *header
109) {
546efe9f
NC
110 FILE *const out = fopen(filename, "w");
111
112 if (!out) {
113 fprintf(stderr, "%s: Could not open '%s': %s\n", progname, filename,
1604cfb0 114 strerror(errno));
546efe9f
NC
115 exit(1);
116 }
117
51ecf1ac
DM
118 fprintf(out, "/* %s:\n", filename);
119 fprintf(out, " * THIS FILE IS AUTO-GENERATED DURING THE BUILD by: %s\n",
120 progname);
121 fprintf(out, " *\n%s\n*/\n{\n", header);
546efe9f
NC
122 format_function(out, thing, count);
123 fputs("}\n", out);
869053c8
NC
124
125 if (fclose(out)) {
126 fprintf(stderr, "%s: Could not close '%s': %s\n", progname, filename,
1604cfb0 127 strerror(errno));
869053c8
NC
128 exit(1);
129 }
130}
131
132
6d62b57d
NC
133static const char PL_uuemap[]
134= "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
135
136typedef unsigned char U8;
137
e87b2888 138/* This will ensure it is initialized to all zeros. */
6d62b57d 139static char PL_uudmap[256];
efa50c51 140static char PL_bitcount[256];
6d62b57d 141
2b1d1392 142int main(int argc, char **argv) {
6d62b57d 143 size_t i;
efa50c51 144 int bits;
6f83ef0e 145 struct mg_data_raw_t *p = mg_data_raw;
2b1d1392 146
6f83ef0e
NC
147 if (argc < 4 || argv[1][0] == '\0' || argv[2][0] == '\0'
148 || argv[3][0] == '\0') {
149 fprintf(stderr, "Usage: %s uudemap.h bitcount.h mg_data.h\n", argv[0]);
2b1d1392
NC
150 return 1;
151 }
152
6d62b57d 153 for (i = 0; i < sizeof(PL_uuemap) - 1; ++i)
0934c9d9 154 PL_uudmap[(U8)PL_uuemap[i]] = (char)i;
6d62b57d
NC
155 /*
156 * Because ' ' and '`' map to the same value,
157 * we need to decode them both the same.
158 */
159 PL_uudmap[(U8)' '] = 0;
160
546efe9f 161 output_to_file(argv[0], argv[1], &format_char_block,
1604cfb0 162 (const void *)PL_uudmap, sizeof(PL_uudmap),
51ecf1ac
DM
163 " * These values will populate PL_uumap[], as used by unpack('u')"
164 );
6d62b57d 165
efa50c51
NC
166 for (bits = 1; bits < 256; bits++) {
167 if (bits & 1) PL_bitcount[bits]++;
168 if (bits & 2) PL_bitcount[bits]++;
169 if (bits & 4) PL_bitcount[bits]++;
170 if (bits & 8) PL_bitcount[bits]++;
171 if (bits & 16) PL_bitcount[bits]++;
172 if (bits & 32) PL_bitcount[bits]++;
173 if (bits & 64) PL_bitcount[bits]++;
174 if (bits & 128) PL_bitcount[bits]++;
175 }
176
546efe9f 177 output_to_file(argv[0], argv[2], &format_char_block,
1604cfb0 178 (const void *)PL_bitcount, sizeof(PL_bitcount),
51ecf1ac
DM
179 " * These values will populate PL_bitcount[]:\n"
180 " * this is a count of bits for each U8 value 0..255"
181 );
efa50c51 182
6f83ef0e
NC
183 while (p->value) {
184 mg_data[p->type].value = p->value;
185 mg_data[p->type].comment = p->comment;
186 ++p;
187 }
188
189 output_to_file(argv[0], argv[3], &format_mg_data,
1604cfb0 190 (const void *)mg_data, sizeof(mg_data)/sizeof(mg_data[0]),
51ecf1ac
DM
191 " * These values will populate PL_magic_data[]: this is an array of\n"
192 " * per-magic U8 values containing an index into PL_magic_vtables[]\n"
193 " * plus two flags:\n"
194 " * PERL_MAGIC_READONLY_ACCEPTABLE\n"
195 " * PERL_MAGIC_VALUE_MAGIC"
196 );
6f83ef0e 197
6d62b57d
NC
198 return 0;
199}