ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
recordparser.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
16#include <stdexcept>
17#if !ALIB_MONOMEM && ALIB_CONTAINERS
18# include <unordered_map>
19#endif
20//============================================== Module ============================================
21#if ALIB_C20_MODULES
22 module ALib.EnumRecords.Bootstrap;
23 import ALib.Lang;
24 import ALib.EnumRecords;
25#if ALIB_MONOMEM && ALIB_CONTAINERS
26 import ALib.Monomem;
27 import ALib.Containers.HashTable;
28#endif
29#if ALIB_FORMAT
30 import ALib.Format;
31#endif
32#else
33# include "ALib.Lang.H"
34# include "ALib.EnumRecords.H"
36#if ALIB_MONOMEM && ALIB_CONTAINERS
37# include "ALib.Monomem.H"
39#endif
40# include "ALib.Format.H"
41#endif
42//========================================== Implementation ========================================
44
45//##################################################################################################
46// EnumRecordParser
47//##################################################################################################
48#if !DOXYGEN
49
50namespace {
51void assembleMsgAndThrow [[noreturn]] ( const NString& error ) {
53 - EnumRecordParser::Input .Length();
54
55 NAString msg;
56 msg << "ERROR WHILE PARSING ENUMERATION RECORD STRING" << NEW_LINE
57 << " Detail: " << error << NEW_LINE
58 << " Resrc : "; if(EnumRecordParser::ResourceCategory.IsNotEmpty() )
60 << "\" / \"" << EnumRecordParser::ResourceName << '"';
61 else
62 msg << "(Not resourced)";
63 msg << NEW_LINE
64 << " Column: " << column + 1 << NEW_LINE
65 << " Input : \"" << EnumRecordParser::OriginalInput << '"' << NEW_LINE
66 << " ";
67 for( integer i= column ; i >= 0 ; --i )
68 msg << (i != 0 ? '-' : '>');
69 msg << "^<--";
70
71 throw std::runtime_error( msg.Terminate() );
72}
73} // anonymous namespace
74
81
82void EnumRecordParser::error [[noreturn]] (const NCString& what)
83{ assembleMsgAndThrow( NString256() << what << '.' ); }
84
86 if( Input.IsNotEmpty()
88 assembleMsgAndThrow( NString256() << "Found whitespaces "
89 << where );
90}
91
93 if( token.LastIndexOfAny<lang::Inclusion::Exclude>( DEFAULT_WHITESPACES ) != token.Length() -1 )
94 assembleMsgAndThrow( NString256() << "Found trailing whitespaces in string value \""
95 << token << '"' );
96}
97
98void EnumRecordParser::assertNoUnnecessary(character specificChar, const NCString& where) {
99 if( Input.CharAtStart() == specificChar )
100 assembleMsgAndThrow( NString256() << "Unnecessary character \""
101 << specificChar
102 << "\" found " << where );
103}
104
105void EnumRecordParser::assertChar(character specificChar, const NCString& where)
106{
107 if( !Input.ConsumeChar(specificChar) )
108 assembleMsgAndThrow( NString256() << where << '\"' << specificChar << '\"');
109}
110
112 if ( Input.IsEmpty() )
113 return;
114 assertNoWhitespaces( "after record" );
115 if( Input.CharAtStart() != OuterDelimChar )
116 assembleMsgAndThrow( NString256() << "Expected outer delimiter or end of input" );
117}
118
120{
121 if ( !Input.IsEmpty() )
122 assembleMsgAndThrow( NString256() << "Expected end of parsable input string" );
123}
124
125integer EnumRecordParser::getInteger( bool isLastField ) {
126 integer bigInt;
127 assertNoWhitespaces( "before integral value" );
128 assertNoUnnecessary( A_CHAR('+'), "before integral value" );
129
130 if( Input.ConsumeString<lang::Case::Ignore>( A_CHAR("max") ) )
131 bigInt= (std::numeric_limits<integer>::max)();
132 else if( Input.ConsumeString<lang::Case::Ignore>( A_CHAR("min") ) ) bigInt= (std::numeric_limits<integer>::min)();
133 else if( Input.ConsumeChar( A_CHAR('^') ) ) {
134 int exp;
135 if( !Input.ConsumeDec( exp ) )
136 error("Power of 2 symbol '^' is not followed by a number" );
137 bigInt= integer(1LL << exp);
138 } else {
139 if( (!isLastField && ( Input.CharAtStart() == InnerDelimChar ) )
140 || ( isLastField && ( Input.CharAtStart() == OuterDelimChar || Input.IsEmpty()) ) )
141 bigInt= 0;
142 else
143 if( ! Input.ConsumeInt( bigInt ) )
144 error( "Not an integral value" );
145 }
146
147 if( !isLastField )
148 Delim();
149 else
151 return bigInt;
152}
153
154
155void EnumRecordParser::Get( String& result, bool isLastField ) {
156 assertNoWhitespaces( "before string" );
157 if( !isLastField )
158 result= Input.ConsumeToken(InnerDelimChar);
159 else
160 Input.ConsumeChars<NC>( Input.IndexOfOrLength( OuterDelimChar ), result );
162 if( isLastField )
164}
165
166void EnumRecordParser::Get( character& result, bool isLastField ) {
167 assertNoWhitespaces( "before a character value" );
168 result= Input.ConsumeChar<CHK, lang::Whitespaces::Keep>();
169 if( (!isLastField && ( result == InnerDelimChar ) )
170 || ( isLastField && ( result == OuterDelimChar || result == '\0' ) ) )
171 result= '\0';
172 else {
173 if( result == '\0' )
174 error("End of input when parsing a character." );
175 assertNoWhitespaces( "after a character value" );
176 if( !isLastField )
177 Delim();
178 else
180} }
181
182void EnumRecordParser::Get( double& result, bool isLastField ) {
183 assertNoWhitespaces( "before a floating point value" );
184 assertNoUnnecessary( A_CHAR('+'), "before floating point value" );
185 if( (!isLastField && ( Input.CharAtStart() == InnerDelimChar ) )
186 || ( isLastField && ( Input.CharAtStart() == OuterDelimChar || Input.IsEmpty()) ) )
187 result= 0.0;
188 else
189 if( !Input.ConsumeFloat( result ) )
190 error("Not a floating point value" );
191
192 if( !isLastField )
193 Delim();
194 else
196}
197
199 assertNoWhitespaces( "before a delimiter");
200 assertChar(InnerDelimChar,"expected inner delimiter" );
201 assertNoWhitespaces( "after an inner delimiter");
202}
203
205 assertNoWhitespaces( "before an outer delimiter");
206 assertChar(OuterDelimChar,"expected outer delimiter" );
207 assertNoWhitespaces( "after an outer delimiter");
208}
209
210#endif // #if !DOXYGEN
211
212
213//##################################################################################################
214// enumrecords::detail::bootstrap()
215//##################################################################################################
216} namespace alib::enumrecords::detail {
217
218# include "ALib.Lang.CIFunctions.H"
219void shutdown() {
220 #if ALIB_MONOMEM && ALIB_CONTAINERS
221 getInternalRecordMap().Reset();
222 #endif
223}
224
225} // namespace [alib::enumrecords::detail]
226# include "ALib.Lang.CIMethods.H"
#define A_CHAR(STR)
HashMap< MonoAllocator, EnumRecordKey, const void *, EnumRecordKey::Hash, EnumRecordKey::EqualTo > & getInternalRecordMap()
Definition records.cpp:87
@ Keep
Keep whitespaces in string.
@ Exclude
Chooses exclusion.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:616
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2198
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
strings::TCString< nchar > NCString
Type alias in namespace alib.
Definition cstring.inl:484
constexpr CString DEFAULT_WHITESPACES
A zero-terminated string of default whitespace characters.
Definition cstring.inl:636
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256>.
characters::character character
Type alias in namespace alib.
strings::TSubstring< character > Substring
Type alias in namespace alib.
static ALIB_DLL character InnerDelimChar
The delimiter of fields of a record.
static ALIB_DLL void assertNoTrailingWhitespaces(String &token)
static ALIB_DLL character OuterDelimChar
The delimiter of records.
static ALIB_DLL void assertChar(character specificChar, const NCString &where)
static ALIB_DLL Substring Input
The remaining input string.
static ALIB_DLL void error(const NCString &what)
static ALIB_DLL void assertNoWhitespaces(const NCString &where)
static ALIB_DLL void assertNoUnnecessary(character specificChar, const NCString &where)
static ALIB_DLL String OriginalInput
A backup of the originally given string to parse.
static ALIB_DLL void Get(String &result, bool isLastField=false)
static ALIB_DLL integer getInteger(bool isLastField)
static ALIB_DLL NString ResourceCategory
The resource category (if a resourced string was parsed).
static ALIB_DLL NString ResourceName
The resource name (if a resourced string was parsed).