1 /* -*-C-*-
2
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6 Institute of Technology
7
8 This file is part of MIT/GNU Scheme.
9
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24
25 */
26
27 /* Utility to extract LIARC declarations from source files. */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <ctype.h>
33
34 static void process_file (const char *);
35 static const char * filename_prefix (const char *);
36 static const char * apply_prefix_rules (const char *);
37 static void mangle_line (const char *, const char *);
38 static const char * skip_name (const char *);
39 static const char * skip_lws (const char *);
40 static const char * skip_fixed (const char *, char);
41 static void write_string (const char *);
42 static void write_char (char);
43 static const char * read_line (FILE *);
44 static void * xmalloc (size_t);
45 static void * xrealloc (void *, size_t);
46
47 typedef struct
48 {
49 const char * pattern;
50 const char * replacement;
51 } prefix_rule_t;
52
53 static unsigned int n_prefix_rules;
54 static unsigned int prefix_rules_size;
55 static prefix_rule_t * prefix_rules;
56
57 int
main(int argc,const char ** argv)58 main (int argc, const char ** argv)
59 {
60 const char ** scan = (argv + 1);
61 const char ** end = (argv + argc);
62
63 n_prefix_rules = 0;
64 prefix_rules_size = 16;
65 prefix_rules = (xmalloc (prefix_rules_size * (sizeof (prefix_rule_t))));
66
67 while ((scan < end) && ((strcmp ((*scan), "--rewrite")) == 0))
68 {
69 if ((scan + 3) > end)
70 abort ();
71 if (n_prefix_rules == prefix_rules_size)
72 {
73 prefix_rules_size *= 2;
74 prefix_rules
75 = (xrealloc (prefix_rules,
76 (prefix_rules_size * (sizeof (prefix_rule_t)))));
77 }
78 ((prefix_rules[n_prefix_rules]) . pattern) = (scan[1]);
79 ((prefix_rules[n_prefix_rules]) . replacement) = (scan[2]);
80 n_prefix_rules += 1;
81 scan += 3;
82 }
83
84 while (scan < end)
85 {
86 if ((strcmp ((*scan), "--rewrite")) == 0)
87 abort ();
88 process_file (*scan++);
89 }
90
91 return (0);
92 }
93
94 static void
process_file(const char * filename)95 process_file (const char * filename)
96 {
97 const char * prefix_from_file;
98 const char * prefix_to_use;
99 FILE * s;
100
101 prefix_from_file = (filename_prefix (filename));
102 prefix_to_use
103 = (apply_prefix_rules ((prefix_from_file == 0)
104 ? ""
105 : prefix_from_file));
106
107 s = (fopen (filename, "r"));
108 if (s == 0)
109 abort ();
110
111 while (1)
112 {
113 const char * line = (read_line (s));
114 if (line == 0)
115 break;
116 if (((strncmp (line, "DECLARE_COMPILED_", 17)) == 0)
117 || ((strncmp (line, "DECLARE_DATA_OBJECT", 19)) == 0))
118 mangle_line (line, prefix_to_use);
119 free ((void *) line);
120 }
121
122 if (prefix_from_file != 0)
123 free ((void *) prefix_from_file);
124 fclose (s);
125 }
126
127 static const char *
filename_prefix(const char * filename)128 filename_prefix (const char * filename)
129 {
130 const char * p = (strrchr (filename, '/'));
131 if (p == 0)
132 return (0);
133 {
134 unsigned int n = ((p + 1) - filename);
135 char * prefix = (xmalloc (n + 1));
136 strncpy (prefix, filename, n);
137 (prefix[n]) = '\0';
138 return (prefix);
139 }
140 }
141
142 static const char *
apply_prefix_rules(const char * prefix)143 apply_prefix_rules (const char * prefix)
144 {
145 unsigned int index;
146
147 for (index = 0; (index < n_prefix_rules); index += 1)
148 if ((strcmp (((prefix_rules[index]) . pattern), prefix)) == 0)
149 return ((prefix_rules[index]) . replacement);
150 return (prefix);
151 }
152
153 static void
mangle_line(const char * line,const char * prefix)154 mangle_line (const char * line, const char * prefix)
155 {
156 const char * scan = (skip_name (line));
157 scan = (skip_lws (scan));
158 scan = (skip_fixed (scan, '('));
159 scan = (skip_lws (scan));
160 scan = (skip_fixed (scan, '"'));
161 write_string (prefix);
162 write_string (scan);
163 write_char ('\n');
164 fflush (stdout);
165 }
166
167 static const char *
skip_name(const char * scan)168 skip_name (const char * scan)
169 {
170 while ((isalnum ((unsigned char) (*scan))) || ((*scan) == '_'))
171 write_char (*scan++);
172 return (scan);
173 }
174
175 static const char *
skip_lws(const char * scan)176 skip_lws (const char * scan)
177 {
178 while (((*scan) == ' ') || ((*scan) == '\t'))
179 write_char (*scan++);
180 return (scan);
181 }
182
183 static const char *
skip_fixed(const char * scan,char c)184 skip_fixed (const char * scan, char c)
185 {
186 if ((*scan) != c)
187 abort ();
188 write_char (*scan++);
189 return (scan);
190 }
191
192 static void
write_string(const char * s)193 write_string (const char * s)
194 {
195 while (1)
196 {
197 char c = (*s++);
198 if (c == '\0')
199 break;
200 write_char (c);
201 }
202 }
203
204 static void
write_char(char c)205 write_char (char c)
206 {
207 if ((putc (c, stdout)) == EOF)
208 abort ();
209 }
210
211 static const char *
read_line(FILE * s)212 read_line (FILE * s)
213 {
214 size_t index = 0;
215 size_t buffer_size = 16;
216 char * buffer = (xmalloc (buffer_size));
217
218 while (1)
219 {
220 int c = (getc (s));
221 if (c == EOF)
222 {
223 if (!feof (s))
224 abort ();
225 if (index == 0)
226 return (0);
227 break;
228 }
229 if (c == '\n')
230 break;
231 if (index == buffer_size)
232 {
233 buffer_size *= 2;
234 buffer = (xrealloc (buffer, buffer_size));
235 }
236 (buffer[index++]) = c;
237 }
238
239 if (index == buffer_size)
240 {
241 buffer_size += 1;
242 buffer = (xrealloc (buffer, buffer_size));
243 }
244 (buffer[index++]) = '\0';
245
246 if (index < buffer_size)
247 buffer = (xrealloc (buffer, index));
248
249 return (buffer);
250 }
251
252 static void *
xmalloc(size_t n)253 xmalloc (size_t n)
254 {
255 void * p = (malloc (n));
256 if (p == 0)
257 abort ();
258 return (p);
259 }
260
261 static void *
xrealloc(void * p,size_t n)262 xrealloc (void * p, size_t n)
263 {
264 void * p2 = (realloc (p, n));
265 if (p2 == 0)
266 abort ();
267 return (p2);
268 }
269