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