ACE_Svc_Conf_Lexer Class Reference

#include <Svc_Conf_Lexer.h>

List of all members.

Static Public Member Functions

static int yylex (YYSTYPE *ace_yylval, ACE_Svc_Conf_Param *param)

Static Private Member Functions

static size_t input (ACE_Svc_Conf_Param *param, char *buf, size_t max_size)
static int scan (YYSTYPE *ace_yylval, ACE_Svc_Conf_Param *param)


Detailed Description

This class lexes the classic ACE Service Configurator language. The entry point is similar to what flex would generate. However, it is a static method in this class (which is really just name space).

Definition at line 33 of file Svc_Conf_Lexer.h.


Member Function Documentation

size_t ACE_Svc_Conf_Lexer::input ( ACE_Svc_Conf_Param param,
char *  buf,
size_t  max_size 
) [static, private]

Definition at line 226 of file Svc_Conf_Lexer.cpp.

References ACE_TEXT, ace_yyerror(), ACE_Svc_Conf_Param::buffer, ACE_OS::clearerr(), ACE_Svc_Conf_Param::directive, ACE_OS::exit(), ACE_Svc_Conf_Param::file, ACE_OS::fprintf(), ACE_OS::fread(), ACE_OS::memcpy(), ACE_Svc_Conf_Param::source, ace_yy_buffer_state::start_, ACE_OS::strlen(), ACE_Svc_Conf_Param::SVC_CONF_DIRECTIVE, ACE_Svc_Conf_Param::SVC_CONF_FILE, ACE_Svc_Conf_Param::type, ACE_Svc_Conf_Param::yyerrno, and ACE_Svc_Conf_Param::yylineno.

Referenced by yylex().

00228 {
00229   size_t result = 0;
00230 
00231   switch (param->type)
00232     {
00233     case ACE_Svc_Conf_Param::SVC_CONF_FILE:
00234       errno = 0;
00235       while ((result = ACE_OS::fread (buf, 1,
00236                                       max_size, param->source.file)) == 0 &&
00237              ferror (param->source.file))
00238         {
00239           if (errno == EINTR)
00240             {
00241               errno = 0;
00242 #if !defined (ACE_LACKS_CLEARERR)
00243               ACE_OS::clearerr (param->source.file);
00244 #endif /* !ACE_LACKS_CLEARERR */
00245             }
00246           else
00247             {
00248               ACE_OS::fprintf (stderr, "ERROR: input in scanner failed\n");
00249               ACE_OS::exit (2);
00250             }
00251         }
00252       break;
00253     case ACE_Svc_Conf_Param::SVC_CONF_DIRECTIVE:
00254       result = ACE_OS::strlen (param->source.directive +
00255                                param->buffer->start_) * sizeof (ACE_TCHAR);
00256       if (result != 0)
00257         {
00258           // Make sure that the amount we are going to copy
00259           // fits in the buffer
00260           if (result > max_size)
00261             {
00262               result = max_size;
00263             }
00264           ACE_OS::memcpy (buf,
00265                           param->source.directive + param->buffer->start_,
00266                           result);
00267           param->buffer->start_ += (result / sizeof (ACE_TCHAR));
00268         }
00269       break;
00270     default:
00271       ace_yyerror (++param->yyerrno,
00272                    param->yylineno,
00273                    ACE_TEXT ("Invalid Service Configurator type in ")
00274                    ACE_TEXT ("ACE_Svc_Conf_Lexer::input"));
00275     }
00276 
00277   return result;
00278 }

int ACE_Svc_Conf_Lexer::scan ( YYSTYPE ace_yylval,
ACE_Svc_Conf_Param param 
) [static, private]

Definition at line 281 of file Svc_Conf_Lexer.cpp.

References ACE_ACTIVE, ACE_COMMENT, ACE_DYNAMIC, ACE_IDENT, ACE_INACTIVE, ACE_OS::ace_isdigit(), ACE_MODULE_T, ACE_NO_STATE, ACE_PATHNAME, ACE_REMOVE, ACE_RESUME, ACE_STATIC, ACE_STREAM_T, ACE_STRING, ACE_SUSPEND, ACE_SVC_OBJ_T, ACE_TEMPORARY_STRING, ACE_TEXT, ACE_OS::ace_tolower(), ACE_USTREAM, ACE_YY_CONVERSION_SPACE, ace_yyerror(), ACE_Svc_Conf_Param::buffer, ace_yy_buffer_state::eof_, YYSTYPE::ident_, ace_yy_buffer_state::index_, ace_yy_buffer_state::input_, ACE_Svc_Conf_Param::obstack, ace_yy_buffer_state::size_, ace_yy_buffer_state::state_, ACE_OS::strchr(), ACE_OS::strcmp(), ace_yy_buffer_state::string_start_, ACE_OS::strncpy(), ACE_Svc_Conf_Param::yyerrno, and ACE_Svc_Conf_Param::yylineno.

