Subversion Repositories DevTools

Rev

Rev 227 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
/*
2
 * This replace for the standard WATCOM supplied argv processing
3
 * function __Init_Argv.
4
 *
5
 *  Handles $<env-name>... expands into the named environment variabe
6
 *                         accepts $(<env-name>) or ${<env-name>} to
7
 *                         allow for trailing characters which would
8
 *                         normally be a part of the name. The value
9
 *                         of <env-name> is substituted into the string.
10
 *
11
 *  Handles @cmd-file-name read arguments.. any number per line, any
12
 *                         number of lines from <cmd-file-name>.. lines
13
 *                         read from the file get glob'd too!
14
 *
15
 *
16
 *  Handles "" strings     $<env-name> still expanded but results
17
 *                         in a single argument.
18
 *
19
 *  Handles '' strings     nothing inside expanded & results in a
20
 *                         single argument.
21
 *
22
 *  Handles `` expansion   where the command inside the backquotes
23
 *                         gets executed and its output substituted
24
 *                         in place of the string.
25
 *
26
 *  Handles unix like wildcards.. including [] character sets and
27
 *  {} type alternations.
28
 *
29
 */
30
 
31
#include <stdio.h>
32
#include <strings.h>
33
#include <ctype.h>
34
#include <sys/stat.h>
35
#include <sys/types.h>
36
#include <fcntl.h>
37
#include <dirent.h>
38
#include <malloc.h>
39
 
40
#include "glob.h"         /* filename globbing */
41
 
42
 
43
 
44
/*
45
 * Increments for growing various arrays.
46
 */
47
#define ARGV_GROW_SIZE 100
48
#define ARG_GROW_SIZE  2000
49
 
50
/*
51
 * The following are part of the Watcom runtime
52
 */
5659 dpurdie 53
extern char **___Argv;          /* the eventual argv */
54
extern int  ___Argc;            /* the eventual argc */
55
extern char *_LpPgmName;        /* the program name */
56
extern char *_LpCmdLine;        /* the raw cmdline */
57
extern char **environ;          /* the environment strings */
227 dpurdie 58
 
59
/*
60
 * How big the array pointed to by __Argv really is.
61
 */
62
static int argv_allocated = 0;
63
 
64
/*
65
 * Non-zero if any wildcards were seen processing the arguments.
66
 */
67
static int wildcards_seen = 0;
68
 
69
/*
70
 * Hmmm, should be in a header someplace... maybe... perhaps.
71
 */
72
extern FILE *popen();
73
extern void pclose();
74
 
75
/*
76
 * Internal functions.
77
 */
78
static void glob_cmd_line(char *);
79
static void glob_env(int);
80
static void expand(char*, char*, int, int);
81
static char **exec_prog(char*m, int);
82
static char **read_cmd_file(char*);
83
static int  whitespace_p(char *s, int quote);
84
static char *xgetenv(char *);
85
static void add_arg(char*);
86
static glob_t *wildcard_expand(char*, int);
87
 
88
/*
89
 * Flag given to expand().
90
 */
91
#define ENV_ARG     1
92
#define CMDLINE_ARG 0
93
 
94
/*
95
 * True if `c' is a space, tab.
96
 */
97
#define WS_P(c) ((c) == ' ' || (c) == '\t')
98
 
99
/*
100
 * True if `c' is a CR or LF.
101
 */
102
#define NL_P(c) ((c) == '\r' || (c) == '\n')
103
 
104
/*
105
 * True if `c' is special to filename expansion.
106
 */
107
#define SPECIAL(c) ((c) == '*' || (c) == '?' || (c) == '[' || (c) == '{')
108
 
109
 
110
/******************************************************************************
111
 *
112
 * Primary entry point. By linking in this code we simply replace the standard
113
 * WATCOM supplied version of command line handling: the function __Init_Argv.
114
 *
115
 *****************************************************************************/
116
 
