db2323536ad0cadffc32dd5570cf67921b97801d
[external/ragel.git] / common / common.cpp
1 /*
2  *  Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
3  */
4
5 /*  This file is part of Ragel.
6  *
7  *  Ragel is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  * 
12  *  Ragel is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  * 
17  *  You should have received a copy of the GNU General Public License
18  *  along with Ragel; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
20  */
21
22 #include "common.h"
23
24 HostType hostTypesC[] =
25 {
26         { "char",     0,       true,   CHAR_MIN,  CHAR_MAX,   sizeof(char) },
27         { "unsigned", "char",  false,  0,         UCHAR_MAX,  sizeof(unsigned char) },
28         { "short",    0,       true,   SHRT_MIN,  SHRT_MAX,   sizeof(short) },
29         { "unsigned", "short", false,  0,         USHRT_MAX,  sizeof(unsigned short) },
30         { "int",      0,       true,   INT_MIN,   INT_MAX,    sizeof(int) },
31         { "unsigned", "int",   false,  0,         UINT_MAX,   sizeof(unsigned int) },
32         { "long",     0,       true,   LONG_MIN,  LONG_MAX,   sizeof(long) },
33         { "unsigned", "long",  false,  0,         ULONG_MAX,  sizeof(unsigned long) }
34 };
35
36 HostType hostTypesD[] =
37 {
38         { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
39         { "ubyte",    0,  false,  0,         UCHAR_MAX,   1 },
40         { "char",     0,  false,  0,         UCHAR_MAX,   1 },
41         { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
42         { "ushort",   0,  false,  0,         USHRT_MAX,   2 },
43         { "wchar",    0,  false,  0,         USHRT_MAX,   2 },
44         { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
45         { "uint",     0,  false,  0,         UINT_MAX,    4 },
46         { "dchar",    0,  false,  0,         UINT_MAX,    4 }
47 };
48
49 HostType hostTypesJava[] = 
50 {
51         { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
52         { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
53         { "char",     0,  false,  0,         USHRT_MAX,   2 },
54         { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
55 };
56
57 HostLang hostLangC =    { hostTypesC,    8, hostTypesC+0,    true };
58 HostLang hostLangD =    { hostTypesD,    9, hostTypesD+2,    true };
59 HostLang hostLangJava = { hostTypesJava, 4, hostTypesJava+2, false };
60
61 HostLang *hostLang = &hostLangC;
62 HostLangType hostLangType = CCode;
63
64 /* Construct a new parameter checker with for paramSpec. */
65 ParamCheck::ParamCheck(char *paramSpec, int argc, char **argv)
66 :
67         state(noparam),
68         argOffset(0),
69         curArg(0),
70         iCurArg(1),
71         paramSpec(paramSpec), 
72         argc(argc), 
73         argv(argv)
74 {
75 }
76
77 /* Check a single option. Returns the index of the next parameter.  Sets p to
78  * the arg character if valid, 0 otherwise.  Sets parg to the parameter arg if
79  * there is one, NULL otherwise. */
80 bool ParamCheck::check()
81 {
82         bool requiresParam;
83
84         if ( iCurArg >= argc ) {            /* Off the end of the arg list. */
85                 state = noparam;
86                 return false;
87         }
88
89         if ( argOffset != 0 && *argOffset == 0 ) {
90                 /* We are at the end of an arg string. */
91                 iCurArg += 1;
92                 if ( iCurArg >= argc ) {
93                         state = noparam;
94                         return false;
95                 }
96                 argOffset = 0;
97         }
98
99         if ( argOffset == 0 ) {
100                 /* Set the current arg. */
101                 curArg = argv[iCurArg];
102
103                 /* We are at the beginning of an arg string. */
104                 if ( argv[iCurArg] == 0 ||        /* Argv[iCurArg] is null. */
105                          argv[iCurArg][0] != '-' ||   /* Not a param. */
106                          argv[iCurArg][1] == 0 ) {    /* Only a dash. */
107                         parameter = 0;
108                         parameterArg = 0;
109
110                         iCurArg += 1;
111                         state = noparam;
112                         return true;
113                 }
114                 argOffset = argv[iCurArg] + 1;
115         }
116
117         /* Get the arg char. */
118         char argChar = *argOffset;
119         
120         /* Loop over all the parms and look for a match. */
121         char *pSpec = paramSpec;
122         while ( *pSpec != 0 ) {
123                 char pSpecChar = *pSpec;
124
125                 /* If there is a ':' following the char then
126                  * it requires a parm.  If a parm is required
127                  * then move ahead two in the parmspec. Otherwise
128                  * move ahead one in the parm spec. */
129                 if ( pSpec[1] == ':' ) {
130                         requiresParam = true;
131                         pSpec += 2;
132                 }
133                 else {
134                         requiresParam = false;
135                         pSpec += 1;
136                 }
137
138                 /* Do we have a match. */
139                 if ( argChar == pSpecChar ) {
140                         if ( requiresParam ) {
141                                 if ( argOffset[1] == 0 ) {
142                                         /* The param must follow. */
143                                         if ( iCurArg + 1 == argc ) {
144                                                 /* We are the last arg so there
145                                                  * cannot be a parameter to it. */
146                                                 parameter = argChar;
147                                                 parameterArg = 0;
148                                                 iCurArg += 1;
149                                                 argOffset = 0;
150                                                 state = invalid;
151                                                 return true;
152                                         }
153                                         else {
154                                                 /* the parameter to the arg is the next arg. */
155                                                 parameter = pSpecChar;
156                                                 parameterArg = argv[iCurArg + 1];
157                                                 iCurArg += 2;
158                                                 argOffset = 0;
159                                                 state = match;
160                                                 return true;
161                                         }
162                                 }
163                                 else {
164                                         /* The param for the arg is built in. */
165                                         parameter = pSpecChar;
166                                         parameterArg = argOffset + 1;
167                                         iCurArg += 1;
168                                         argOffset = 0;
169                                         state = match;
170                                         return true;
171                                 }
172                         }
173                         else {
174                                 /* Good, we matched the parm and no
175                                  * arg is required. */
176                                 parameter = pSpecChar;
177                                 parameterArg = 0;
178                                 argOffset += 1;
179                                 state = match;
180                                 return true;
181                         }
182                 }
183         }
184
185         /* We did not find a match. Bad Argument. */
186         parameter = argChar;
187         parameterArg = 0;
188         argOffset += 1;
189         state = invalid;
190         return true;
191 }
192
193