"Fossies" - the Fresh Open Source Software Archive

Member "cppcheck-1.89/externals/simplecpp/simplecpp.h" (1 Sep 2019, 10307 Bytes) of package /windows/misc/cppcheck-1.89.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "simplecpp.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.87_vs_1.88.

    1 /*
    2  * simplecpp - A simple and high-fidelity C/C++ preprocessor library
    3  * Copyright (C) 2016 Daniel Marjamäki.
    4  *
    5  * This library is free software: you can redistribute it and/or
    6  * modify it under the terms of the GNU Lesser General Public
    7  * License as published by the Free Software Foundation, either
    8  * version 3 of the License, or (at your option) any later version.
    9  *
   10  * This library is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13  * Lesser General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU Lesser General Public
   16  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
   17  */
   18 
   19 #ifndef simplecppH
   20 #define simplecppH
   21 
   22 #include <cctype>
   23 #include <cstddef>
   24 #include <istream>
   25 #include <list>
   26 #include <map>
   27 #include <set>
   28 #include <string>
   29 #include <vector>
   30 
   31 #ifdef _WIN32
   32 #  ifdef SIMPLECPP_EXPORT
   33 #    define SIMPLECPP_LIB __declspec(dllexport)
   34 #  elif defined(SIMPLECPP_IMPORT)
   35 #    define SIMPLECPP_LIB __declspec(dllimport)
   36 #  else
   37 #    define SIMPLECPP_LIB
   38 #  endif
   39 #else
   40 #  define SIMPLECPP_LIB
   41 #endif
   42 
   43 
   44 namespace simplecpp {
   45 
   46     typedef std::string TokenString;
   47 
   48     /**
   49      * Location in source code
   50      */
   51     class SIMPLECPP_LIB Location {
   52     public:
   53         explicit Location(const std::vector<std::string> &f) : files(f), fileIndex(0), line(1U), col(0U) {}
   54 
   55         Location(const Location &loc) : files(loc.files), fileIndex(loc.fileIndex), line(loc.line), col(loc.col) {}
   56 
   57         Location &operator=(const Location &other) {
   58             if (this != &other) {
   59                 fileIndex = other.fileIndex;
   60                 line = other.line;
   61                 col  = other.col;
   62             }
   63             return *this;
   64         }
   65 
   66         /** increment this location by string */
   67         void adjust(const std::string &str);
   68 
   69         bool operator<(const Location &rhs) const {
   70             if (fileIndex != rhs.fileIndex)
   71                 return fileIndex < rhs.fileIndex;
   72             if (line != rhs.line)
   73                 return line < rhs.line;
   74             return col < rhs.col;
   75         }
   76 
   77         bool sameline(const Location &other) const {
   78             return fileIndex == other.fileIndex && line == other.line;
   79         }
   80 
   81         const std::string& file() const {
   82             return fileIndex < files.size() ? files[fileIndex] : emptyFileName;
   83         }
   84 
   85         const std::vector<std::string> &files;
   86         unsigned int fileIndex;
   87         unsigned int line;
   88         unsigned int col;
   89     private:
   90         static const std::string emptyFileName;
   91     };
   92 
   93     /**
   94      * token class.
   95      * @todo don't use std::string representation - for both memory and performance reasons
   96      */
   97     class SIMPLECPP_LIB Token {
   98     public:
   99         Token(const TokenString &s, const Location &loc) :
  100             location(loc), previous(NULL), next(NULL), string(s) {
  101             flags();
  102         }
  103 
  104         Token(const Token &tok) :
  105             macro(tok.macro), location(tok.location), previous(NULL), next(NULL), string(tok.string) {
  106             flags();
  107         }
  108 
  109         void flags() {
  110             name = (std::isalpha((unsigned char)string[0]) || string[0] == '_' || string[0] == '$');
  111             comment = string.size() > 1U && string[0] == '/' && (string[1] == '/' || string[1] == '*');
  112             number = std::isdigit((unsigned char)string[0]) || (string.size() > 1U && string[0] == '-' && std::isdigit((unsigned char)string[1]));
  113             op = (string.size() == 1U) ? string[0] : '\0';
  114         }
  115 
  116         const TokenString& str() const {
  117             return string;
  118         }
  119         void setstr(const std::string &s) {
  120             string = s;
  121             flags();
  122         }
  123 
  124         bool isOneOf(const char ops[]) const;
  125         bool startsWithOneOf(const char c[]) const;
  126         bool endsWithOneOf(const char c[]) const;
  127 
  128         TokenString macro;
  129         char op;
  130         bool comment;
  131         bool name;
  132         bool number;
  133         Location location;
  134         Token *previous;
  135         Token *next;
  136 
  137         const Token *previousSkipComments() const {
  138             const Token *tok = this->previous;
  139             while (tok && tok->comment)
  140                 tok = tok->previous;
  141             return tok;
  142         }
  143 
  144         const Token *nextSkipComments() const {
  145             const Token *tok = this->next;
  146             while (tok && tok->comment)
  147                 tok = tok->next;
  148             return tok;
  149         }
  150 
  151         void printAll() const;
  152         void printOut() const;
  153     private:
  154         TokenString string;
  155 
  156         // Not implemented - prevent assignment
  157         Token &operator=(const Token &tok);
  158     };
  159 
  160     /** Output from preprocessor */
  161     struct SIMPLECPP_LIB Output {
  162         explicit Output(const std::vector<std::string> &files) : type(ERROR), location(files) {}
  163         enum Type {
  164             ERROR, /* #error */
  165             WARNING, /* #warning */
  166             MISSING_HEADER,
  167             INCLUDE_NESTED_TOO_DEEPLY,
  168             SYNTAX_ERROR,
  169             PORTABILITY_BACKSLASH,
  170             UNHANDLED_CHAR_ERROR
  171         } type;
  172         Location location;
  173         std::string msg;
  174     };
  175 
  176     typedef std::list<Output> OutputList;
  177 
  178     /** List of tokens. */
  179     class SIMPLECPP_LIB TokenList {
  180     public:
  181         explicit TokenList(std::vector<std::string> &filenames);
  182         TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = NULL);
  183         TokenList(const TokenList &other);
  184 #if __cplusplus >= 201103L
  185         TokenList(TokenList &&other);
  186 #endif
  187         ~TokenList();
  188         TokenList &operator=(const TokenList &other);
  189 #if __cplusplus >= 201103L
  190         TokenList &operator=(TokenList &&other);
  191 #endif
  192 
  193         void clear();
  194         bool empty() const {
  195             return !frontToken;
  196         }
  197         void push_back(Token *tok);
  198 
  199         void dump() const;
  200         std::string stringify() const;
  201 
  202         void readfile(std::istream &istr, const std::string &filename=std::string(), OutputList *outputList = NULL);
  203         void constFold();
  204 
  205         void removeComments();
  206 
  207         Token *front() {
  208             return frontToken;
  209         }
  210 
  211         const Token *cfront() const {
  212             return frontToken;
  213         }
  214 
  215         Token *back() {
  216             return backToken;
  217         }
  218 
  219         const Token *cback() const {
  220             return backToken;
  221         }
  222 
  223         void deleteToken(Token *tok) {
  224             if (!tok)
  225                 return;
  226             Token *prev = tok->previous;
  227             Token *next = tok->next;
  228             if (prev)
  229                 prev->next = next;
  230             if (next)
  231                 next->previous = prev;
  232             if (frontToken == tok)
  233                 frontToken = next;
  234             if (backToken == tok)
  235                 backToken = prev;
  236             delete tok;
  237         }
  238 
  239         void takeTokens(TokenList &other) {
  240             if (!other.frontToken)
  241                 return;
  242             if (!frontToken) {
  243                 frontToken = other.frontToken;
  244             } else {
  245                 backToken->next = other.frontToken;
  246                 other.frontToken->previous = backToken;
  247             }
  248             backToken = other.backToken;
  249             other.frontToken = other.backToken = NULL;
  250         }
  251 
  252         /** sizeof(T) */
  253         std::map<std::string, std::size_t> sizeOfType;
  254 
  255     private:
  256         void combineOperators();
  257 
  258         void constFoldUnaryNotPosNeg(Token *tok);
  259         void constFoldMulDivRem(Token *tok);
  260         void constFoldAddSub(Token *tok);
  261         void constFoldShift(Token *tok);
  262         void constFoldComparison(Token *tok);
  263         void constFoldBitwise(Token *tok);
  264         void constFoldLogicalOp(Token *tok);
  265         void constFoldQuestionOp(Token **tok1);
  266 
  267         std::string readUntil(std::istream &istr, const Location &location, char start, char end, OutputList *outputList, unsigned int bom);
  268         void lineDirective(unsigned int fileIndex, unsigned int line, Location *location);
  269 
  270         std::string lastLine(int maxsize=100000) const;
  271 
  272         unsigned int fileIndex(const std::string &filename);
  273 
  274         Token *frontToken;
  275         Token *backToken;
  276         std::vector<std::string> &files;
  277     };
  278 
  279     /** Tracking how macros are used */
  280     struct SIMPLECPP_LIB MacroUsage {
  281         explicit MacroUsage(const std::vector<std::string> &f, bool macroValueKnown_) : macroLocation(f), useLocation(f), macroValueKnown(macroValueKnown_) {}
  282         std::string macroName;
  283         Location    macroLocation;
  284         Location    useLocation;
  285         bool        macroValueKnown;
  286     };
  287 
  288     /**
  289      * Command line preprocessor settings.
  290      * On the command line these are configured by -D, -U, -I, --include
  291      */
  292     struct SIMPLECPP_LIB DUI {
  293         DUI() {}
  294         std::list<std::string> defines;
  295         std::set<std::string> undefined;
  296         std::list<std::string> includePaths;
  297         std::list<std::string> includes;
  298     };
  299 
  300     SIMPLECPP_LIB std::map<std::string, TokenList*> load(const TokenList &rawtokens, std::vector<std::string> &filenames, const DUI &dui, OutputList *outputList = NULL);
  301 
  302     /**
  303      * Preprocess
  304      * @todo simplify interface
  305      * @param output TokenList that receives the preprocessing output
  306      * @param rawtokens Raw tokenlist for top sourcefile
  307      * @param files internal data of simplecpp
  308      * @param filedata output from simplecpp::load()
  309      * @param dui defines, undefs, and include paths
  310      * @param outputList output: list that will receive output messages
  311      * @param macroUsage output: macro usage
  312      */
  313     SIMPLECPP_LIB void preprocess(TokenList &output, const TokenList &rawtokens, std::vector<std::string> &files, std::map<std::string, TokenList*> &filedata, const DUI &dui, OutputList *outputList = NULL, std::list<MacroUsage> *macroUsage = NULL);
  314 
  315     /**
  316      * Deallocate data
  317      */
  318     SIMPLECPP_LIB void cleanup(std::map<std::string, TokenList*> &filedata);
  319 
  320     /** Simplify path */
  321     SIMPLECPP_LIB std::string simplifyPath(std::string path);
  322 
  323     /** Convert Cygwin path to Windows path */
  324     SIMPLECPP_LIB std::string convertCygwinToWindowsPath(const std::string &cygwinPath);
  325 }
  326 
  327 #endif