~ubuntu-branches/ubuntu/utopic/exuberant-ctags/utopic

« back to all changes in this revision

Viewing changes to main.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2006-07-31 09:09:12 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 edgy)
  • Revision ID: james.westby@ubuntu.com-20060731090912-rxe2jt8nz6g2k2zx
Tags: 1:5.6-1
* New upstream release (closes: #374097).
* Fix accidentally-unrendered line in ctags(1) (closes: #271323).
* Policy version 3.7.2: no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
*   $Id: main.c,v 1.22 2004/03/26 05:07:18 darren Exp $
 
2
*   $Id: main.c,v 1.24 2006/05/30 04:37:12 darren Exp $
3
3
*
4
4
*   Copyright (c) 1996-2003, Darren Hiebert
5
5
*
21
21
/*
22
22
*   INCLUDE FILES
23
23
*/
24
 
#include "general.h"    /* must always come first */
 
24
#include "general.h"  /* must always come first */
25
25
 
26
26
#include <string.h>
27
27
 
42
42
/*  To provide directory searching for recursion feature.
43
43
 */
44
44
#ifdef AMIGA
45
 
# include <dos/dosasl.h>        /* for struct AnchorPath */
46
 
# include <clib/dos_protos.h>   /* function prototypes */
 
45
# include <dos/dosasl.h>       /* for struct AnchorPath */
 
46
# include <clib/dos_protos.h>  /* function prototypes */
47
47
# define ANCHOR_BUF_SIZE 512
48
48
# define ANCHOR_SIZE (sizeof (struct AnchorPath) + ANCHOR_BUF_SIZE)
49
49
# ifdef __SASC
57
57
#  define boolean BORLAND_boolean
58
58
# endif
59
59
# ifdef HAVE_SYS_TYPES_H
60
 
#  include <sys/types.h>    /* required by dirent.h */
 
60
#  include <sys/types.h>  /* required by dirent.h */
61
61
# endif
62
 
# include <dirent.h>    /* to declare opendir() */
 
62
# include <dirent.h>  /* to declare opendir() */
63
63
# undef boolean
64
64
#endif
65
65
#ifdef HAVE_DIRECT_H
66
 
# include <direct.h>    /* to _getcwd() */
 
66
# include <direct.h>  /* to _getcwd() */
67
67
#endif
68
68
#ifdef HAVE_DOS_H
69
 
# include <dos.h>       /* to declare FA_DIREC */
 
69
# include <dos.h>  /* to declare FA_DIREC */
70
70
#endif
71
71
#ifdef HAVE_DIR_H
72
 
# include <dir.h>       /* to declare findfirst() and findnext */
 
72
# include <dir.h>  /* to declare findfirst() and findnext */
73
73
#endif
74
74
#ifdef HAVE_IO_H
75
 
# include <io.h>        /* to declare _findfirst() */
 
75
# include <io.h>  /* to declare _findfirst() */
76
76
#endif
77
77
 
78
78
 
86
86
/*
87
87
*   MACROS
88
88
*/
89
 
#define plural(value)           (((unsigned long)(value) == 1L) ? "" : "s")
 
89
#define plural(value)  (((unsigned long)(value) == 1L) ? "" : "s")
90
90
 
91
91
/*
92
92
*   DATA DEFINITIONS
114
114
*/
115
115
 
116
116
extern void addTotals (
117
 
        const unsigned int files, const long unsigned int lines,
118
 
        const long unsigned int bytes)
 
117
                const unsigned int files, const long unsigned int lines,
 
118
                const long unsigned int bytes)
119
119
{
120
 
    Totals.files += files;
121
 
    Totals.lines += lines;
122
 
    Totals.bytes += bytes;
 
120
        Totals.files += files;
 
121
        Totals.lines += lines;
 
122
        Totals.bytes += bytes;
123
123
}
124
124
 
125
125
extern boolean isDestinationStdout (void)
126
126
{
127
 
    boolean toStdout = FALSE;
 
127
        boolean toStdout = FALSE;
128
128
 
129
 
    if (Option.xref  ||  Option.filter  ||
130
 
        (Option.tagFileName != NULL  &&  (strcmp (Option.tagFileName, "-") == 0
 
129
        if (Option.xref  ||  Option.filter  ||
 
130
                (Option.tagFileName != NULL  &&  (strcmp (Option.tagFileName, "-") == 0
131
131
#if defined (VMS)
132
 
    || strcmp (Option.tagFileName, "sys$output") == 0
 
132
        || strcmp (Option.tagFileName, "sys$output") == 0
133
133
#else
134
 
    || strcmp (Option.tagFileName, "/dev/stdout") == 0
 
134
        || strcmp (Option.tagFileName, "/dev/stdout") == 0
135
135
#endif
136
 
        )))
137
 
        toStdout = TRUE;
138
 
    return toStdout;
 
136
                )))
 
137
                toStdout = TRUE;
 
138
        return toStdout;
139
139
}
140
140
 
141
141
#if defined (HAVE_OPENDIR)
142
142
static boolean recurseUsingOpendir (const char *const dirName)
143
143
{
144
 
    boolean resize = FALSE;
145
 
    DIR *const dir = opendir (dirName);
146
 
    if (dir == NULL)
147
 
        error (WARNING | PERROR, "cannot recurse into directory \"%s\"", dirName);
148
 
    else
149
 
    {
150
 
        struct dirent *entry;
151
 
        while ((entry = readdir (dir)) != NULL)
152
 
        {
153
 
            if (strcmp (entry->d_name, ".") != 0  &&
154
 
                strcmp (entry->d_name, "..") != 0)
155
 
            {
156
 
                vString *filePath;
157
 
                if (strcmp (dirName, ".") == 0)
158
 
                    filePath = vStringNewInit (entry->d_name);
159
 
                else
160
 
                    filePath = combinePathAndFile (dirName, entry->d_name);
161
 
                resize |= createTagsForEntry (vStringValue (filePath));
 
144
        boolean resize = FALSE;
 
145
        DIR *const dir = opendir (dirName);
 
146
        if (dir == NULL)
 
147
                error (WARNING | PERROR, "cannot recurse into directory \"%s\"", dirName);
 
148
        else
 
149
        {
 
150
                struct dirent *entry;
 
151
                while ((entry = readdir (dir)) != NULL)
 
152
                {
 
153
                        if (strcmp (entry->d_name, ".") != 0  &&
 
154
                                strcmp (entry->d_name, "..") != 0)
 
155
                        {
 
156
                                vString *filePath;
 
157
                                if (strcmp (dirName, ".") == 0)
 
158
                                        filePath = vStringNewInit (entry->d_name);
 
159
                                else
 
160
                                        filePath = combinePathAndFile (dirName, entry->d_name);
 
161
                                resize |= createTagsForEntry (vStringValue (filePath));
 
162
                                vStringDelete (filePath);
 
163
                        }
 
164
                }
 
165
                closedir (dir);
 
166
        }
 
167
        return resize;
 
168
}
 
169
 
 
170
#elif defined (HAVE_FINDFIRST) || defined (HAVE__FINDFIRST)
 
171
 
 
172
static boolean createTagsForWildcardEntry (
 
173
                const char *const pattern, const size_t dirLength,
 
174
                const char *const entryName)
 
175
{
 
176
        boolean resize = FALSE;
 
177
        /* we must not recurse into the directories "." or ".." */
 
178
        if (strcmp (entryName, ".") != 0  &&  strcmp (entryName, "..") != 0)
 
179
        {
 
180
                vString *const filePath = vStringNew ();
 
181
                vStringNCopyS (filePath, pattern, dirLength);
 
182
                vStringCatS (filePath, entryName);
 
183
                resize = createTagsForEntry (vStringValue (filePath));
162
184
                vStringDelete (filePath);
163
 
            }
164
185
        }
165
 
        closedir (dir);
166
 
    }
167
 
    return resize;
168
 
}
169
 
 
170
 
#elif defined (HAVE_FINDFIRST) || defined (HAVE__FINDFIRST)
171
 
 
172
 
static boolean createTagsForWildcardEntry (
173
 
        const char *const pattern, const size_t dirLength,
174
 
        const char *const entryName)
175
 
{
176
 
    boolean resize = FALSE;
177
 
    /* we must not recurse into the directories "." or ".." */
178
 
    if (strcmp (entryName, ".") != 0  &&  strcmp (entryName, "..") != 0)
179
 
    {
180
 
        vString *const filePath = vStringNew ();
181
 
        vStringNCopyS (filePath, pattern, dirLength);
182
 
        vStringCatS (filePath, entryName);
183
 
        resize = createTagsForEntry (vStringValue (filePath));
184
 
        vStringDelete (filePath);
185
 
    }
186
 
    return resize;
 
186
        return resize;
187
187
}
188
188
 
189
189
static boolean createTagsForWildcardUsingFindfirst (const char *const pattern)
190
190
{
191
 
    boolean resize = FALSE;
192
 
    const size_t dirLength = baseFilename (pattern) - pattern;
 
191
        boolean resize = FALSE;
 
192
        const size_t dirLength = baseFilename (pattern) - pattern;
193
193
#if defined (HAVE_FINDFIRST)
194
 
    struct ffblk fileInfo;
195
 
    int result = findfirst (pattern, &fileInfo, FA_DIREC);
196
 
    while (result == 0)
197
 
    {
198
 
        const char *const entry = (const char *) fileInfo.ff_name;
199
 
        resize |= createTagsForWildcardEntry (pattern, dirLength, entry);
200
 
        result = findnext (&fileInfo);
201
 
    }
 
194
        struct ffblk fileInfo;
 
195
        int result = findfirst (pattern, &fileInfo, FA_DIREC);
 
196
        while (result == 0)
 
197
        {
 
198
                const char *const entry = (const char *) fileInfo.ff_name;
 
199
                resize |= createTagsForWildcardEntry (pattern, dirLength, entry);
 
200
                result = findnext (&fileInfo);
 
201
        }
202
202
#elif defined (HAVE__FINDFIRST)
203
 
    struct _finddata_t fileInfo;
204
 
    findfirst_t hFile = _findfirst (pattern, &fileInfo);
205
 
    if (hFile != -1L)
206
 
    {
207
 
        do
 
203
        struct _finddata_t fileInfo;
 
204
        findfirst_t hFile = _findfirst (pattern, &fileInfo);
 
205
        if (hFile != -1L)
208
206
        {
209
 
            const char *const entry = (const char *) fileInfo.name;
210
 
            resize |= createTagsForWildcardEntry (pattern, dirLength, entry);
211
 
        } while (_findnext (hFile, &fileInfo) == 0);
212
 
        _findclose (hFile);
213
 
    }
 
207
                do
 
208
                {
 
209
                        const char *const entry = (const char *) fileInfo.name;
 
210
                        resize |= createTagsForWildcardEntry (pattern, dirLength, entry);
 
211
                } while (_findnext (hFile, &fileInfo) == 0);
 
212
                _findclose (hFile);
 
213
        }
214
214
#endif
215
 
    return resize;
 
215
        return resize;
216
216
}
217
217
 
218
218
#elif defined (AMIGA)
219
219
 
220
220
static boolean createTagsForAmigaWildcard (const char *const pattern)
221
221
{
222
 
    boolean resize = FALSE;
223
 
    struct AnchorPath *const anchor =
224
 
            (struct AnchorPath *) eMalloc ((size_t) ANCHOR_SIZE);
225
 
    LONG result;
 
222
        boolean resize = FALSE;
 
223
        struct AnchorPath *const anchor =
 
224
                        (struct AnchorPath *) eMalloc ((size_t) ANCHOR_SIZE);
 
225
        LONG result;
226
226
 
227
 
    memset (anchor, 0, (size_t) ANCHOR_SIZE);
228
 
    anchor->ap_Strlen = ANCHOR_BUF_SIZE;
229
 
    /* Allow '.' for current directory */
 
227
        memset (anchor, 0, (size_t) ANCHOR_SIZE);
 
228
        anchor->ap_Strlen = ANCHOR_BUF_SIZE;
 
229
        /* Allow '.' for current directory */
230
230
#ifdef APF_DODOT
231
 
    anchor->ap_Flags = APF_DODOT | APF_DOWILD;
 
231
        anchor->ap_Flags = APF_DODOT | APF_DOWILD;
232
232
#else
233
 
    anchor->ap_Flags = APF_DoDot | APF_DoWild;
 
233
        anchor->ap_Flags = APF_DoDot | APF_DoWild;
234
234
#endif
235
 
    result = MatchFirst ((UBYTE *) pattern, anchor);
236
 
    while (result == 0)
237
 
    {
238
 
        resize |= createTagsForEntry ((char *) anchor->ap_Buf);
239
 
        result = MatchNext (anchor);
240
 
    }
241
 
    MatchEnd (anchor);
242
 
    eFree (anchor);
243
 
    return resize;
 
235
        result = MatchFirst ((UBYTE *) pattern, anchor);
 
236
        while (result == 0)
 
237
        {
 
238
                resize |= createTagsForEntry ((char *) anchor->ap_Buf);
 
239
                result = MatchNext (anchor);
 
240
        }
 
241
        MatchEnd (anchor);
 
242
        eFree (anchor);
 
243
        return resize;
244
244
}
245
245
#endif
246
246
 
247
247
static boolean recurseIntoDirectory (const char *const dirName)
248
248
{
249
 
    boolean resize = FALSE;
250
 
    if (isRecursiveLink (dirName))
251
 
        verbose ("ignoring \"%s\" (recursive link)\n", dirName);
252
 
    else if (! Option.recurse)
253
 
        verbose ("ignoring \"%s\" (directory)\n", dirName);
254
 
    else
255
 
    {
256
 
        verbose ("RECURSING into directory \"%s\"\n", dirName);
 
249
        boolean resize = FALSE;
 
250
        if (isRecursiveLink (dirName))
 
251
                verbose ("ignoring \"%s\" (recursive link)\n", dirName);
 
252
        else if (! Option.recurse)
 
253
                verbose ("ignoring \"%s\" (directory)\n", dirName);
 
254
        else
 
255
        {
 
256
                verbose ("RECURSING into directory \"%s\"\n", dirName);
257
257
#if defined (HAVE_OPENDIR)
258
 
        resize = recurseUsingOpendir (dirName);
 
258
                resize = recurseUsingOpendir (dirName);
259
259
#elif defined (HAVE_FINDFIRST) || defined (HAVE__FINDFIRST)
260
 
        {
261
 
            vString *const pattern = vStringNew ();
262
 
            vStringCopyS (pattern, dirName);
263
 
            vStringPut (pattern, OUTPUT_PATH_SEPARATOR);
264
 
            vStringCatS (pattern, "*.*");
265
 
            resize = createTagsForWildcardUsingFindfirst (vStringValue (pattern));
266
 
            vStringDelete (pattern);
267
 
        }
 
260
                {
 
261
                        vString *const pattern = vStringNew ();
 
262
                        vStringCopyS (pattern, dirName);
 
263
                        vStringPut (pattern, OUTPUT_PATH_SEPARATOR);
 
264
                        vStringCatS (pattern, "*.*");
 
265
                        resize = createTagsForWildcardUsingFindfirst (vStringValue (pattern));
 
266
                        vStringDelete (pattern);
 
267
                }
268
268
#elif defined (AMIGA)
269
 
        {
270
 
            vString *const pattern = vStringNew ();
271
 
            if (*dirName != '\0'  &&  strcmp (dirName, ".") != 0)
272
 
            {
273
 
                vStringCopyS (pattern, dirName);
274
 
                if (dirName [strlen (dirName) - 1] != '/')
275
 
                    vStringPut (pattern, '/');
276
 
            }
277
 
            vStringCatS (pattern, "#?");
278
 
            resize = createTagsForAmigaWildcard (vStringValue (pattern));
279
 
            vStringDelete (pattern);
280
 
        }
 
269
                {
 
270
                        vString *const pattern = vStringNew ();
 
271
                        if (*dirName != '\0'  &&  strcmp (dirName, ".") != 0)
 
272
                        {
 
273
                                vStringCopyS (pattern, dirName);
 
274
                                if (dirName [strlen (dirName) - 1] != '/')
 
275
                                        vStringPut (pattern, '/');
 
276
                        }
 
277
                        vStringCatS (pattern, "#?");
 
278
                        resize = createTagsForAmigaWildcard (vStringValue (pattern));
 
279
                        vStringDelete (pattern);
 
280
                }
281
281
#endif
282
 
    }
283
 
    return resize;
 
282
        }
 
283
        return resize;
284
284
}
285
285
 
286
286
static boolean createTagsForEntry (const char *const entryName)
287
287
{
288
 
    boolean resize = FALSE;
289
 
    fileStatus *status = eStat (entryName);
290
 
 
291
 
    Assert (entryName != NULL);
292
 
    if (isExcludedFile (entryName))
293
 
        verbose ("excluding \"%s\"\n", entryName);
294
 
    else if (status->isSymbolicLink  &&  ! Option.followLinks)
295
 
        verbose ("ignoring \"%s\" (symbolic link)\n", entryName);
296
 
    else if (! status->exists)
297
 
        error (WARNING | PERROR, "cannot open source file \"%s\"", entryName);
298
 
    else if (status->isDirectory)
299
 
        resize = recurseIntoDirectory (entryName);
300
 
    else if (! status->isNormalFile)
301
 
        verbose ("ignoring \"%s\" (special file)\n", entryName);
302
 
    else
303
 
        resize = parseFile (entryName);
304
 
 
305
 
    return resize;
 
288
        boolean resize = FALSE;
 
289
        fileStatus *status = eStat (entryName);
 
290
 
 
291
        Assert (entryName != NULL);
 
292
        if (isExcludedFile (entryName))
 
293
                verbose ("excluding \"%s\"\n", entryName);
 
294
        else if (status->isSymbolicLink  &&  ! Option.followLinks)
 
295
                verbose ("ignoring \"%s\" (symbolic link)\n", entryName);
 
296
        else if (! status->exists)
 
297
                error (WARNING | PERROR, "cannot open source file \"%s\"", entryName);
 
298
        else if (status->isDirectory)
 
299
                resize = recurseIntoDirectory (entryName);
 
300
        else if (! status->isNormalFile)
 
301
                verbose ("ignoring \"%s\" (special file)\n", entryName);
 
302
        else
 
303
                resize = parseFile (entryName);
 
304
 
 
305
        return resize;
306
306
}
307
307
 
308
308
#ifdef MANUAL_GLOBBING
309
309
 
310
310
static boolean createTagsForWildcardArg (const char *const arg)
311
311
{
312
 
    boolean resize = FALSE;
313
 
    vString *const pattern = vStringNewInit (arg);
314
 
    char *patternS = vStringValue (pattern);
 
312
        boolean resize = FALSE;
 
313
        vString *const pattern = vStringNewInit (arg);
 
314
        char *patternS = vStringValue (pattern);
315
315
 
316
316
#if defined (HAVE_FINDFIRST) || defined (HAVE__FINDFIRST)
317
 
    /*  We must transform the "." and ".." forms into something that can
318
 
     *  be expanded by the findfirst/_findfirst functions.
319
 
     */
320
 
    if (Option.recurse  &&
321
 
        (strcmp (patternS, ".") == 0  ||  strcmp (patternS, "..") == 0))
322
 
    {
323
 
        vStringPut (pattern, OUTPUT_PATH_SEPARATOR);
324
 
        vStringCatS (pattern, "*.*");
325
 
    }
326
 
    resize |= createTagsForWildcardUsingFindfirst (patternS);
 
317
        /*  We must transform the "." and ".." forms into something that can
 
318
         *  be expanded by the findfirst/_findfirst functions.
 
319
         */
 
320
        if (Option.recurse  &&
 
321
                (strcmp (patternS, ".") == 0  ||  strcmp (patternS, "..") == 0))
 
322
        {
 
323
                vStringPut (pattern, OUTPUT_PATH_SEPARATOR);
 
324
                vStringCatS (pattern, "*.*");
 
325
        }
 
326
        resize |= createTagsForWildcardUsingFindfirst (patternS);
327
327
#endif
328
 
    vStringDelete (pattern);
329
 
    return resize;
 
328
        vStringDelete (pattern);
 
329
        return resize;
330
330
}
331
331
 
332
332
#endif
333
333
 
334
 
static boolean createTagsForArgs (cookedArgs* const args)
 
334
static boolean createTagsForArgs (cookedArgs *const args)
335
335
{
336
 
    boolean resize = FALSE;
 
336
        boolean resize = FALSE;
337
337
 
338
 
    /*  Generate tags for each argument on the command line.
339
 
     */
340
 
    while (! cArgOff (args))
341
 
    {
342
 
        const char *const arg = cArgItem (args);
 
338
        /*  Generate tags for each argument on the command line.
 
339
         */
 
340
        while (! cArgOff (args))
 
341
        {
 
342
                const char *const arg = cArgItem (args);
343
343
 
344
344
#ifdef MANUAL_GLOBBING
345
 
        resize |= createTagsForWildcardArg (arg);
 
345
                resize |= createTagsForWildcardArg (arg);
346
346
#else
347
 
        resize |= createTagsForEntry (arg);
 
347
                resize |= createTagsForEntry (arg);
348
348
#endif
349
 
        cArgForth (args);
350
 
        parseOptions (args);
351
 
    }
352
 
    return resize;
 
349
                cArgForth (args);
 
350
                parseOptions (args);
 
351
        }
 
352
        return resize;
353
353
}
354
354
 
355
355
/*  Read from an opened file a list of file names for which to generate tags.
356
356
 */
357
 
static boolean createTagsFromFileInput (FILE* const fp, const boolean filter)
 
357
static boolean createTagsFromFileInput (FILE *const fp, const boolean filter)
358
358
{
359
 
    boolean resize = FALSE;
360
 
    if (fp != NULL)
361
 
    {
362
 
        cookedArgs* args = cArgNewFromLineFile (fp);
363
 
        parseOptions (args);
364
 
        while (! cArgOff (args))
 
359
        boolean resize = FALSE;
 
360
        if (fp != NULL)
365
361
        {
366
 
            resize |= createTagsForEntry (cArgItem (args));
367
 
            if (filter)
368
 
            {
369
 
                if (Option.filterTerminator != NULL)
370
 
                    fputs (Option.filterTerminator, stdout);
371
 
                fflush (stdout);
372
 
            }
373
 
            cArgForth (args);
374
 
            parseOptions (args);
 
362
                cookedArgs *args = cArgNewFromLineFile (fp);
 
363
                parseOptions (args);
 
364
                while (! cArgOff (args))
 
365
                {
 
366
                        resize |= createTagsForEntry (cArgItem (args));
 
367
                        if (filter)
 
368
                        {
 
369
                                if (Option.filterTerminator != NULL)
 
370
                                        fputs (Option.filterTerminator, stdout);
 
371
                                fflush (stdout);
 
372
                        }
 
373
                        cArgForth (args);
 
374
                        parseOptions (args);
 
375
                }
 
376
                cArgDelete (args);
375
377
        }
376
 
        cArgDelete (args);
377
 
    }
378
 
    return resize;
 
378
        return resize;
379
379
}
380
380
 
381
381
/*  Read from a named file a list of file names for which to generate tags.
382
382
 */
383
 
static boolean createTagsFromListFile (const char* const fileName)
 
383
static boolean createTagsFromListFile (const char *const fileName)
384
384
{
385
 
    boolean resize;
386
 
    Assert (fileName != NULL);
387
 
    if (strcmp (fileName, "-") == 0)
388
 
        resize = createTagsFromFileInput (stdin, FALSE);
389
 
    else
390
 
    {
391
 
        FILE* const fp = fopen (fileName, "r");
392
 
        if (fp == NULL)
393
 
            error (FATAL | PERROR, "cannot open list file \"%s\"", fileName);
394
 
        resize = createTagsFromFileInput (fp, FALSE);
395
 
        fclose (fp);
396
 
    }
397
 
    return resize;
 
385
        boolean resize;
 
386
        Assert (fileName != NULL);
 
387
        if (strcmp (fileName, "-") == 0)
 
388
                resize = createTagsFromFileInput (stdin, FALSE);
 
389
        else
 
390
        {
 
391
                FILE *const fp = fopen (fileName, "r");
 
392
                if (fp == NULL)
 
393
                        error (FATAL | PERROR, "cannot open list file \"%s\"", fileName);
 
394
                resize = createTagsFromFileInput (fp, FALSE);
 
395
                fclose (fp);
 
396
        }
 
397
        return resize;
398
398
}
399
399
 
400
400
#if defined (HAVE_CLOCK)
401
401
# define CLOCK_AVAILABLE
402
402
# ifndef CLOCKS_PER_SEC
403
 
#  define CLOCKS_PER_SEC        1000000
 
403
#  define CLOCKS_PER_SEC                1000000
404
404
# endif
405
405
#elif defined (HAVE_TIMES)
406
406
# define CLOCK_AVAILABLE
407
407
# define CLOCKS_PER_SEC 60
408
408
static clock_t clock (void)
409
409
{
410
 
    struct tms buf;
 
410
        struct tms buf;
411
411
 
412
 
    times (&buf);
413
 
    return (buf.tms_utime + buf.tms_stime);
 
412
        times (&buf);
 
413
        return (buf.tms_utime + buf.tms_stime);
414
414
}
415
415
#else
416
416
# define clock()  (clock_t)0
418
418
 
419
419
static void printTotals (const clock_t *const timeStamps)
420
420
{
421
 
    const unsigned long totalTags = TagFile.numTags.added +
422
 
                                    TagFile.numTags.prev;
423
 
 
424
 
    fprintf (errout, "%ld file%s, %ld line%s (%ld kB) scanned",
425
 
            Totals.files, plural (Totals.files),
426
 
            Totals.lines, plural (Totals.lines),
427
 
            Totals.bytes/1024L);
428
 
#ifdef CLOCK_AVAILABLE
429
 
    {
430
 
        const double interval = ((double) (timeStamps [1] - timeStamps [0])) /
431
 
                                CLOCKS_PER_SEC;
432
 
 
433
 
        fprintf (errout, " in %.01f seconds", interval);
434
 
        if (interval != (double) 0.0)
435
 
            fprintf (errout, " (%lu kB/s)",
436
 
                    (unsigned long) (Totals.bytes / interval) / 1024L);
437
 
    }
438
 
#endif
439
 
    fputc ('\n', errout);
440
 
 
441
 
    fprintf (errout, "%lu tag%s added to tag file",
442
 
            TagFile.numTags.added, plural (TagFile.numTags.added));
443
 
    if (Option.append)
444
 
        fprintf (errout, " (now %lu tags)", totalTags);
445
 
    fputc ('\n', errout);
446
 
 
447
 
    if (totalTags > 0  &&  Option.sorted != SO_UNSORTED)
448
 
    {
449
 
        fprintf (errout, "%lu tag%s sorted", totalTags, plural (totalTags));
450
 
#ifdef CLOCK_AVAILABLE
451
 
        fprintf (errout, " in %.02f seconds",
452
 
                ((double) (timeStamps [2] - timeStamps [1])) / CLOCKS_PER_SEC);
453
 
#endif
454
 
        fputc ('\n', errout);
455
 
    }
 
421
        const unsigned long totalTags = TagFile.numTags.added +
 
422
                                                                        TagFile.numTags.prev;
 
423
 
 
424
        fprintf (errout, "%ld file%s, %ld line%s (%ld kB) scanned",
 
425
                        Totals.files, plural (Totals.files),
 
426
                        Totals.lines, plural (Totals.lines),
 
427
                        Totals.bytes/1024L);
 
428
#ifdef CLOCK_AVAILABLE
 
429
        {
 
430
                const double interval = ((double) (timeStamps [1] - timeStamps [0])) /
 
431
                                                                CLOCKS_PER_SEC;
 
432
 
 
433
                fprintf (errout, " in %.01f seconds", interval);
 
434
                if (interval != (double) 0.0)
 
435
                        fprintf (errout, " (%lu kB/s)",
 
436
                                        (unsigned long) (Totals.bytes / interval) / 1024L);
 
437
        }
 
438
#endif
 
439
        fputc ('\n', errout);
 
440
 
 
441
        fprintf (errout, "%lu tag%s added to tag file",
 
442
                        TagFile.numTags.added, plural (TagFile.numTags.added));
 
443
        if (Option.append)
 
444
                fprintf (errout, " (now %lu tags)", totalTags);
 
445
        fputc ('\n', errout);
 
446
 
 
447
        if (totalTags > 0  &&  Option.sorted != SO_UNSORTED)
 
448
        {
 
449
                fprintf (errout, "%lu tag%s sorted", totalTags, plural (totalTags));
 
450
#ifdef CLOCK_AVAILABLE
 
451
                fprintf (errout, " in %.02f seconds",
 
452
                                ((double) (timeStamps [2] - timeStamps [1])) / CLOCKS_PER_SEC);
 
453
#endif
 
454
                fputc ('\n', errout);
 
455
        }
456
456
 
457
457
#ifdef DEBUG
458
 
    fprintf (errout, "longest tag line = %lu\n",
459
 
            (unsigned long) TagFile.max.line);
 
458
        fprintf (errout, "longest tag line = %lu\n",
 
459
                        (unsigned long) TagFile.max.line);
460
460
#endif
461
461
}
462
462
 
463
 
static void makeTags (cookedArgs* args)
464
 
{
465
 
    clock_t timeStamps [3];
466
 
    boolean resize = FALSE;
467
 
    boolean files = (boolean)(! cArgOff (args) || Option.fileList != NULL
468
 
                              || Option.filter);
469
 
 
470
 
    if (! files  &&  ! Option.recurse)
471
 
    {
472
 
        if (filesRequired ())
473
 
            error (FATAL, "No files specified. Try \"%s --help\".",
474
 
                getExecutableName ());
475
 
        else
476
 
            return;
477
 
    }
 
463
static boolean etagsInclude (void)
 
464
{
 
465
        return (boolean)(Option.etags && Option.etagsInclude != NULL);
 
466
}
 
467
 
 
468
static void makeTags (cookedArgs *args)
 
469
{
 
470
        clock_t timeStamps [3];
 
471
        boolean resize = FALSE;
 
472
        boolean files = (boolean)(! cArgOff (args) || Option.fileList != NULL
 
473
                                                          || Option.filter);
 
474
 
 
475
        if (! files)
 
476
        {
 
477
                if (filesRequired ())
 
478
                        error (FATAL, "No files specified. Try \"%s --help\".",
 
479
                                getExecutableName ());
 
480
                else if (! Option.recurse && ! etagsInclude ())
 
481
                        return;
 
482
        }
 
483
 
478
484
#define timeStamp(n) timeStamps[(n)]=(Option.printTotals ? clock():(clock_t)0)
479
 
    if (! Option.filter)
480
 
        openTagFile ();
481
 
 
482
 
    timeStamp (0);
483
 
 
484
 
    if (! cArgOff (args))
485
 
    {
486
 
        verbose ("Reading command line arguments\n");
487
 
        resize = createTagsForArgs (args);
488
 
    }
489
 
    if (Option.fileList != NULL)
490
 
    {
491
 
        verbose ("Reading list file\n");
492
 
        resize = (boolean) (createTagsFromListFile (Option.fileList) || resize);
493
 
    }
494
 
    if (Option.filter)
495
 
    {
496
 
        verbose ("Reading filter input\n");
497
 
        resize = (boolean) (createTagsFromFileInput (stdin, TRUE) || resize);
498
 
    }
499
 
    if (! files  &&  Option.recurse)
500
 
        resize = recurseIntoDirectory (".");
501
 
 
502
 
    timeStamp (1);
503
 
 
504
 
    if (! Option.filter)
505
 
        closeTagFile (resize);
506
 
 
507
 
    timeStamp (2);
508
 
 
509
 
    if (Option.printTotals)
510
 
        printTotals (timeStamps);
 
485
        if (! Option.filter)
 
486
                openTagFile ();
 
487
 
 
488
        timeStamp (0);
 
489
 
 
490
        if (! cArgOff (args))
 
491
        {
 
492
                verbose ("Reading command line arguments\n");
 
493
                resize = createTagsForArgs (args);
 
494
        }
 
495
        if (Option.fileList != NULL)
 
496
        {
 
497
                verbose ("Reading list file\n");
 
498
                resize = (boolean) (createTagsFromListFile (Option.fileList) || resize);
 
499
        }
 
500
        if (Option.filter)
 
501
        {
 
502
                verbose ("Reading filter input\n");
 
503
                resize = (boolean) (createTagsFromFileInput (stdin, TRUE) || resize);
 
504
        }
 
505
        if (! files  &&  Option.recurse)
 
506
                resize = recurseIntoDirectory (".");
 
507
 
 
508
        timeStamp (1);
 
509
 
 
510
        if (! Option.filter)
 
511
                closeTagFile (resize);
 
512
 
 
513
        timeStamp (2);
 
514
 
 
515
        if (Option.printTotals)
 
516
                printTotals (timeStamps);
511
517
#undef timeStamp
512
518
}
513
519
 
514
520
/*
515
 
 *      Start up code
 
521
 *              Start up code
516
522
 */
517
523
 
518
524
extern int main (int __unused__ argc, char **argv)
519
525
{
520
 
    cookedArgs *args;
 
526
        cookedArgs *args;
521
527
#ifdef VMS
522
 
    extern int getredirection (int *ac, char ***av);
 
528
        extern int getredirection (int *ac, char ***av);
523
529
 
524
 
    /* do wildcard expansion and I/O redirection */
525
 
    getredirection (&argc, &argv);
 
530
        /* do wildcard expansion and I/O redirection */
 
531
        getredirection (&argc, &argv);
526
532
#endif
527
533
 
528
534
#ifdef AMIGA
529
 
    /* This program doesn't work when started from the Workbench */
530
 
    if (argc == 0)
531
 
        exit (1);
 
535
        /* This program doesn't work when started from the Workbench */
 
536
        if (argc == 0)
 
537
                exit (1);
532
538
#endif
533
539
 
534
540
#ifdef __EMX__
535
 
    _wildcard (&argc, &argv);   /* expand wildcards in argument list */
 
541
        _wildcard (&argc, &argv);  /* expand wildcards in argument list */
536
542
#endif
537
543
 
538
544
#if defined (macintosh) && BUILD_MPW_TOOL == 0
539
 
    argc = ccommand (&argv);
 
545
        argc = ccommand (&argv);
540
546
#endif
541
547
 
542
 
    setCurrentDirectory ();
543
 
    setExecutableName (*argv++);
544
 
    checkRegex ();
545
 
 
546
 
    args = cArgNewFromArgv (argv);
547
 
    previewFirstOption (args);
548
 
    testEtagsInvocation ();
549
 
    initializeParsing ();
550
 
    initOptions ();
551
 
    readOptionConfiguration ();
552
 
    verbose ("Reading initial options from command line\n");
553
 
    parseOptions (args);
554
 
    checkOptions ();
555
 
    makeTags (args);
556
 
 
557
 
    /*  Clean up.
558
 
     */
559
 
    cArgDelete (args);
560
 
    freeKeywordTable ();
561
 
    freeRoutineResources ();
562
 
    freeSourceFileResources ();
563
 
    freeTagFileResources ();
564
 
    freeOptionResources ();
565
 
    freeParserResources ();
566
 
    freeRegexResources ();
567
 
 
568
 
    exit (0);
569
 
    return 0;
 
548
        setCurrentDirectory ();
 
549
        setExecutableName (*argv++);
 
550
        checkRegex ();
 
551
 
 
552
        args = cArgNewFromArgv (argv);
 
553
        previewFirstOption (args);
 
554
        testEtagsInvocation ();
 
555
        initializeParsing ();
 
556
        initOptions ();
 
557
        readOptionConfiguration ();
 
558
        verbose ("Reading initial options from command line\n");
 
559
        parseOptions (args);
 
560
        checkOptions ();
 
561
        makeTags (args);
 
562
 
 
563
        /*  Clean up.
 
564
         */
 
565
        cArgDelete (args);
 
566
        freeKeywordTable ();
 
567
        freeRoutineResources ();
 
568
        freeSourceFileResources ();
 
569
        freeTagFileResources ();
 
570
        freeOptionResources ();
 
571
        freeParserResources ();
 
572
        freeRegexResources ();
 
573
 
 
574
        exit (0);
 
575
        return 0;
570
576
}
571
577
 
572
 
/* vi:set tabstop=8 shiftwidth=4: */
 
578
/* vi:set tabstop=4 shiftwidth=4: */