1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Portions Copyright 2008 Denis Cheng
  27  */
  28 
  29 %{
  30 
  31 #include <stdlib.h>
  32 #include <sys/types.h>
  33 #include <assert.h>
  34 #include <string.h>
  35 #include <errno.h>
  36 #ifdef HAVE_STDINT_H
  37 #include <stdint.h>
  38 #endif
  39 
  40 #include "filebench.h"
  41 #include "parsertypes.h"
  42 #include "utils.h"
  43 #include "parser_gram.h"
  44 
  45 int lex_lineno = 1;             /* line-number for error reporting */
  46 extern void yyerror(char *s);
  47 extern int dofile;                      /* are we processing a file? */
  48 %}
  49 
  50 %s WHITESTRINGSTATE
  51 
  52 %a 50000
  53 %p 50000
  54 %o 50000
  55 %n 5000
  56 
  57 %%
  58 
  59 \n                      { lex_lineno++; }
  60 
  61 <INITIAL>[ \t]+                   ;
  62 
  63 <INITIAL>#.*                      ;
  64 
  65 create                  { return FSC_CREATE; }
  66 define                  { return FSC_DEFINE; }
  67 debug                   { return FSC_DEBUG; }
  68 domultisync             { return FSC_DOMULTISYNC; }
  69 echo                    { return FSC_ECHO; }
  70 enable                  { return FSC_ENABLE; }
  71 eventgen                { return FSC_EVENTGEN; }
  72 exit                    { return FSC_QUIT; }
  73 foreach                 { return FSC_FOREACH; }
  74 flowop                  { return FSC_FLOWOP; }
  75 fscheck                 { return FSC_FSCHECK; }
  76 fsflush                 { return FSC_FSFLUSH; }
  77 help                    { return FSC_HELP; }
  78 list                    { return FSC_LIST; }
  79 load                    { return FSC_LOAD; }
  80 log                     { return FSC_LOG; }
  81 nousestats              { return FSC_NOUSESTATS; }
  82 run                     { return FSC_RUN; }
  83 set                     { return FSC_SET; }
  84 shutdown                { return FSC_SHUTDOWN; }
  85 sleep                   { return FSC_SLEEP; }
  86 stats                   { return FSC_STATS; }
  87 system                  { return FSC_SYSTEM; }
  88 usage                   { return FSC_USAGE; }
  89 vars                    { return FSC_VARS; }
  90 version                 { return FSC_VERSION; }
  91 warmup                  { return FSC_WARMUP; }
  92 quit                    { return FSC_QUIT; }
  93 
  94 file[s]*                { return FSE_FILE; }
  95 fileset[s]*             { return FSE_FILESET; }
  96 directory               { return FSE_DIRECTORY; }
  97 command                 { return FSE_COMMAND; }
  98 process[es]*            { return FSE_PROC; }
  99 thread                  { return FSE_THREAD; }
 100 randvar                 { return FSE_RAND; }
 101 clear                   { return FSE_CLEAR; }
 102 snap                    { return FSE_SNAP; }
 103 dump                    { return FSE_DUMP; }
 104 xmldump                 { return FSE_XMLDUMP; }
 105 multidump               { return FSE_MULTIDUMP; }
 106 all                     { return FSE_ALL; }
 107 mode                    { return FSE_MODE; }
 108 multi                   { return FSE_MULTI; }
 109 
 110 alldone                 { return FSA_ALLDONE; }
 111 blocking                { return FSA_BLOCKING; }
 112 cached                  { return FSA_CACHED; }
 113 client                  { return FSA_CLIENT; }
 114 dirwidth                { return FSA_DIRWIDTH; }
 115 dirdepthrv              { return FSA_DIRDEPTHRV; }
 116 directio                { return FSA_DIRECTIO; }
 117 dirgamma                { return FSA_DIRGAMMA; }
 118 dsync                   { return FSA_DSYNC;  }
 119 entries                 { return FSA_ENTRIES;}
 120 fd                      { return FSA_FD; }
 121 filename                { return FSA_FILE; }
 122 filesetname             { return FSA_FILE; }
 123 filesize                { return FSA_SIZE; }
 124 filesizegamma           { return FSA_FILESIZEGAMMA; }
 125 firstdone               { return FSA_FIRSTDONE; }
 126 fstype                  { return FSA_FSTYPE; }
 127 gamma                   { return FSA_RANDGAMMA; }
 128 highwater               { return FSA_HIGHWATER; }
 129 indexed                 { return FSA_INDEXED; }
 130 instances               { return FSA_INSTANCES;}                  
 131 iosize                  { return FSA_IOSIZE; }
 132 iters                   { return FSA_ITERS;}
 133 leafdirs                { return FSA_LEAFDIRS;}
 134 master                  { return FSA_MASTER; }
 135 mean                    { return FSA_RANDMEAN; }
 136 memsize                 { return FSA_MEMSIZE; }
 137 min                     { return FSA_RANDMIN; }
 138 name                    { return FSA_NAME;}
 139 namelength              { return FSA_NAMELENGTH; }
 140 nice                    { return FSA_NICE;}
 141 opennext                { return FSA_ROTATEFD; }
 142 paralloc                { return FSA_PARALLOC; }
 143 path                    { return FSA_PATH; }
 144 prealloc                { return FSA_PREALLOC; }
 145 procname                { return FSA_PROCESS; }
 146 random                  { return FSA_RANDOM;}
 147 randsrc                 { return FSA_RANDSRC; }
 148 randtable               { return FSA_RANDTABLE; }
 149 rate                    { return FSA_RATE;}
 150 readonly                { return FSA_READONLY; }
 151 reuse                   { return FSA_REUSE; }
 152 round                   { return FSA_RANDROUND; }
 153 seed                    { return FSA_RANDSEED; }
 154 size                    { return FSA_SIZE; }
 155 srcfd                   { return FSA_SRCFD; }
 156 target                  { return FSA_TARGET;}
 157 timeout                 { return FSA_TIMEOUT; }
 158 trusttree               { return FSA_TRUSTTREE; }
 159 type                    { return FSA_TYPE; }
 160 useism                  { return FSA_USEISM;}
 161 value                   { return FSA_VALUE;}
 162 workingset              { return FSA_WSS; }
 163 
 164 uniform                 { return FSV_RANDUNI; }
 165 tabular                 { return FSV_RANDTAB; }
 166 "."type                 { return FSS_TYPE; }
 167 "."seed                 { return FSS_SEED; }
 168 "."gamma                { return FSS_GAMMA; }
 169 "."mean                 { return FSS_MEAN; }
 170 "."min                  { return FSS_MIN; }
 171 "."round                { return FSS_ROUND; }
 172 "."randsrc              { return FSS_SRC; }
 173 urandom                 { return FSV_URAND; }
 174 rand48                  { return FSV_RAND48; }
 175 
 176 
 177 <INITIAL>\"                       { 
 178                                 BEGIN WHITESTRINGSTATE;
 179                                 return FSK_QUOTE;
 180                         }
 181 
 182 <WHITESTRINGSTATE>\"    {
 183                                 BEGIN INITIAL;
 184                                 return FSK_QUOTE;
 185                         }
 186 
 187 <WHITESTRINGSTATE>[^$^\\^"][^$^"]*[^\\^$^"] {
 188                                 if ((yylval.sval = strdup(yytext)) == NULL) {
 189                                         yyerror("Out of memory");
 190                                         filebench_shutdown(E_ERROR);
 191                                 }
 192                                 return FSV_WHITESTRING;
 193                 }
 194 
 195 <WHITESTRINGSTATE>\\n     {
 196                                 yylval.sval = "\n";
 197                                 return FSV_WHITESTRING;
 198                 }
 199 
 200 
 201 <WHITESTRINGSTATE>\\$[^"^$^\\]+   {
 202                                 if ((yylval.sval = strdup(yytext + 1)) == NULL) {
 203                                         yyerror("Out of memory");
 204                                         filebench_shutdown(E_ERROR);
 205                                 }
 206                                 return FSV_WHITESTRING;
 207                 }
 208 
 209 <WHITESTRINGSTATE>[^$^\\^"] {
 210                                 if ((yylval.sval = strdup(yytext)) == NULL) {
 211                                         yyerror("Out of memory");
 212                                         filebench_shutdown(E_ERROR);
 213                                 }
 214                                 return FSV_WHITESTRING;
 215                 }
 216 
 217 
 218 <INITIAL>\{                       { return FSK_OPENLST; }
 219 <INITIAL>\}                       { return FSK_CLOSELST; }
 220 <INITIAL>=                        { return FSK_ASSIGN; }
 221 <INITIAL>\,                       { return FSK_SEPLST; }
 222 <INITIAL>in                     { return FSK_IN; }
 223 <INITIAL>\+                     { return FSK_PLUS; }
 224 <INITIAL>\-                     { return FSK_MINUS; }
 225 <INITIAL>\*                     { return FSK_MULTIPLY; }
 226 <INITIAL>\/                     { return FSK_DIVIDE; }
 227 
 228 <INITIAL>[0-9]+   {
 229                                 errno = 0;
 230                                 yylval.ival = strtoll(yytext, NULL, 10);
 231                                 if (errno == EINVAL || errno == ERANGE) {
 232                                         (void) filebench_log(LOG_ERROR, 
 233                                                 "Invalid I value '%s':%s", yytext,
 234                                                 strerror(errno));
 235                                 }
 236                                 return FSV_VAL_INT;
 237 }
 238 
 239 <INITIAL>[0-9]+k  {
 240                                 errno = 0;
 241                                 yylval.ival = KB * strtoll(yytext, NULL, 10);
 242                                 if (errno == EINVAL || errno == ERANGE) {
 243                                         (void) filebench_log(LOG_ERROR, 
 244                                                 "Invalid I value '%s':%s", yytext,
 245                                                 strerror(errno));
 246                                 }
 247                                 return FSV_VAL_INT;
 248 }
 249 
 250 <INITIAL>[0-9]+m  {
 251                                 errno = 0;
 252                                 yylval.ival = MB * strtoll(yytext, NULL, 10);
 253                                 if (errno == EINVAL || errno == ERANGE) {
 254                                         (void) filebench_log(LOG_ERROR, 
 255                                                 "Invalid I value '%s':%s", yytext,
 256                                                 strerror(errno));
 257                                 }
 258                                 return FSV_VAL_INT;
 259 }
 260 
 261 <INITIAL>[0-9]+g  {
 262                                 errno = 0;
 263                                 yylval.ival = GB * strtoll(yytext, NULL, 10);
 264                                 if (errno == EINVAL || errno == ERANGE) {
 265                                         (void) filebench_log(LOG_ERROR, 
 266                                                 "Invalid I value '%s':%s", yytext,
 267                                                 strerror(errno));
 268                                 }
 269                                 return FSV_VAL_INT;
 270 }
 271 
 272 <INITIAL>true     {
 273                                 yylval.bval = TRUE;
 274                                 return FSV_VAL_BOOLEAN;
 275                 }
 276 
 277 <INITIAL>false    {
 278                                 yylval.bval = FALSE;
 279                                 return FSV_VAL_BOOLEAN;
 280                 }
 281 
 282 $[({A-Za-z][A-Za-z0-9_]*[A-Za-z0-9][)}]*        {
 283                                 if ((yylval.sval = strdup(yytext)) == NULL) {
 284                                         yyerror("Out of memory");
 285                                         filebench_shutdown(E_ERROR);
 286                                 }
 287 
 288                                 return FSV_VARIABLE;
 289                         }
 290 
 291 
 292 $[({A-Za-z][A-Za-z0-9_]*"."[A-Za-z0-9][)}]*     {
 293                                 int backtrack;
 294 
 295                                 if ((backtrack =
 296                                     var_is_set4_randvar(yytext)) != 0)
 297                                         yyless(yyleng - backtrack);
 298 
 299                                 if ((yylval.sval = strdup(yytext)) == NULL) {
 300                                         yyerror("Out of memory");
 301                                         filebench_shutdown(E_ERROR);
 302                                 }
 303 
 304                                 return FSV_RANDVAR;
 305                         }
 306 
 307 
 308 <INITIAL>[/A-Za-z-][/A-Za-z0-9._-]*       {
 309                                 if ((yylval.sval = strdup(yytext)) == NULL) {
 310                                         yyerror("Out of memory");
 311                                         filebench_shutdown(E_ERROR);
 312                                 }
 313                                 return FSV_STRING;
 314                         }
 315 
 316 
 317 .                       {
 318                                 yyerror("Illegal character");
 319                         }
 320 
 321 %%
 322 
 323 void
 324 yyerror(char *s)
 325 {
 326         if (dofile == FS_TRUE) {
 327                 if (yytext[0] == '\0') {
 328                         filebench_log(LOG_ERROR, 
 329                                       "%s, token expected",
 330                                       s);
 331                         return;
 332                 }
 333                 (void) filebench_log(LOG_ERROR, 
 334                                      "%s at '%s'", 
 335                                      s,
 336                                      yytext);
 337         } else {
 338                 if (yytext[0] == '\0') {
 339                         (void) filebench_log(LOG_ERROR, 
 340                                              "%s, token expected", s);
 341                         return;
 342                 }
 343                 (void) filebench_log(LOG_ERROR, "%s at '%s'", s, yytext);
 344         }
 345 }
 346 
 347 struct yy_buffer_state *parent;
 348 struct yy_buffer_state *script;
 349 
 350 int
 351 yy_switchfileparent(FILE *file)
 352 {
 353         script = YY_CURRENT_BUFFER;
 354         parent = (struct yy_buffer_state *)yy_create_buffer(yyin, 128);
 355         yy_switch_to_buffer(parent);
 356         return (0);
 357 }
 358 
 359 int
 360 yy_switchfilescript(FILE *file)
 361 {
 362         yy_switch_to_buffer(script);
 363         return (0);
 364 }
 365