1/* makemsg.c - aeb - 940605 */ 2/* 3 * Read a file input with lines 4 * LABEL "text" 5 * and either output two files: 6 * a file msgout.c with content char *msg[] = { "text", ... }; 7 * and a file msgout.h with content #define LABEL 1 8 * or output a single file: 9 * a message catalog with lines 1 "text" 10 * 11 * The former two are used during compilation of the main program 12 * and give default (English) messages. The latter output file is 13 * input for gencat, and used in non-English locales. 14 * 15 * Call: 16 * makemsg input msgout.h msgout.c 17 * or 18 * makemsg -c input message_catalog 19 */ 20#include <stdio.h> 21#include <unistd.h> 22#ifdef __QNX__ 23#include <unix.h> 24#endif 25extern char *index(const char *, int); 26extern char *rindex(const char *, int); 27 28#define BUFSIZE 4096 29 30#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') 31 32static void 33usage(void){ 34 fprintf (stderr, "call is: makemsg input msgout.h msgout.c\n"); 35 fprintf (stderr, "or: makemsg -c input catalog\n"); 36 exit (1); 37} 38 39int 40main(int argc, char **argv) { 41 FILE *fin, *foh, *foc; 42 char *s, *t; 43 char *infile, *outcfile, *outhfile; 44 char buf[BUFSIZE]; 45 int defct = 0; 46 int makecat = 0; 47 48#define getbuf if (fgets (buf, sizeof(buf), fin) == NULL) {\ 49 fprintf (stderr, "makemsg: unexpected end of input\n");\ 50 fprintf (stderr, "[output file(s) removed]\n");\ 51 unlink (outcfile);\ 52 if (!makecat) unlink (outhfile);\ 53 exit (1);\ 54 } 55 56 if (argc != 4) 57 usage (); 58 59 outhfile = 0; foh = 0; /* just to keep gcc happy */ 60 61 if (!strcmp(argv[1], "-c")) { 62 makecat = 1; 63 infile = argv[2]; 64 outcfile = argv[3]; 65 } else { 66 infile = argv[1]; 67 outhfile = argv[2]; 68 outcfile = argv[3]; 69 } 70 71 fin = fopen (infile, "r"); 72 if (!fin) { 73 perror (infile); 74 fprintf (stderr, "makemsg: cannot open input file %s\n", infile); 75 usage (); 76 } 77 78 /* help people not to confuse the order of these args */ 79 if (!makecat) { 80 s = rindex(outhfile, '.'); 81 if (!s || s[1] != 'h') { 82 fprintf (stderr, "defines output file should have name ending in .h\n"); 83 usage (); 84 } 85 s = rindex(outcfile, '.'); 86 if (!s || s[1] != 'c') { 87 fprintf (stderr, "string output file should have name ending in .c\n"); 88 usage (); 89 } 90 } 91 92 if (!makecat) { 93 foh = fopen (outhfile, "w"); 94 if (!foh) { 95 perror (argv[1]); 96 fprintf (stderr, "makemsg: cannot open output file %s\n", outhfile); 97 usage (); 98 } 99 } 100 foc = fopen (outcfile, "w"); 101 if (!foc) { 102 perror (argv[2]); 103 fprintf (stderr, "makemsg: cannot open output file %s\n", outcfile); 104 usage (); 105 } 106 107 if (makecat) 108 fputs ("$quote \"\n$set 1\n", foc); 109 else 110 fputs ("char *msg[] = {\n \"\",\n", foc); 111 112 while (fgets (buf, sizeof(buf), fin) != NULL) { 113 char ss; 114 115 /* skip leading blanks and blank lines */ 116 s = buf; 117 while (whitespace(*s)) 118 s++; 119 if (*s == 0) 120 continue; 121 122 /* extract label part */ 123 t = s; 124 while (*s && !whitespace(*s)) 125 s++; 126 ss = *s; 127 *s = 0; 128 if (makecat) { 129 /* the format here used to be "%d ", but that breaks 130 glibc-2.1.2 gencat */ 131 fprintf (foc, "%d ", ++defct); /* gencat cannot handle %2d */ 132 } else { 133 fprintf (foh, "#define %s %d\n", t, ++defct); 134 fprintf (foc, "/* %2d */ ", defct); 135 } 136 *s = ss; 137 138 /* skip blanks and newlines until string found */ 139 while (whitespace(*s) || *s == 0) { 140 if (*s == 0) { 141 getbuf; 142 s = buf; 143 } else 144 s++; 145 } 146 147 /* output string - it may extend over several lines */ 148 while ((t = index(s, '\n')) == NULL || (t > buf && t[-1] == '\\')) { 149 fputs (s, foc); 150 getbuf; 151 s = buf; 152 } 153 *t = 0; 154 fputs (s, foc); 155 if (makecat) 156 fputs ("\n", foc); 157 else 158 fputs (",\n", foc); 159 } 160 161 if (!makecat) { 162 fputs ("};\n", foc); 163 fprintf (foh, "\n#define MAXMSG %d\n", defct); 164 } 165 166 if (!makecat) { 167 fclose (foh); 168 } 169 170 fclose (foc); 171 fclose (fin); 172 173 return 0; 174} 175