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
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>
16 #define FATAL(str) do { \
17 fprintf (stderr, "%s: fatal: ", argv[0]); \
18 fputs (str, stderr); \
19 fputs (".\n", stderr); exit (1); } while (0)
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)
36 int filenumber
= 0, ifdef_nesting
= 0, lines_in_file
= 0;
37 char *output_name
= NULL
;
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
47 /* Do we split out a separate *ini.c file? */
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.
64 if (fgets (buffer
, sizeof (buffer
), stdin
) == NULL
)
66 if (strncmp (buffer
, "#ifdef", 6) == 0
67 || strncmp (buffer
, "#ifndef", 7) == 0)
70 if (strncmp (&buffer
[7], "INI", 3) == 0)
73 else if (strncmp (buffer
, "#endif", 6) == 0)
84 main (int argc
, string
*argv
)
91 setmode(fileno(stdout
), _O_BINARY
);
94 while ((option
= getopt(argc
, argv
, "il:")) != -1) {
100 max_lines
= atoi(optarg
);
102 FATAL("[-i] [-l lines] name");
105 FATAL("[-i] [-l lines] name");
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";
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)
167 if (buffer
[0] == '#' || buffer
[0] == '\n' || buffer
[0] == '}'
168 || buffer
[0] == '/' || buffer
[0] == ' '
169 || strncmp (buffer
, "typedef", 7) == 0)
172 fputs ("EXTERN ", out
);
177 if (strncmp (&buffer
[10], coerce
, coerce_len
) != 0)
178 FATAL1 ("No #include %s line", coerce
);
181 xfclose (out
, filename
);
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 */
199 temp
= xfopen (tempfile
, "wb+");
203 fputs (buffer
, temp
);
204 if (buffer
[0] == '}')
205 break; /* End of procedure */
207 while (ifdef_nesting
> 0 && read_line ())
208 fputs (buffer
, temp
);
211 if (do_ini
&& has_ini
)
212 { /* Contained "#ifdef INI..." */
213 while (fgets (buffer
, sizeof (buffer
), temp
))
217 { /* Doesn't contain "#ifdef INI..." */
218 while (fgets (buffer
, sizeof (buffer
), temp
))
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
);
237 while (!feof (stdin
));
239 xfclose (out
, filename
);
240 if (lines_in_file
== 0)
244 xfclose (ini
, ini_name
);
246 if (unlink (tempfile
)) {