~ubuntu-branches/ubuntu/utopic/geany/utopic

« back to all changes in this revision

Viewing changes to .pc/git_build_with_latest_glib.patch/tagmanager/parse.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-04-19 21:00:25 UTC
  • Revision ID: package-import@ubuntu.com-20130419210025-tsuvhqufntxj5rsy
Tags: 1.22+dfsg-2ubuntu1
* debian/patches/git_build_with_latest_glib.patch:
  - Backport patch from 1.23 to fix build failure with glib 2.36

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
*
 
3
*   Copyright (c) 1996-2001, Darren Hiebert
 
4
*
 
5
*   This source code is released for free distribution under the terms of the
 
6
*   GNU General Public License.
 
7
*
 
8
*   This module contains functions for managing source languages and
 
9
*   dispatching files to the appropriate language parser.
 
10
*/
 
11
 
 
12
/*
 
13
*   INCLUDE FILES
 
14
*/
 
15
#include "general.h"    /* must always come first */
 
16
 
 
17
#include <string.h>
 
18
#include <mio/mio.h>
 
19
 
 
20
 
 
21
#include "entry.h"
 
22
#include "main.h"
 
23
#define OPTION_WRITE
 
24
#include "options.h"
 
25
#include "parsers.h"
 
26
#include "read.h"
 
27
#include "vstring.h"
 
28
 
 
29
/*
 
30
*   DATA DEFINITIONS
 
31
*/
 
32
static parserDefinitionFunc* BuiltInParsers[] = { PARSER_LIST };
 
33
parserDefinition** LanguageTable = NULL;
 
34
static unsigned int LanguageCount = 0;
 
35
tagEntryFunction TagEntryFunction = NULL;
 
36
tagEntrySetArglistFunction TagEntrySetArglistFunction = NULL;
 
37
 
 
38
/*
 
39
*   FUNCTION DEFINITIONS
 
40
*/
 
41
 
 
42
extern void makeSimpleTag (const vString* const name,
 
43
                           kindOption* const kinds, const int kind)
 
44
{
 
45
    if (name != NULL  &&  vStringLength (name) > 0)
 
46
    {
 
47
        tagEntryInfo e;
 
48
        initTagEntry (&e, vStringValue (name));
 
49
 
 
50
        e.kindName = kinds [kind].name;
 
51
        e.kind     = kinds [kind].letter;
 
52
 
 
53
        makeTagEntry (&e);
 
54
    }
 
55
}
 
56
 
 
57
 
 
58
extern void makeSimpleScopedTag (const vString* const name,
 
59
                                 kindOption* const kinds, const int kind,
 
60
                                 const char* scope, const char *scope2,
 
61
                                 const char *laccess)
 
62
{
 
63
    if (name != NULL  &&  vStringLength (name) > 0)
 
64
    {
 
65
        tagEntryInfo e;
 
66
        initTagEntry (&e, vStringValue (name));
 
67
 
 
68
        e.kindName = kinds [kind].name;
 
69
        e.kind     = kinds [kind].letter;
 
70
        e.extensionFields.scope[0] = scope;
 
71
        e.extensionFields.scope[1] = scope2;
 
72
        e.extensionFields.access = laccess;
 
73
 
 
74
        makeTagEntry (&e);
 
75
    }
 
76
}
 
77
 
 
78
/*
 
79
*   parserDescription mapping management
 
80
*/
 
81
 
 
82
extern parserDefinition* parserNew (const char* name)
 
83
{
 
84
    parserDefinition* result = xCalloc (1, parserDefinition);
 
85
    result->name = eStrdup (name);
 
86
    return result;
 
87
}
 
88
 
 
89
extern const char *getLanguageName (const langType language)
 
90
{
 
91
    /*Assert (0 <= language  &&  language < (int) LanguageCount);*/
 
92
    if (language < 0) return NULL;
 
93
        return LanguageTable [language]->name;
 
94
}
 
95
 
 
96
extern langType getNamedLanguage (const char *const name)
 
97
{
 
98
    langType result = LANG_IGNORE;
 
99
    unsigned int i;
 
100
    Assert (name != NULL);
 
101
        for (i = 0  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)
 
102
    {
 
103
        if (LanguageTable [i]->name != NULL)
 
104
            if (stricmp (name, LanguageTable [i]->name) == 0)
 
105
                result = i;
 
106
    }
 
107
    return result;
 
108
}
 