Referenced by yylex().

00284 {
00285   ace_yy_buffer_state* buffer = param->buffer;
00286 
00287   // If we are not currently in any state, skip over whitespace
00288   if (buffer->state_ == ACE_NO_STATE)
00289     {
00290       while (buffer->index_ < buffer->size_ &&
00291              isspace (buffer->input_[buffer->index_]))
00292         {
00293           // Make sure that we count all of the new lines
00294           if (buffer->input_[buffer->index_] == '\n')
00295             {
00296               ++param->yylineno;
00297             }
00298           ++buffer->index_;
00299         }
00300     }
00301 
00302   size_t current;
00303   size_t last = buffer->size_ + (buffer->eof_ ? 1 : 0);
00304   for (current = buffer->index_; current < last; current++)
00305     {
00306       static const char* separators = " \t\r\n:*(){}";
00307       char c = (buffer->eof_ && current == buffer->size_ ?
00308                                      '\n' : buffer->input_[current]);
00309       switch (buffer->state_)
00310         {
00311           case ACE_COMMENT:
00312             if (c == '\n')
00313               {
00314                 buffer->state_ = ACE_NO_STATE;
00315                 buffer->index_ = current + 1;
00316                 ++param->yylineno;
00317               }
00318             break;
00319           case ACE_STRING:
00320             if (!(c >= ' ' && c <= '~'))
00321               {
00322                 // The character at currrent is definitely not part of
00323                 // the string so we need to move current back one.
00324                 --current;
00325 
00326                 // Get the starting point of our string (skipping the quote)
00327                 char* source = buffer->input_ + buffer->index_ + 1;
00328 
00329                 // Now, we need to move back in the string until we find the
00330                 // same character that started the string
00331                 bool string_end_found = false;
00332                 if (current > buffer->index_)
00333                   {
00334                     for (size_t i = current - buffer->index_; i-- != 0; )
00335                       {
00336                         if (source[i] == buffer->string_start_)
00337                           {
00338                             current = buffer->index_ + i + 1;
00339                             string_end_found = true;
00340                             break;
00341                           }
00342                       }
00343                   }
00344 
00345                 if (!string_end_found)
00346                   {
00347                     ace_yyerror (++param->yyerrno,
00348                                  param->yylineno,
00349                                  ACE_TEXT ("Unable to find the end of the string"));
00350                     return ACE_NO_STATE;
00351                   }
00352 
00353                 size_t amount = (current - buffer->index_) - 1;
00354 #if defined (ACE_USES_WCHAR)
00355                 ACE_TCHAR target[ACE_YY_CONVERSION_SPACE] = ACE_TEXT ("");
00356                 size_t length = 0;
00357                 if (!convert_from_utf8 (buffer->converter_,
00358                                         source,
00359                                         amount,
00360                                         target,
00361                                         ACE_YY_CONVERSION_SPACE,
00362                                         length))
00363                   {
00364                     ace_yyerror (++param->yyerrno,
00365                                  param->yylineno,
00366                                  ACE_TEXT ("Unable to convert string from UTF-8"));
00367                     return ACE_NO_STATE;
00368                   }
00369                 amount = length;
00370 #else
00371                 char* target = source;
00372 #endif /* ACE_USES_WCHAR */
00373                 ace_yylval->ident_ = param->obstack.copy (target, amount);
00374                 buffer->state_ = ACE_NO_STATE;
00375                 buffer->index_ = current + 1;
00376                 return ACE_STRING;
00377               }
00378             break;
00379           case ACE_NO_STATE:
00380             if (c == '"' || c == '\'')
00381               {
00382                 buffer->string_start_ = c;
00383                 buffer->state_ = ACE_STRING;
00384               }
00385             else if (c == '#')
00386               {
00387                 buffer->state_ = ACE_COMMENT;
00388               }
00389             else if (ACE_OS::strchr (separators, c) != 0)
00390               {
00391                 if (c == '\n')
00392                   {
00393                     ++param->yylineno;
00394                   }
00395 
00396                 if (current == buffer->index_ + 1)
00397                   {
00398                     int lower = ACE_OS::ace_tolower (
00399                                           buffer->input_[current - 1]);
00400                     if (c == ':' &&
00401                         (buffer->input_[current - 1] == '%' ||
00402                          (lower >= 'a' && lower <= 'z')))
00403                       {
00404                         // This is considered a path, so we need to
00405                         // skip over the ':' and go around the loop
00406                         // again
00407                         break;
00408                       }
00409                   }
00410 
00411                 if (current == buffer->index_)
00412                   {
00413                     buffer->index_ = current + 1;
00414                     if (isspace (c))
00415                       {
00416                         // This is an empty line.
00417                         // Let's look for something else.
00418                         break;
00419                       }
00420                     else
00421                       {
00422                         return c;
00423                       }
00424                   }
00425 
00426                 // String from buffer->index_ to current (inclusive)
00427                 size_t size = (current - buffer->index_) + 1;
00428                 ACE_TEMPORARY_STRING (str, size);
00429                 ACE_OS::strncpy (str, buffer->input_ + buffer->index_,
00430                                  size - 1);
00431                 str[size - 1] = '\0';
00432 
00433 
00434                 if (ACE_OS::strcmp (str, "dynamic") == 0)
00435                   {
00436                     buffer->index_ = current;
00437                     return ACE_DYNAMIC;
00438                   }
00439                 else if (ACE_OS::strcmp (str, "static") == 0)
00440                   {
00441                     buffer->index_ = current;
00442                     return ACE_STATIC;
00443                   }
00444                 else if (ACE_OS::strcmp (str, "suspend") == 0)
00445                   {
00446                     buffer->index_ = current;
00447                     return ACE_SUSPEND;
00448                   }
00449                 else if (ACE_OS::strcmp (str, "resume") == 0)
00450                   {
00451                     buffer->index_ = current;
00452                     return ACE_RESUME;
00453                   }
00454                 else if (ACE_OS::strcmp (str, "remove") == 0)
00455                   {
00456                     buffer->index_ = current;
00457                     return ACE_REMOVE;
00458                   }
00459                 else if (ACE_OS::strcmp (str, "stream") == 0)
00460                   {
00461                     buffer->index_ = current;
00462                     return ACE_USTREAM;
00463                   }
00464                 else if (ACE_OS::strcmp (str, "Module") == 0)
00465                   {
00466                     buffer->index_ = current;
00467                     return ACE_MODULE_T;
00468                   }
00469                 else if (ACE_OS::strcmp (str, "Service_Object") == 0)
00470                   {
00471                     buffer->index_ = current;
00472                     return ACE_SVC_OBJ_T;
00473                   }
00474                 else if (ACE_OS::strcmp (str, "STREAM") == 0)
00475                   {
00476                     buffer->index_ = current;
00477                     return ACE_STREAM_T;
00478                   }
00479                 else if (ACE_OS::strcmp (str, "active") == 0)
00480                   {
00481                     buffer->index_ = current;
00482                     return ACE_ACTIVE;
00483                   }
00484                 else if (ACE_OS::strcmp (str, "inactive") == 0)
00485                   {
00486                     buffer->index_ = current;
00487                     return ACE_INACTIVE;
00488                   }
00489                 else
00490                   {
00491                     // Get the string and save it in ace_yylval
00492                     int token = ACE_IDENT;
00493                     size_t amount = size - 1;
00494 #if defined (ACE_USES_WCHAR)
00495                     ACE_TCHAR target[ACE_YY_CONVERSION_SPACE] = ACE_TEXT ("");
00496                     size_t length = 0;
00497                     if (!convert_from_utf8 (buffer->converter_,
00498                                             str,
00499                                             amount,
00500                                             target,
00501                                             ACE_YY_CONVERSION_SPACE,
00502                                             length))
00503                       {
00504                         ace_yyerror (++param->yyerrno,
00505                                      param->yylineno,
00506                                      ACE_TEXT ("Unable to convert ")
00507                                      ACE_TEXT ("identifier from UTF-8"));
00508                         return ACE_NO_STATE;
00509                       }
00510                     amount = length;
00511 #else
00512                     char* target = str;
00513 #endif /* ACE_USES_WCHAR */
00514                     ace_yylval->ident_ = param->obstack.copy (target, amount);
00515 
00516                     // Determine the difference between pathname and ident
00517                     if (ACE_OS::ace_isdigit (ace_yylval->ident_[0]))
00518                       {
00519                         token = ACE_PATHNAME;
00520                       }
00521                     else
00522                       {
00523                         static const ACE_TCHAR* path_parts =
00524                                                 ACE_TEXT ("/\\:%.~-");
00525                         for (const ACE_TCHAR* p = path_parts; *p != '\0'; p++)
00526                           {
00527                             if (ACE_OS::strchr (ace_yylval->ident_, *p) != 0)
00528                               {
00529                                 token = ACE_PATHNAME;
00530                                 break;
00531                               }
00532                           }
00533                       }
00534 
00535                     buffer->state_ = ACE_NO_STATE;
00536                     buffer->index_ = current;
00537                     return token;
00538                   }
00539               }
00540             break;
00541           default:
00542             ace_yyerror (++param->yyerrno,
00543                          param->yylineno,
00544                          ACE_TEXT ("Unexpected state in ACE_Svc_Conf_Lexer::scan"));
00545             return ACE_NO_STATE;
00546         }
00547     }
00548 
00549   // We need more from the input source so, we will move the remainder of
00550   // the buffer to the front and signal that we need more
00551   if (!buffer->eof_)
00552     {
00553       buffer->need_more_ = true;
00554       if (buffer->state_ == ACE_COMMENT)
00555         {
00556           buffer->index_ = 0;
00557           buffer->size_  = 0;
00558         }
00559       else
00560         {
00561           buffer->size_ = current - buffer->index_;
00562           if (buffer->size_ != 0 && buffer->index_ != 0)
00563             ACE_OS::memmove (buffer->input_,
00564                              buffer->input_ + buffer->index_, buffer->size_);
00565           buffer->index_ = 0;
00566           buffer->state_ = ACE_NO_STATE;
00567         }
00568     }
00569   return ACE_NO_STATE;
00570 }

