1/** 2 * Copyright (C) 1999-2007 Free Software Foundation, Inc. 3 * 4 * This file is part of GNU gengetopt 5 * 6 * GNU gengetopt is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3, or (at your option) 9 * any later version. 10 * 11 * GNU gengetopt is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 14 * Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with gengetopt; see the file COPYING. If not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21 22%{ 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include <string.h> 28#include <sstream> 29 30#include "argsdef.h" 31#include "parser.h" 32extern int gengetopt_count_line; 33 34static void update_count_line (char *str); 35static void updateTokenInfo (int pos); 36 37// the buffer for strings (possibly spanning more lines) 38static std::ostringstream buff; 39 40static void buffer(const char *s); 41static char *flush_buffer(); 42 43#define LINEBUF_LEN 1024 44 45#define PUSH(s) yy_push_state(s); 46#define POP() yy_pop_state(); 47 48int tokenpos = 0; 49char linebuf[LINEBUF_LEN] ; /* current line */ 50 51//#define DEBUG_SCANNER 52#ifdef DEBUG_SCANNER 53#include <iostream> // for debug 54#define DEB(s) std::cerr << s << std::endl; 55#define DEB2(s,s2) std::cerr << s << ": " << s2 << std::endl; 56#else 57#define DEB(s) 58#define DEB2(s,s2) 59#endif 60 61%} 62 63%option stack nomain yylineno noyywrap nounput 64 65ws [ ]+ 66tabs [\t]+ 67 68%s SIZE_STATE STRING_STATE 69 70%% 71 72 73<INITIAL>string updateTokenInfo (-1); yylval.argtype = ARG_STRING; return TOK_ARGTYPE; 74<INITIAL>int updateTokenInfo (-1); yylval.argtype = ARG_INT; return TOK_ARGTYPE; 75<INITIAL>short updateTokenInfo (-1); yylval.argtype = ARG_SHORT; return TOK_ARGTYPE; 76<INITIAL>long updateTokenInfo (-1); yylval.argtype = ARG_LONG; return TOK_ARGTYPE; 77<INITIAL>float updateTokenInfo (-1); yylval.argtype = ARG_FLOAT; return TOK_ARGTYPE; 78<INITIAL>double updateTokenInfo (-1); yylval.argtype = ARG_DOUBLE; return TOK_ARGTYPE; 79<INITIAL>longdouble updateTokenInfo (-1); yylval.argtype = ARG_LONGDOUBLE; return TOK_ARGTYPE; 80<INITIAL>longlong updateTokenInfo (-1); yylval.argtype = ARG_LONGLONG; return TOK_ARGTYPE; 81<INITIAL>enum updateTokenInfo (-1); yylval.argtype = ARG_ENUM; return TOK_ARGTYPE; 82 83<INITIAL>package updateTokenInfo (-1); return TOK_PACKAGE; 84<INITIAL>version updateTokenInfo (-1); return TOK_VERSION; 85<INITIAL>groupoption updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_GROUPOPTION; 86<INITIAL>modeoption updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_MODEOPTION; 87<INITIAL>yes|required updateTokenInfo (-1); return TOK_YES; 88<INITIAL>no|optional updateTokenInfo (-1); return TOK_NO; 89<INITIAL>option updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_OPTION; 90<INITIAL>flag updateTokenInfo (-1); return TOK_FLAG; 91<INITIAL>on updateTokenInfo (-1); return TOK_ON; 92<INITIAL>off updateTokenInfo (-1); return TOK_OFF; 93<INITIAL>purpose updateTokenInfo (-1); return TOK_PURPOSE; 94<INITIAL>description updateTokenInfo (-1); return TOK_DESCRIPTION; 95<INITIAL>usage updateTokenInfo (-1); return TOK_USAGE; 96<INITIAL>default updateTokenInfo (-1); return TOK_DEFAULT; 97<INITIAL>typestr updateTokenInfo (-1); return TOK_TYPESTR; 98<INITIAL>group updateTokenInfo (-1); return TOK_GROUP; 99<INITIAL>groupdesc updateTokenInfo (-1); return TOK_GROUPDESC; 100<INITIAL>defgroup updateTokenInfo (-1); return TOK_DEFGROUP; 101<INITIAL>mode updateTokenInfo (-1); return TOK_MODE; 102<INITIAL>modedesc updateTokenInfo (-1); return TOK_MODEDESC; 103<INITIAL>defmode updateTokenInfo (-1); return TOK_DEFMODE; 104<INITIAL>multiple updateTokenInfo (-1); return TOK_MULTIPLE; 105<INITIAL>argoptional updateTokenInfo (-1); return TOK_ARGOPTIONAL; 106<INITIAL>sectiondesc updateTokenInfo (-1); return TOK_SECTIONDESC; 107<INITIAL>section updateTokenInfo (-1); return TOK_SECTION; 108<INITIAL>values updateTokenInfo (-1); return TOK_VALUES; 109<INITIAL>hidden updateTokenInfo (-1); return TOK_HIDDEN; 110<INITIAL>dependon updateTokenInfo (-1); return TOK_DEPENDON; 111<INITIAL>details updateTokenInfo (-1); return TOK_DETAILS; 112<INITIAL>text updateTokenInfo (-1); return TOK_TEXT; 113<INITIAL>versiontext updateTokenInfo (-1); return TOK_VERSIONTEXT; 114<INITIAL>args updateTokenInfo (-1); return TOK_ARGS; 115 116<INITIAL>"=" { updateTokenInfo (-1); return '='; } 117<INITIAL>"," { updateTokenInfo (-1); return ','; } 118 119<INITIAL>"(" { PUSH(SIZE_STATE); updateTokenInfo (-1); return '('; } 120<SIZE_STATE>"-" { updateTokenInfo (-1); return '-'; } 121<SIZE_STATE>[[:digit:]]+ { updateTokenInfo (-1); yylval.str = strdup(yytext); return TOK_SIZE; } 122<SIZE_STATE>")" { POP(); updateTokenInfo (-1); return ')'; } 123 124<INITIAL>[[:alnum:]-]|\? updateTokenInfo (-1); yylval.chr = yytext[0]; return TOK_CHAR; 125 126<INITIAL>\" { updateTokenInfo (-1); DEB("start string"); PUSH(STRING_STATE) ; } 127<STRING_STATE>\\\\n { updateTokenInfo (2); buffer("\\\\n"); } 128<STRING_STATE>\\n { updateTokenInfo (1); buffer("\n"); } 129<STRING_STATE>\n+ { update_count_line (yytext); buffer( yytext ) ; } 130<STRING_STATE>\\{ws}*\n { update_count_line (yytext); /* a line break */ } 131<STRING_STATE>\\\" { updateTokenInfo (-1); buffer(yytext); } 132<STRING_STATE>\" { updateTokenInfo (-1); DEB("end string"); POP() ; yylval.str = flush_buffer(); return TOK_STRING; } 133<STRING_STATE>[^\n] { updateTokenInfo (-1); buffer( yytext ) ; } 134 135<INITIAL>{ws} updateTokenInfo (-1); 136<INITIAL>{tabs} updateTokenInfo (8*yyleng); 137 138<INITIAL,SIZE_STATE>#[^\n]* /* comments begin with # in any place (but strings) */ 139<INITIAL>\n.* update_count_line (0); yyless(1) ; /* give back all but the \n to rescan */ 140 141\r {} 142 143. { 144 return 1000; /* little hack to produce a parse error too. */ 145} 146 147%% 148 149#pragma GCC diagnostic push 150#pragma GCC diagnostic ignored "-Wunused-function" 151static void suppress_unused_function_warning_for_yy_top_state(void) 152{ 153 (void)yy_top_state; 154} 155#pragma GCC diagnostic pop 156 157/* 158 Otherwise '\n' within a TOK_MLSTRING would not be counted 159*/ 160void 161update_count_line (char *str) 162{ 163 if (str) 164 { 165 char *p; 166 for (p = str; *p; ++p) 167 if (*p == '\n') { 168 ++gengetopt_count_line; 169 tokenpos = 0 ; /* reset token position */ 170 strncpy (linebuf, ( (p+1) ? p+1 : ""), LINEBUF_LEN - 1); 171 } 172 } 173 else 174 { 175 ++gengetopt_count_line; 176 tokenpos = 0 ; /* reset token position */ 177 strncpy (linebuf, yytext+1, LINEBUF_LEN - 1); /* save the next line */ 178 } 179} 180 181void 182updateTokenInfo( int pos ) 183{ 184 if ( pos >= 0 ) 185 tokenpos += pos ; 186 else 187 tokenpos += yyleng ; 188} 189 190void buffer(const char *s) 191{ 192 buff << s; 193} 194 195char *flush_buffer() 196{ 197 char *ret = strdup(buff.str().c_str()); 198 buff.str(""); 199 return ret; 200} 201