8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / exstr / exstr.c
blob72270f6ccda029da470f0c49f177322bcec3ded9
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <stdio.h>
34 #include <ctype.h>
35 #include <sys/types.h>
36 #include <signal.h>
37 #include <setjmp.h>
38 #include <string.h>
40 /* external functions */
42 extern int getopt();
43 extern void exit();
44 extern int atoi();
45 extern int _filbuf();
46 extern char *optarg;
47 extern int optind, opterr;
49 /* static functions */
51 static void extract();
52 static void replace();
53 static void yankstr();
54 static void badformat();
55 static void prstr();
56 static int getachar();
57 static void usage();
59 /* static variables */
61 static int eflg; /* find strings in source file(s) */
62 static int dflg; /* use replaced string a second argument */
63 static int rflg; /* replace strings by function calls */
64 static int errflg; /* syntax error on command line */
65 static char *Fname; /* name of source file */
66 static int Lineno; /* line number in source file */
67 static int Posno; /* character position within line */
68 static int flag; /* sets when newline is encountered */
69 static jmp_buf to_eof;
72 int
73 main(int argc, char *argv[])
75 int ch;
77 while ((ch = getopt(argc, argv, "erd")) != -1)
78 switch (ch) {
79 case 'e':
80 if (rflg)
81 errflg++;
82 else
83 eflg++;
84 continue;
85 case 'r':
86 if (eflg)
87 errflg++;
88 else
89 rflg++;
90 continue;
91 case 'd':
92 if (eflg)
93 errflg++;
94 else
95 dflg++;
96 continue;
97 default:
98 errflg++;
100 if (optind == argc || errflg)
101 usage();
102 if (!rflg)
103 for (; optind < argc; optind++)
104 extract(argv[optind]);
105 else {
106 if (optind+1 != argc)
107 usage();
108 replace(argv[optind]);
110 return (0);
113 static void
114 extract(name)
115 char *name;
117 if (freopen(name, "r", stdin) == NULL) {
118 (void) fprintf(
119 stderr, "exstr: ERROR: couldn't open file '%s'\n", name);
120 exit(1);
122 Fname = name;
123 flag = 1;
124 Lineno = 0;
126 if (setjmp(to_eof) != 0)
127 return;
129 for (;;) {
130 char ch;
132 ch = getachar();
134 switch (ch) {
135 case '#':
136 if (Posno != 0)
137 continue;
138 do {
139 ch = getachar();
140 } while (isspace(ch));
141 if (ch == 'd')
142 continue;
143 while (getachar() != '\n');
144 break;
145 case '"':
146 yankstr();
147 break;
148 case '\'':
149 while ((ch = getachar()) != '\'')
150 if (ch == '\\')
151 ch = getachar();
152 break;
154 case '/':
155 ch = getachar();
156 if (ch == '*') {
157 int level = 0;
158 while (level != 2) {
159 ch = getachar();
160 if (level == 0 && ch == '*')
161 level++;
162 else if (level == 1 && ch == '/')
163 level++;
164 else
165 level = 0;
168 break;
173 static void
174 yankstr()
176 char cc;
177 char dbuf[BUFSIZ];
178 register char *dp = dbuf;
179 int saved_posno;
180 int saved_lineno;
182 saved_posno = Posno;
183 saved_lineno = Lineno;
184 while ((cc = getachar()) != '"') {
185 if (cc == '\\') {
186 *dp++ = cc;
187 cc = getachar();
189 if (cc == '\n') {
190 dp--;
191 continue;
193 *dp++ = cc;
195 *dp = 0;
196 prstr(dbuf, saved_lineno, saved_posno);
199 static void
200 prstr(cp, lineno, posno)
201 register char *cp;
203 if (eflg)
204 (void) fprintf(stdout, "%s:%d:%d:::%s\n", Fname, lineno, posno,
205 cp);
206 else
207 (void) fprintf(stdout, "%s:%s\n", Fname, cp);
211 static void
212 usage()
214 (void) fprintf(stderr, "usage: exstr [-e] files\n");
215 (void) fprintf(stderr, "or : exstr -r [-d] file\n");
216 exit(1);
219 static int
220 getachar()
222 int cc;
224 cc = getchar();
225 if (flag) {
226 Lineno++;
227 Posno = 0;
228 flag = 0;
229 } else
230 Posno++;
231 if (cc == EOF)
232 longjmp(to_eof, 1);
233 if (cc == '\n')
234 flag = 1;
235 return (cc);
239 static void
240 replace(name)
241 char *name;
243 char linebuf[BUFSIZ];
244 char *cp;
245 int curlineno; /* line number in strings file */
246 int curposno; /* character position in string file */
247 int savelineno = 0;
248 int curmsgno; /* message number in strings file */
249 int wrong_msg; /* invalid message number */
250 int cont_str = 0; /* string continues in the next line */
251 char *repstr;
252 char repbuf[BUFSIZ], *repbufp;
253 char curline[BUFSIZ];
254 char outbuf[BUFSIZ];
255 /* keeps track of character position within input file */
256 char *inp;
257 /* keeps track of character position within output buffer */
258 char *outp;
259 char *msgfile;
260 FILE *fi; /* input source file pointer */
262 inp = linebuf;
263 outp = outbuf;
264 linebuf[0] = '\0';
265 /* open input C source file */
266 if ((fi = fopen(name, "r")) == (FILE *)NULL) {
267 (void) fprintf(stderr,
268 "exstr: ERROR: couldn't open file '%s'\n", name);
269 exit(1);
271 Fname = name;
273 (void) fprintf(stdout, "extern char *gettxt();\n");
275 /* process file containing the list of strings */
276 while (fgets(repbuf, sizeof (repbuf), stdin) != (char *)NULL) {
278 wrong_msg = 0;
280 /* save a copy of the current line */
281 (void) strcpy(curline, repbuf);
283 /* take apart the input string */
284 repbufp = strchr(repbuf, ':');
285 if (repbufp == (char *)NULL)
286 badformat(curline);
287 *repbufp++ = '\0';
288 /* verify that string belongs to the input C source file */
289 if (strcmp(repbuf, name) != NULL)
290 continue;
291 repstr = strchr(repbufp, ':');
292 if (repstr == (char *)NULL)
293 badformat(curline);
294 *repstr++ = '\0';
295 curlineno = atoi(repbufp);
296 if (curlineno < savelineno) {
297 (void) fprintf(stderr,
298 "exstr: ERROR: stdin: line out of order\n");
299 (void) fprintf(stderr, "%s", curline);
300 exit(1);
302 savelineno = curlineno;
303 repbufp = repstr;
304 repstr = strchr(repbufp, ':');
305 if (repstr == (char *)NULL)
306 badformat(curline);
307 repstr[strlen(repstr) - 1 ] = '\0';
308 *repstr++ = '\0';
309 curposno = atoi(repbufp);
310 repbufp = repstr;
311 repstr = strchr(repbufp, ':');
312 if (repstr == (char *)NULL)
313 badformat(curline);
314 *repstr++ = '\0';
315 msgfile = repbufp;
316 if (strlen(msgfile) > (size_t)14 || *msgfile == '\0') {
317 (void) fprintf(stderr,
318 "exstr: ERROR: stdin: invalid message file name "
319 "'%s'\n", msgfile);
320 (void) fprintf(stderr, "%s", curline);
321 exit(1);
323 repbufp = repstr;
324 repstr = strchr(repbufp, ':');
325 if (repstr == (char *)NULL)
326 badformat(curline);
327 *repstr++ = '\0';
328 cp = repbufp;
329 while (*cp)
330 if (!isdigit(*cp++)) {
331 wrong_msg++;
332 break;
334 if (*repbufp == '\0' || wrong_msg) {
335 (void) fprintf(stderr, "exstr: ERROR: stdin: invalid "
336 "message number '%s'\n", repbufp);
337 (void) fprintf(stderr, "%s", curline);
338 exit(1);
340 curmsgno = atoi(repbufp);
342 /* move up to this line */
343 while (Lineno != curlineno) {
344 if (outp != outbuf) {
345 while (*inp != '\0')
346 *outp++ = *inp++;
347 *outp = '\0';
348 (void) fputs(outbuf, stdout);
349 } else if (*linebuf != '\0')
350 (void) fputs(linebuf, stdout);
351 outp = outbuf;
352 inp = linebuf;
353 if (fgets(linebuf,
354 sizeof (linebuf), fi) == (char *)NULL) {
355 (void) fprintf(stderr, "read error\n");
356 exit(1);
358 Lineno++;
359 Posno = 0;
361 if (Posno > curposno) {
362 (void) fprintf(stderr,
363 "Bad input record line number %d\n", Lineno);
364 exit(1);
366 while (Posno != curposno) {
367 *outp++ = *inp++;
368 Posno++;
370 if (*inp != '"') {
371 (void) fprintf(stderr, "exstr: ERROR: cannot replace "
372 "string '%s' in line (%d) of file (%s)\n", repstr,
373 Lineno, Fname);
374 exit(1);
376 /* check if string continues in next line */
377 while (inp[strlen(inp)-2] == '\\' &&
378 inp[strlen(inp)-1] == '\n') {
379 if (fgets(linebuf,
380 sizeof (linebuf), fi) == (char *)NULL) {
381 (void) fprintf(stderr, "exstr: ERROR: read "
382 "error in file (%s)\n", Fname);
383 exit(1);
385 cont_str++;
386 Lineno++;
388 if (cont_str) {
389 cp = linebuf;
390 while (*cp != '\0' && *cp++ != '"')
392 if (*cp == '\0') {
393 (void) fprintf(stderr, "exstr: ERROR: cannot "
394 "replace string '%s' in line (%d) of file "
395 "(%s)\n", repstr, Lineno, Fname);
396 exit(1);
398 inp = cp;
399 Posno = cp - linebuf;
401 if (dflg)
402 outp += snprintf(outp, BUFSIZ - (outp - outbuf),
403 "gettxt(\"%s:%d\", \"%s\")", msgfile, curmsgno,
404 repstr);
405 else
406 outp += snprintf(outp, BUFSIZ - (outp - outbuf),
407 "gettxt(\"%s:%d\", \"\")", msgfile, curmsgno);
408 if (!cont_str) {
409 inp += strlen(repstr)+2;
410 Posno += strlen(repstr)+2;
412 else
413 cont_str = 0;
415 if (outp != outbuf) {
416 while (*inp != '\0')
417 *outp++ = *inp++;
418 *outp = '\0';
419 (void) fputs(outbuf, stdout);
421 while (fgets(linebuf, sizeof (linebuf), fi) != (char *)NULL)
422 (void) fputs(linebuf, stdout);
424 (void) fclose(fi);
427 static void
428 badformat(line)
429 char *line;
431 (void) fprintf(stderr, "exstr: ERROR: stdin: Badly formatted "
432 "replacement string\n%s", line);
433 exit(1);