w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

fixwrites.c
Go to the documentation of this file.
1 /* fixwrites -- convert Pascal write/writeln's into fprintf's or putc's.
2  Originally by Tim Morgan, October 10, 1987. */
3 
4 #include <w2c/config.h>
5 #include <kpathsea/c-pathmx.h>
6 
7 char buf[BUFSIZ], filename[PATH_MAX], args[100];
8 char *file, *argp, *as, *cmd;
9 
10 int tex = false;
11 
12 /* Replace the last (should be only) newline in S with a null. */
13 
14 static void
15 remove_newline (string s)
16 {
17  char *temp = strrchr (s, '\n');
18  if (temp == NULL)
19  {
20  fprintf (stderr, "Lost newline somehow.\n");
21  /* This is so the convert script can delete the output file on error. */
22  puts ("@error@");
23  exit (1);
24  }
25 
26  *temp = 0;
27 }
28 
29 
30 static char *
31 insert_long (string cp)
32 {
33  char tbuf[BUFSIZ];
34  register int i;
35 
36  for (i = 0; &buf[i] < cp; ++i)
37  tbuf[i] = buf[i];
38  strcpy (&tbuf[i], "(long)");
39  strcpy (&tbuf[i + 6], cp);
40  strcpy (buf, tbuf);
41  return cp + 6;
42 }
43 
44 
45 static void
46 join (string cp)
47 {
48  char temp[BUFSIZ], *tp;
49 
50  if (!fgets (temp, BUFSIZ, stdin))
51  return;
53 
54  *cp++ = ' ';
55  for (tp = temp; *tp == ' '; ++tp)
56  ;
57 
58  strcpy (cp, tp);
59 }
60 
61 
62 static void
64 {
65  register int i;
66 
67  for (i = 0; i < indent / 8; i++)
68  putchar ('\t');
69  indent %= 8;
70  for (i = 0; i < indent; i++)
71  putchar (' ');
72 }
73 
74 
75 /* Return true if we have a whole write/writeln statement. We determine
76  this by matching parens, ignoring those within strings. */
77 static int
78 whole (string cp)
79 {
80  register int depth = 0;
81 
82  while (cp && *cp)
83  {
84  switch (*cp)
85  {
86  case '(':
87  ++depth;
88  break;
89  case ')':
90  --depth;
91  break;
92  case '"':
93  for (++cp; cp && *cp && *cp != '"'; ++cp)
94  if (*cp == '\\')
95  ++cp;
96  break;
97  case '\'':
98  ++cp;
99  if (*cp == '\\') ++cp;
100  ++cp;
101  break;
102  }
103  ++cp;
104  }
105  return depth <= 0;
106 }
107 
108 
109 /* Skips to the next , or ), skipping over balanced paren pairs. */
110 
111 static char *
113 {
114  register int depth = 0;
115 
116  while (depth > 0 || (*cp != ',' && *cp != ')'))
117  {
118  switch (*cp)
119  {
120  case '(':
121  ++depth;
122  break;
123  case ')':
124  --depth;
125  break;
126  }
127  ++cp;
128  }
129  return cp;
130 }
131 
132 
133 /* Return true if c appears, except inside a quoted string */
134 
135 static int
136 bare (string cp, char c)
137 {
138  for (; *cp && *cp != c; ++cp)
139  {
140  if (*cp == '"')
141  {
142  ++cp; /* skip over initial quotation mark */
143  while (*cp && *cp != '"')
144  { /* skip to closing double quote */
145  if (*cp == '\\')
146  ++cp;
147  ++cp;
148  }
149  }
150  else if (*cp == '\'')
151  {
152  ++cp; /* skip to contained char */
153  if (*cp == '\'')
154  ++cp; /* if backslashed, it's double */
155  ++cp; /* skip to closing single-quote mark */
156  }
157  }
158  return *cp;
159 }
160 
161 ␌
162 /* xchr[...] is supposed to be replaced by Xchr(...) when characters
163  take more than a single octet each, as is the case in Aleph. Now
164  there are several occurrences of xchr[...[...]...], which are
165  translated into Xchr(...[...)...], and the compiler dies on syntax
166  errors. Ensures that it is the matching bracket that is replaced,
167  not the first one. */
168 
169 static char *
170 advance_cp (char *cp, int lefts)
171 {
172  char *cp1;
173  char *cp2;
174 
175  cp1 = strchr (cp + 1, ']');
176  cp2 = strchr (cp + 1, '[');
177  if (cp2 && cp2 < cp1)
178  return advance_cp (cp2, lefts + 1);
179  if (lefts == 1)
180  return cp1;
181  return advance_cp (cp1, lefts - 1);
182 }
183 
184 #ifdef WIN32
185 #include <io.h>
186 #include <fcntl.h>
187 #endif
188 
189 int
190 main (int argc, string *argv)
191 {
192  register char *cp;
193  int blanks_done, indent, i;
194  const char *program_name = "";
195 
196 #ifdef WIN32
198 #endif
199  for (i = 1; i < argc; i++)
200  {
201  if (STREQ(argv[i],"-t"))
202  tex = true;
203  else
204  program_name = argv[i];
205  }
206 
207  while (fgets (buf, BUFSIZ, stdin))
208  {
210  blanks_done = false;
211 
212  for (cp = buf; *cp; ++cp) ;
213 
214  while (cp != buf && *--cp == ' ') ;
215 
216  while (*cp == '.')
217  {
218  join (cp + 1);
219  while (*cp)
220  ++cp;
221  while (*--cp == ' ') ;
222  }
223 
224  for (cp = buf, indent = 0; *cp == ' ' || *cp == '\t'; ++cp)
225  {
226  if (*cp == ' ')
227  indent++;
228  else
229  indent += 8;
230  }
231 
232  if (!*cp)
233  { /* All blanks, possibly with "{" */
234  puts (buf);
235  continue;
236  }
237  if (*cp == '{')
238 
239  {
240  do_blanks (indent);
241  putchar ('{');
242  ++cp;
243  while (*cp == ' ' || *cp == '\t')
244  ++cp;
245  blanks_done = true;
246  if (!*cp)
247  {
248  putchar ('\n');
249  continue;
250  }
251  }
252 
253  if (!blanks_done)
254  do_blanks (indent);
255 
256  if (strncmp (cp, "read ( input", 12) == 0)
257  {
258  char variable_name[20];
259  if (sscanf (cp, "read ( input , %s )", variable_name) != 1)
260  {
261  fprintf (stderr, "sscanf failed\n");
262  exit (1);
263  }
264  printf ("%s = getint();\n", variable_name);
265  continue;
266  }
267 
268  if (strncmp (cp, "lab", 3) == 0 && strchr (cp, ':'))
269  {
270  do
271  {
272  putchar (*cp);
273  }
274  while (*cp++ != ':');
275 
276  while (*cp == ' ')
277  ++cp;
278  putchar (' ');
279  }
280 
281  if (strncmp (cp, "else write", 10) == 0)
282  {
283  puts ("else");
284  do_blanks (indent);
285  cp += 5;
286  while (*cp == ' ')
287  ++cp;
288  }
289 
290  if (bare (cp, '{'))
291  {
292  while (*cp != '{')
293  {
294  putchar (*cp);
295  ++cp;
296  }
297  ++cp;
298  puts ("{");
299  indent += 4;
300  do_blanks (indent);
301  while (*cp == ' ')
302  ++cp;
303  }
304 
305  if (strncmp (cp, "write (", 7) && strncmp (cp, "writeln (", 9))
306  {
307  /* if not a write/writeln, just copy it to stdout and continue */
308  puts (cp);
309  continue;
310  }
311  cmd = cp;
312  while (!whole (buf)) /* make sure we have whole stmt */
313  {
314  if (!fgets (&buf[strlen (buf)], BUFSIZ - strlen (buf), stdin))
315  break;
317  }
318 
319  while (*cp != '(')
320  ++cp;
321  ++cp;
322  while (*(cp + 1) == ' ')
323  ++cp;
324 
325  /* Some writes start with a variable, instead of a file. */
326  if (*(cp + 1) == '"' || *(cp + 1) == '\''
327  || strncmp (cp + 1, "buffer", 6) == 0
328  || strncmp (cp + 1, "xchr", 4) == 0
329  || strncmp (cp + 1, "k ,", 3) == 0
330  || strncmp (cp + 1, "s ,", 3) == 0
331  || strncmp (cp + 1, "dig", 3) == 0
332  || strncmp (cp + 1, "HEX", 3) == 0
333  || strncmp (cp + 1, "versionstring", 13) == 0
334  || strncmp (cp + 1, "kpathseaversionstring", 21) == 0
335  )
336  strcpy (filename, "stdout");
337  else
338  {
339  file = filename;
340  while (*cp != ',' && *cp != ')')
341  *file++ = *cp++;
342  *file = '\0';
343  }
344  if (*cp == ')')
345  {
346  printf ("putc ('\\n', %s);\n", filename);
347  continue;
348  }
349  argp = ++cp;
350  as = args;
351  while (*cp == ' ')
352  ++cp;
353  while (*cp != ')')
354  {
355  if (*cp == '\'' || strncmp (cp, "xchr", 4) == 0
356  || (strncmp (cp ,"HEX", 3) == 0
357  && (STREQ (program_name, "ofm2opl")
358  || STREQ (program_name, "opl2ofm")
359  || STREQ (program_name, "ovp2ovf")
360  || STREQ (program_name, "ovf2ovp")))
361  || strncmp (cp, "ASCII04", 7) == 0
362  || strncmp (cp, "ASCII1", 6) == 0
363  || strncmp (cp, "ASCIIall", 8) == 0
364  || strncmp (cp, "months", 6) == 0
365  || strncmp (cp, "nameoffile", 10) == 0
366  || (strncmp (cp, "buffer", 6) == 0
367  && (STREQ (program_name, "vptovf")
368  || STREQ (program_name, "pltotf")
369  || STREQ (program_name, "ppltotf")
370  || STREQ (program_name, "uppltotf")
371  || STREQ (program_name, "ovp2ovf")
372  || STREQ (program_name, "opl2ofm")))
373  || (((strncmp (cp, "buf", 3) == 0
374  || strncmp (cp, "xdig", 4) == 0
375  || strncmp (cp, "xext", 4) == 0
376  || strncmp (cp, "xhyf", 4) == 0)
377  && STREQ (program_name, "patgen")))
378  )
379  {
380  *as++ = '%';
381  *as++ = 'c';
382  if (tex && strncmp (cp, "xchr", 4) == 0)
383  {
384  *cp = 'X';
385  cp = strchr (cp, '[');
386  *cp = '(';
387  cp = advance_cp(cp,1);
388  *cp++ = ')';
389  }
390  else if (*cp == '\'')
391  cp += 2;
392  }
393 
394  else if (*cp == '"')
395  {
396  *as++ = '%';
397  *as++ = 's';
398  while (*++cp != '"') /* skip to end of string */
399  if (*cp == '\\')
400  ++cp; /* allow \" in string */
401  }
402 
403  /* More kludges -- recognize some things as strings and use %s:
404  - versionstring
405  - poolname
406  - formatengine
407  - dumpname */
408  else if (strncmp (cp, "versionstring", 13) == 0
409  || strncmp (cp, "poolname", 8) == 0
410  || strncmp (cp, "formatengine", 12) == 0
411  || strncmp (cp, "dumpname", 8) == 0)
412  {
413  *as++ = '%';
414  *as++ = 's';
415  }
416 
417  /* And yet another kludge, to handle stringcast (<whatever>) */
418  else if (strncmp (cp, "stringcast", 10) == 0
419  || strncmp (cp, "conststringcast", 15) == 0)
420  {
421  *as++ = '%';
422  *as++ = 's';
423  cp = skip_balanced (cp); /* Skip cast expression */
424  }
425 
426  else
427  {
428  *as++ = '%';
429  *as++ = 'l';
430  *as++ = 'd';
431  cp = insert_long (cp);
432  cp = skip_balanced (cp); /* It's a numeric expression */
433  }
434  while (*cp != ',' && *cp != ')')
435  ++cp;
436  while (*cp == ',' || *cp == ' ')
437  ++cp;
438  }
439 
440  if (strncmp (cmd, "writeln", 7) == 0)
441  {
442  *as++ = '\\';
443  *as++ = 'n';
444  }
445 
446  *as = '\0';
447  if (strcmp (args, "%c") == 0)
448  {
449  for (as = argp; *as; ++as) ;
450  while (*--as != ')') ;
451  *as = '\0';
452  printf ("putc (%s, %s);\n", argp, filename);
453  }
454  else if (strcmp (args, "%c\\n") == 0)
455  {
456  for (as = argp; *as; ++as) ;
457  while (*--as != ')') ;
458  *as = '\0';
459  printf ("{ putc (%s, %s); ", argp, filename);
460  printf ("putc ( '\\n', %s); }\n", filename);
461  }
462  else if (strcmp (args, "%s") == 0)
463  printf ("Fputs (%s, %s\n", filename, argp);
464  else
465  printf ("fprintf (%s, \"%s\", %s\n", filename, args, argp);
466  }
467 
468  return EXIT_SUCCESS;
469 }
cp
Definition: action.c:1035
#define depth(a)
Definition: aptex-macros.h:199
#define strrchr
Definition: detex.c:67
#define STREQ(s, t)
Definition: defs.h:149
#define fgets
Definition: xxstdio.h:29
int strcmp()
Definition: coll.cpp:143
int sscanf()
int printf()
char * strcpy()
char * temp
Definition: dvidvi.c:137
#define tp
#define s
Definition: afcover.h:80
#define c(n)
Definition: gpos-common.c:150
#define strchr
Definition: gsftopk.c:59
#define EXIT_SUCCESS
Definition: cdjpeg.h:175
#define PATH_MAX
Definition: ftmac.c:91
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
#define fileno
Definition: win32lib.h:72
int indent
Definition: main.c:118
#define fprintf
Definition: mendex.h:64
char args[100]
Definition: fixwrites.c:7
char * as
Definition: fixwrites.c:8
static char * advance_cp(char *cp, int lefts)
Definition: fixwrites.c:170
static void remove_newline(string s)
Definition: fixwrites.c:15
char * argp
Definition: fixwrites.c:8
static char * skip_balanced(string cp)
Definition: fixwrites.c:112
static char * insert_long(string cp)
Definition: fixwrites.c:31
static void join(string cp)
Definition: fixwrites.c:46
static int bare(string cp, char c)
Definition: fixwrites.c:136
char filename[PATH_MAX]
Definition: fixwrites.c:7
int main(int argc, string *argv)
Definition: fixwrites.c:190
char * cmd
Definition: fixwrites.c:8
int tex
Definition: fixwrites.c:10
char * file
Definition: fixwrites.c:8
char buf[BUFSIZ]
Definition: fixwrites.c:7
static int whole(string cp)
Definition: fixwrites.c:78
static void do_blanks(int indent)
Definition: fixwrites.c:63
int setmode()
#define program_name
Definition: error.c:122
int strncmp()
#define _O_BINARY
Definition: lfs.c:127
Definition: usprintf.c:39
Definition: filedef.h:30
*job_name strlen((char *) job_name) - 4)
#define BUFSIZ
Definition: ps.c:61
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269