134 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* $Id$ */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <alloc.h>
 | |
| 
 | |
| #include "position.h"
 | |
| #include "idf.h"
 | |
| #include "file.h"
 | |
| #include "symbol.h"
 | |
| #include "misc.h"
 | |
| 
 | |
| static	line_positions();
 | |
| extern char	*dirs[];
 | |
| extern FILE	*fopen();
 | |
| extern FILE	*db_out;
 | |
| extern t_lineno	currline;
 | |
| extern int	interrupted;
 | |
| 
 | |
| static void
 | |
| mk_filnm(dir, file, newname)
 | |
|   char	*dir;
 | |
|   char	*file;
 | |
|   char	**newname;
 | |
| {
 | |
|   register char	*dst = Malloc((unsigned) (strlen(dir) + strlen(file) + 2));
 | |
| 
 | |
|   *newname = dst;
 | |
|   if (*dir) {
 | |
| 	while (*dst++ = *dir++) /* nothing */;
 | |
| 	*(dst - 1) = '/';
 | |
|   }
 | |
|   while (*dst++ = *file++) /* nothing */;
 | |
| }
 | |
| 
 | |
| static FILE *
 | |
| open_file(fn, mode, ffn)
 | |
|   char	*fn;
 | |
|   char	*mode;
 | |
|   char	**ffn;
 | |
| {
 | |
|   FILE	*f;
 | |
|   char	**p;
 | |
| 
 | |
|   if (fn[0] == '/') {
 | |
| 	*ffn = fn;
 | |
| 	return fopen(fn, mode);
 | |
|   }
 | |
|   p = dirs;
 | |
|   while (*p) {	
 | |
| 	mk_filnm(*p++, fn, ffn);
 | |
| 	if ((f = fopen(*ffn, mode)) != NULL) {
 | |
| 		return f;
 | |
| 	}
 | |
| 	free(*ffn);
 | |
|   }
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| lines(file, l1, l2)
 | |
|   register p_file file;
 | |
|   int		l1, l2;
 | |
| {
 | |
|   static p_file last_file;
 | |
|   static FILE *last_f;
 | |
|   register FILE	*f;
 | |
|   register int	n;
 | |
| 
 | |
|   if (last_file != file) {
 | |
| 	if (last_f) fclose(last_f);
 | |
| 	last_f = 0;
 | |
|   	if (!(f = open_file(file->f_sym->sy_idf->id_text, 
 | |
| 			    "r",
 | |
| 			    &file->f_fullname))) {
 | |
| 		error("could not open %s", file->f_sym->sy_idf->id_text);
 | |
| 		return;
 | |
| 	}
 | |
| 	last_file = file;
 | |
| 	last_f = f;
 | |
| 	if (! file->f_linepos) {
 | |
| 		line_positions(file, f);
 | |
| 	}
 | |
|   }
 | |
|   else f = last_f;
 | |
| 
 | |
|   if (l1 < 1) l1 = 1;
 | |
|   if (l1 > file->f_nlines) l1 = file->f_nlines;
 | |
|   if (l1+l2-1 > file->f_nlines) l2 = file->f_nlines - l1 + 1;
 | |
| 
 | |
|   fseek(f, *(file->f_linepos+(l1-1)), 0);
 | |
|   for (n = l1; n < l1 + l2; n++) {
 | |
| 	register int	c;
 | |
| 
 | |
| 	if (interrupted) return;
 | |
| 	fprintf(db_out, "%c%5d\t", currfile && file == currfile->sy_file && n == currline ? '>' : ' ', n);
 | |
| 	do {
 | |
| 		c = getc(f);
 | |
| 		if (c != EOF) putc(c, db_out);
 | |
| 	} while (c != '\n' && c != EOF);
 | |
| 	if (c == EOF) break;
 | |
|   }
 | |
|   clearerr(f);
 | |
| }
 | |
| 
 | |
| static
 | |
| line_positions(file, f)
 | |
|   p_file	file;
 | |
|   register FILE	*f;
 | |
| {
 | |
|   int		nl;
 | |
|   unsigned int	n_alloc = 256;
 | |
|   register long	cnt = 0;
 | |
|   register int	c;
 | |
| 
 | |
|   file->f_linepos = (long *) Malloc(n_alloc * sizeof(long));
 | |
|   file->f_linepos[0] = 0;
 | |
|   nl = 1;
 | |
|   while ((c = getc(f)) != EOF) {
 | |
| 	cnt++;
 | |
| 	if (c == '\n') {
 | |
| 		if (nl == n_alloc) {
 | |
| 			n_alloc <<= 1;
 | |
| 			file->f_linepos =
 | |
| 				(long *) Realloc((char *)(file->f_linepos),
 | |
| 						 n_alloc * sizeof(long));
 | |
| 		}
 | |
| 		file->f_linepos[nl++] = cnt;
 | |
| 	}
 | |
|   }
 | |
|   if (cnt == file->f_linepos[nl-1]) nl--;
 | |
|   file->f_linepos = (long *) Realloc((char *)(file->f_linepos),
 | |
| 					(unsigned)nl * sizeof(long));
 | |
|   file->f_nlines = nl;
 | |
|   clearerr(f);
 | |
| }
 |