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