1*6c97f889SErik Pilkington //===----- FormatStringParsing.h - Format String Parsing --------*- C++ -*-===// 2*6c97f889SErik Pilkington // 3*6c97f889SErik Pilkington // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*6c97f889SErik Pilkington // See https://llvm.org/LICENSE.txt for license information. 5*6c97f889SErik Pilkington // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*6c97f889SErik Pilkington // 7*6c97f889SErik Pilkington //===----------------------------------------------------------------------===// 8*6c97f889SErik Pilkington // 9*6c97f889SErik Pilkington // This provides some shared functions between printf and scanf format string 10*6c97f889SErik Pilkington // parsing code. 11*6c97f889SErik Pilkington // 12*6c97f889SErik Pilkington //===----------------------------------------------------------------------===// 13*6c97f889SErik Pilkington 14314fbfa1STim Northover #ifndef LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 15314fbfa1STim Northover #define LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 16314fbfa1STim Northover 17314fbfa1STim Northover #include "clang/AST/ASTContext.h" 18314fbfa1STim Northover #include "clang/AST/Type.h" 19314fbfa1STim Northover #include "clang/AST/FormatString.h" 20314fbfa1STim Northover 21314fbfa1STim Northover namespace clang { 22314fbfa1STim Northover 23314fbfa1STim Northover class LangOptions; 24314fbfa1STim Northover 25314fbfa1STim Northover template <typename T> 26314fbfa1STim Northover class UpdateOnReturn { 27314fbfa1STim Northover T &ValueToUpdate; 28314fbfa1STim Northover const T &ValueToCopy; 29314fbfa1STim Northover public: UpdateOnReturn(T & valueToUpdate,const T & valueToCopy)30314fbfa1STim Northover UpdateOnReturn(T &valueToUpdate, const T &valueToCopy) 31314fbfa1STim Northover : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {} 32314fbfa1STim Northover ~UpdateOnReturn()33314fbfa1STim Northover ~UpdateOnReturn() { 34314fbfa1STim Northover ValueToUpdate = ValueToCopy; 35314fbfa1STim Northover } 36314fbfa1STim Northover }; 37314fbfa1STim Northover 38314fbfa1STim Northover namespace analyze_format_string { 39314fbfa1STim Northover 40314fbfa1STim Northover OptionalAmount ParseAmount(const char *&Beg, const char *E); 41314fbfa1STim Northover OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, 42314fbfa1STim Northover unsigned &argIndex); 43314fbfa1STim Northover 44314fbfa1STim Northover OptionalAmount ParsePositionAmount(FormatStringHandler &H, 45314fbfa1STim Northover const char *Start, const char *&Beg, 46314fbfa1STim Northover const char *E, PositionContext p); 47314fbfa1STim Northover 48314fbfa1STim Northover bool ParseFieldWidth(FormatStringHandler &H, 49314fbfa1STim Northover FormatSpecifier &CS, 50314fbfa1STim Northover const char *Start, const char *&Beg, const char *E, 51314fbfa1STim Northover unsigned *argIndex); 52314fbfa1STim Northover 53314fbfa1STim Northover bool ParseArgPosition(FormatStringHandler &H, 54314fbfa1STim Northover FormatSpecifier &CS, const char *Start, 55314fbfa1STim Northover const char *&Beg, const char *E); 56314fbfa1STim Northover 570ff50d49SMatt Arsenault bool ParseVectorModifier(FormatStringHandler &H, 580ff50d49SMatt Arsenault FormatSpecifier &FS, const char *&Beg, const char *E, 590ff50d49SMatt Arsenault const LangOptions &LO); 600ff50d49SMatt Arsenault 61314fbfa1STim Northover /// Returns true if a LengthModifier was parsed and installed in the 62314fbfa1STim Northover /// FormatSpecifier& argument, and false otherwise. 63314fbfa1STim Northover bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, 64314fbfa1STim Northover const LangOptions &LO, bool IsScanf = false); 65314fbfa1STim Northover 66314fbfa1STim Northover /// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8 67314fbfa1STim Northover /// string; check that it won't go further than \p FmtStrEnd and write 68314fbfa1STim Northover /// up the total size in \p Len. 69314fbfa1STim Northover bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, 70314fbfa1STim Northover const char *FmtStrEnd, unsigned &Len); 71314fbfa1STim Northover 72314fbfa1STim Northover template <typename T> class SpecifierResult { 73314fbfa1STim Northover T FS; 74314fbfa1STim Northover const char *Start; 75314fbfa1STim Northover bool Stop; 76314fbfa1STim Northover public: 77314fbfa1STim Northover SpecifierResult(bool stop = false) Start(nullptr)78314fbfa1STim Northover : Start(nullptr), Stop(stop) {} SpecifierResult(const char * start,const T & fs)79314fbfa1STim Northover SpecifierResult(const char *start, 80314fbfa1STim Northover const T &fs) 81314fbfa1STim Northover : FS(fs), Start(start), Stop(false) {} 82314fbfa1STim Northover getStart()83314fbfa1STim Northover const char *getStart() const { return Start; } shouldStop()84314fbfa1STim Northover bool shouldStop() const { return Stop; } hasValue()85314fbfa1STim Northover bool hasValue() const { return Start != nullptr; } getValue()86314fbfa1STim Northover const T &getValue() const { 87314fbfa1STim Northover assert(hasValue()); 88314fbfa1STim Northover return FS; 89314fbfa1STim Northover } getValue()90314fbfa1STim Northover const T &getValue() { return FS; } 91314fbfa1STim Northover }; 92314fbfa1STim Northover 93314fbfa1STim Northover } // end analyze_format_string namespace 94314fbfa1STim Northover } // end clang namespace 95314fbfa1STim Northover 96314fbfa1STim Northover #endif 97