117
void __Init_Argv(void)
118
{
119
  int  nenv_args = 0;
120
  char *tmp;
121
 
5659 dpurdie 122
  extern void __setenvp(void);  /* A WATCOM thing which sets up environ */
227 dpurdie 123
  __setenvp();                  /* found by grovelling                  */
124
 
125
 
126
#ifdef TEST
127
    printf("_LpCmdLine: %x\n", _LpCmdLine);
128
    printf("_LpPgmName: %x\n", _LpPgmName);
129
    printf("_LpCmdLine: \"%s\"\n", _LpCmdLine);
130
    printf("_LpPgmName: \"%s\"\n", _LpPgmName);
131
#endif
132
  ___Argc = 0;
133
  strlwr(_LpPgmName);
134
 
135
  for (tmp = _LpPgmName; *tmp; tmp++)
136
    {
137
      if (*tmp == '\\')
5659 dpurdie 138
        *tmp = '/';
227 dpurdie 139
    }
140
  add_arg(_LpPgmName);
141
 
142
  if ((tmp = xgetenv("_argc")) != 0)
143
    {
144
#ifdef TEST
145
      printf("getenv(_argc): %x, \"%s\"\n", tmp, tmp);
146
#endif
147
      nenv_args = atoi(tmp);
148
    }
149
 
150
  /*
151
   *  Stuff from the environment goes first.
152
   */
153
  if (nenv_args)
154
    {
155
      glob_env(nenv_args);
156
    }
157
 
158
  /*
159
   * Tack anything from the command line on the end of the
160
   * argument array.
161
   */
162
  glob_cmd_line(_LpCmdLine);
163
 
164
  ___Argv[___Argc] = 0;
165
 
166
  if (wildcards_seen && ___Argc == 1)
167
    {
168
      printf("No match.\n");
169
      exit(1);
170
    }
171
 
172
#ifdef TEST
173
  printf("final argc: %d\n", ___Argc);
174
#endif
175
}
176
 
177
 
178
/******************************************************************************
179
 *
180
 * Loop through the environment grabbing arguments from it.
181
 *
182
 *****************************************************************************/
183
 
184
static void glob_env(int nargs)
185
{
186
  int i;
187
  char *arg;
188
  char env_name[80];
189
 
190
  if (nargs > 999999)
191
    {
192
      fprintf(stderr, "glob_env: too many arguments (>= 1000000)\n");
193
      exit(42);
194
    }
195
 
196
  for (i = 1; i < nargs; i++)
197
    {
198
      sprintf(env_name, "_argv%d", i);
199
      if ((arg = xgetenv(env_name)) == 0)
5659 dpurdie 200
        {
201
          fprintf(stderr, "glob_env: BAD environment: _argc: %d, no _argv%d\n",
202
                  nargs, i);
203
          exit(42);
204
        }
227 dpurdie 205
      expand(0, arg, ENV_ARG, 0);
206
    }
207
}
208
 
209
 
210
 
211
/******************************************************************************
212
 *
213
 * Find each distinct argument on the command line, taking note
214
 * of quotes etc. then expand & add each argument to the final
215
 * argument vector. Leaves the quote characters intact (for now).
216
 *
217
 *****************************************************************************/
218
 
219
static void glob_cmd_line(const char *cmd_line)
220
{
221
  char *l   = strdup(cmd_line);
222
  char argc = 0;
5659 dpurdie 223
  char *argv[64];       /* can't get more than this on a DOS command line */
227 dpurdie 224
  int  i;
225
 
226
  while (*l)
227
    {
228
      /*
229
       * Find the start of the argument.
230
       */
231
      while (*l == ' ' || *l == '\t') l++;
232
 
233
      argv[argc++] = l;
234
 
235
      /*
236
       * Find the end of the argument.
237
       */
238
      for (;*l; l++)
5659 dpurdie 239
        {
240
          if (*l == '\'' || *l == '\"' || *l == '`')
241
            {
242
              int quote_char = *l++;
243
 
244
              do
245
                {
246
                  if (!*l)
247
                    {
248
                      fprintf(stderr, "Unmatched %c.\n", quote_char);
249
                      exit(42);
250
                    }
251
                } while (*l++ != quote_char);
252
            }
227 dpurdie 253
 
5659 dpurdie 254
          if (*l == ' ' || *l == '\t')
255
            {
256
              *l++ = '\0';
257
              break;
258
            }
259
        }
227 dpurdie 260
    }
261
 
262
  for (i = 0; i < argc; i++)
263
    {
264
      expand(0, argv[i], CMDLINE_ARG, 0);
265
    }
266
}
267
 
