Enabled rlgen-ruby in the top-level makefile. Merged the remaining parts of the
[external/ragel.git] / common / common.cpp
1 /*
2  *  Copyright 2006-2007 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 "pcheck.h"
23 #include "common.h"
24
25 HostType hostTypesC[] =
26 {
27         { "char",     0,       true,   CHAR_MIN,  CHAR_MAX,   sizeof(char) },
28         { "unsigned", "char",  false,  0,         UCHAR_MAX,  sizeof(unsigned char) },
29         { "short",    0,       true,   SHRT_MIN,  SHRT_MAX,   sizeof(short) },
30         { "unsigned", "short", false,  0,         USHRT_MAX,  sizeof(unsigned short) },
31         { "int",      0,       true,   INT_MIN,   INT_MAX,    sizeof(int) },
32         { "unsigned", "int",   false,  0,         UINT_MAX,   sizeof(unsigned int) },
33         { "long",     0,       true,   LONG_MIN,  LONG_MAX,   sizeof(long) },
34         { "unsigned", "long",  false,  0,         ULONG_MAX,  sizeof(unsigned long) }
35 };
36
37 HostType hostTypesD[] =
38 {
39         { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
40         { "ubyte",    0,  false,  0,         UCHAR_MAX,   1 },
41         { "char",     0,  false,  0,         UCHAR_MAX,   1 },
42         { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
43         { "ushort",   0,  false,  0,         USHRT_MAX,   2 },
44         { "wchar",    0,  false,  0,         USHRT_MAX,   2 },
45         { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
46         { "uint",     0,  false,  0,         UINT_MAX,    4 },
47         { "dchar",    0,  false,  0,         UINT_MAX,    4 }
48 };
49
50 HostType hostTypesJava[] = 
51 {
52         { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
53         { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
54         { "char",     0,  false,  0,         USHRT_MAX,   2 },
55         { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
56 };
57
58 HostType hostTypesRuby[] = 
59 {
60         { "byte",     0,  true,   CHAR_MIN,  CHAR_MAX,    1 },
61         { "short",    0,  true,   SHRT_MIN,  SHRT_MAX,    2 },
62         { "char",     0,  false,  0,         USHRT_MAX,   2 },
63         { "int",      0,  true,   INT_MIN,   INT_MAX,     4 },
64 };
65
66 HostLang hostLangC =    { hostTypesC,    8, hostTypesC+0,    true };
67 HostLang hostLangD =    { hostTypesD,    9, hostTypesD+2,    true };
68 HostLang hostLangJava = { hostTypesJava, 4, hostTypesJava+2, false };
69 HostLang hostLangRuby = { hostTypesRuby, 4, hostTypesRuby+2, false };
70
71 HostLang *hostLang = &hostLangC;
72 HostLangType hostLangType = CCode;
73
74 /* Construct a new parameter checker with for paramSpec. */
75 ParamCheck::ParamCheck(char *paramSpec, int argc, char **argv)
76 :
77         state(noparam),
78         argOffset(0),
79         curArg(0),
80         iCurArg(1),
81         paramSpec(paramSpec), 
82         argc(argc), 
83         argv(argv)
84 {
85 }
86
87 /* Check a single option. Returns the index of the next parameter.  Sets p to
88  * the arg character if valid, 0 otherwise.  Sets parg to the parameter arg if
89  * there is one, NULL otherwise. */
90 bool ParamCheck::check()
91 {
92         bool requiresParam;
93
94         if ( iCurArg >= argc ) {            /* Off the end of the arg list. */
95                 state = noparam;
96                 return false;
97         }
98
99         if ( argOffset != 0 && *argOffset == 0 ) {
100                 /* We are at the end of an arg string. */
101                 iCurArg += 1;
102                 if ( iCurArg >= argc ) {
103                         state = noparam;
104                         return false;
105                 }
106                 argOffset = 0;
107         }
108
109         if ( argOffset == 0 ) {
110                 /* Set the current arg. */
111                 curArg = argv[iCurArg];
112
113                 /* We are at the beginning of an arg string. */
114                 if ( argv[iCurArg] == 0 ||        /* Argv[iCurArg] is null. */
115                          argv[iCurArg][0] != '-' ||   /* Not a param. */
116                          argv[iCurArg][1] == 0 ) {    /* Only a dash. */
117                         parameter = 0;
118                         parameterArg = 0;
119
120                         iCurArg += 1;
121                         state = noparam;
122                         return true;
123                 }
124                 argOffset = argv[iCurArg] + 1;
125         }
126
127         /* Get the arg char. */
128         char argChar = *argOffset;
129         
130         /* Loop over all the parms and look for a match. */
131         char *pSpec = paramSpec;
132         while ( *pSpec != 0 ) {
133                 char pSpecChar = *pSpec;
134
135                 /* If there is a ':' following the char then
136                  * it requires a parm.  If a parm is required
137                  * then move ahead two in the parmspec. Otherwise
138                  * move ahead one in the parm spec. */
139                 if ( pSpec[1] == ':' ) {
140                         requiresParam = true;
141                         pSpec += 2;
142                 }
143                 else {
144                         requiresParam = false;
145                         pSpec += 1;
146                 }
147
148                 /* Do we have a match. */
149                 if ( argChar == pSpecChar ) {
150                         if ( requiresParam ) {
151                                 if ( argOffset[1] == 0 ) {
152                                         /* The param must follow. */
153                                         if ( iCurArg + 1 == argc ) {
154                                                 /* We are the last arg so there
155                                                  * cannot be a parameter to it. */
156                                                 parameter = argChar;
157                                                 parameterArg = 0;
158                                                 iCurArg += 1;
159                                                 argOffset = 0;
160                                                 state = invalid;
161                                                 return true;
162                                         }
163                                         else {
164                                                 /* the parameter to the arg is the next arg. */
165                                                 parameter = pSpecChar;
166                                                 parameterArg = argv[iCurArg + 1];
167                                                 iCurArg += 2;
168                                                 argOffset = 0;
169                                                 state = match;
170                                                 return true;
171                                         }
172                                 }
173                                 else {
174                                         /* The param for the arg is built in. */
175                                         parameter = pSpecChar;
176                                         parameterArg = argOffset + 1;
177                                         iCurArg += 1;
178                                         argOffset = 0;
179                                         state = match;
180                                         return true;
181                                 }
182                         }
183                         else {
184                                 /* Good, we matched the parm and no
185                                  * arg is required. */
186                                 parameter = pSpecChar;
187                                 parameterArg = 0;
188                                 argOffset += 1;
189                                 state = match;
190                                 return true;
191                         }
192                 }
193         }
194
195         /* We did not find a match. Bad Argument. */
196         parameter = argChar;
197         parameterArg = 0;
198         argOffset += 1;
199         state = invalid;
200         return true;
201 }
202
203