~ubuntu-branches/ubuntu/utopic/texlive-bin/utopic

« back to all changes in this revision

Viewing changes to utils/chktex/chktex-1.6.4/OpSys.c

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2012-04-10 10:16:01 UTC
  • mfrom: (1.2.3)
  • Revision ID: package-import@ubuntu.com-20120410101601-7mt8nyn280xrgza6
Tags: 2011.20120410-1
* new upstream checkout:
  - remove decls of popen and pclose (Closes: #64524) (!yow, 5 digit bug!)
  - do not declare getopt in C++, fixes FTBFS with g++ >= 4.7 
    (Closes: #667392)
* add patches (maybe to be included upstream) that allows inclusion of
  one config file in another for (x)dvipdfmx. This will be
  used by the paper code.
* fix description of libptexenc-dev package (Closes: #667694)
* remove xdvik patch, included upstream
* remove conflict with ptex-bin, we are building a transitional package now
* build with internal t1lib, as t1lib is going to disappear in
  wheezy (Closes: #667912) (no, dropping xdvi is not an option!)
  (add a lintian override otherwise this gives a lintian error)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  ChkTeX, operating system specific code for ChkTeX.
3
 
 *  Copyright (C) 1995-96 Jens T. Berger Thielemann
4
 
 *
5
 
 *  This program is free software; you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation; either version 2 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
 *
19
 
 *  Contact the author at:
20
 
 *              Jens Berger
21
 
 *              Spektrumvn. 4
22
 
 *              N-0666 Oslo
23
 
 *              Norway
24
 
 *              E-mail: <jensthi@ifi.uio.no>
25
 
 *
26
 
 *
27
 
 */
28
 
 
29
 
 
30
 
/*
31
 
 * Some functions which have to be made different from OS to OS,
32
 
 * unfortunately...:\
33
 
 *
34
 
 */
35
 
 
36
 
#include "ChkTeX.h"
37
 
#include "OpSys.h"
38
 
#include "Utility.h"
39
 
 
40
 
#ifdef HAVE_SYS_STAT_H
41
 
#  include <sys/stat.h>
42
 
#endif
43
 
#ifdef HAVE_STAT_H
44
 
#  include <stat.h>
45
 
#endif
46
 
 
47
 
#if HAVE_DIRENT_H
48
 
#  include <dirent.h>
49
 
#  define NAMLEN(dirent) strlen((dirent)->d_name)
50
 
#else
51
 
#  define dirent direct
52
 
#  define NAMLEN(dirent) (dirent)->d_namlen
53
 
#  if HAVE_SYS_NDIR_H
54
 
#    include <sys/ndir.h>
55
 
#  endif
56
 
#  if HAVE_SYS_DIR_H
57
 
#    include <sys/dir.h>
58
 
#  endif
59
 
#  if HAVE_NDIR_H
60
 
#    include <ndir.h>
61
 
#  endif
62
 
#endif
63
 
 
64
 
#if defined(HAVE_OPENDIR) && defined(HAVE_CLOSEDIR) && \
65
 
    defined(HAVE_READDIR) && defined(HAVE_STAT) && \
66
 
    defined(S_IFDIR) && defined(SLASH)
67
 
#  define USE_RECURSE 1
68
 
#else
69
 
#  define USE_RECURSE 0
70
 
#endif
71
 
 
72
 
#if defined(HAVE_LIBTERMCAP) || defined(HAVE_LIBTERMLIB)
73
 
#  define USE_TERMCAP 1
74
 
#endif
75
 
 
76
 
 
77
 
#ifdef USE_TERMCAP
78
 
#  ifdef HAVE_TERMCAP_H
79
 
#    include <termcap.h>
80
 
#  elif HAVE_TERMLIB_H
81
 
#    include <termlib.h>
82
 
#  else
83
 
int tgetent(char *BUFFER, char *TERMTYPE);
84
 
char *tgetstr(char *NAME, char **AREA);
85
 
#  endif
86
 
static char term_buffer[2048];
87
 
#endif
88
 
 
89
 
/*  -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=-  */
90
 
 
91
 
/*
92
 
 * This is the name of the global resource file.
93
 
 */
94
 
 
95
 
#ifndef SYSCONFDIR
96
 
#  if defined(__unix__)
97
 
#    define SYSCONFDIR "/usr/local/lib/"
98
 
#  elif defined(__MSDOS__)
99
 
#    define SYSCONFDIR "\\emtex\\data\\"
100
 
#  else
101
 
#    define SYSCONFDIR
102
 
#  endif
103
 
#endif
104
 
#define RCBASENAME              "chktexrc"
105
 
 
106
 
#ifdef __MSDOS__
107
 
#  define LOCALRCFILE             RCBASENAME
108
 
#else
109
 
#  define LOCALRCFILE             "." RCBASENAME
110
 
#endif
111
 
 
112
 
char ConfigFile[BUFSIZ] = LOCALRCFILE;
113
 
const char *ReverseOn;
114
 
const char *ReverseOff;
115
 
 
116
 
 
117
 
static int HasFile(char *Dir, const char *Filename, const char *App);
118
 
 
119
 
#if USE_RECURSE
120
 
static int SearchFile(char *Dir, const char *Filename, const char *App);
121
 
#endif /* USE_RECURSE */
122
 
 
123
 
/*  -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=-  */
124
 
 
125
 
 
126
 
/*
127
 
 * Modify this one to suit your needs. In any case, it should fill
128
 
 * the ConfigFile (sized BUFLEN) buffer above with full name & path
129
 
 * for the configuration file. The macro RCFILE will give you the
130
 
 * filename part of the file, if you need that.
131
 
 *
132
 
 * Note: This routine will be called several times. Your mission will
133
 
 * be to look in each location, and see whether a .chktexrc file exist
134
 
 * there.
135
 
 *
136
 
 * If you choose to do nothing, only the current directory will be
137
 
 * searched.
138
 
 *
139
 
 */
140
 
 
141
 
 
142
 
enum LookIn
143
 
{
144
 
    liMin,
145
 
    liSysDir,
146
 
    liUsrDir,
147
 
    liEnvir,
148
 
    liCurDir,
149
 
    liNFound,
150
 
    liMax
151
 
};
152
 
 
153
 
 
154
 
int SetupVars(void)
155
 
{
156
 
    char *Env;
157
 
#ifdef __MSDOS__
158
 
 
159
 
    char *Ptr;
160
 
#endif
161
 
 
162
 
    static enum LookIn i = liMin;
163
 
    static int FoundFile;
164
 
 
165
 
    while (++i < liMax)
166
 
    {
167
 
        switch (i)
168
 
        {
169
 
        case liCurDir:         /* Current directory */
170
 
            strcpy(ConfigFile, LOCALRCFILE);
171
 
            break;
172
 
        case liEnvir:          /* Environment defined */
173
 
#ifdef __MSDOS__
174
 
 
175
 
            if ((Env = getenv("CHKTEXRC")) || (Env = getenv("CHKTEX_HOME")))
176
 
#else
177
 
 
178
 
            if ((Env = getenv("CHKTEXRC")))
179
 
#endif
180
 
 
181
 
            {
182
 
                strcpy(ConfigFile, Env);
183
 
                tackon(ConfigFile, LOCALRCFILE);
184
 
            }
185
 
            else
186
 
#ifdef __MSDOS__
187
 
            if ((Env = getenv("EMTEXDIR")))
188
 
            {
189
 
                strcpy(ConfigFile, Env);
190
 
                tackon(ConfigFile, "data");
191
 
                tackon(ConfigFile, LOCALRCFILE);
192
 
            }
193
 
            else
194
 
#endif
195
 
 
196
 
                *ConfigFile = 0;
197
 
            break;
198
 
        case liUsrDir:         /* User dir for resource files */
199
 
#if defined(__unix__)
200
 
 
201
 
            if ((Env = getenv("HOME")) || (Env = getenv("LOGDIR")))
202
 
            {
203
 
                strcpy(ConfigFile, Env);
204
 
                tackon(ConfigFile, LOCALRCFILE);
205
 
            }
206
 
            else
207
 
#elif defined(__MSDOS__)
208
 
 
209
 
            strcpy(ConfigFile, PrgName);
210
 
            if ((Ptr = strrchr(ConfigFile, '\\')) ||
211
 
                (Ptr = strchr(ConfigFile, ':')))
212
 
                strcpy(++Ptr, RCBASENAME);
213
 
            else
214
 
#endif
215
 
                *ConfigFile = 0;
216
 
 
217
 
            break;
218
 
        case liSysDir:         /* System dir for resource files */
219
 
#ifdef TEX_LIVE
220
 
            if ((Env = getenv("CHKTEX_CONFIG")))
221
 
            {
222
 
                strcpy(ConfigFile, Env);
223
 
            }
224
 
            else
225
 
            {
226
 
                FILE *f;
227
 
                *ConfigFile = 0;
228
 
                if ((f = popen("kpsewhich -expand-var='$TEXMFMAIN'", "r")))
229
 
                {
230
 
                    if (1 == fscanf(f, "%1024s", ConfigFile))
231
 
                    {
232
 
                        tackon(ConfigFile, "chktex");
233
 
                        tackon(ConfigFile, RCBASENAME);
234
 
                    }
235
 
                    (void)pclose(f);
236
 
                }
237
 
            }
238
 
#else /* TEX_LIVE */
239
 
#if defined(__unix__) || defined(__MSDOS__)
240
 
            strcpy(ConfigFile, SYSCONFDIR);
241
 
            tackon(ConfigFile, RCBASENAME);
242
 
#else
243
 
            *ConfigFile = 0;
244
 
#endif
245
 
#endif /* TEX_LIVE */
246
 
 
247
 
            break;
248
 
        case liNFound:
249
 
        case liMin:
250
 
        case liMax:
251
 
            *ConfigFile = 0;
252
 
            if (!FoundFile)
253
 
                PrintPrgErr(pmNoRsrc);
254
 
        }
255
 
 
256
 
        if (*ConfigFile && fexists(ConfigFile))
257
 
            break;
258
 
    }
259
 
    FoundFile |= *ConfigFile;
260
 
 
261
 
    return (*ConfigFile);
262
 
}
263
 
 
264
 
 
265
 
/*  -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=-  */
266
 
 
267
 
/*
268
 
 * This function should initialize the global variables ReverseOn
269
 
 * and ReverseOff to magic cookies, which when printed, makes the
270
 
 * text in between stand out.
271
 
 */
272
 
 
273
 
void SetupTerm(void)
274
 
{
275
 
#ifdef USE_TERMCAP
276
 
    char *termtype = getenv("TERM");
277
 
    int success;
278
 
    char *buffer;
279
 
    static char str_so[3] = "so", str_se[3] = "se";
280
 
 
281
 
    if (termtype)
282
 
    {
283
 
 
284
 
        success = tgetent(term_buffer, termtype);
285
 
        if (success < 0)
286
 
            PrintPrgErr(pmNoTermData);
287
 
        if (success == 0)
288
 
            PrintPrgErr(pmNoTermDefd);
289
 
 
290
 
        buffer = (char *) malloc(sizeof(term_buffer));
291
 
        ReverseOn = tgetstr(str_so, &buffer);
292
 
        ReverseOff = tgetstr(str_se, &buffer);
293
 
 
294
 
        if (ReverseOn && ReverseOff)
295
 
            return;
296
 
    }
297
 
#endif
298
 
 
299
 
    ReverseOn = PRE_ERROR_STR;
300
 
    ReverseOff = POST_ERROR_STR;
301
 
}
302
 
 
303
 
/*  -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=-  */
304
 
 
305
 
/*
306
 
 * Concatenates the `File' string to the `Dir' string, leaving the result
307
 
 * in the `Dir' buffer. Takes care of inserting `directory' characters;
308
 
 * if we've got the strings "/usr/foo" and "bar", we'll get
309
 
 * "/usr/foo/bar".
310
 
 *
311
 
 * Behaviour somewhat controlled by the macros SLASH and DIRCHARS in the
312
 
 * OpSys.h file.
313
 
 *
314
 
 */
315
 
 
316
 
void tackon(char *Dir, const char *File)
317
 
{
318
 
    int EndC;
319
 
    unsigned long SLen;
320
 
 
321
 
    if (Dir && (SLen = strlen(Dir)))
322
 
    {
323
 
        EndC = Dir[SLen - 1];
324
 
        if (!(strchr(DIRCHARS, EndC)))
325
 
        {
326
 
            Dir[SLen++] = SLASH;
327
 
            Dir[SLen] = 0L;
328
 
        }
329
 
    }
330
 
 
331
 
    strcat(Dir, File);
332
 
}
333
 
 
334
 
/*
335
 
 * This function should add the appendix App to the filename Name.
336
 
 * If the resulting filename gets too long due to this, it may 
337
 
 * overwrite the old appendix.
338
 
 *
339
 
 * Name may be assumed to be a legal filename under your OS.
340
 
 *
341
 
 * The appendix should contain a leading dot.
342
 
 */
343
 
 
344
 
void AddAppendix(char *Name, const char *App)
345
 
{
346
 
#ifdef __MSDOS__
347
 
    char *p;
348
 
 
349
 
    if ((p = strrchr(Name, '.')))
350
 
        strcpy(p, App);
351
 
    else
352
 
        strcat(Name, App);
353
 
#else
354
 
    /*
355
 
     * NOTE! This may fail if your system has a claustrophobic file
356
 
     * name length limit.
357
 
     */
358
 
    strcat(Name, App);
359
 
#endif
360
 
 
361
 
}
362
 
 
363
 
/*  -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=-  */
364
 
 
365
 
 
366
 
/*
367
 
 * Locates a file, given a wordlist containing paths. If a
368
 
 * dir ends in a double SLASH, we'll search it recursively.
369
 
 *
370
 
 * We assume that
371
 
 *   a) a deeper level in the dir. tree. has a longer path than
372
 
 *      one above.
373
 
 *   b) adding a level doesn't change any of the previous levels.
374
 
 *
375
 
 * If this function returns TRUE, Dest is guaranteed to contain
376
 
 * path & name of the found file.
377
 
 *
378
 
 * FALSE indicates that the file was not found; Dest is then
379
 
 * unspecified.
380
 
 */
381
 
 
382
 
 
383
 
int LocateFile(const char *Filename,    /* File to search for */
384
 
               char *Dest,      /* Where to put final file */
385
 
               const char *App, /* Extra optional appendix */
386
 
               struct WordList *wl)     /* List of paths, entries
387
 
                                         * ending in // will be recursed
388
 
                                         */
389
 
{
390
 
    unsigned long i;
391
 
#if USE_RECURSE
392
 
 
393
 
    unsigned long Len;
394
 
#endif
395
 
 
396
 
    FORWL(i, *wl)
397
 
    {
398
 
        strcpy(Dest, wl->Stack.Data[i]);
399
 
 
400
 
#if USE_RECURSE
401
 
 
402
 
        Len = strlen(Dest);
403
 
 
404
 
        if (Len && (Dest[Len - 1] == SLASH) && (Dest[Len - 2] == SLASH))
405
 
        {
406
 
            Dest[Len - 1] = Dest[Len - 2] = 0;
407
 
            if (SearchFile(Dest, Filename, App))
408
 
                return (TRUE);
409
 
        }
410
 
        else
411
 
#endif /* USE_RECURSE */
412
 
 
413
 
        {
414
 
            if (HasFile(Dest, Filename, App))
415
 
                return (TRUE);
416
 
        }
417
 
    }
418
 
    return (FALSE);
419
 
}
420
 
 
421
 
static int HasFile(char *Dir, const char *Filename, const char *App)
422
 
{
423
 
    int DirLen = strlen(Dir);
424
 
 
425
 
    tackon(Dir, Filename);
426
 
    if (fexists(Dir))
427
 
        return (TRUE);
428
 
 
429
 
    if (App)
430
 
    {
431
 
        AddAppendix(Dir, App);
432
 
        if (fexists(Dir))
433
 
            return (TRUE);
434
 
    }
435
 
 
436
 
    Dir[DirLen] = 0;
437
 
    return (FALSE);
438
 
 
439
 
}
440
 
 
441
 
 
442
 
#if USE_RECURSE
443
 
static int SearchFile(char *Dir, const char *Filename, const char *App)
444
 
{
445
 
    struct stat *statbuf;
446
 
    struct dirent *de;
447
 
    DIR *dh;
448
 
 
449
 
    int DirLen = strlen(Dir);
450
 
    int Found = FALSE;
451
 
 
452
 
    DEBUG(("Searching %s for %s\n", Dir, Filename));
453
 
 
454
 
    if (HasFile(Dir, Filename, App))
455
 
        return (TRUE);
456
 
    else
457
 
    {
458
 
        if ((statbuf = malloc(sizeof(struct stat))))
459
 
        {
460
 
            if ((dh = opendir(Dir)))
461
 
            {
462
 
                while (!Found && (de = readdir(dh)))
463
 
                {
464
 
                    Dir[DirLen] = 0;
465
 
                    if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
466
 
                    {
467
 
                        tackon(Dir, de->d_name);
468
 
 
469
 
                        if (!stat(Dir, statbuf))
470
 
                        {
471
 
                            if ((statbuf->st_mode & S_IFMT) == S_IFDIR)
472
 
                                Found = SearchFile(Dir, Filename, App);
473
 
                        }
474
 
                    }
475
 
                }
476
 
                closedir(dh);
477
 
            }
478
 
            else
479
 
                PrintPrgErr(pmNoOpenDir, Dir);
480
 
            free(statbuf);
481
 
        }
482
 
    }
483
 
    return (Found);
484
 
}
485
 
#endif /* USE_RECURSE */