beta-0.89.2
[luatex.git] / source / texk / web2c / web2c / splitup.c
blob88c37399441d32732aebce45616655829f176b04
1 /* splitup -- take TeX or MF in C as a single stream on stdin,
2 and it produces several .c and .h files in the current directory
3 as its output.
5 $Id: splitup.c 37504 2015-06-12 08:45:07Z peter $
7 Tim Morgan September 19, 1987. */
9 #include <w2c/config.h>
10 #include <kpathsea/getopt.h>
12 #if defined (FATAL)
13 #undef FATAL
14 #endif
16 #define FATAL(str) do { \
17 fprintf (stderr, "%s: fatal: ", argv[0]); \
18 fputs (str, stderr); \
19 fputs (".\n", stderr); exit (1); } while (0)
22 #if defined (FATAL1)
23 #undef FATAL1
24 #endif
26 #define FATAL1(str, e1) do { \
27 fprintf (stderr, "%s: fatal: ", argv[0]); \
28 fprintf (stderr, str, e1); \
29 fputs (".\n", stderr); exit (1); } while (0)
32 #ifdef VMS
33 #define unlink delete
34 #endif
36 int filenumber = 0, ifdef_nesting = 0, lines_in_file = 0;
37 char *output_name = NULL;
38 boolean has_ini;
40 /* This used to be a fixed 2000, but since bibtex.c is almost 10000 lines
41 (200+K), we may as well decrease the number of split files we create.
42 Probably faster for the compiler, definitely faster for the linker,
43 simpler for the Makefiles, and generally better. Now we specify this
44 in 'convert'. */
45 long int max_lines;
47 /* Do we split out a separate *ini.c file? */
48 boolean do_ini;
50 /* Don't need long filenames, since we generate them all. */
51 char buffer[1024], tempfile[100], filename[100], ini_name[100];
53 FILE *out, *ini, *temp;
56 * Read a line of input into the buffer, returning `false' on EOF.
57 * If the line is of the form "#ifdef INI...", we set "has_ini"
58 * `true' else `false'. We also keep up with the #ifdef/#endif nesting
59 * so we know when it's safe to finish writing the current file.
61 static int
62 read_line (void)
64 if (fgets (buffer, sizeof (buffer), stdin) == NULL)
65 return false;
66 if (strncmp (buffer, "#ifdef", 6) == 0
67 || strncmp (buffer, "#ifndef", 7) == 0)
69 ++ifdef_nesting;
70 if (strncmp (&buffer[7], "INI", 3) == 0)
71 has_ini = true;
73 else if (strncmp (buffer, "#endif", 6) == 0)
74 --ifdef_nesting;
75 return true;
78 #ifdef WIN32
79 #include <io.h>
80 #include <fcntl.h>
81 #endif
83 int
84 main (int argc, string *argv)
86 const_string coerce;
87 unsigned coerce_len;
88 int option;
90 #ifdef WIN32
91 setmode(fileno(stdout), _O_BINARY);
92 #endif
94 while ((option = getopt(argc, argv, "il:")) != -1) {
95 switch (option) {
96 case 'i':
97 do_ini = true;
98 break;
99 case 'l':
100 max_lines = atoi(optarg);
101 if (max_lines <= 0)
102 FATAL("[-i] [-l lines] name");
103 break;
104 default:
105 FATAL("[-i] [-l lines] name");
106 break;
109 if (optind + 1 != argc)
110 FATAL("[-i] [-l lines] name");
111 output_name = argv[optind];
113 sprintf (filename, "%sd.h", output_name);
114 sprintf (tempfile, "%s.tmp", output_name);
115 out = xfopen (filename, FOPEN_W_MODE);
116 fputs ("#undef TRIP\n#undef TRAP\n", out);
117 /* We have only one binary that can do both ini stuff and vir stuff. */
118 fputs ("#define STAT\n#define INI\n", out);
120 if (STREQ (output_name, "mf")) {
121 fputs ("#define INIMF\n#define MF\n#define onlyMF\n", out);
122 coerce = "mfcoerce.h";
123 } else if (STREQ (output_name, "mflua")) {
124 fputs ("#define INIMF\n#define MF\n#define MFLua\n", out);
125 coerce = "mfluacoerce.h";
126 } else if (STREQ (output_name, "mfluajit")) {
127 fputs ("#define INIMF\n#define MF\n#define MFLuaJIT\n", out);
128 coerce = "mfluajitcoerce.h";
129 } else if (STREQ (output_name, "tex")) {
130 fputs ("#define INITEX\n#define TeX\n#define onlyTeX\n", out);
131 coerce = "texcoerce.h";
132 } else if (STREQ (output_name, "aleph")) {
133 fputs ("#define INITEX\n#define TeX\n#define Aleph\n", out);
134 coerce = "alephcoerce.h";
135 } else if (STREQ (output_name, "etex")) {
136 fputs ("#define INITEX\n#define TeX\n#define eTeX\n", out);
137 coerce = "etexcoerce.h";
138 } else if (STREQ (output_name, "pdftex")) {
139 fputs ("#define INITEX\n#define TeX\n#define pdfTeX\n", out);
140 coerce = "pdftexcoerce.h";
141 } else if (STREQ (output_name, "ptex")) {
142 fputs ("#define INITEX\n#define TeX\n#define pTeX\n", out);
143 coerce = "ptexcoerce.h";
144 } else if (STREQ (output_name, "eptex")) {
145 fputs ("#define INITEX\n#define TeX\n#define epTeX\n", out);
146 coerce = "eptexcoerce.h";
147 } else if (STREQ (output_name, "euptex")) {
148 fputs ("#define INITEX\n#define TeX\n#define eupTeX\n", out);
149 coerce = "euptexcoerce.h";
150 } else if (STREQ (output_name, "uptex")) {
151 fputs ("#define INITEX\n#define TeX\n#define upTeX\n", out);
152 coerce = "uptexcoerce.h";
153 } else if (STREQ (output_name, "xetex")) {
154 fputs ("#define INITEX\n#define TeX\n#define XeTeX\n", out);
155 coerce = "xetexcoerce.h";
156 } else
157 FATAL1 ("Can only split mf, tex, aleph, eptex, euptex, etex, pdftex, ptex, uptex, or xetex,\n not %s", output_name);
159 coerce_len = strlen (coerce);
161 /* Read everything up to coerce.h. */
162 while (fgets (buffer, sizeof (buffer), stdin))
164 if (strncmp (&buffer[10], coerce, coerce_len) == 0)
165 break;
167 if (buffer[0] == '#' || buffer[0] == '\n' || buffer[0] == '}'
168 || buffer[0] == '/' || buffer[0] == ' '
169 || strncmp (buffer, "typedef", 7) == 0)
170 /*nothing */ ;
171 else
172 fputs ("EXTERN ", out);
174 fputs (buffer, out);
177 if (strncmp (&buffer[10], coerce, coerce_len) != 0)
178 FATAL1 ("No #include %s line", coerce);
180 fputs (buffer, out);
181 xfclose (out, filename);
183 if (do_ini) {
184 sprintf (ini_name, "%sini.c", output_name);
185 ini = xfopen (ini_name, FOPEN_W_MODE);
186 fputs ("#define EXTERN extern\n", ini);
187 fprintf (ini, "#include \"%sd.h\"\n\n", output_name);
190 sprintf (filename, "%s0.c", output_name);
191 out = xfopen (filename, FOPEN_W_MODE);
192 fputs ("#define EXTERN extern\n", out);
193 fprintf (out, "#include \"%sd.h\"\n\n", output_name);
197 /* Read one routine into a temp file */
198 has_ini = false;
199 temp = xfopen (tempfile, "wb+");
201 while (read_line ())
203 fputs (buffer, temp);
204 if (buffer[0] == '}')
205 break; /* End of procedure */
207 while (ifdef_nesting > 0 && read_line ())
208 fputs (buffer, temp);
209 rewind (temp);
211 if (do_ini && has_ini)
212 { /* Contained "#ifdef INI..." */
213 while (fgets (buffer, sizeof (buffer), temp))
214 fputs (buffer, ini);
216 else
217 { /* Doesn't contain "#ifdef INI..." */
218 while (fgets (buffer, sizeof (buffer), temp))
220 fputs (buffer, out);
221 lines_in_file++;
224 xfclose (temp, tempfile);
226 /* Switch to new output file. */
227 if (max_lines && lines_in_file > max_lines)
229 xfclose (out, filename);
230 sprintf (filename, "%s%d.c", output_name, ++filenumber);
231 out = xfopen (filename, FOPEN_W_MODE);
232 fputs ("#define EXTERN extern\n", out);
233 fprintf (out, "#include \"%sd.h\"\n\n", output_name);
234 lines_in_file = 0;
237 while (!feof (stdin));
239 xfclose (out, filename);
240 if (lines_in_file == 0)
241 unlink (filename);
243 if (do_ini)
244 xfclose (ini, ini_name);
246 if (unlink (tempfile)) {
247 perror (tempfile);
248 exit (EXIT_FAILURE);
251 return EXIT_SUCCESS;