109
 
 
110
static langType getExtensionLanguage (const char *const extension)
 
111
{
 
112
    langType result = LANG_IGNORE;
 
113
    unsigned int i;
 
114
    for (i = 0  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)
 
115
    {
 
116
        stringList* const exts = LanguageTable [i]->currentExtensions;
 
117
        if (exts != NULL  &&  stringListExtensionMatched (exts, extension))
 
118
            result = i;
 
119
    }
 
120
    return result;
 
121
}
 
122
 
 
123
static langType getPatternLanguage (const char *const fileName)
 
124
{
 
125
    langType result = LANG_IGNORE;
 
126
    const char* base = baseFilename (fileName);
 
127
    unsigned int i;
 
128
    for (i = 0  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)
 
129
    {
 
130
        stringList* const ptrns = LanguageTable [i]->currentPatterns;
 
131
        if (ptrns != NULL  &&  stringListFileMatched (ptrns, base))
 
132
            result = i;
 
133
    }
 
134
    return result;
 
135
}
 
136
 
 
137
#ifdef SYS_INTERPRETER
 
138
 
 
139
/*  The name of the language interpreter, either directly or as the argument
 
140
 *  to "env".
 
141
 */
 
142
static vString* determineInterpreter (const char* const cmd)
 
143
{
 
144
    vString* const interpreter = vStringNew ();
 
145
    const char* p = cmd;
 
146
    do
 
147
    {
 
148
        vStringClear (interpreter);
 
149
        for ( ;  isspace (*p)  ;  ++p)
 
150
            ; /* no-op */
 
151
        for ( ;  *p != '\0'  &&  ! isspace (*p)  ;  ++p)
 
152
            vStringPut (interpreter, (int) *p);
 
153
        vStringTerminate (interpreter);
 
154
    } while (strcmp (vStringValue (interpreter), "env") == 0);
 
155
    return interpreter;
 
156
}
 
157
 
 
158
static langType getInterpreterLanguage (const char *const fileName)
 
159
{
 
160
    langType result = LANG_IGNORE;
 
161
    FILE* const fp = g_fopen (fileName, "r");
 
162
    if (fp != NULL)
 
163
    {
 
164
        vString* const vLine = vStringNew ();
 
165
        const char* const line = readLine (vLine, fp);
 
166
        if (line != NULL  &&  line [0] == '#'  &&  line [1] == '!')
 
167
        {
 
168
            const char* const lastSlash = strrchr (line, '/');
 
169
            const char *const cmd = lastSlash != NULL ? lastSlash+1 : line+2;
 
170
            vString* const interpreter = determineInterpreter (cmd);
 
171
            result = getExtensionLanguage (vStringValue (interpreter));
 
172
            vStringDelete (interpreter);
 
173
        }
 
174
        vStringDelete (vLine);
 
175
        fclose (fp);
 
176
    }
 
177
    return result;
 
178
}
 
179
 
 
180
#endif
 
181
 
 
182
extern langType getFileLanguage (const char *const fileName)
 
183
{
 
184
    langType language = Option.language;
 
185
    if (language == LANG_AUTO)
 
186
    {
 
187
        language = getExtensionLanguage (fileExtension (fileName));
 
188
        if (language == LANG_IGNORE)
 
189
            language = getPatternLanguage (fileName);
 
190
#ifdef SYS_INTERPRETER
 
191
        if (language == LANG_IGNORE  &&  isExecutable (fileName))
 
192
            language = getInterpreterLanguage (fileName);
 
193
#endif
 
194
    }
 
195
    return language;
 
196
}
 
197
 
 
198
extern void printLanguageMap (const langType language)
 
199
{
 
200
    boolean first = TRUE;
 
201
    unsigned int i;
 
202
    stringList* map = LanguageTable [language]->currentPatterns;
 
203
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
204
    for (i = 0  ;  map != NULL  &&  i < stringListCount (map)  ;  ++i)
 
205
    {
 
206
        printf ("%s(%s)", (first ? "" : " "),
 
207
                vStringValue (stringListItem (map, i)));
 
208
        first = FALSE;
 
209
    }
 
210
    map = LanguageTable [language]->currentExtensions;
 
211
    for (i = 0  ;  map != NULL  &&  i < stringListCount (map)  ;  ++i)
 
212
    {
 
213
        printf ("%s.%s", (first ? "" : " "),
 
214
                vStringValue (stringListItem (map, i)));
 
215
        first = FALSE;
 
216
    }
 
217
}
 
