1*06f32e7eSjoerg //===----- FormatStringParsing.h - Format String Parsing --------*- C++ -*-===// 2*06f32e7eSjoerg // 3*06f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 5*06f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06f32e7eSjoerg // 7*06f32e7eSjoerg //===----------------------------------------------------------------------===// 8*06f32e7eSjoerg // 9*06f32e7eSjoerg // This provides some shared functions between printf and scanf format string 10*06f32e7eSjoerg // parsing code. 11*06f32e7eSjoerg // 12*06f32e7eSjoerg //===----------------------------------------------------------------------===// 13*06f32e7eSjoerg 14*06f32e7eSjoerg #ifndef LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 15*06f32e7eSjoerg #define LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 16*06f32e7eSjoerg 17*06f32e7eSjoerg #include "clang/AST/ASTContext.h" 18*06f32e7eSjoerg #include "clang/AST/Type.h" 19*06f32e7eSjoerg #include "clang/AST/FormatString.h" 20*06f32e7eSjoerg 21*06f32e7eSjoerg namespace clang { 22*06f32e7eSjoerg 23*06f32e7eSjoerg class LangOptions; 24*06f32e7eSjoerg 25*06f32e7eSjoerg template <typename T> 26*06f32e7eSjoerg class UpdateOnReturn { 27*06f32e7eSjoerg T &ValueToUpdate; 28*06f32e7eSjoerg const T &ValueToCopy; 29*06f32e7eSjoerg public: UpdateOnReturn(T & valueToUpdate,const T & valueToCopy)30*06f32e7eSjoerg UpdateOnReturn(T &valueToUpdate, const T &valueToCopy) 31*06f32e7eSjoerg : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {} 32*06f32e7eSjoerg ~UpdateOnReturn()33*06f32e7eSjoerg ~UpdateOnReturn() { 34*06f32e7eSjoerg ValueToUpdate = ValueToCopy; 35*06f32e7eSjoerg } 36*06f32e7eSjoerg }; 37*06f32e7eSjoerg 38*06f32e7eSjoerg namespace analyze_format_string { 39*06f32e7eSjoerg 40*06f32e7eSjoerg OptionalAmount ParseAmount(const char *&Beg, const char *E); 41*06f32e7eSjoerg OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, 42*06f32e7eSjoerg unsigned &argIndex); 43*06f32e7eSjoerg 44*06f32e7eSjoerg OptionalAmount ParsePositionAmount(FormatStringHandler &H, 45*06f32e7eSjoerg const char *Start, const char *&Beg, 46*06f32e7eSjoerg const char *E, PositionContext p); 47*06f32e7eSjoerg 48*06f32e7eSjoerg bool ParseFieldWidth(FormatStringHandler &H, 49*06f32e7eSjoerg FormatSpecifier &CS, 50*06f32e7eSjoerg const char *Start, const char *&Beg, const char *E, 51*06f32e7eSjoerg unsigned *argIndex); 52*06f32e7eSjoerg 53*06f32e7eSjoerg bool ParseArgPosition(FormatStringHandler &H, 54*06f32e7eSjoerg FormatSpecifier &CS, const char *Start, 55*06f32e7eSjoerg const char *&Beg, const char *E); 56*06f32e7eSjoerg 57*06f32e7eSjoerg bool ParseVectorModifier(FormatStringHandler &H, 58*06f32e7eSjoerg FormatSpecifier &FS, const char *&Beg, const char *E, 59*06f32e7eSjoerg const LangOptions &LO); 60*06f32e7eSjoerg 61*06f32e7eSjoerg /// Returns true if a LengthModifier was parsed and installed in the 62*06f32e7eSjoerg /// FormatSpecifier& argument, and false otherwise. 63*06f32e7eSjoerg bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, 64*06f32e7eSjoerg const LangOptions &LO, bool IsScanf = false); 65*06f32e7eSjoerg 66*06f32e7eSjoerg /// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8 67*06f32e7eSjoerg /// string; check that it won't go further than \p FmtStrEnd and write 68*06f32e7eSjoerg /// up the total size in \p Len. 69*06f32e7eSjoerg bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, 70*06f32e7eSjoerg const char *FmtStrEnd, unsigned &Len); 71*06f32e7eSjoerg 72*06f32e7eSjoerg template <typename T> class SpecifierResult { 73*06f32e7eSjoerg T FS; 74*06f32e7eSjoerg const char *Start; 75*06f32e7eSjoerg bool Stop; 76*06f32e7eSjoerg public: 77*06f32e7eSjoerg SpecifierResult(bool stop = false) Start(nullptr)78*06f32e7eSjoerg : Start(nullptr), Stop(stop) {} SpecifierResult(const char * start,const T & fs)79*06f32e7eSjoerg SpecifierResult(const char *start, 80*06f32e7eSjoerg const T &fs) 81*06f32e7eSjoerg : FS(fs), Start(start), Stop(false) {} 82*06f32e7eSjoerg getStart()83*06f32e7eSjoerg const char *getStart() const { return Start; } shouldStop()84*06f32e7eSjoerg bool shouldStop() const { return Stop; } hasValue()85*06f32e7eSjoerg bool hasValue() const { return Start != nullptr; } getValue()86*06f32e7eSjoerg const T &getValue() const { 87*06f32e7eSjoerg assert(hasValue()); 88*06f32e7eSjoerg return FS; 89*06f32e7eSjoerg } getValue()90*06f32e7eSjoerg const T &getValue() { return FS; } 91*06f32e7eSjoerg }; 92*06f32e7eSjoerg 93*06f32e7eSjoerg } // end analyze_format_string namespace 94*06f32e7eSjoerg } // end clang namespace 95*06f32e7eSjoerg 96*06f32e7eSjoerg #endif 97