summaryrefslogtreecommitdiffstats
path: root/src/makemsg.c
blob: 34b3846489da948874cd1d06f07b9964de26864d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* makemsg.c - aeb - 940605 */
/*
 * Read a file input with lines
 *	LABEL "text"
 * and either output two files:
 * a file msgout.c with content      char *msg[] = { "text", ... };
 * and a file msgout.h with content  #define LABEL 1
 * or output a single file:
 * a message catalog with lines      1 "text"
 *
 * The former two are used during compilation of the main program
 * and give default (English) messages. The latter output file is
 * input for gencat, and used in non-English locales.
 *
 * Call:
 *	makemsg input msgout.h msgout.c 
 * or
 *	makemsg -c input message_catalog
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __QNX__
#include <unix.h>
#endif
extern char *index(const char *, int);
extern char *rindex(const char *, int);

#define BUFSIZE 4096

#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')

static void
usage(void){
    fprintf (stderr, "call is: makemsg input msgout.h msgout.c\n");
    fprintf (stderr, "or:  makemsg -c input catalog\n");
    exit (1);
}

int
main(int argc, char **argv) {
    FILE *fin, *foh, *foc;
    char *s, *t;
    char *infile, *outcfile, *outhfile;
    char buf[BUFSIZE];
    int defct = 0;
    int makecat = 0;

#define getbuf	if (fgets (buf, sizeof(buf), fin) == NULL) {\
		    fprintf (stderr, "makemsg: unexpected end of input\n");\
		    fprintf (stderr, "[output file(s) removed]\n");\
		    unlink (outcfile);\
		    if (!makecat) unlink (outhfile);\
		    exit (1);\
		}

    if (argc != 4)
      usage ();

    outhfile = 0; foh = 0;	/* just to keep gcc happy */

    if (!strcmp(argv[1], "-c")) {
	makecat = 1;
	infile = argv[2];
	outcfile = argv[3];
    } else {
	infile = argv[1];
	outhfile = argv[2];
	outcfile = argv[3];
    }

    fin = fopen (infile, "r");
    if (!fin) {
	perror (infile);
	fprintf (stderr, "makemsg: cannot open input file %s\n", infile);
	usage ();
    }

    /* help people not to confuse the order of these args */
    if (!makecat) {
	s = rindex(outhfile, '.');
	if (!s || s[1] != 'h') {
	    fprintf (stderr, "defines output file should have name ending in .h\n");
	    usage ();
	}
	s = rindex(outcfile, '.');
	if (!s || s[1] != 'c') {
	    fprintf (stderr, "string output file should have name ending in .c\n");
	    usage ();
	}
    }

    if (!makecat) {
	foh = fopen (outhfile, "w");
	if (!foh) {
	    perror (argv[1]);
	    fprintf (stderr, "makemsg: cannot open output file %s\n", outhfile);
	    usage ();
	}
    }
    foc = fopen (outcfile, "w");
    if (!foc) {
	perror (argv[2]);
	fprintf (stderr, "makemsg: cannot open output file %s\n", outcfile);
	usage ();
    }

    if (makecat)
      fputs ("$quote \"\n$set 1\n", foc);
    else
      fputs ("char *msg[] = {\n  \"\",\n", foc);

    while (fgets (buf, sizeof(buf), fin) != NULL) {
	char ss;

	/* skip leading blanks and blank lines */
	s = buf;
	while (whitespace(*s))
	  s++;
	if (*s == 0)
	  continue;

	/* extract label part */
	t = s;
	while (*s && !whitespace(*s))
	  s++;
	ss = *s;
	*s = 0;
	if (makecat) {
	    /* the format here used to be "%d  ", but that breaks
	       glibc-2.1.2 gencat */
	    fprintf (foc, "%d ", ++defct); /* gencat cannot handle %2d */
	} else {
	    fprintf (foh, "#define %s %d\n", t, ++defct);
	    fprintf (foc, "/* %2d */  ", defct);
	}
	*s = ss;

	/* skip blanks and newlines until string found */
	while (whitespace(*s) || *s == 0) {
	    if (*s == 0) {
		getbuf;
		s = buf;
	    } else
	      s++;
	}

	/* output string - it may extend over several lines */
	while ((t = index(s, '\n')) == NULL || (t > buf && t[-1] == '\\')) {
	    fputs (s, foc);
	    getbuf;
	    s = buf;
	}
	*t = 0;
	fputs (s, foc);
	if (makecat)
	  fputs ("\n", foc);
	else
	  fputs (",\n", foc);
    }

    if (!makecat) {
	fputs ("};\n", foc);
	fprintf (foh, "\n#define MAXMSG %d\n", defct);
    }

    if (!makecat) {
	fclose (foh);
    }

    fclose (foc);
    fclose (fin);

    return 0;
}