268
 
269
 
270
/******************************************************************************
271
 *
272
 * Process an argument...
273
 *
274
 * If PREFIX is non-zero then it contains a partial argument
275
 * which has already been processed... it is simply copied into
276
 * the output buffer. This is used when handling variables and
277
 * backquoting.. backquoting particularly crappy because it
278
 * turns a single argument into many.
279
 *
280
 *****************************************************************************/
281
 
282
static void expand(char *prefix, char *arg, int from_env, int in_string)
283
{
284
  int  prefix_len = (prefix)?strlen(prefix):0;
285
  int  buf_len = prefix_len + ARG_GROW_SIZE;
286
  char *buf = (char*)malloc(buf_len);
287
  char *bufp = buf;
288
  int   in_quote = 0;
289
 
290
#ifdef TEST
291
  printf("expand(prefix: \"%s\", arg: \"%s\")\n",
5659 dpurdie 292
          prefix?prefix:"(nil)", arg);
227 dpurdie 293
#endif
294
 
5659 dpurdie 295
#define CHECK_BUF_END(l)                                        \
296
  {                                                             \
297
    int offset = bufp - buf;                                    \
298
    while ((offset + (l)) >= buf_len)                           \
299
      {                                                         \
300
        buf = (char*)realloc(buf, buf_len += ARG_GROW_SIZE);    \
301
      }                                                         \
302
    bufp = buf + offset;                                        \
227 dpurdie 303
  }
304
 
305
  if (!buf)
306
    {
307
      fprintf(stderr, "expand: Out of memory\n");
308
      exit(42);
309
    }
310
 
311
  if (prefix)
312
    {
313
      strcpy(buf, prefix);
314
      bufp += prefix_len;
315
    }
316
 
317
 
318
  /*
319
   * do stuff..
320
   */
321
  for (;*arg; arg++)
322
    {
323
      switch (*arg)
5659 dpurdie 324
        {
325
        case '\'':
326
          {
327
            in_quote = !in_quote;
328
            arg;
329
            break;
330
          }
227 dpurdie 331
 
5659 dpurdie 332
        case '\"':
333
          {
334
            if (!in_quote)
335
              {
336
                in_string = !in_string;
337
                arg;
338
              }
339
            else
340
              goto copy_it;
341
            break;
342
          }
227 dpurdie 343
 
5659 dpurdie 344
        case '`':
345
          {
346
            if (!in_quote)
347
              {
348
                char *start = ++arg;
349
                char **lines;
227 dpurdie 350
 
5659 dpurdie 351
                for (arg++; *arg != '`'; arg++);
352
                CHECK_BUF_END(arg - start);
353
                strncpy(bufp, start, arg - start);
354
                *(bufp + (arg - start)) = '\0';
355
                lines =  exec_prog(bufp, in_string);
356
                *bufp = '\0';
227 dpurdie 357
 
5659 dpurdie 358
                if (lines)
359
                  {
360
                    for (;*lines; lines++)
361
                      {
362
                        if (lines[1])
363
                          {
364
                            /* more arguments after this one. */
365
                            expand((bufp == buf)?0:buf, *lines, 0, in_string);
366
                            bufp = buf;
367
                          }
368
                        else
369
                          {
370
                            char *new_arg;
371
                            /* last argument.. tack the rest of arg onto it. */
372
                            new_arg = (char*)malloc(strlen(*lines) +
373
                                                    strlen(arg + 1) + 1);
374
                            if (!new_arg)
375
                              {
376
                                fprintf(stderr, "expand: Out of memory\n");
377
                              }
378
                            strcpy(new_arg, *lines);
379
                            strcat(new_arg, arg + 1);
380
                            expand((bufp == buf)?0:buf, new_arg, 0, in_string);
381
                            free(new_arg);
382
                          }
383
                      }
384
                  }
385
                return;
386
              }
387
            else
388
              goto copy_it;
389
            break;
390
          }
227 dpurdie 391
 
5659 dpurdie 392
        case '$':
393
          {
394
            if (!in_quote)
395
              {
396
                char *start  = ++arg;
397
                int  bracket = 0;
398
                char var_name[200];
399
                char *new_arg;
400
                char *var_val;
227 dpurdie 401
 
5659 dpurdie 402
                if (*start == '(')
403
                  {
404
                    bracket = ')';
405
                    start++;
406
                  }
407
                else
408
                  if (*start == '{')
409
                    {
410
                      bracket = '}';
411
                      start++;
412
                    }
227 dpurdie 413
 
5659 dpurdie 414
                if (bracket)
415
                  {
416
                    while (*arg && *arg != bracket)
417
                      arg++;
418
                    if (!*arg)
419
                      {
420
                        fprintf(stderr, "Missing %c.\n", bracket);
421
                        exit(42);
422
                      }
423
                    strncpy(var_name, start, arg - start);
424
                    var_name[arg-start] = '\0';
425
                    arg++;
426
                  }
427
                else
428
                  {
429
                    while (*arg && (isalnum(*arg) || *arg == '_'))
430
                      arg++;
431
                    strncpy(var_name, start, arg - start);
432
                    var_name[arg-start] = '\0';
433
                  }
227 dpurdie 434
 
5659 dpurdie 435
                if (var_val = xgetenv(var_name))
436
                  {
437
                    new_arg = (char *)malloc(strlen(arg) +
438
                                             strlen(var_val) + 1);
439
                    if (!new_arg)
440
                      {
441
                        fprintf(stderr, "expand: Out of memory (expanding var)\n");
442
                        exit(42);
443
                      }
444
                    strcpy(new_arg, var_val);
445
                    strcat(new_arg, arg);
446
                    *bufp = '\0';
447
                    expand((bufp == buf)?0:buf, new_arg, 0, in_string);
448
                    free(new_arg);
449
                  }
450
                else
451
                  {
452
                    fprintf(stderr, "Undefined variable: %s\n", var_name);
453
                    exit(42);
454
                  }
455
                return;
456
              }
457
            else
458
              goto copy_it;
459
            break;
460
          }
227 dpurdie 461
 
5659 dpurdie 462
        default:
463
          {
464
          copy_it:
465
            if (SPECIAL(*arg) && (in_quote || in_string))
466
              {
467
                CHECK_BUF_END(1);
468
                *bufp++ = '\\';
469
              }
470
            CHECK_BUF_END(1);
471
            *bufp++ = *arg;
472
            break;
473
          }
474
        }
227 dpurdie 475
    }
476
 
477
  CHECK_BUF_END(1);
478
  *bufp = '\0';
479
 
480
  /*
481
   * Check for a reference to a command file..
482
   */
483
  if (*buf == '@')
484
    {
485
      char **lines = read_cmd_file(buf + 1);
486
      while (lines && *lines)
5659 dpurdie 487
        {
488
          expand(0, *lines++, 0, 0);
489
        }
227 dpurdie 490
      free(buf);
491
      return;
492
    }
493
 
494
  /*
495
   * wildcard expand the argument... arguments from the environment
496
   * only get wildcarded if they don't contain any spaces.
497
   */
498
  if (*buf)
499
    {
500
      if (from_env && (strchr(buf, ' ') || strchr(buf, '\t')))
5659 dpurdie 501
        add_arg(buf);
227 dpurdie 502
      else
5659 dpurdie 503
        {
504
          glob_t *gb = wildcard_expand(buf, 1);
505
          int    i;
506
          if (gb)
507
            {
508
              for (i = 0; i < gb->nused; i++)
509
                add_arg(gb->paths[i]);
510
              arg_free_glob_t(gb);
511
            }
512
          else
513
            add_arg(buf); /* no wildcards in `buf' so just add it */
514
        }
227 dpurdie 515
    }
516
 
517
  free(buf);
518
}
519
 