218
 
 
219
extern void installLanguageMapDefault (const langType language)
 
220
{
 
221
    Assert (language >= 0);
 
222
    if (LanguageTable [language]->currentPatterns != NULL)
 
223
        stringListDelete (LanguageTable [language]->currentPatterns);
 
224
    if (LanguageTable [language]->currentExtensions != NULL)
 
225
        stringListDelete (LanguageTable [language]->currentExtensions);
 
226
 
 
227
    if (LanguageTable [language]->patterns == NULL)
 
228
        LanguageTable [language]->currentPatterns = stringListNew ();
 
229
    else
 
230
    {
 
231
        LanguageTable [language]->currentPatterns =
 
232
            stringListNewFromArgv (LanguageTable [language]->patterns);
 
233
    }
 
234
    if (LanguageTable [language]->extensions == NULL)
 
235
        LanguageTable [language]->currentExtensions = stringListNew ();
 
236
    else
 
237
    {
 
238
        LanguageTable [language]->currentExtensions =
 
239
            stringListNewFromArgv (LanguageTable [language]->extensions);
 
240
    }
 
241
}
 
242
 
 
243
extern void installLanguageMapDefaults (void)
 
244
{
 
245
    unsigned int i;
 
246
    for (i = 0  ;  i < LanguageCount  ;  ++i)
 
247
    {
 
248
        installLanguageMapDefault (i);
 
249
    }
 
250
}
 
251
 
 
252
extern void clearLanguageMap (const langType language)
 
253
{
 
254
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
255
    stringListClear (LanguageTable [language]->currentPatterns);
 
256
    stringListClear (LanguageTable [language]->currentExtensions);
 
257
}
 
258
 
 
259
extern void addLanguagePatternMap (const langType language, const char* ptrn)
 
260
{
 
261
    vString* const str = vStringNewInit (ptrn);
 
262
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
263
    if (LanguageTable [language]->currentPatterns == NULL)
 
264
        LanguageTable [language]->currentPatterns = stringListNew ();
 
265
    stringListAdd (LanguageTable [language]->currentPatterns, str);
 
266
}
 
267
 
 
268
extern void addLanguageExtensionMap (const langType language,
 
269
                                     const char* extension)
 
270
{
 
271
    vString* const str = vStringNewInit (extension);
 
272
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
273
    stringListAdd (LanguageTable [language]->currentExtensions, str);
 
274
}
 
275
 
 
276
extern void enableLanguages (const boolean state)
 
277
{
 
278
    unsigned int i;
 
279
    for (i = 0  ;  i < LanguageCount  ;  ++i)
 
280
        LanguageTable [i]->enabled = state;
 
281
}
 
282
 
 
283
extern void enableLanguage (const langType language, const boolean state)
 
284
{
 
285
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
286
    LanguageTable [language]->enabled = state;
 
287
}
 
288
 
 
289
static void initializeParsers (void)
 
290
{
 
291
    unsigned int i;
 
292
    for (i = 0  ;  i < LanguageCount  ;  ++i)
 
293
        if (LanguageTable [i]->initialize != NULL)
 
294
            (LanguageTable [i]->initialize) ((langType) i);
 
295
}
 
296
 
 
297
extern void initializeParsing (void)
 
298
{
 
299
    unsigned int builtInCount;
 
300
    unsigned int i;
 
301
 
 
302
    builtInCount = sizeof (BuiltInParsers) / sizeof (BuiltInParsers [0]);
 
303
    LanguageTable = xMalloc (builtInCount, parserDefinition*);
 
304
 
 
305
    for (i = 0  ;  i < builtInCount  ;  ++i)
 
306
    {
 
307
        parserDefinition* const def = (*BuiltInParsers [i]) ();
 
308
        if (def != NULL)
 
309
        {
 
310
            boolean accepted = FALSE;
 
311
            if (def->name == NULL  ||  def->name[0] == '\0')
 
312
                error (FATAL, "parser definition must contain name\n");
 
313
            else if (def->regex)
 
314
            {
 
315
#ifdef HAVE_REGEX
 
316
                def->parser = findRegexTags;
 
317
                accepted = TRUE;
 
318
#endif
 
319
            }
 
320
            else if ((def->parser == NULL)  ==  (def->parser2 == NULL))
 
321
                error (FATAL,
 
322
        "%s parser definition must define one and only one parsing routine\n",
 
323
                       def->name);
 
324
            else
 
325
                accepted = TRUE;
 
326
            if (accepted)
 
327
            {
 
328
                def->id = LanguageCount++;
 
329
                LanguageTable [def->id] = def;
 
330
            }
 
331
        }
 
332
    }
 
333
    enableLanguages (TRUE);
 
334
    initializeParsers ();
 
335
}
 
