out: exit if there is no room for more relocations or symbols
[neatcc.git] / npp.c
blob23c17c8d3a5d3865d1aaf0b0d30c80a1626e7c7a
1 /*
2 * neatpp - a small and simple C preprocessor
4 * Copyright (C) 2010-2012 Ali Gholami Rudi
6 * This file is released under GNU GPL version 2.
7 */
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <sys/stat.h>
16 #include "tok.h"
18 #define OBUFSZ (1 << 19)
20 static int rmcomments(char *d, char *s, int l)
22 char *e = s + l;
23 char *d1 = d;
24 char *r = s;
25 while (r < e) {
26 if (r + 3 < e && r[0] == '/' && r[1] == '*') {
27 memcpy(d, s, r - s);
28 d += r - s;
29 while (r + 1 < e) {
30 r++;
31 if (r[0] == '*' && r[1] == '/') {
32 r++;
33 break;
36 s = r + 1;
38 if (r + 1 < e && (r[0] == '\'' || r[0] == '"')) {
39 char c = r[0];
40 r++;
41 while (r < e && *r != c) {
42 if (*r == '\\')
43 r++;
44 r++;
47 r++;
49 memcpy(d, s, e - s);
50 d += e - s;
51 return d - d1;
54 static int xwrite(int fd, char *buf, int len)
56 int nw = 0;
57 while (nw < len) {
58 int ret = write(fd, buf + nw, len - nw);
59 if (ret == -1 && (errno == EAGAIN || errno == EINTR))
60 continue;
61 if (ret < 0)
62 break;
63 nw += ret;
65 return nw;
68 void err(char *fmt, ...)
70 va_list ap;
71 char msg[512];
72 va_start(ap, fmt);
73 vsprintf(msg, fmt, ap);
74 va_end(ap);
75 die(msg);
78 int main(int argc, char *argv[])
80 int ofd = 1;
81 int i = 1;
82 char *s1, *s2;
83 int len = 0;
84 char *cbuf;
85 int clen;
86 while (i < argc && argv[i][0] == '-') {
87 if (argv[i][1] == 'I')
88 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
89 if (argv[i][1] == 'D') {
90 char *name = argv[i] + 2;
91 char *def = "";
92 char *eq = strchr(name, '=');
93 if (eq) {
94 *eq = '\0';
95 def = eq + 1;
97 cpp_define(name, def);
99 i++;
101 if (i + 1 >= argc) {
102 printf("usage: npp [-I idir] [-D define] input output\n");
103 return 0;
105 if (cpp_init(argv[i++]))
106 die("npp: cannot open <%s>\n", argv[i - 1]);
107 ofd = open(argv[i++], O_WRONLY | O_TRUNC | O_CREAT, 0600);
108 if (ofd < 0)
109 die("npp: cannot open <%s>\n", argv[i - 1]);
110 s1 = malloc(OBUFSZ);
111 s2 = malloc(OBUFSZ);
112 if (!s1 || !s2)
113 die("npp: cannot allocate enough memory\n");
114 while (!cpp_read(&cbuf, &clen)) {
115 memcpy(s1 + len, cbuf, clen);
116 len += clen;
118 len = rmcomments(s2, s1, len);
119 xwrite(ofd, s2, len);
120 close(ofd);
121 return 0;