520
 
521
 
522
/******************************************************************************
523
 *
524
 * Add an argument to ___Argv.. expanding Argv if required.
525
 *
526
 *****************************************************************************/
527
 
528
static void add_arg(char *arg)
529
{
530
  char *str = strdup(arg);
531
 
532
 
533
#ifdef TEST
534
  printf("add_arg: \"%s\"\n", arg);
535
#endif
536
 
537
  if (!str)
538
    {
539
      fprintf(stderr, "add_arg: Out of memory.\n");
540
      exit(42);
541
    }
5659 dpurdie 542
 
227 dpurdie 543
  if (___Argc >= argv_allocated)
544
    {
545
      if (!argv_allocated)
5659 dpurdie 546
        {
547
          argv_allocated = ARGV_GROW_SIZE;
548
          ___Argv = (char**)malloc(argv_allocated * sizeof(char*));
549
        }
227 dpurdie 550
      else
5659 dpurdie 551
        {
552
          argv_allocated += ARGV_GROW_SIZE;
553
          ___Argv = (char**)localRealloc(___Argv, argv_allocated * sizeof(char*));
554
        }
227 dpurdie 555
    }
556
 
557
  if (!___Argv)
558
    {
559
      fprintf(stderr, "add_arg: Out of memory.\n");
560
      exit(42);
561
    }
562
  ___Argv[___Argc++] = str;
563
}
564
 
