tools/icheck/parser/src/libs/cplusplus/pp-scanner.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 /*
       
    42   Copyright 2005 Roberto Raggi <roberto@kdevelop.org>
       
    43 
       
    44   Permission to use, copy, modify, distribute, and sell this software and its
       
    45   documentation for any purpose is hereby granted without fee, provided that
       
    46   the above copyright notice appear in all copies and that both that
       
    47   copyright notice and this permission notice appear in supporting
       
    48   documentation.
       
    49 
       
    50   The above copyright notice and this permission notice shall be included in
       
    51   all copies or substantial portions of the Software.
       
    52 
       
    53   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    54   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    55   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
       
    56   KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
       
    57   AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
       
    58   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       
    59 */
       
    60 
       
    61 #include "pp-scanner.h"
       
    62 #include "pp-cctype.h"
       
    63 
       
    64 using namespace CPlusPlus;
       
    65 
       
    66 const char *pp_skip_blanks::operator () (const char *__first, const char *__last)
       
    67 {
       
    68     lines = 0;
       
    69 
       
    70     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
    71         if (*__first == '\\') {
       
    72             const char *__begin = __first;
       
    73             ++__begin;
       
    74 
       
    75             if (__begin != __last && *__begin == '\n')
       
    76                 ++__first;
       
    77             else
       
    78                 break;
       
    79         } else if (*__first == '\n' || !pp_isspace (*__first))
       
    80             break;
       
    81     }
       
    82 
       
    83     return __first;
       
    84 }
       
    85 
       
    86 const char *pp_skip_whitespaces::operator () (const char *__first, const char *__last)
       
    87 {
       
    88     lines = 0;
       
    89 
       
    90     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
    91         if (! pp_isspace (*__first))
       
    92             break;
       
    93     }
       
    94 
       
    95     return __first;
       
    96 }
       
    97 
       
    98 const char *pp_skip_comment_or_divop::operator () (const char *__first, const char *__last)
       
    99 {
       
   100     enum {
       
   101         MAYBE_BEGIN,
       
   102         BEGIN,
       
   103         MAYBE_END,
       
   104         END,
       
   105         IN_COMMENT,
       
   106         IN_CXX_COMMENT
       
   107     } state (MAYBE_BEGIN);
       
   108 
       
   109     lines = 0;
       
   110 
       
   111     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
   112         switch (state) {
       
   113         default:
       
   114             break;
       
   115 
       
   116         case MAYBE_BEGIN:
       
   117             if (*__first != '/')
       
   118                 return __first;
       
   119 
       
   120             state = BEGIN;
       
   121             break;
       
   122 
       
   123         case BEGIN:
       
   124             if (*__first == '*')
       
   125                 state = IN_COMMENT;
       
   126             else if (*__first == '/')
       
   127                 state = IN_CXX_COMMENT;
       
   128             else
       
   129                 return __first;
       
   130             break;
       
   131 
       
   132         case IN_COMMENT:
       
   133             if (*__first == '*')
       
   134                 state = MAYBE_END;
       
   135             break;
       
   136 
       
   137         case IN_CXX_COMMENT:
       
   138             if (*__first == '\n')
       
   139                 return __first;
       
   140             break;
       
   141 
       
   142         case MAYBE_END:
       
   143             if (*__first == '/')
       
   144                 state = END;
       
   145             else if (*__first != '*')
       
   146                 state = IN_COMMENT;
       
   147             break;
       
   148 
       
   149         case END:
       
   150             return __first;
       
   151         }
       
   152     }
       
   153 
       
   154     return __first;
       
   155 }
       
   156 
       
   157 const char *pp_skip_identifier::operator () (const char *__first, const char *__last)
       
   158 {
       
   159     lines = 0;
       
   160 
       
   161     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
   162         if (! pp_isalnum (*__first) && *__first != '_')
       
   163             break;
       
   164     }
       
   165 
       
   166     return __first;
       
   167 }
       
   168 
       
   169 const char *pp_skip_number::operator () (const char *__first, const char *__last)
       
   170 {
       
   171     lines = 0;
       
   172 
       
   173     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
   174         if (! pp_isalnum (*__first) && *__first != '.')
       
   175             break;
       
   176     }
       
   177 
       
   178     return __first;
       
   179 }
       
   180 
       
   181 const char *pp_skip_string_literal::operator () (const char *__first, const char *__last)
       
   182 {
       
   183     enum {
       
   184         BEGIN,
       
   185         IN_STRING,
       
   186         QUOTE,
       
   187         END
       
   188     } state (BEGIN);
       
   189 
       
   190     lines = 0;
       
   191 
       
   192     for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
   193         switch (state)
       
   194         {
       
   195         default:
       
   196             break;
       
   197 
       
   198         case BEGIN:
       
   199             if (*__first != '\"')
       
   200                 return __first;
       
   201             state = IN_STRING;
       
   202             break;
       
   203 
       
   204         case IN_STRING:
       
   205             if (! (*__first != '\n'))
       
   206                 return __last;
       
   207 
       
   208             if (*__first == '\"')
       
   209                 state = END;
       
   210             else if (*__first == '\\')
       
   211                 state = QUOTE;
       
   212             break;
       
   213 
       
   214         case QUOTE:
       
   215             state = IN_STRING;
       
   216             break;
       
   217 
       
   218         case END:
       
   219             return __first;
       
   220         }
       
   221     }
       
   222 
       
   223     return __first;
       
   224 }
       
   225 
       
   226 const char *pp_skip_char_literal::operator () (const char *__first, const char *__last)
       
   227 {
       
   228     enum {
       
   229         BEGIN,
       
   230         IN_STRING,
       
   231         QUOTE,
       
   232         END
       
   233     } state (BEGIN);
       
   234 
       
   235     lines = 0;
       
   236 
       
   237     for (; state != END && __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) {
       
   238         switch (state)
       
   239         {
       
   240         default:
       
   241             break;
       
   242 
       
   243         case BEGIN:
       
   244             if (*__first != '\'')
       
   245                 return __first;
       
   246             state = IN_STRING;
       
   247             break;
       
   248 
       
   249         case IN_STRING:
       
   250             if (! (*__first != '\n'))
       
   251                 return __last;
       
   252 
       
   253             if (*__first == '\'')
       
   254                 state = END;
       
   255             else if (*__first == '\\')
       
   256                 state = QUOTE;
       
   257             break;
       
   258 
       
   259         case QUOTE:
       
   260             state = IN_STRING;
       
   261             break;
       
   262         }
       
   263     }
       
   264 
       
   265     return __first;
       
   266 }
       
   267 
       
   268 const char *pp_skip_argument::operator () (const char *__first, const char *__last)
       
   269 {
       
   270     int depth = 0;
       
   271     lines = 0;
       
   272 
       
   273     while (__first != __last) {
       
   274         if (!depth && (*__first == ')' || *__first == ','))
       
   275             break;
       
   276         else if (*__first == '(')
       
   277             ++depth, ++__first;
       
   278         else if (*__first == ')')
       
   279             --depth, ++__first;
       
   280         else if (*__first == '\"') {
       
   281             __first = skip_string_literal (__first, __last);
       
   282             lines += skip_string_literal.lines;
       
   283         } else if (*__first == '\'') {
       
   284             __first = skip_char_literal (__first, __last);
       
   285             lines += skip_char_literal.lines;
       
   286         } else if (*__first == '/') {
       
   287             __first = skip_comment_or_divop (__first, __last);
       
   288             lines += skip_comment_or_divop.lines;
       
   289         } else if (pp_isalpha (*__first) || *__first == '_') {
       
   290             __first = skip_identifier (__first, __last);
       
   291             lines += skip_identifier.lines;
       
   292         } else if (pp_isdigit (*__first)) {
       
   293             __first = skip_number (__first, __last);
       
   294             lines += skip_number.lines;
       
   295         } else if (*__first == '\n') {
       
   296             ++__first;
       
   297             ++lines;
       
   298         } else
       
   299             ++__first;
       
   300     }
       
   301 
       
   302     return __first;
       
   303 }
       
   304