30
30
inputFile File; /* globally read through macros */
31
static fpos_t StartOfLine; /* holds deferred position of start of line */
32
static int bufferStartOfLine; /* the same as StartOfLine but for buffer */
35
static int readNextChar (void);
36
static int pushBackChar (int c);
31
static MIOPos StartOfLine; /* holds deferred position of start of line */
35
/* Read a character choosing automatically between file or buffer, depending
36
* on which mode we are.
38
#define readNextChar() (mio_getc (File.mio))
40
/* Replaces ungetc() for file. In case of buffer we'll perform the same action:
41
* fpBufferPosition-- and write of the param char into the buf.
43
#define pushBackChar(c) (mio_ungetc (File.mio, c))
39
46
* FUNCTION DEFINITIONS
254
261
/* If another file was already open, then close it.
263
if (File.mio != NULL)
258
fclose (File.fp); /* close any open source file */
265
mio_free (File.mio); /* close any open source file */
262
File.fp = g_fopen (fileName, openMode);
269
File.mio = mio_new_file_full (fileName, openMode, g_fopen, fclose);
270
if (File.mio == NULL)
264
271
error (WARNING | PERROR, "cannot open \"%s\"", fileName);
269
276
setInputFileName (fileName);
270
fgetpos (File.fp, &StartOfLine);
271
fgetpos (File.fp, &File.filePosition);
277
mio_getpos (File.mio, &StartOfLine);
278
mio_getpos (File.mio, &File.filePosition);
272
279
File.currentLine = NULL;
273
280
File.language = language;
274
281
File.lineNumber = 0L;
298
305
boolean opened = FALSE;
300
/* Check whether a file of a buffer were already open, then close them.
307
/* Check whether a file of a buffer were already open, then close them.
302
if (File.fp != NULL) {
303
fclose (File.fp); /* close any open source file */
309
if (File.mio != NULL) {
310
mio_free (File.mio); /* close any open source file */
307
if (File.fpBuffer != NULL) {
308
error(PERROR, "An unallocated buffer was found. Please check you called \
309
correctly bufferClose ()\n");
310
File.fpBuffer = NULL;
313
314
/* check if we got a good buffer */
314
315
if (buffer == NULL || buffer_size == 0) {
321
File.fpBuffer = buffer;
322
File.mio = mio_new_memory (buffer, buffer_size, NULL, NULL);
322
323
setInputFileName (fileName);
323
bufferStartOfLine = 0;
324
File.fpBufferPosition = 0;
325
File.fpBufferSize = buffer_size;
324
mio_getpos (File.mio, &StartOfLine);
325
mio_getpos (File.mio, &File.filePosition);
326
326
File.currentLine = NULL;
327
327
File.language = language;
328
328
File.lineNumber = 0L;
339
339
getLanguageName (language),
340
340
File.source.isHeader ? "include " : "");
345
345
extern void fileClose (void)
347
if (File.mio != NULL)
349
349
/* The line count of the file is 1 too big, since it is one-based
350
350
* and is incremented upon each newline.
353
353
addTotals (0, File.lineNumber - 1L,
354
354
getFileSize (vStringValue (File.name)));
361
/* user should take care of freeing the buffer */
362
extern void bufferClose (void)
364
if (File.fpBuffer != NULL) {
365
File.fpBuffer = NULL;
406
/* FIXME: find out a better way to do this check */
408
fsetpos (File.fp, &StartOfLine);
410
File.fpBufferPosition = bufferStartOfLine;
398
mio_setpos (File.mio, &StartOfLine);
412
400
c = readNextChar ();
419
407
else if (c == NEWLINE)
421
409
File.newLine = TRUE;
422
if (File.fp != NULL) /* we have a file */
423
fgetpos (File.fp, &StartOfLine);
424
else /* it's a buffer */
425
bufferStartOfLine = File.fpBufferPosition;
410
mio_getpos (File.mio, &StartOfLine);
427
412
else if (c == CRETURN)
438
423
c = NEWLINE; /* convert CR into newline */
439
424
File.newLine = TRUE;
441
fgetpos (File.fp, &StartOfLine);
443
bufferStartOfLine = File.fpBufferPosition;
425
mio_getpos (File.mio, &StartOfLine);
445
427
DebugStatement ( debugPutc (DEBUG_RAW, c); )
538
/* Read a character choosing automatically between file or buffer, depending
539
* on which mode we are.
541
static int readNextChar(void)
543
if (File.fp != NULL) {
544
return getc(File.fp);
548
if (File.fpBufferPosition >= File.fpBufferSize)
551
c = File.fpBuffer[File.fpBufferPosition];
552
File.fpBufferPosition++;
558
/* Replaces ungetc() for file. In case of buffer we'll perform the same action:
559
* fpBufferPosition-- and write of the param char into the buf.
561
static int pushBackChar (int c)
563
if (File.fp != NULL) {
564
return ungetc (c, File.fp);
567
File.fpBufferPosition--;
568
if (File.fpBufferPosition < 0)
570
File.fpBuffer[File.fpBufferPosition] = c;
571
return File.fpBuffer[File.fpBufferPosition];
576
/* replacement for fsetpos, applied to a buffer */
577
extern void setBufPos (int new_position)
579
File.fpBufferPosition = new_position;
582
/* replacement for fgetpos, applied to a buffer */
583
extern int getBufPos (void)
585
return File.fpBufferPosition;
588
extern boolean useFile (void)
597
522
* Source file line reading with automatic buffer sizing
598
* Does not perform file/buffer checks. Only file is supported.
600
extern char *readLine (vString *const vLine, FILE *const fp)
524
extern char *readLine (vString *const vLine, MIO *const mio)
602
526
char *result = NULL;
604
528
vStringClear (vLine);
605
if (fp == NULL) /* to free memory allocated to buffer */
606
error (FATAL, "NULL file pointer");
529
if (mio == NULL) /* to free memory allocated to buffer */
530
error (FATAL, "NULL MIO pointer");
609
533
boolean reReadLine;
618
542
char *const pLastChar = vStringValue (vLine) + vStringSize (vLine) -2;
621
fgetpos (fp, &startOfLine);
545
mio_getpos (mio, &startOfLine);
622
546
reReadLine = FALSE;
623
547
*pLastChar = '\0';
624
result = fgets (vStringValue (vLine), (int) vStringSize (vLine), fp);
548
result = mio_gets (mio, vStringValue (vLine), (int) vStringSize (vLine));
625
549
if (result == NULL)
628
552
error (FATAL | PERROR, "Failure on attempt to read file");
630
554
else if (*pLastChar != '\0' &&
633
557
/* buffer overflow */
634
558
reReadLine = vStringAutoResize (vLine);
636
fsetpos (fp, &startOfLine);
560
mio_setpos (mio, &startOfLine);
638
562
error (FATAL | PERROR, "input line too big; out of memory");
660
584
/* Places into the line buffer the contents of the line referenced by
663
extern char *readSourceLine (vString *const vLine, fpos_t location,
587
extern char *readSourceLine (vString *const vLine, MIOPos location,
664
588
long *const pSeekValue)
666
fpos_t orignalPosition;
590
MIOPos orignalPosition;
669
fgetpos (File.fp, &orignalPosition);
670
fsetpos (File.fp, &location);
593
mio_getpos (File.mio, &orignalPosition);
594
mio_setpos (File.mio, &location);
671
595
if (pSeekValue != NULL)
672
*pSeekValue = ftell (File.fp);
673
result = readLine (vLine, File.fp);
596
*pSeekValue = mio_tell (File.mio);
597
result = readLine (vLine, File.mio);
674
598
if (result == NULL)
675
599
error (FATAL, "Unexpected end of file: %s", vStringValue (File.name));
676
fsetpos (File.fp, &orignalPosition);
600
mio_setpos (File.mio, &orignalPosition);