565
 
566
/*****************************************************************************
567
 *
568
 * Do the work of expanding the wild card characters in a string.
569
 *
570
 *****************************************************************************/
571
 
572
static glob_t *wildcard_expand(char *s, int no_match_ok)
573
{
574
  glob_t *gb = 0;
575
 
576
#ifdef TEST
577
  printf("wildcard_expand: \"%s\"\n", s);
578
#endif
579
 
580
  if (wildcard_p(s, 0))
581
    {
582
      int status;
583
      char *mess;
584
 
585
      wildcards_seen++;
586
 
587
      if ((gb = (glob_t *) malloc(sizeof(glob_t))) == 0)
5659 dpurdie 588
        {
589
          fprintf(stderr, "argv: Out of memory.\n");
590
          exit(42);
591
        }
227 dpurdie 592
      gb->nused = 0;
593
      gb->paths = 0;
594
      gb->nallocated = 0;
595
      status = arg_glob(s, GLOB_FLAGS, gb);
596
 
597
#ifdef TEST
598
      printf("globbing finds %d names\n", gb->nused);
599
#endif
600
 
601
      if (status == E_NOMATCH)
5659 dpurdie 602
        {
603
          if (no_match_ok)
604
            status = 0;
605
          else
606
            mess = "No match\n";
607
        }
227 dpurdie 608
      else
609
      if (status == E_NOMEMORY)
5659 dpurdie 610
        mess = "glob: out of memory\n";
227 dpurdie 611
      else
612
      if (status == E_IMPOSSIBLE)
5659 dpurdie 613
        mess = "glob: can't handle wildcard drive names\n";
227 dpurdie 614
      else
615
      if (status == E_NODIR)
5659 dpurdie 616
        mess = "glob: failed opening directory\n";
227 dpurdie 617
 
618
      if (status)
5659 dpurdie 619
        {
620
          fprintf(stderr, mess);
621
          exit(42);
622
        }
227 dpurdie 623
    }
624
  return gb;
625
}
626
 
627
 
628
 
629
 
630
 
631
 
632
 
