153 lines
3.7 KiB
C
153 lines
3.7 KiB
C
|
/* Originally this program just generated uudmap.h
|
||
|
However, when we later wanted to generate bitcount.h, it was easier to
|
||
|
refactor it and keep the same name, than either alternative - rename it,
|
||
|
or duplicate all of the Makefile logic for a second program. */
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
/* If it turns out that we need to make this conditional on config.sh derived
|
||
|
values, it might be easier just to rip out the use of strerrer(). */
|
||
|
#include <string.h>
|
||
|
/* If a platform doesn't support errno.h, it's probably so strange that
|
||
|
"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;
|
||
|
|
||
|
fputs(" ", out);
|
||
|
while (count--) {
|
||
|
fprintf(out, "%d", *block);
|
||
|
block++;
|
||
|
if (count) {
|
||
|
fputs(", ", out);
|
||
|
if (!(count & 15)) {
|
||
|
fputs("\n ", out);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fputc('\n', out);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
output_to_file(const char *progname, const char *filename,
|
||
|
void (format_function)(FILE *out, const void *thing, size_t count),
|
||
|
const void *thing, size_t count) {
|
||
|
FILE *const out = fopen(filename, "w");
|
||
|
|
||
|
if (!out) {
|
||
|
fprintf(stderr, "%s: Could not open '%s': %s\n", progname, filename,
|
||
|
strerror(errno));
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
fputs("{\n", out);
|
||
|
format_function(out, thing, count);
|
||
|
fputs("}\n", out);
|
||
|
|
||
|
if (fclose(out)) {
|
||
|
fprintf(stderr, "%s: Could not close '%s': %s\n", progname, filename,
|
||
|
strerror(errno));
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static const char PL_uuemap[]
|
||
|
= "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
|
||
|
|
||
|
typedef unsigned char U8;
|
||
|
|
||
|
/* This will ensure it is initialized to all zeros. */
|
||
|
static char PL_uudmap[256];
|
||
|
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 < 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;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < sizeof(PL_uuemap) - 1; ++i)
|
||
|
PL_uudmap[(U8)PL_uuemap[i]] = (char)i;
|
||
|
/*
|
||
|
* Because ' ' and '`' map to the same value,
|
||
|
* we need to decode them both the same.
|
||
|
*/
|
||
|
PL_uudmap[(U8)' '] = 0;
|
||
|
|
||
|
output_to_file(argv[0], argv[1], &format_char_block,
|
||
|
(const void *)PL_uudmap, sizeof(PL_uudmap));
|
||
|
|
||
|
for (bits = 1; bits < 256; bits++) {
|
||
|
if (bits & 1) PL_bitcount[bits]++;
|
||
|
if (bits & 2) PL_bitcount[bits]++;
|
||
|
if (bits & 4) PL_bitcount[bits]++;
|
||
|
if (bits & 8) PL_bitcount[bits]++;
|
||
|
if (bits & 16) PL_bitcount[bits]++;
|
||
|
if (bits & 32) PL_bitcount[bits]++;
|
||
|
if (bits & 64) PL_bitcount[bits]++;
|
||
|
if (bits & 128) PL_bitcount[bits]++;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|