update for HEAD-2003050101
[reactos.git] / lib / tgetopt / getopt.c
1 /* $Id$
2 */
3 /*
4  tgetopt -- POSIX-compliant implementation of getopt() with string-type-generic
5  semantics
6
7  This is public domain software
8 */
9
10 #include <tchar.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <tgetopt.h>
14
15 int _topterr = 1;
16 int _toptind = 1;
17 int _toptopt;
18 _TCHAR * _toptarg;
19
20 int _tgetopt(int argc, _TCHAR * const argv[], const _TCHAR * optstring)
21 {
22  static int s_nArgChar = 0;
23  _TCHAR * pcOptChar;
24
25  /* we're done */
26  if(_toptind >= argc) return -1;
27
28  /* last time we reached the end of argv[_toptind] */
29  if(s_nArgChar != 0 && argv[_toptind][s_nArgChar] == 0)
30  {
31   /* scan the next argument */
32   ++ _toptind;
33
34   /* we're done */
35   if(_toptind >= argc) return -1;
36
37   s_nArgChar = 0;
38  }
39
40  /* first time we scan argv[_toptind] */
41  if(s_nArgChar == 0)
42  {
43   /* argument is NULL - we're done */
44   if(argv[_toptind] == NULL)
45    return (int)-1;
46   /* argument is empty - we're done */
47   else if(argv[_toptind][0] == 0)
48    return (int)-1;
49   /* argument begins with '-' */
50   else if(argv[_toptind][0] == _T('-'))
51   {
52    /* argument is "--" */
53    if(argv[_toptind][1] == _T('-'))
54    {
55     /* increment optind */
56     ++ _toptind;
57     s_nArgChar = 0;
58
59     /* we're done */
60     return (int)-1;
61    }
62    /* argument is "-" */
63    else if(argv[_toptind][1] == 0)
64    {
65     /* we're done */
66     return (int)-1;
67    }
68    /* possible option */
69    else
70     ++ s_nArgChar;
71   }
72   /* argument doesn't begin with a dash - we're done */
73   else
74    return (int)-1;
75  }
76
77  /* return the current character */
78  _toptopt = argv[_toptind][s_nArgChar];
79
80  /* advance to the next character */
81  ++ s_nArgChar;
82
83  /* unrecognized option */
84  if(_toptopt == _T(':') || (pcOptChar = _tcschr(optstring, _toptopt)) == NULL)
85  {
86   /* print an error message */
87   if(_topterr && optstring[0] != _T(':'))
88    _ftprintf(stderr, _T("%s: illegal option -- %c\n"), argv[0], _toptopt);;
89
90   /* return an error */
91   return _T('?');
92  }
93
94  /* the option requires an argument */
95  if(pcOptChar[1] == _T(':'))
96  {
97   /* we are at the end of the argument */
98   if(argv[_toptind][s_nArgChar] == 0)
99   {
100    /* the argument of the option is the next argument */
101    ++ _toptind;
102    s_nArgChar = 0;
103
104    /* this is the last argument */
105    if(_toptopt >= argc)
106    {
107     /* print an error message */
108     if(_topterr && optstring[0] != _T(':'))
109     {
110      _ftprintf
111      (
112       stderr,
113       _T("%s: option requires an argument -- %c\n"),
114       argv[0],
115       _toptopt
116      );
117     }
118
119     /* return an error */
120     return ((optstring[0] == _T(':')) ? _T(':') : _T('?'));
121    }
122
123    /* return the argument */
124    _toptarg = argv[_toptind];
125   }
126   /* the rest of the argument is the argument of the option */
127   else
128    _toptarg = argv[_toptind] + s_nArgChar;
129  }
130  
131  /* success */
132  return _toptopt;
133 }
134
135 /* EOF */