2 * File source.c - source file handling for internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
29 struct searchlist
* next
;
37 struct open_filelist
* next
;
40 unsigned int * linelist
;
43 static struct open_filelist
* ofiles
;
45 static struct searchlist
* listhead
;
46 static char DEBUG_current_sourcefile
[PATH_MAX
];
47 static int DEBUG_start_sourceline
= -1;
48 static int DEBUG_end_sourceline
= -1;
53 struct searchlist
* sl
;
55 fprintf(stderr
,"Search list :\n");
56 for(sl
= listhead
; sl
; sl
= sl
->next
)
58 fprintf(stderr
, "\t%s\n", sl
->path
);
60 fprintf(stderr
, "\n");
64 DEBUG_AddPath(const char * path
)
66 struct searchlist
* sl
;
68 sl
= (struct searchlist
*) xmalloc(sizeof(struct searchlist
));
75 sl
->path
= xstrdup(path
);
82 struct searchlist
* sl
;
83 struct searchlist
* nxt
;
85 for(sl
= listhead
; sl
; sl
= nxt
)
97 DEBUG_DisplaySource(char * sourcefile
, int start
, int end
)
103 struct open_filelist
* ol
;
106 struct searchlist
* sl
;
109 char tmppath
[PATH_MAX
];
112 * First see whether we have the file open already. If so, then
113 * use that, otherwise we have to try and open it.
115 for(ol
= ofiles
; ol
; ol
= ol
->next
)
117 if( strcmp(ol
->path
, sourcefile
) == 0 )
126 * Try again, stripping the path from the opened file.
128 for(ol
= ofiles
; ol
; ol
= ol
->next
)
130 pnt
= strrchr(ol
->path
, '/');
131 if( pnt
!= NULL
&& strcmp(pnt
+ 1, sourcefile
) == 0 )
142 * See if this is a DOS style name or not.
144 pnt
= strchr(sourcefile
, '\\' );
147 pnt
= strchr(sourcefile
, '/' );
155 * Crapola. We need to try and open the file.
157 status
= stat(sourcefile
, &statbuf
);
160 strcpy(tmppath
, sourcefile
);
164 for(sl
= listhead
; sl
; sl
= sl
->next
)
166 strcpy(tmppath
, sl
->path
);
167 if( tmppath
[strlen(tmppath
)-1] != '/' )
169 strcat(tmppath
, "/");
172 * Now append the base file name.
174 strcat(tmppath
, pnt
);
176 status
= stat(tmppath
, &statbuf
);
186 * Still couldn't find it. Ask user for path to add.
188 fprintf(stderr
,"Enter path to file %s: ", sourcefile
);
189 fgets(tmppath
, sizeof(tmppath
), stdin
);
191 if( tmppath
[strlen(tmppath
)-1] == '\n' )
193 tmppath
[strlen(tmppath
)-1] = '\0';
196 if( tmppath
[strlen(tmppath
)-1] != '/' )
198 strcat(tmppath
, "/");
201 * Now append the base file name.
203 strcat(tmppath
, pnt
);
205 status
= stat(tmppath
, &statbuf
);
209 * OK, I guess the user doesn't really want to see it
212 ol
= (struct open_filelist
*) xmalloc(sizeof(*ol
));
213 ol
->path
= xstrdup(sourcefile
);
214 ol
->real_path
= NULL
;
219 fprintf(stderr
,"Unable to open file %s\n", tmppath
);
225 * Create header for file.
227 ol
= (struct open_filelist
*) xmalloc(sizeof(*ol
));
228 ol
->path
= xstrdup(sourcefile
);
229 ol
->real_path
= xstrdup(tmppath
);
233 ol
->size
= statbuf
.st_size
;
237 * Now open and map the file.
239 fd
= open(tmppath
, O_RDONLY
);
245 addr
= mmap(0, statbuf
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
246 if( addr
== (char *) -1 )
252 * Now build up the line number mapping table.
256 while(pnt
< addr
+ ol
->size
)
265 ol
->linelist
= (unsigned int*) xmalloc(ol
->nlines
* sizeof(unsigned int) );
269 ol
->linelist
[nlines
++] = 0;
270 while(pnt
< addr
+ ol
->size
)
274 ol
->linelist
[nlines
++] = pnt
- addr
;
277 ol
->linelist
[nlines
++] = pnt
- addr
;
283 * We know what the file is, we just need to reopen it and remap it.
285 fd
= open(ol
->real_path
, O_RDONLY
);
291 addr
= mmap(0, ol
->size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
292 if( addr
== (char *) -1 )
299 * All we need to do is to display the source lines here.
301 for(i
=start
- 1; i
<= end
- 1; i
++)
303 if( i
< 0 || i
>= ol
->nlines
- 1)
308 memset(&buffer
, 0, sizeof(buffer
));
309 if( ol
->linelist
[i
+1] != ol
->linelist
[i
] )
311 memcpy(&buffer
, addr
+ ol
->linelist
[i
],
312 (ol
->linelist
[i
+1] - ol
->linelist
[i
]) - 1);
314 fprintf(stderr
,"%d\t%s\n", i
+ 1, buffer
);
317 munmap(addr
, ol
->size
);
323 DEBUG_List(struct list_id
* source1
, struct list_id
* source2
,
331 * We need to see what source file we need. Hopefully we only have
332 * one specified, otherwise we might as well punt.
336 && source1
->sourcefile
!= NULL
337 && source2
->sourcefile
!= NULL
338 && strcmp(source1
->sourcefile
, source2
->sourcefile
) != 0 )
340 fprintf(stderr
, "Ambiguous source file specification.\n");
345 if( source1
!= NULL
&& source1
->sourcefile
!= NULL
)
347 sourcefile
= source1
->sourcefile
;
350 if( sourcefile
== NULL
352 && source2
->sourcefile
!= NULL
)
354 sourcefile
= source2
->sourcefile
;
357 if( sourcefile
== NULL
)
359 sourcefile
= (char *) &DEBUG_current_sourcefile
;
362 if( sourcefile
== NULL
)
364 fprintf(stderr
, "No source file specified.\n");
369 * Now figure out the line number range to be listed.
374 if( source1
!= NULL
)
376 start
= source1
->line
;
379 if( source2
!= NULL
)
384 if( start
== -1 && end
== -1 )
388 end
= DEBUG_start_sourceline
;
393 start
= DEBUG_end_sourceline
;
397 else if( start
== -1 )
407 * Now call this function to do the dirty work.
409 DEBUG_DisplaySource(sourcefile
, start
, end
);
411 if( sourcefile
!= (char *) &DEBUG_current_sourcefile
)
413 strcpy(DEBUG_current_sourcefile
, sourcefile
);
415 DEBUG_start_sourceline
= start
;
416 DEBUG_end_sourceline
= end
;
425 DEBUG_AddPath("../../de");
428 fscanf(stdin
,"%d %d", &i
, &j
);
429 DEBUG_DisplaySource("dumpexe.c", i
, j
);