51
51
static void setInputFileName (const char *const fileName)
53
const char *const head = fileName;
54
const char *const tail = baseFilename (head);
56
if (File.name != NULL)
57
vStringDelete (File.name);
58
File.name = vStringNewInit (fileName);
60
if (File.path != NULL)
61
vStringDelete (File.path);
66
const size_t length = tail - head - 1;
67
File.path = vStringNew ();
68
vStringNCopyS (File.path, fileName, length);
53
const char *const head = fileName;
54
const char *const tail = baseFilename (head);
56
if (File.name != NULL)
57
vStringDelete (File.name);
58
File.name = vStringNewInit (fileName);
60
if (File.path != NULL)
61
vStringDelete (File.path);
66
const size_t length = tail - head - 1;
67
File.path = vStringNew ();
68
vStringNCopyS (File.path, fileName, length);
72
72
static void setSourceFileParameters (vString *const fileName)
74
if (File.source.name != NULL)
75
vStringDelete (File.source.name);
76
File.source.name = fileName;
78
if (File.source.tagPath != NULL)
79
eFree (File.source.tagPath);
80
if (! Option.tagRelative || isAbsolutePath (vStringValue (fileName)))
81
File.source.tagPath = eStrdup (vStringValue (fileName));
84
relativeFilename (vStringValue (fileName), TagFile.directory);
86
if (vStringLength (fileName) > TagFile.max.file)
87
TagFile.max.file = vStringLength (fileName);
89
File.source.isHeader = isIncludeFile (vStringValue (fileName));
90
File.source.language = getFileLanguage (vStringValue (fileName));
74
if (File.source.name != NULL)
75
vStringDelete (File.source.name);
76
File.source.name = fileName;
78
if (File.source.tagPath != NULL)
79
eFree (File.source.tagPath);
80
if (! Option.tagRelative || isAbsolutePath (vStringValue (fileName)))
81
File.source.tagPath = eStrdup (vStringValue (fileName));
84
relativeFilename (vStringValue (fileName), TagFile.directory);
86
if (vStringLength (fileName) > TagFile.max.file)
87
TagFile.max.file = vStringLength (fileName);
89
File.source.isHeader = isIncludeFile (vStringValue (fileName));
90
File.source.language = getFileLanguage (vStringValue (fileName));
93
93
static boolean setSourceFileName (vString *const fileName)
95
boolean result = FALSE;
96
if (getFileLanguage (vStringValue (fileName)) != LANG_IGNORE)
99
if (isAbsolutePath (vStringValue (fileName)) || File.path == NULL)
100
pathName = vStringNewCopy (fileName);
102
pathName = combinePathAndFile (vStringValue (File.path),
103
vStringValue (fileName));
104
setSourceFileParameters (pathName);
95
boolean result = FALSE;
96
if (getFileLanguage (vStringValue (fileName)) != LANG_IGNORE)
99
if (isAbsolutePath (vStringValue (fileName)) || File.path == NULL)
100
pathName = vStringNewCopy (fileName);
102
pathName = combinePathAndFile (
103
vStringValue (File.path), vStringValue (fileName));
104
setSourceFileParameters (pathName);
147
147
static vString *readFileName (void)
149
vString *const fileName = vStringNew ();
150
boolean quoteDelimited = FALSE;
151
int c = skipWhite ();
155
c = getc (File.fp); /* skip double-quote */
156
quoteDelimited = TRUE;
158
while (c != EOF && c != '\n' &&
159
(quoteDelimited ? (c != '"') : (c != ' ' && c != '\t')))
161
vStringPut (fileName, c);
166
vStringPut (fileName, '\0');
149
vString *const fileName = vStringNew ();
150
boolean quoteDelimited = FALSE;
151
int c = skipWhite ();
155
c = getc (File.fp); /* skip double-quote */
156
quoteDelimited = TRUE;
158
while (c != EOF && c != '\n' &&
159
(quoteDelimited ? (c != '"') : (c != ' ' && c != '\t')))
161
vStringPut (fileName, c);
166
vStringPut (fileName, '\0');
171
171
static boolean parseLineDirective (void)
173
boolean result = FALSE;
174
int c = skipWhite ();
175
DebugStatement ( const char* lineStr = ""; )
182
else if (c == 'l' && getc (File.fp) == 'i' &&
183
getc (File.fp) == 'n' && getc (File.fp) == 'e')
186
if (c == ' ' || c == '\t')
188
DebugStatement ( lineStr = "line"; )
194
const unsigned long lNum = readLineNumber ();
199
vString *const fileName = readFileName ();
200
if (vStringLength (fileName) == 0)
202
File.source.lineNumber = lNum - 1; /* applies to NEXT line */
203
DebugStatement ( debugPrintf (DEBUG_RAW, "#%s %ld", lineStr, lNum); )
205
else if (setSourceFileName (fileName))
207
File.source.lineNumber = lNum - 1; /* applies to NEXT line */
208
DebugStatement ( debugPrintf (DEBUG_RAW, "#%s %ld \"%s\"",
209
lineStr, lNum, vStringValue (fileName)); )
212
if (Option.include.fileNames && vStringLength (fileName) > 0 &&
216
initTagEntry (&tag, baseFilename (vStringValue (fileName)));
218
tag.isFileEntry = TRUE;
219
tag.lineNumberEntry = TRUE;
221
tag.kindName = "file";
226
vStringDelete (fileName);
173
boolean result = FALSE;
174
int c = skipWhite ();
175
DebugStatement ( const char* lineStr = ""; )
182
else if (c == 'l' && getc (File.fp) == 'i' &&
183
getc (File.fp) == 'n' && getc (File.fp) == 'e')
186
if (c == ' ' || c == '\t')
188
DebugStatement ( lineStr = "line"; )
194
const unsigned long lNum = readLineNumber ();
199
vString *const fileName = readFileName ();
200
if (vStringLength (fileName) == 0)
202
File.source.lineNumber = lNum - 1; /* applies to NEXT line */
203
DebugStatement ( debugPrintf (DEBUG_RAW, "#%s %ld", lineStr, lNum); )
205
else if (setSourceFileName (fileName))
207
File.source.lineNumber = lNum - 1; /* applies to NEXT line */
208
DebugStatement ( debugPrintf (DEBUG_RAW, "#%s %ld \"%s\"",
209
lineStr, lNum, vStringValue (fileName)); )
212
if (Option.include.fileNames && vStringLength (fileName) > 0 &&
216
initTagEntry (&tag, baseFilename (vStringValue (fileName)));
218
tag.isFileEntry = TRUE;
219
tag.lineNumberEntry = TRUE;
221
tag.kindName = "file";
226
vStringDelete (fileName);
240
240
extern boolean fileOpen (const char *const fileName, const langType language)
243
const char *const openMode = "r";
243
const char *const openMode = "r";
245
const char *const openMode = "rb";
245
const char *const openMode = "rb";
247
boolean opened = FALSE;
249
/* If another file was already open, then close it.
253
fclose (File.fp); /* close any open source file */
257
File.fp = fopen (fileName, openMode);
259
error (WARNING | PERROR, "cannot open \"%s\"", fileName);
264
setInputFileName (fileName);
265
fgetpos (File.fp, &StartOfLine);
266
fgetpos (File.fp, &File.filePosition);
267
File.currentLine = NULL;
268
File.language = language;
269
File.lineNumber = 0L;
273
if (File.line != NULL)
274
vStringClear (File.line);
276
setSourceFileParameters (vStringNewInit (fileName));
277
File.source.lineNumber = 0L;
279
verbose ("OPENING %s as %s language %sfile\n", fileName,
280
getLanguageName (language),
281
File.source.isHeader ? "include " : "");
247
boolean opened = FALSE;
249
/* If another file was already open, then close it.
253
fclose (File.fp); /* close any open source file */
257
File.fp = fopen (fileName, openMode);
259
error (WARNING | PERROR, "cannot open \"%s\"", fileName);
264
setInputFileName (fileName);
265
fgetpos (File.fp, &StartOfLine);
266
fgetpos (File.fp, &File.filePosition);
267
File.currentLine = NULL;
268
File.language = language;
269
File.lineNumber = 0L;
273
if (File.line != NULL)
274
vStringClear (File.line);
276
setSourceFileParameters (vStringNewInit (fileName));
277
File.source.lineNumber = 0L;
279
verbose ("OPENING %s as %s language %sfile\n", fileName,
280
getLanguageName (language),
281
File.source.isHeader ? "include " : "");
286
286
extern void fileClose (void)
290
/* The line count of the file is 1 too big, since it is one-based
291
* and is incremented upon each newline.
293
if (Option.printTotals)
295
fileStatus *status = eStat (vStringValue (File.name));
296
addTotals (0, File.lineNumber - 1L, status->size);
290
/* The line count of the file is 1 too big, since it is one-based
291
* and is incremented upon each newline.
293
if (Option.printTotals)
295
fileStatus *status = eStat (vStringValue (File.name));
296
addTotals (0, File.lineNumber - 1L, status->size);
303
303
extern boolean fileEOF (void)
308
308
/* Action to take for each encountered source newline.
310
310
static void fileNewline (void)
312
File.filePosition = StartOfLine;
313
File.newLine = FALSE;
315
File.source.lineNumber++;
316
DebugStatement ( if (Option.breakLine == File.lineNumber) lineBreak (); )
317
DebugStatement ( debugPrintf (DEBUG_RAW, "%6ld: ", File.lineNumber); )
312
File.filePosition = StartOfLine;
313
File.newLine = FALSE;
315
File.source.lineNumber++;
316
DebugStatement ( if (Option.breakLine == File.lineNumber) lineBreak (); )
317
DebugStatement ( debugPrintf (DEBUG_RAW, "%6ld: ", File.lineNumber); )
320
320
/* This function reads a single character from the stream, performing newline
323
323
static int iFileGetc (void)
329
/* If previous character was a newline, then we're starting a line.
331
if (File.newLine && c != EOF)
334
if (c == '#' && Option.lineDirectives)
336
if (parseLineDirective ())
340
fsetpos (File.fp, &StartOfLine);
348
else if (c == NEWLINE)
351
fgetpos (File.fp, &StartOfLine);
353
else if (c == CRETURN)
355
/* Turn line breaks into a canonical form. The three commonly
356
* used forms if line breaks: LF (UNIX), CR (MacIntosh), and
357
* CR-LF (MS-DOS) are converted into a generic newline.
329
/* If previous character was a newline, then we're starting a line.
359
const int next = getc (File.fp); /* is CR followed by LF? */
362
ungetc (next, File.fp);
364
c = NEWLINE; /* convert CR into newline */
366
fgetpos (File.fp, &StartOfLine);
368
DebugStatement ( debugPutc (DEBUG_RAW, c); )
331
if (File.newLine && c != EOF)
334
if (c == '#' && Option.lineDirectives)
336
if (parseLineDirective ())
340
fsetpos (File.fp, &StartOfLine);
348
else if (c == NEWLINE)
351
fgetpos (File.fp, &StartOfLine);
353
else if (c == CRETURN)
355
/* Turn line breaks into a canonical form. The three commonly
356
* used forms if line breaks: LF (UNIX), CR (MacIntosh), and
357
* CR-LF (MS-DOS) are converted into a generic newline.
359
const int next = getc (File.fp); /* is CR followed by LF? */
362
ungetc (next, File.fp);
364
c = NEWLINE; /* convert CR into newline */
366
fgetpos (File.fp, &StartOfLine);
368
DebugStatement ( debugPutc (DEBUG_RAW, c); )
372
372
extern void fileUngetc (int c)
377
377
static vString *iFileGetLine (void)
379
vString *result = NULL;
381
if (File.line == NULL)
382
File.line = vStringNew ();
383
vStringClear (File.line);
388
vStringPut (File.line, c);
389
if (c == '\n' || (c == EOF && vStringLength (File.line) > 0))
379
vString *result = NULL;
381
if (File.line == NULL)
382
File.line = vStringNew ();
383
vStringClear (File.line);
391
vStringTerminate (File.line);
388
vStringPut (File.line, c);
389
if (c == '\n' || (c == EOF && vStringLength (File.line) > 0))
391
vStringTerminate (File.line);
392
392
#ifdef HAVE_REGEX
393
if (vStringLength (File.line) > 0)
394
matchRegex (File.line, File.source.language);
393
if (vStringLength (File.line) > 0)
394
matchRegex (File.line, File.source.language);
400
Assert (result != NULL || File.eof);
400
Assert (result != NULL || File.eof);
404
404
/* Do not mix use of fileReadLine () and fileGetc () for the same file.
406
406
extern int fileGetc (void)
410
/* If there is an ungotten character, then return it. Don't do any
411
* other processing on it, though, because we already did that the
412
* first time it was read through fileGetc ().
414
if (File.ungetch != '\0')
418
return c; /* return here to avoid re-calling debugPutc () */
422
if (File.currentLine != NULL)
424
c = *File.currentLine++;
426
File.currentLine = NULL;
430
vString* const line = iFileGetLine ();
432
File.currentLine = (unsigned char*) vStringValue (line);
433
if (File.currentLine == NULL)
439
DebugStatement ( debugPutc (DEBUG_READ, c); )
410
/* If there is an ungotten character, then return it. Don't do any
411
* other processing on it, though, because we already did that the
412
* first time it was read through fileGetc ().
414
if (File.ungetch != '\0')
418
return c; /* return here to avoid re-calling debugPutc () */
422
if (File.currentLine != NULL)
424
c = *File.currentLine++;
426
File.currentLine = NULL;
430
vString* const line = iFileGetLine ();
432
File.currentLine = (unsigned char*) vStringValue (line);
433
if (File.currentLine == NULL)
439
DebugStatement ( debugPutc (DEBUG_READ, c); )
443
443
/* An alternative interface to fileGetc (). Do not mix use of fileReadLine()
448
448
extern const unsigned char *fileReadLine (void)
450
vString* const line = iFileGetLine ();
451
const unsigned char* result = NULL;
454
result = (const unsigned char*) vStringValue (line);
455
vStringStripNewline (line);
456
DebugStatement ( debugPrintf (DEBUG_READ, "%s\n", result); )
450
vString* const line = iFileGetLine ();
451
const unsigned char* result = NULL;
454
result = (const unsigned char*) vStringValue (line);
455
vStringStripNewline (line);
456
DebugStatement ( debugPrintf (DEBUG_READ, "%s\n", result); )
464
464
extern char *readLine (vString *const vLine, FILE *const fp)
468
vStringClear (vLine);
469
if (fp == NULL) /* to free memory allocated to buffer */
470
error (FATAL, "NULL file pointer");
475
/* If reading the line places any character other than a null or a
476
* newline at the last character position in the buffer (one less
477
* than the buffer size), then we must resize the buffer and
478
* reattempt to read the line.
468
vStringClear (vLine);
469
if (fp == NULL) /* to free memory allocated to buffer */
470
error (FATAL, "NULL file pointer");
482
char *const pLastChar = vStringValue (vLine) + vStringSize (vLine) -2;
485
fgetpos (fp, &startOfLine);
488
result = fgets (vStringValue (vLine), (int) vStringSize (vLine), fp);
492
error (FATAL | PERROR, "Failure on attempt to read file");
494
else if (*pLastChar != '\0' &&
495
*pLastChar != '\n' && *pLastChar != '\r')
497
/* buffer overflow */
498
reReadLine = vStringAutoResize (vLine);
500
fsetpos (fp, &startOfLine);
502
error (FATAL | PERROR, "input line too big; out of memory");
507
vStringSetLength (vLine);
508
/* canonicalize new line */
509
eol = vStringValue (vLine) + vStringLength (vLine) - 1;
512
else if (*(eol - 1) == '\r' && *eol == '\n')
475
/* If reading the line places any character other than a null or a
476
* newline at the last character position in the buffer (one less
477
* than the buffer size), then we must resize the buffer and
478
* reattempt to read the line.
519
} while (reReadLine);
482
char *const pLastChar = vStringValue (vLine) + vStringSize (vLine) -2;
485
fgetpos (fp, &startOfLine);
488
result = fgets (vStringValue (vLine), (int) vStringSize (vLine), fp);
492
error (FATAL | PERROR, "Failure on attempt to read file");
494
else if (*pLastChar != '\0' &&
495
*pLastChar != '\n' && *pLastChar != '\r')
497
/* buffer overflow */
498
reReadLine = vStringAutoResize (vLine);
500
fsetpos (fp, &startOfLine);
502
error (FATAL | PERROR, "input line too big; out of memory");
507
vStringSetLength (vLine);
508
/* canonicalize new line */
509
eol = vStringValue (vLine) + vStringLength (vLine) - 1;
512
else if (*(eol - 1) == '\r' && *eol == '\n')
519
} while (reReadLine);
524
524
/* Places into the line buffer the contents of the line referenced by
527
extern char *readSourceLine (vString *const vLine, fpos_t location,
528
long *const pSeekValue)
527
extern char *readSourceLine (
528
vString *const vLine, fpos_t location, long *const pSeekValue)
530
fpos_t orignalPosition;
533
fgetpos (File.fp, &orignalPosition);
534
fsetpos (File.fp, &location);
535
if (pSeekValue != NULL)
536
*pSeekValue = ftell (File.fp);
537
result = readLine (vLine, File.fp);
539
error (FATAL, "Unexpected end of file: %s", vStringValue (File.name));
540
fsetpos (File.fp, &orignalPosition);
530
fpos_t orignalPosition;
533
fgetpos (File.fp, &orignalPosition);
534
fsetpos (File.fp, &location);
535
if (pSeekValue != NULL)
536
*pSeekValue = ftell (File.fp);
537
result = readLine (vLine, File.fp);
539
error (FATAL, "Unexpected end of file: %s", vStringValue (File.name));
540
fsetpos (File.fp, &orignalPosition);
545
/* vi:set tabstop=8 shiftwidth=4: */
545
/* vi:set tabstop=4 shiftwidth=4: */