336
 
 
337
extern void freeParserResources (void)
 
338
{
 
339
    unsigned int i;
 
340
    for (i = 0  ;  i < LanguageCount  ;  ++i)
 
341
    {
 
342
        freeList (&LanguageTable [i]->currentPatterns);
 
343
        freeList (&LanguageTable [i]->currentExtensions);
 
344
        eFree (LanguageTable [i]->name);
 
345
        LanguageTable [i]->name = NULL;
 
346
        eFree (LanguageTable [i]);
 
347
    }
 
348
    eFree (LanguageTable);
 
349
    LanguageTable = NULL;
 
350
    LanguageCount = 0;
 
351
}
 
352
 
 
353
/*
 
354
*   Option parsing
 
355
*/
 
356
 
 
357
extern void processLanguageDefineOption (const char *const option,
 
358
                                         const char *const __unused__ parameter)
 
359
{
 
360
#ifdef HAVE_REGEX
 
361
    if (parameter [0] == '\0')
 
362
        error (WARNING, "No language specified for \"%s\" option", option);
 
363
    else if (getNamedLanguage (parameter) != LANG_IGNORE)
 
364
        error (WARNING, "Language \"%s\" already defined", parameter);
 
365
    else
 
366
    {
 
367
        unsigned int i = LanguageCount++;
 
368
        parserDefinition* const def = parserNew (parameter);
 
369
        def->parser            = findRegexTags;
 
370
        def->currentPatterns   = stringListNew ();
 
371
        def->currentExtensions = stringListNew ();
 
372
        def->regex             = TRUE;
 
373
        def->enabled           = TRUE;
 
374
        def->id                = i;
 
375
        LanguageTable = xRealloc (LanguageTable, i + 1, parserDefinition*);
 
376
        LanguageTable [i] = def;
 
377
    }
 
378
#else
 
379
    error (WARNING, "regex support not available; required for --%s option",
 
380
           option);
 
381
#endif
 
382
}
 
383
 
 
384
static kindOption *langKindOption (const langType language, const int flag)
 
385
{
 
386
    unsigned int i;
 
387
    kindOption* result = NULL;
 
388
    const parserDefinition* lang;
 
389
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
390
    lang = LanguageTable [language];
 
391
    for (i=0  ;  i < lang->kindCount  &&  result == NULL  ;  ++i)
 
392
        if (lang->kinds [i].letter == flag)
 
393
            result = &lang->kinds [i];
 
394
    return result;
 
395
}
 
396
 
 
397
extern void processLegacyKindOption (const char *const parameter)
 
398
{
 
399
    const langType lang = getNamedLanguage ("c");
 
400
    boolean clear = FALSE;
 
401
    const char* p = parameter;
 
402
    boolean mode = TRUE;
 
403
    int c;
 
404
 
 
405
    error (WARNING, "-i option is deprecated; use --c-types option instead");
 
406
    if (*p == '=')
 
407
    {
 
408
        clear = TRUE;
 
409
        ++p;
 
410
    }
 
411
    if (clear  &&  *p != '+'  &&  *p != '-')
 
412
    {
 
413
        unsigned int i;
 
414
        for (i = 0  ;  i < LanguageTable [lang]->kindCount  ;  ++i)
 
415
            LanguageTable [lang]->kinds [i].enabled = FALSE;
 
416
        Option.include.fileNames= FALSE;
 
417
        Option.include.fileScope= FALSE;
 
418
    }
 
419
    while ((c = *p++) != '\0') switch (c)
 
420
    {
 
421
        case '+': mode = TRUE;  break;
 
422
        case '-': mode = FALSE; break;
 
423
 
 
424
        case 'F': Option.include.fileNames = mode; break;
 
425
        case 'S': Option.include.fileScope = mode; break;
 
426
 
 
427
        default:
 
428
        {
 
429
            kindOption* const opt = langKindOption (lang, c);
 
430
            if (opt != NULL)
 
431
                opt->enabled = mode;
 
432
            else
 
433
                error (WARNING, "Unsupported parameter '%c' for -i option", c);
 
434
        } break;
 
435
    }
 
436
}
 
