tr: escaped spaces inside macro arguments
[neatroff.git] / roff.c
blob170a0f27808eb4377180cde3f8d485ec0ce832c5
1 /*
2 * neatroff troff clone
4 * Copyright (C) 2012-2014 Ali Gholami Rudi <ali at rudi dot ir>
6 * This program is released under the Modified BSD license.
7 */
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include "roff.h"
14 void errmsg(char *fmt, ...)
16 va_list ap;
17 va_start(ap, fmt);
18 vfprintf(stderr, fmt, ap);
19 va_end(ap);
22 void errdie(char *msg)
24 fprintf(stderr, msg);
25 exit(1);
28 void *xmalloc(long len)
30 void *m = malloc(len);
31 if (!m)
32 errdie("neatroff: malloc() failed\n");
33 return m;
36 static int xopens(char *path)
38 FILE *filp = fopen(path, "r");
39 if (filp)
40 fclose(filp);
41 return filp != NULL;
44 static char *usage =
45 "Usage: neatroff [options] input\n\n"
46 "Options:\n"
47 " -mx \tinclude macro x\n"
48 " -C \tenable compatibility mode\n"
49 " -Tdev \tset output device\n"
50 " -Fdir \tset font directory (" TROFFFDIR ")\n"
51 " -Mdir \tset macro directory (" TROFFMDIR ")\n";
53 int main(int argc, char **argv)
55 char fontdir[PATHLEN] = TROFFFDIR;
56 char macrodir[PATHLEN] = TROFFMDIR;
57 char dev[PATHLEN] = "utf";
58 char path[PATHLEN];
59 int i;
60 int ret;
61 for (i = 1; i < argc; i++) {
62 if (argv[i][0] != '-' || !argv[i][1])
63 break;
64 switch (argv[i][1]) {
65 case 'C':
66 n_cp = 1;
67 break;
68 case 'm':
69 sprintf(path, "%s/%s.tmac", macrodir, argv[i] + 2);
70 if (!xopens(path))
71 sprintf(path, "%s/tmac.%s", macrodir, argv[i] + 2);
72 if (!xopens(path))
73 sprintf(path, "%s/%s", macrodir, argv[i] + 2);
74 in_queue(path);
75 break;
76 case 'F':
77 strcpy(fontdir, argv[i][2] ? argv[i] + 2 : argv[++i]);
78 break;
79 case 'M':
80 strcpy(macrodir, argv[i][2] ? argv[i] + 2 : argv[++i]);
81 break;
82 case 'T':
83 strcpy(dev, argv[i][2] ? argv[i] + 2 : argv[++i]);
84 break;
85 default:
86 printf("%s", usage);
87 return 0;
90 if (dev_open(fontdir, dev)) {
91 fprintf(stderr, "neatroff: cannot open device %s\n", dev);
92 return 1;
94 hyph_init();
95 env_init();
96 tr_init();
97 if (i == argc)
98 in_queue(NULL); /* reading from standard input */
99 for (; i < argc; i++)
100 in_queue(!strcmp("-", argv[i]) ? NULL : argv[i]);
101 out("s%d\n", n_s);
102 out("f%d\n", n_f);
103 ret = render();
104 out("V%d\n", n_p);
105 env_done();
106 dev_close();
107 return ret;