2 * Copyright 2006-2007 Adrian Thurston <thurston@complang.org>
5 /* This file is part of Ragel.
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.
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.
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
28 HostType hostTypesC[] =
30 { "char", 0, "char", true, CHAR_MIN, CHAR_MAX, sizeof(char) },
31 { "unsigned", "char", "uchar", false, 0, UCHAR_MAX, sizeof(unsigned char) },
32 { "short", 0, "short", true, SHRT_MIN, SHRT_MAX, sizeof(short) },
33 { "unsigned", "short", "ushort", false, 0, USHRT_MAX, sizeof(unsigned short) },
34 { "int", 0, "int", true, INT_MIN, INT_MAX, sizeof(int) },
35 { "unsigned", "int", "uint", false, 0, UINT_MAX, sizeof(unsigned int) },
36 { "long", 0, "long", true, LONG_MIN, LONG_MAX, sizeof(long) },
37 { "unsigned", "long", "ulong", false, 0, ULONG_MAX, sizeof(unsigned long) }
40 #define S8BIT_MIN -128
46 #define S16BIT_MIN -32768
47 #define S16BIT_MAX 32767
50 #define U16BIT_MAX 65535
52 #define S32BIT_MIN –2147483648l
53 #define S32BIT_MAX 2147483647l
56 #define U32BIT_MAX 4294967295l
58 #define S64BIT_MIN –9223372036854775808ll
59 #define S64BIT_MAX 9223372036854775807ll
62 #define U64BIT_MAX 18446744073709551615ll
64 HostType hostTypesD[] =
66 { "byte", 0, "byte", true, CHAR_MIN, CHAR_MAX, 1 },
67 { "ubyte", 0, "ubyte", false, 0, UCHAR_MAX, 1 },
68 { "char", 0, "char", false, 0, UCHAR_MAX, 1 },
69 { "short", 0, "short", true, SHRT_MIN, SHRT_MAX, 2 },
70 { "ushort", 0, "ushort", false, 0, USHRT_MAX, 2 },
71 { "wchar", 0, "wchar", false, 0, USHRT_MAX, 2 },
72 { "int", 0, "int", true, INT_MIN, INT_MAX, 4 },
73 { "uint", 0, "uint", false, 0, UINT_MAX, 4 },
74 { "dchar", 0, "dchar", false, 0, UINT_MAX, 4 }
77 HostType hostTypesJava[] =
79 { "byte", 0, "byte", true, CHAR_MIN, CHAR_MAX, 1 },
80 { "short", 0, "short", true, SHRT_MIN, SHRT_MAX, 2 },
81 { "char", 0, "char", false, 0, USHRT_MAX, 2 },
82 { "int", 0, "int", true, INT_MIN, INT_MAX, 4 },
85 /* What are the appropriate types for ruby? */
86 HostType hostTypesRuby[] =
88 { "char", 0, "char", true, CHAR_MIN, CHAR_MAX, 1 },
89 { "int", 0, "int", true, INT_MIN, INT_MAX, 4 },
92 HostType hostTypesCSharp[] =
94 { "sbyte", 0, "sbyte", true, CHAR_MIN, CHAR_MAX, 1 },
95 { "byte", 0, "byte", false, 0, UCHAR_MAX, 1 },
96 { "short", 0, "short", true, SHRT_MIN, SHRT_MAX, 2 },
97 { "ushort", 0, "ushort", false, 0, USHRT_MAX, 2 },
98 { "char", 0, "char", false, 0, USHRT_MAX, 2 },
99 { "int", 0, "int", true, INT_MIN, INT_MAX, 4 },
100 { "uint", 0, "uint", false, 0, UINT_MAX, 4 },
101 { "long", 0, "long", true, LONG_MIN, LONG_MAX, 8 },
102 { "ulong", 0, "ulong", false, 0, ULONG_MAX, 8 }
105 HostLang hostLangC = { HostLang::C, hostTypesC, 8, hostTypesC+0, true };
106 HostLang hostLangD = { HostLang::D, hostTypesD, 9, hostTypesD+2, true };
107 HostLang hostLangJava = { HostLang::Java, hostTypesJava, 4, hostTypesJava+2, false };
108 HostLang hostLangRuby = { HostLang::Ruby, hostTypesRuby, 2, hostTypesRuby+0, false };
109 HostLang hostLangCSharp = { HostLang::CSharp, hostTypesCSharp, 9, hostTypesCSharp+4, true };
111 HostLang *hostLang = &hostLangC;
113 HostType *findAlphType( const char *s1 )
115 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
116 if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 &&
117 hostLang->hostTypes[i].data2 == 0 )
119 return hostLang->hostTypes + i;
126 HostType *findAlphType( const char *s1, const char *s2 )
128 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
129 if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 &&
130 hostLang->hostTypes[i].data2 != 0 &&
131 strcmp( s2, hostLang->hostTypes[i].data2 ) == 0 )
133 return hostLang->hostTypes + i;
140 HostType *findAlphTypeInternal( const char *s1 )
142 for ( int i = 0; i < hostLang->numHostTypes; i++ ) {
143 if ( strcmp( s1, hostLang->hostTypes[i].internalName ) == 0 )
144 return hostLang->hostTypes + i;
150 /* Construct a new parameter checker with for paramSpec. */
151 ParamCheck::ParamCheck( const char *paramSpec, int argc, const char **argv )
157 paramSpec(paramSpec),
163 /* Check a single option. Returns the index of the next parameter. Sets p to
164 * the arg character if valid, 0 otherwise. Sets parg to the parameter arg if
165 * there is one, NULL otherwise. */
166 bool ParamCheck::check()
170 if ( iCurArg >= argc ) { /* Off the end of the arg list. */
175 if ( argOffset != 0 && *argOffset == 0 ) {
176 /* We are at the end of an arg string. */
178 if ( iCurArg >= argc ) {
185 if ( argOffset == 0 ) {
186 /* Set the current arg. */
187 curArg = argv[iCurArg];
189 /* We are at the beginning of an arg string. */
190 if ( argv[iCurArg] == 0 || /* Argv[iCurArg] is null. */
191 argv[iCurArg][0] != '-' || /* Not a param. */
192 argv[iCurArg][1] == 0 ) { /* Only a dash. */
200 argOffset = argv[iCurArg] + 1;
203 /* Get the arg char. */
204 char argChar = *argOffset;
206 /* Loop over all the parms and look for a match. */
207 const char *pSpec = paramSpec;
208 while ( *pSpec != 0 ) {
209 char pSpecChar = *pSpec;
211 /* If there is a ':' following the char then
212 * it requires a parm. If a parm is required
213 * then move ahead two in the parmspec. Otherwise
214 * move ahead one in the parm spec. */
215 if ( pSpec[1] == ':' ) {
216 requiresParam = true;
220 requiresParam = false;
224 /* Do we have a match. */
225 if ( argChar == pSpecChar ) {
226 if ( requiresParam ) {
227 if ( argOffset[1] == 0 ) {
228 /* The param must follow. */
229 if ( iCurArg + 1 == argc ) {
230 /* We are the last arg so there
231 * cannot be a parameter to it. */
240 /* the parameter to the arg is the next arg. */
241 parameter = pSpecChar;
242 paramArg = argv[iCurArg + 1];
250 /* The param for the arg is built in. */
251 parameter = pSpecChar;
252 paramArg = argOffset + 1;
260 /* Good, we matched the parm and no
261 * arg is required. */
262 parameter = pSpecChar;
271 /* We did not find a match. Bad Argument. */
279 /* Counts newlines before sending sync. */
280 int output_filter::sync( )
283 return std::filebuf::sync();
286 /* Counts newlines before sending data out to file. */
287 std::streamsize output_filter::xsputn( const char *s, std::streamsize n )
289 for ( int i = 0; i < n; i++ ) {
293 return std::filebuf::xsputn( s, n );
296 /* Scans a string looking for the file extension. If there is a file
297 * extension then pointer returned points to inside the string
298 * passed in. Otherwise returns null. */
299 const char *findFileExtension( const char *stemFile )
301 const char *ppos = stemFile + strlen(stemFile) - 1;
303 /* Scan backwards from the end looking for the first dot.
304 * If we encounter a '/' before the first dot, then stop the scan. */
306 /* If we found a dot or got to the beginning of the string then
308 if ( ppos == stemFile || *ppos == '.' )
311 /* If we hit a / then there is no extension. Done. */
312 if ( *ppos == '/' ) {
319 /* If we got to the front of the string then bail we
320 * did not find an extension */
321 if ( ppos == stemFile )
327 /* Make a file name from a stem. Removes the old filename suffix and
328 * replaces it with a new one. Returns a newed up string. */
329 const char *fileNameFromStem( const char *stemFile, const char *suffix )
331 long len = strlen( stemFile );
334 /* Get the extension. */
335 const char *ppos = findFileExtension( stemFile );
337 /* If an extension was found, then shorten what we think the len is. */
339 len = ppos - stemFile;
341 /* Make the return string from the stem and the suffix. */
342 char *retVal = new char[ len + strlen( suffix ) + 1 ];
343 strncpy( retVal, stemFile, len );
344 strcpy( retVal + len, suffix );
351 void operator<<( std::ostream &out, exit_object & )