437
 
 
438
static void disableLanguageKinds (const langType language)
 
439
{
 
440
    if (LanguageTable [language]->regex)
 
441
#ifdef HAVE_REGEX
 
442
        disableRegexKinds (language);
 
443
#else
 
444
        ;
 
445
#endif
 
446
    else
 
447
    {
 
448
        unsigned int i;
 
449
        for (i = 0  ;  i < LanguageTable [language]->kindCount  ;  ++i)
 
450
            LanguageTable [language]->kinds [i].enabled = FALSE;
 
451
    }
 
452
}
 
453
 
 
454
static boolean enableLanguageKind (const langType language,
 
455
                                   const int kind, const boolean mode)
 
456
{
 
457
    boolean result = FALSE;
 
458
    if (LanguageTable [language]->regex)
 
459
#ifdef HAVE_REGEX
 
460
        result = enableRegexKind (language, kind, mode);
 
461
#else
 
462
        ;
 
463
#endif
 
464
    else
 
465
    {
 
466
        kindOption* const opt = langKindOption (language, kind);
 
467
        if (opt != NULL)
 
468
        {
 
469
            opt->enabled = mode;
 
470
            result = TRUE;
 
471
        }
 
472
    }
 
473
    return result;
 
474
}
 
475
 
 
476
static void processLangKindOption (const langType language,
 
477
                                   const char *const option,
 
478
                                   const char *const parameter)
 
479
{
 
480
    const char *p = parameter;
 
481
    boolean mode = TRUE;
 
482
    int c;
 
483
 
 
484
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
485
    if (*p != '+'  &&  *p != '-')
 
486
        disableLanguageKinds (language);
 
487
    while ((c = *p++) != '\0') switch (c)
 
488
    {
 
489
        case '+': mode = TRUE;  break;
 
490
        case '-': mode = FALSE; break;
 
491
 
 
492
        default:
 
493
        {
 
494
            if (! enableLanguageKind (language, c, mode))
 
495
                error (WARNING, "Unsupported parameter '%c' for --%s option",
 
496
                    c, option);
 
497
        } break;
 
498
    }
 
499
}
 
500
 
 
501
extern boolean processKindOption (const char *const option,
 
502
                                  const char *const parameter)
 
503
{
 
504
    boolean handled = FALSE;
 
505
    const char* const dash = strchr (option, '-');
 
506
    if (dash != NULL  &&
 
507
        (strcmp (dash + 1, "types") == 0  ||  strcmp (dash + 1, "kinds") == 0))
 
508
    {
 
509
        langType language;
 
510
        vString* langName = vStringNew ();
 
511
        vStringNCopyS (langName, option, dash - option);
 
512
        language = getNamedLanguage (vStringValue (langName));
 
513
        if (language == LANG_IGNORE)
 
514
            error (WARNING, "Unknown language specified in \"%s\" option", option);
 
515
        else
 
516
            processLangKindOption (language, option, parameter);
 
517
        vStringDelete (langName);
 
518
        handled = TRUE;
 
519
    }
 
520
    return handled;
 
521
}
 
522
 
 
523
static void printLangugageKindOption (const kindOption* const kind)
 
524
{
 
525
    printf ("          %c  %s%s\n", kind->letter,
 
526
        kind->description != NULL ? kind->description :
 
527
            (kind->name != NULL ? kind->name : ""),
 
528
        kind->enabled ? "" : " [off]");
 
529
}
 
530
 
 
531
static void printLangugageKindOptions (const langType language)
 
532
{
 
533
    const parserDefinition* lang;
 
534
    Assert (0 <= language  &&  language < (int) LanguageCount);
 
535
    lang = LanguageTable [language];
 
536
    if (lang->kinds != NULL  ||  lang->regex)
 
537
    {
 
538
        unsigned int i;
 
539
        char* const name = newLowerString (lang->name);
 
540
        printf ("  --%s-types=[+|-]kinds\n", name);
 
541
        eFree (name);
 
542
        if (lang->kinds != NULL)
 
543
            for (i = 0  ;  i < lang->kindCount  ;  ++i)
 
544
                printLangugageKindOption (lang->kinds + i);
 
545
#ifdef HAVE_REGEX
 
546
        /*printRegexKindOptions (language);*/ /* unused */
 
547
#endif
 
548
    }
 
549
}
 
