214 lines
3.7 KiB
C
214 lines
3.7 KiB
C
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
char **unique_ids;
|
|
int unique_ids_size;
|
|
int unique_ids_maxsize;
|
|
|
|
int cmp(const void *p1, const void *p2) {
|
|
return strcmp(*(char *const *)p1, *(char *const *)p2);
|
|
}
|
|
|
|
/* return 1 if s was not already known, 0 if it was */
|
|
int new_unique_id(char *s, char *input_file) {
|
|
if (unique_ids_size)
|
|
if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) {
|
|
printf("error: ID %s is not unique in %s\n", s, input_file);
|
|
return 0;
|
|
}
|
|
|
|
if (unique_ids_size == unique_ids_maxsize) {
|
|
unique_ids_maxsize += 256;
|
|
unique_ids = realloc(unique_ids, unique_ids_maxsize * sizeof(char *));
|
|
|
|
if (unique_ids == NULL) {
|
|
printf("error: out of memory\n");
|
|
abort();
|
|
}
|
|
}
|
|
|
|
unique_ids[unique_ids_size] = strdup(s);
|
|
|
|
if (unique_ids[unique_ids_size] == NULL) {
|
|
printf("error: out of memory\n");
|
|
abort();
|
|
}
|
|
|
|
unique_ids_size++;
|
|
qsort(unique_ids, unique_ids_size, sizeof(char *), cmp);
|
|
return 1;
|
|
}
|
|
|
|
char *bufname;
|
|
int bufname_size;
|
|
int bufname_maxsize;
|
|
|
|
void putname(int c) {
|
|
if (bufname_size == bufname_maxsize) {
|
|
bufname_maxsize += 256;
|
|
bufname = realloc(bufname, bufname_maxsize);
|
|
|
|
if (bufname == NULL) {
|
|
printf("error: memory allocation error\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
bufname[bufname_size] = c;
|
|
bufname_size++;
|
|
}
|
|
|
|
char *bufvalue;
|
|
int bufvalue_size;
|
|
int bufvalue_maxsize;
|
|
|
|
void putvalue(int c) {
|
|
if (bufvalue_size == bufvalue_maxsize) {
|
|
bufvalue_maxsize += 256;
|
|
bufvalue = realloc(bufvalue, bufvalue_maxsize);
|
|
|
|
if (bufvalue == NULL) {
|
|
printf("error: memory allocation error\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
bufvalue[bufvalue_size] = c;
|
|
bufvalue_size++;
|
|
}
|
|
|
|
void smash_spaces(FILE *f) {
|
|
int c;
|
|
|
|
while (1) {
|
|
c = fgetc(f);
|
|
|
|
if (isspace(c)) continue;
|
|
|
|
if (c == ' ') continue;
|
|
|
|
if (c == '\t') continue;
|
|
|
|
if (c == '\n') continue;
|
|
|
|
if (c == 10 || c == 13) continue;
|
|
|
|
if (c == '#') {
|
|
while (1) {
|
|
c = fgetc(f);
|
|
|
|
if (c == '\n' || c == EOF) break;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (c != EOF) ungetc(c, f);
|
|
}
|
|
|
|
void get_line(FILE *f, char **name, char **value) {
|
|
int c;
|
|
bufname_size = 0;
|
|
bufvalue_size = 0;
|
|
*name = NULL;
|
|
*value = NULL;
|
|
smash_spaces(f);
|
|
c = fgetc(f);
|
|
|
|
while (!(c == '=' || isspace(c) || c == EOF)) {
|
|
putname(c);
|
|
c = fgetc(f);
|
|
}
|
|
|
|
if (c == EOF) return;
|
|
|
|
putname(0);
|
|
|
|
while (!(c == EOF || c == '=')) c = fgetc(f);
|
|
|
|
if (c == EOF) return;
|
|
|
|
smash_spaces(f);
|
|
c = fgetc(f);
|
|
|
|
while (!(c == 10 || c == 13 || c == EOF)) {
|
|
putvalue(c);
|
|
c = fgetc(f);
|
|
}
|
|
|
|
putvalue(0);
|
|
|
|
if (bufname_size <= 1) return;
|
|
|
|
if (bufvalue_size <= 1) return;
|
|
|
|
*name = bufname;
|
|
*value = bufvalue;
|
|
}
|
|
|
|
int main(int n, char **v) {
|
|
FILE *in;
|
|
FILE *out;
|
|
char *name;
|
|
char *value;
|
|
char *in_name;
|
|
char *out_name;
|
|
|
|
if (n != 3) {
|
|
printf("error: gimme <source> <dest>\n");
|
|
exit(1);
|
|
}
|
|
|
|
n = 0;
|
|
in_name = v[1];
|
|
out_name = v[2];
|
|
in = fopen(in_name, "r");
|
|
|
|
if (in == NULL) {
|
|
perror(in_name);
|
|
exit(1);
|
|
}
|
|
|
|
out = fopen(out_name, "w");
|
|
|
|
if (out == NULL) {
|
|
perror(out_name);
|
|
exit(1);
|
|
}
|
|
|
|
fprintf(out, "/* generated file, do not edit by hand */\n\n");
|
|
|
|
while (1) {
|
|
get_line(in, &name, &value);
|
|
|
|
if (name == NULL) break;
|
|
|
|
if (isspace(value[strlen(value)-1])) {
|
|
printf("error: bad value '%s' (no space at the end please!)\n", value);
|
|
unlink(out_name);
|
|
exit(1);
|
|
}
|
|
|
|
if (!strcmp(name, "ID")) {
|
|
if (!new_unique_id(value, in_name)) {
|
|
unlink(out_name);
|
|
exit(1);
|
|
}
|
|
|
|
fprintf(out, "#define T_%s T_ID(%d)\n", value, n);
|
|
n++;
|
|
}
|
|
}
|
|
|
|
fprintf(out, "#define T_NUMBER_OF_IDS %d\n", n);
|
|
fclose(in);
|
|
fclose(out);
|
|
return 0;
|
|
}
|