int ACE_Svc_Conf_Lexer::yylex ( YYSTYPE ace_yylval,
ACE_Svc_Conf_Param param 
) [static]

This is similar to the C function, ace_yylex, which a bison generated parser expects. It returns information in the ace_yylval parameter and uses input stored in the param parameter.

Definition at line 145 of file Svc_Conf_Lexer.cpp.

References ACE_NEW_RETURN, ACE_NO_STATE, ACE_TEXT, ACE_YY_BUF_SIZE, ace_yyerror(), ACE_Svc_Conf_Param::buffer, ace_yy_buffer_state::eof_, input(), ace_yy_buffer_state::input_, ACE_OS::memmove(), ace_yy_buffer_state::need_more_, normalize(), scan(), and ace_yy_buffer_state::size_.

Referenced by ace_yylex().

00147 {
00148 #if defined (ACE_USES_WCHAR)
00149   bool look_for_bom = false;
00150   ACE_Encoding_Converter_Factory::Encoding_Hint hint =
00151                 ACE_Encoding_Converter_Factory::ACE_NONE;
00152 #endif /* ACE_USES_WCHAR */
00153   if (param->buffer == 0)
00154     {
00155 #if defined (ACE_USES_WCHAR)
00156       look_for_bom = true;
00157 #endif /* ACE_USES_WCHAR */
00158       ACE_NEW_RETURN (param->buffer,
00159                       ace_yy_buffer_state,
00160                       -1);
00161     }
00162 
00163   int token = ACE_NO_STATE;
00164   do {
00165     if (param->buffer->need_more_)
00166       {
00167 #if defined (ACE_USES_WCHAR)
00168         size_t skip_bytes = 0;
00169 #endif /* ACE_USES_WCHAR */
00170         param->buffer->need_more_ = false;
00171         size_t amount =
00172                input (param,
00173                       param->buffer->input_ + param->buffer->size_,
00174                       normalize (ACE_YY_BUF_SIZE -
00175                                  param->buffer->size_));
00176         if (amount == 0)
00177           {
00178             param->buffer->eof_ = true;
00179 #if defined (ACE_USES_WCHAR)
00180             skip_bytes = param->buffer->size_;
00181 #endif /* ACE_USES_WCHAR */
00182           }
00183         else
00184           {
00185 #if defined (ACE_USES_WCHAR)
00186             if (look_for_bom)
00187               {
00188                 size_t read_more = 0;
00189 
00190                 look_for_bom = false;
00191                 hint = locate_bom (param->buffer->input_, amount, read_more);
00192 
00193                 if (read_more != 0)
00194                   {
00195                     input (param,
00196                            param->buffer->input_ + amount,
00197                            read_more);
00198                     ACE_OS::memmove (param->buffer->input_,
00199                                      param->buffer->input_ + read_more,
00200                                      amount);
00201                   }
00202               }
00203             skip_bytes = param->buffer->size_;
00204 #endif /* ACE_USES_WCHAR */
00205             param->buffer->size_ += amount;
00206           }
00207 
00208 #if defined (ACE_USES_WCHAR)
00209         if (!convert_to_utf8 (param, skip_bytes, hint))
00210           {
00211             ace_yyerror (++param->yyerrno,
00212                          param->yylineno,
00213                          ACE_TEXT ("Unable to convert input stream to UTF-8"));
00214             return ACE_NO_STATE;
00215           }
00216 #endif /* ACE_USES_WCHAR */
00217       }
00218 
00219     token = scan (ace_yylval, param);
00220   } while (token == ACE_NO_STATE && param->buffer->need_more_);
00221 
00222   return token;
00223 }


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:35:43 2010 for ACE by  doxygen 1.4.7