550
 
 
551
extern void printKindOptions (void)
 
552
{
 
553
    unsigned int i;
 
554
 
 
555
    printf (
 
556
 "\n  The following options are used to specify which language-specific tag\n\
 
557
  types (or kinds) should be included in the tag file. \"Kinds\" is a group of\n\
 
558
  one-letter flags designating kinds of tags to either include or exclude from\n\
 
559
  the output. Each letter or group of letters may be preceded by either '+' to\n\
 
560
  add it to those already included, or '-' to exclude it from the output. In\n\
 
561
  the absence of any preceding '+' or '-' sign, only those kinds listed in\n\
 
562
  \"kinds\" will be included in the output. Below each option is a list of the\n\
 
563
  flags accepted. All kinds are enabled by default unless otherwise noted.\n\n");
 
564
 
 
565
    for (i = 0  ;  i < LanguageCount  ;  ++i)
 
566
        printLangugageKindOptions (i);
 
567
}
 
568
 
 
569
/*
 
570
*   File parsing
 
571
*/
 
572
 
 
573
static void makeFileTag (const char *const fileName)
 
574
{
 
575
    if (Option.include.fileNames)
 
576
    {
 
577
        tagEntryInfo tag;
 
578
        initTagEntry (&tag, baseFilename (fileName));
 
579
 
 
580
        tag.isFileEntry     = TRUE;
 
581
        tag.lineNumberEntry = TRUE;
 
582
        tag.lineNumber      = 1;
 
583
        tag.kindName        = "file";
 
584
        tag.kind            = 'F';
 
585
 
 
586
        makeTagEntry (&tag);
 
587
    }
 
588
}
 
589
 
 
590
static boolean createTagsForFile (const char *const fileName,
 
591
                                  const langType language,
 
592
                                  const unsigned int passCount)
 
593
{
 
594
    boolean retried = FALSE;
 
595
 
 
596
    if (fileOpen (fileName, language))
 
597
    {
 
598
 
 
599
        makeFileTag (fileName);
 
600
 
 
601
        if (LanguageTable [language]->parser != NULL)
 
602
            LanguageTable [language]->parser ();
 
603
        else if (LanguageTable [language]->parser2 != NULL)
 
604
            retried = LanguageTable [language]->parser2 (passCount);
 
605
 
 
606
 
 
607
        fileClose ();
 
608
    }
 
609
 
 
610
    return retried;
 
611
}
 
612
 
 
613
static boolean createTagsWithFallback (const char *const fileName,
 
614
                                       const langType language)
 
615
{
 
616
    const unsigned long numTags = TagFile.numTags.added;
 
617
    MIOPos tagFilePosition;
 
618
    unsigned int passCount = 0;
 
619
    boolean tagFileResized = FALSE;
 
620
 
 
621
    mio_getpos (TagFile.mio, &tagFilePosition);
 
622
    while (createTagsForFile (fileName, language, ++passCount))
 
623
    {
 
624
        /*  Restore prior state of tag file.
 
625
         */
 
626
        mio_setpos (TagFile.mio, &tagFilePosition);
 
627
        TagFile.numTags.added = numTags;
 
628
        tagFileResized = TRUE;
 
629
    }
 
630
    return tagFileResized;
 
631
}
 
632
 
 
633
extern boolean parseFile (const char *const fileName)
 
634
{
 
635
    boolean tagFileResized = FALSE;
 
636
    langType language = Option.language;
 
637
    if (Option.language == LANG_AUTO)
 
638
        language = getFileLanguage (fileName);
 
639
    Assert (language != LANG_AUTO);
 
640
        if (Option.filter)
 
641
            openTagFile ();
 
642
 
 
643
        tagFileResized = createTagsWithFallback (fileName, language);
 
644
 
 
645
        addTotals (1, 0L, 0L);
 
646
 
 
647
    return tagFileResized;
 
648
}
 
649
 
 
650
/* vi:set tabstop=8 shiftwidth=4 nowrap: */