633
/******************************************************************************
634
 *
635
 * Exec a subprogram and returns it's output as an array of strings.
636
 * If in_string is non-zero only newlines separate fields.
637
 *
638
 *****************************************************************************/
639
 
640
static char **exec_prog(char *cmd_line, int in_string)
641
{
642
  int   buf_len   = ARG_GROW_SIZE;
643
  char *buf       = malloc(ARG_GROW_SIZE); /* the input line buffer */
644
  char *l         = buf;
645
 
646
  int    argc     = 0;
647
  char **argv     = 0;
648
 
649
  FILE  *fp;
650
  int    ch;
651
 
652
#ifdef TEST
653
  printf("exec_prog(\"%s\")\n", cmd_line);
654
#endif
655
 
656
  if ((fp = popen(cmd_line, "r")) == 0)
657
    {
658
      fprintf(stderr, "exec of subcommand failed...\n");
659
      perror("argv-handler");
660
      exit(42);
661
    }
662
 
663
  /*
664
   * Suck in all the output of the exec'd program.
665
   */
666
 
667
  while ((ch = fgetc(fp)) != EOF)
668
    {
669
      if (l >= (buf + buf_len - 1))
5659 dpurdie 670
        {
671
          int offset = l - buf;
672
          buf = (char*)realloc(buf, buf_len += ARG_GROW_SIZE);
673
          l = buf + offset;
674
        }
227 dpurdie 675
      *l++ = ch;
676
    }
677
  *l++ = '\0';
678
  pclose(fp);
679
 
680
#ifdef TEST
681
  printf("Output from exec'd prog: |%s|\n", buf);
682
#endif
683
 
684
  /*
685
   * Parse it into fields... straight up guess the sizeof argv as
686
   * half the length of the buffer (ie, every second character a
687
   * space).
688
   */
689
  if (0 == (argv = malloc(((l - buf) / 2) * sizeof(char *))))
690
    {
691
      fprintf(stderr, "Out of memory executing backquote.\n");
692
      exit(42);
693
    }
694
 
695
  for (l = buf; *l;)
696
    {
697
      /*
698
       * Kill leading whitespace.
699
       */
700
      while ( NL_P(*l) || (!in_string && WS_P(*l)))
5659 dpurdie 701
        l++;
227 dpurdie 702
 
703
      if (*l)
5659 dpurdie 704
        {
705
          argv[argc++] = l;
227 dpurdie 706
 
5659 dpurdie 707
          /*
708
           * Skip to next whitespace or end of string.
709
           */
710
          while (*l && !(NL_P(*l) || (!in_string && WS_P(*l))))
711
            l++;
227 dpurdie 712
 
5659 dpurdie 713
          /*
714
           * Only terminate if not at end of input.
715
           */
716
          if (*l)
717
            *l++ = '\0';
718
        }
227 dpurdie 719
    }
720
 
721
  /*
722
   * Fix up the size of the returned array.
723
   */
5659 dpurdie 724
  argv = localRealloc(argv, sizeof(char *) * (argc + 1));
227 dpurdie 725
  argv[argc] = 0;
726
 
727
  return argv;
728
}
729
 
730
 
731
 
732
 
733
/******************************************************************************
734
 *
735
 * Read a command file.. returns a null terminated array of fields..
736
 *
737
 *****************************************************************************/
738
 
