This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
generate_uudmap.c: Clarify comment
[perl5.git] / generate_uudmap.c
CommitLineData
efa50c51
NC
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
6d62b57d
NC
6#include <stdio.h>
7#include <stdlib.h>
2b1d1392
NC
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>
6d62b57d 14
6f83ef0e
NC
15struct mg_data_raw_t {
16 unsigned char type;
17 const char *value;
18 const char *comment;
19};
20
21static 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
30struct mg_data_t {
31 const char *value;
32 const char *comment;
33};
34
35static struct mg_data_t mg_data[256];
36
37static void
38format_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
546efe9f
NC
55static void
56format_char_block(FILE *out, const void *thing, size_t count) {
57 const char *block = (const char *)thing;
869053c8 58
546efe9f 59 fputs(" ", out);
869053c8
NC
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 }
546efe9f
NC
70 fputc('\n', out);
71}
72
73static void
74output_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);
869053c8
NC
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
6d62b57d
NC
97static const char PL_uuemap[]
98= "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
99
100typedef unsigned char U8;
101
e87b2888 102/* This will ensure it is initialized to all zeros. */
6d62b57d 103static char PL_uudmap[256];
efa50c51 104static char PL_bitcount[256];
6d62b57d 105
2b1d1392 106int main(int argc, char **argv) {
6d62b57d 107 size_t i;
efa50c51 108 int bits;
6f83ef0e 109 struct mg_data_raw_t *p = mg_data_raw;
2b1d1392 110
6f83ef0e
NC
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]);
2b1d1392
NC
114 return 1;
115 }
116
6d62b57d 117 for (i = 0; i < sizeof(PL_uuemap) - 1; ++i)
0934c9d9 118 PL_uudmap[(U8)PL_uuemap[i]] = (char)i;
6d62b57d
NC
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
546efe9f
NC
125 output_to_file(argv[0], argv[1], &format_char_block,
126 (const void *)PL_uudmap, sizeof(PL_uudmap));
6d62b57d 127
efa50c51
NC
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
546efe9f
NC
139 output_to_file(argv[0], argv[2], &format_char_block,
140 (const void *)PL_bitcount, sizeof(PL_bitcount));
efa50c51 141
6f83ef0e
NC
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
6d62b57d
NC
151 return 0;
152}