page breaks for 4.4BSD manuals
[unix-history] / usr / src / contrib / gas-1.38 / input-scrub.c
CommitLineData
fb6a1768
KB
1/*-
2 * This code is derived from software copyrighted by the Free Software
3 * Foundation.
4 *
5 * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
6 */
1ffa63ce 7
fb6a1768
KB
8#ifndef lint
9static char sccsid[] = "@(#)input-scrub.c 6.4 (Berkeley) %G%";
10#endif /* not lint */
1ffa63ce 11
9d9eaa6a
DS
12/* input_scrub.c - layer between app and the rest of the world
13 Copyright (C) 1987 Free Software Foundation, Inc.
14
15This file is part of GAS, the GNU Assembler.
16
17GAS is free software; you can redistribute it and/or modify
18it under the terms of the GNU General Public License as published by
19the Free Software Foundation; either version 1, or (at your option)
20any later version.
21
22GAS is distributed in the hope that it will be useful,
23but WITHOUT ANY WARRANTY; without even the implied warranty of
24MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25GNU General Public License for more details.
26
27You should have received a copy of the GNU General Public License
28along with GAS; see the file COPYING. If not, write to
29the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
30
31#include "as.h"
32#include "read.h"
33#include "input-file.h"
34
35/*
36 * O/S independent module to supply buffers of sanitised source code
37 * to rest of assembler. We get raw input data of some length.
38 * Also looks after line numbers, for e.g. error messages.
39 * This module used to do the sanitising, but now a pre-processor program
40 * (app) does that job so this module is degenerate.
41 * Now input is pre-sanitised, so we only worry about finding the
42 * last partial line. A buffer of full lines is returned to caller.
43 * The last partial line begins the next buffer we build and return to caller.
44 * The buffer returned to caller is preceeded by BEFORE_STRING and followed
45 * by AFTER_STRING. The last character before AFTER_STRING is a newline.
46 */
47
48/*
49 * We expect the following sanitation has already been done.
50 *
51 * No comments, reduce a comment to a space.
52 * Reduce a tab to a space unless it is 1st char of line.
53 * All multiple tabs and spaces collapsed into 1 char. Tab only
54 * legal if 1st char of line.
55 * # line file statements converted to .line x;.file y; statements.
56 * Escaped newlines at end of line: remove them but add as many newlines
57 * to end of statement as you removed in the middle, to synch line numbers.
58 */
59\f
60#define BEFORE_STRING ("\n")
61#define AFTER_STRING ("\0") /* bcopy of 0 chars might choke. */
62#define BEFORE_SIZE (1)
63#define AFTER_SIZE (1)
64
65static char * buffer_start; /* -> 1st char of full buffer area. */
66static char * partial_where; /* -> after last full line in buffer. */
67static int partial_size; /* >=0. Number of chars in partial line in buffer. */
68static char save_source [AFTER_SIZE];
69 /* Because we need AFTER_STRING just after last */
70 /* full line, it clobbers 1st part of partial */
71 /* line. So we preserve 1st part of partial */
72 /* line here. */
73static int buffer_length; /* What is the largest size buffer that */
74 /* input_file_give_next_buffer() could */
75 /* return to us? */
76
77static void as_1_char ();
78
79/*
80We never have more than one source file open at once.
81We may, however, read more than 1 source file in an assembly.
82NULL means we have no file open right now.
83*/
84
85
86/*
87We must track the physical file and line number for error messages.
88We also track a "logical" file and line number corresponding to (C?)
89compiler source line numbers.
90Whenever we open a file we must fill in physical_input_file. So if it is NULL
91we have not opened any files yet.
92*/
93
94static
95char * physical_input_file,
96 * logical_input_file;
97
98
99
100typedef unsigned int line_numberT; /* 1-origin line number in a source file. */
101 /* A line ends in '\n' or eof. */
102
103static
104line_numberT physical_input_line,
105 logical_input_line;
106\f
107void
108input_scrub_begin ()
109{
110 know( strlen(BEFORE_STRING) == BEFORE_SIZE );
111 know( strlen( AFTER_STRING) == AFTER_SIZE );
112
113 input_file_begin ();
114
115 buffer_length = input_file_buffer_size ();
116
117 buffer_start = xmalloc ((long)(BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
118 bcopy (BEFORE_STRING, buffer_start, (int)BEFORE_SIZE);
119
120 /* Line number things. */
121 logical_input_line = 0;
122 logical_input_file = (char *)NULL;
123 physical_input_file = NULL; /* No file read yet. */
124 do_scrub_begin();
125}
126
127void
128input_scrub_end ()
129{
130 input_file_end ();
131}
132
133char * /* Return start of caller's part of buffer. */
134input_scrub_new_file (filename)
135 char * filename;
136{
137 input_file_open (filename, !flagseen['f']);
138 physical_input_file = filename[0] ? filename : "{standard input}";
139 physical_input_line = 0;
140
141 partial_size = 0;
142 return (buffer_start + BEFORE_SIZE);
143}
144
145char *
146input_scrub_next_buffer (bufp)
147char **bufp;
148{
149 register char * limit; /* -> just after last char of buffer. */
150
151#ifdef DONTDEF
152 if(preprocess) {
153 if(save_buffer) {
154 *bufp = save_buffer;
155 save_buffer = 0;
156 }
157 limit = input_file_give_next_buffer(buffer_start+BEFORE_SIZE);
158 if (!limit) {
159 partial_where = 0;
160 if(partial_size)
161 as_warn("Partial line at end of file ignored");
162 return partial_where;
163 }
164
165 if(partial_size)
166 bcopy(save_source, partial_where,(int)AFTER_SIZE);
167 do_scrub(partial_where,partial_size,buffer_start+BEFORE_SIZE,limit-(buffer_start+BEFORE_SIZE),&out_string,&out_length);
168 limit=out_string + out_length;
169 for(p=limit;*--p!='\n';)
170 ;
171 p++;
172 if(p<=buffer_start+BEFORE_SIZE)
173 as_fatal("Source line too long. Please change file '%s' and re-make the assembler.",__FILE__);
174
175 partial_where = p;
176 partial_size = limit-p;
177 bcopy(partial_where, save_source,(int)AFTER_SIZE);
178 bcopy(AFTER_STRING, partial_where, (int)AFTER_SIZE);
179
180 save_buffer = *bufp;
181 *bufp = out_string;
182
183 return partial_where;
184 }
185
186 /* We're not preprocessing. Do the right thing */
187#endif
188 if (partial_size)
189 {
190 bcopy (partial_where, buffer_start + BEFORE_SIZE, (int)partial_size);
191 bcopy (save_source, buffer_start + BEFORE_SIZE, (int)AFTER_SIZE);
192 }
193 limit = input_file_give_next_buffer (buffer_start + BEFORE_SIZE + partial_size);
194 if (limit)
195 {
196 register char * p; /* Find last newline. */
197
198 for (p = limit; * -- p != '\n'; )
199 {
200 }
201 ++ p;
202 if (p <= buffer_start + BEFORE_SIZE)
203 {
204 as_fatal ("Source line too long. Please change file %s then rebuild assembler.", __FILE__);
205 }
206 partial_where = p;
207 partial_size = limit - p;
208 bcopy (partial_where, save_source, (int)AFTER_SIZE);
209 bcopy (AFTER_STRING, partial_where, (int)AFTER_SIZE);
210 }
211 else
212 {
213 partial_where = 0;
214 if (partial_size > 0)
215 {
216 as_warn( "Partial line at end of file ignored" );
217 }
218 }
219 return (partial_where);
220}
221\f
222/*
223 * The remaining part of this file deals with line numbers, error
224 * messages and so on.
225 */
226
227
228int
229seen_at_least_1_file () /* TRUE if we opened any file. */
230{
231 return (physical_input_file != NULL);
232}
233
234void
235bump_line_counters ()
236{
237 ++ physical_input_line;
238 ++ logical_input_line;
239}
240\f
241/*
242 * new_logical_line()
243 *
244 * Tells us what the new logical line number and file are.
245 * If the line_number is <0, we don't change the current logical line number.
246 * If the fname is NULL, we don't change the current logical file name.
247 */
248void
249new_logical_line (fname, line_number)
250 char * fname; /* DON'T destroy it! We point to it! */
251 int line_number;
252{
253 if ( fname )
254 {
255 logical_input_file = fname;
256 }
257 if ( line_number >= 0 )
258 {
259 logical_input_line = line_number;
260 }
261}
262\f
263/*
264 * a s _ w h e r e ( )
265 *
266 * Write a line to stderr locating where we are in reading
267 * input source files.
268 * As a sop to the debugger of AS, pretty-print the offending line.
269 */
270void
271as_where()
272{
273 char *p;
274 line_numberT line;
275
276 if (physical_input_file)
277 { /* we tried to read SOME source */
278 if (input_file_is_open())
279 { /* we can still read lines from source */
280#ifdef DONTDEF
281 fprintf (stderr," @ physical line %ld., file \"%s\"",
282 (long) physical_input_line, physical_input_file);
283 fprintf (stderr," @ logical line %ld., file \"%s\"\n",
284 (long) logical_input_line, logical_input_file);
285 (void)putc(' ', stderr);
286 as_howmuch (stderr);
287 (void)putc('\n', stderr);
288#else
289 p = logical_input_file ? logical_input_file : physical_input_file;
290 line = logical_input_line ? logical_input_line : physical_input_line;
291 fprintf(stderr,"%s:%u:", p, line);
292#endif
293 }
294 else
295 {
296#ifdef DONTDEF
297 fprintf (stderr," After reading source.\n");
298#else
299 p = logical_input_file ? logical_input_file : physical_input_file;
300 line = logical_input_line ? logical_input_line : physical_input_line;
301 fprintf (stderr,"%s:unknown:", p);
302#endif
303 }
304 }
305 else
306 {
307#ifdef DONTDEF
308 fprintf (stderr," Before reading source.\n");
309#else
310#endif
311 }
312}
1ffa63ce
DS
313\f
314/*
596cac1d
DS
315 * Support for source file debugging. These functions handle
316 * logical lines and logical files.
1ffa63ce 317 */
596cac1d
DS
318static char *saved_file;
319static int saved_len;
320static line_numberT saved_line;
321
1ffa63ce 322void
596cac1d 323filestab()
1ffa63ce 324{
1ffa63ce 325 char *file;
1ffa63ce 326 int len;
9d9eaa6a 327
596cac1d
DS
328 if (!physical_input_file ||
329 !input_file_is_open())
1ffa63ce 330 return;
9d9eaa6a 331
1ffa63ce 332 file = logical_input_file ? logical_input_file : physical_input_file;
9d9eaa6a 333
1ffa63ce
DS
334 if (saved_file == 0 || strcmp(file, saved_file) != 0)
335 {
336 stabs(file);
337 len = strlen(file) + 1;
338 if (len > saved_len)
339 {
340 if (saved_file == 0)
341 saved_file = xmalloc(len);
342 else
343 saved_file = xrealloc(saved_file, len);
344 memcpy(saved_file, file, len);
345 saved_len = len;
346 }
347 else
348 strcpy(saved_file, file);
349 saved_line = 0;
350 }
596cac1d
DS
351}
352
353void
354funcstab(func)
355 char *func;
356{
357 if (now_seg != SEG_TEXT)
358 return;
359
360 filestab();
361 stabf(func);
362}
363
364void
365linestab()
366{
367 line_numberT line;
368
369 if (now_seg != SEG_TEXT)
370 return;
371
372 filestab();
373
374 line = logical_input_line ? logical_input_line : physical_input_line;
1ffa63ce
DS
375
376 if (saved_line == 0 || line != saved_line)
377 {
378 stabd(line);
379 saved_line = line;
380 }
381}
9d9eaa6a
DS
382\f
383/*
384 * a s _ h o w m u c h ( )
385 *
386 * Output to given stream how much of line we have scanned so far.
387 * Assumes we have scanned up to and including input_line_pointer.
388 * No free '\n' at end of line.
389 */
390void
391as_howmuch (stream)
392 FILE * stream; /* Opened for write please. */
393{
394 register char * p; /* Scan input line. */
395 /* register char c; JF unused */
396
397 for (p = input_line_pointer - 1; * p != '\n'; --p)
398 {
399 }
400 ++ p; /* p -> 1st char of line. */
401 for (; p <= input_line_pointer; p++)
402 {
403 /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */
404 /* c = *p & 0xFF; JF unused */
405 as_1_char (*p, stream);
406 }
407}
408
409static void
410as_1_char (c,stream)
411 unsigned char c;
412 FILE * stream;
413{
414 if ( c > 127 )
415 {
416 (void)putc( '%', stream);
417 c -= 128;
418 }
419 if ( c < 32 )
420 {
421 (void)putc( '^', stream);
422 c += '@';
423 }
424 (void)putc( c, stream);
425}
426
427/* end: input_scrub.c */