739
static char **read_cmd_file(char *fname)
740
{
741
  struct stat statb;
742
  int    ifile;
743
  char  *buf;
744
  char **argv = 0;
745
  char  *l;
746
  int    r;
747
  int    argc = 0;
748
 
749
#ifdef TEST
750
  printf("read_cmd_file(%s)\n", fname);
751
#endif
752
 
753
  if ((r = stat(fname, &statb)) == 0)
754
    {
755
#ifdef TEST
756
      printf("read_cmd_file: opens: \"%s\"\n", fname);
757
#endif
758
      if ((ifile = open(fname, O_RDONLY | O_BINARY)) >= 0)
5659 dpurdie 759
        {
760
          if ((buf = (char*)malloc(statb.st_size + 1)) != 0)
761
            {
762
              if (statb.st_size == read(ifile, buf, statb.st_size))
763
                {
764
                  buf[statb.st_size] = '\0';
765
                  close(ifile);
766
                }
767
              else
768
                {
769
                  fprintf(stderr, "read_cmd_file: read failed, size: %d\n",
770
                          statb.st_size);
771
                  exit(42);
772
                }
773
            }
774
          else
775
            {
776
              fprintf(stderr, "read_cmd_file: Out of memory\n");
777
              _exit(42);
778
            }
779
        }
227 dpurdie 780
      else
5659 dpurdie 781
        {
782
          perror("read_cmd_file");
783
          exit(42);
784
        }
227 dpurdie 785
    }
786
  else
787
    {
788
      fprintf(stderr, "read_cmd_file: r: %d\n", r);
789
      perror("read_cmd_file: stat failed");
790
      exit(42);
791
    }
792
 
793
 
794
  /*
795
   * Construct the vector of fields... use a straight up guess on the
796
   * size of argv... then fix it up afterwards.
797
   */
798
  if (0 == (argv = (char**)malloc((statb.st_size / 2) * sizeof(char*))))
799
    {
800
      fprintf(stderr, "Out of memory reading command file.\n");
801
      exit(42);
802
    }
803
 
804
  for (l = buf; *l;)
805
    {
806
      char *start = 0;
807
      /*
808
       * Find the start of the argument.
809
       */
810
      while (NL_P(*l) || WS_P(*l))
5659 dpurdie 811
        l++;
227 dpurdie 812
 
813
      if (*l)
5659 dpurdie 814
        start = l;
227 dpurdie 815
 
816
      /*
817
       * Find the end of the argument.
818
       */
819
      for (;*l;l++)
5659 dpurdie 820
        {
821
          if (*l == '\'' || *l == '\"' || *l == '`')
822
            {
823
              int quote_char = *l++;
824
 
825
              do
826
                {
827
                  if (!*l)
828
                    {
829
                      fprintf(stderr, "Unmatched %c. (reading %s)\n",
830
                              quote_char, fname);
831
                      exit(42);
832
                    }
833
                } while (*l++ != quote_char);
834
            }
227 dpurdie 835
 
836
 
5659 dpurdie 837
          if (NL_P(*l) || WS_P(*l))
838
            {
839
              *l++ = '\0';
840
              break;
841
            }
842
        }
227 dpurdie 843
      if (start)
5659 dpurdie 844
        argv[argc++] = start;
227 dpurdie 845
    }
846
 
5659 dpurdie 847
  argv = localRealloc(argv, sizeof(char *) * (argc + 1));
227 dpurdie 848
  argv[argc] = 0;
849
 
850
  return argv;
851
}
852
 
853
 
854
 
855
 
856
/******************************************************************************
857
 *
858
 * A replacement for getenv() which IS case sensitive, the standard
859
 * WATCOM one is not.
860
 *
861
 *****************************************************************************/
862
 
863
static char *xgetenv(char *var_name)
864
{
865
  char **envp = environ;
866
  int  var_len = strlen(var_name);
867
 
868
#ifdef TEST
869
  printf("envp: %x, getenv(\"%s\") returns ", environ, var_name);
870
#endif
871
 
872
  while (envp && *envp)
873
    {
874
      char *endp = (*envp) + var_len;
875
 
876
      if (!strncmp(var_name, *envp, var_len))
5659 dpurdie 877
        {
878
          if (*endp == '=')
879
            {
227 dpurdie 880
#ifdef TEST
5659 dpurdie 881
              printf("%s\n", endp+1);
227 dpurdie 882
#endif
5659 dpurdie 883
              return endp + 1;
884
            }
885
        }
227 dpurdie 886
      envp++;
887
    }
888
#ifdef TEST
889
  printf("(nil)\n");
890
#endif
891
  return 0;
892
}
893