ALib C++ Library
Library Version: 2510 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
23 import ALib.Lang;
24 import ALib.EnumRecords;
25#if ALIB_MONOMEM && ALIB_CONTAINERS
26 import ALib.Monomem;
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 {
51 void assembleMsgAndThrow [[noreturn]] ( const NString& error )
52 {
54 - EnumRecordParser::Input .Length();
55
56 NAString msg;
57 msg << "ERROR WHILE PARSING ENUMERATION RECORD STRING" << NEW_LINE
58 << " Detail: " << error << NEW_LINE
59 << " Resrc : "; if(EnumRecordParser::ResourceCategory.IsNotEmpty() )
61 << "\" / \"" << EnumRecordParser::ResourceName << '"';
62 else
63 msg << "(Not resourced)";
64 msg << NEW_LINE
65 << " Column: " << column + 1 << NEW_LINE
66 << " Input : \"" << EnumRecordParser::OriginalInput << '"' << NEW_LINE
67 << " ";
68 for( integer i= column ; i >= 0 ; --i )
69 msg << (i != 0 ? '-' : '>');
70 msg << "^<--";
71
72 throw std::runtime_error( msg.Terminate() );
73 }
74} // anonymous namespace
75
82
83void EnumRecordParser::error [[noreturn]] (const NCString& what)
84{
85 assembleMsgAndThrow( NString256() << what << '.' );
86}
87
89{
90 if( Input.IsNotEmpty()
92 assembleMsgAndThrow( NString256() << "Found whitespaces "
93 << where );
94}
95
97{
98 if( token.LastIndexOfAny<lang::Inclusion::Exclude>( DEFAULT_WHITESPACES ) != token.Length() -1 )
99 assembleMsgAndThrow( NString256() << "Found trailing whitespaces in string value \""
100 << token << '"' );
101}
102
103void EnumRecordParser::assertNoUnnecessary(character specificChar, const NCString& where)
104{
105 if( Input.CharAtStart() == specificChar )
106 assembleMsgAndThrow( NString256() << "Unnecessary character \""
107 << specificChar
108 << "\" found " << where );
109}
110
111void EnumRecordParser::assertChar(character specificChar, const NCString& where)
112{
113 if( !Input.ConsumeChar(specificChar) )
114 assembleMsgAndThrow( NString256() << where << '\"' << specificChar << '\"');
115}
116
118{
119 if ( Input.IsEmpty() )
120 return;
121 assertNoWhitespaces( "after record" );
122 if( Input.CharAtStart() != OuterDelimChar )
123 assembleMsgAndThrow( NString256() << "Expected outer delimiter or end of input" );
124}
125
127{
128 if ( !Input.IsEmpty() )
129 assembleMsgAndThrow( NString256() << "Expected end of parsable input string" );
130}
131
132integer EnumRecordParser::getInteger( bool isLastField )
133{
134 integer bigInt;
135 assertNoWhitespaces( "before integral value" );
136 assertNoUnnecessary( A_CHAR('+'), "before integral value" );
137
138 if( Input.ConsumeString<lang::Case::Ignore>( A_CHAR("max") ) )
139 bigInt= (std::numeric_limits<integer>::max)();
140 else if( Input.ConsumeString<lang::Case::Ignore>( A_CHAR("min") ) ) bigInt= (std::numeric_limits<integer>::min)();
141 else if( Input.ConsumeChar( A_CHAR('^') ) )
142 {
143 int exp;
144 if( !Input.ConsumeDec( exp ) )
145 error("Power of 2 symbol '^' is not followed by a number" );
146 bigInt= integer(1LL << exp);
147 }
148 else
149 {
150 if( (!isLastField && ( Input.CharAtStart() == InnerDelimChar ) )
151 || ( isLastField && ( Input.CharAtStart() == OuterDelimChar || Input.IsEmpty()) ) )
152 bigInt= 0;
153 else
154 if( ! Input.ConsumeInt( bigInt ) )
155 error( "Not an integral value" );
156 }
157
158 if( !isLastField )
159 Delim();
160 else
162 return bigInt;
163}
164
165
166void EnumRecordParser::Get( String& result, bool isLastField )
167{
168 assertNoWhitespaces( "before string" );
169 if( !isLastField )
170 result= Input.ConsumeToken(InnerDelimChar);
171 else
172 Input.ConsumeChars<NC>( Input.IndexOfOrLength( OuterDelimChar ), result );
174 if( isLastField )
176}
177
178void EnumRecordParser::Get( character& result, bool isLastField )
179{
180 assertNoWhitespaces( "before a character value" );
181 result= Input.ConsumeChar<CHK, lang::Whitespaces::Keep>();
182 if( (!isLastField && ( result == InnerDelimChar ) )
183 || ( isLastField && ( result == OuterDelimChar || result == '\0' ) ) )
184 result= '\0';
185 else
186 {
187 if( result == '\0' )
188 error("End of input when parsing a character." );
189 assertNoWhitespaces( "after a character value" );
190 if( !isLastField )
191 Delim();
192 else
194 }
195}
196
197void EnumRecordParser::Get( double& result, bool isLastField )
198{
199 assertNoWhitespaces( "before a floating point value" );
200 assertNoUnnecessary( A_CHAR('+'), "before floating point value" );
201 if( (!isLastField && ( Input.CharAtStart() == InnerDelimChar ) )
202 || ( isLastField && ( Input.CharAtStart() == OuterDelimChar || Input.IsEmpty()) ) )
203 result= 0.0;
204 else
205 if( !Input.ConsumeFloat( result ) )
206 error("Not a floating point value" );
207
208 if( !isLastField )
209 Delim();
210 else
212}
213
215{
216 assertNoWhitespaces( "before a delimiter");
217 assertChar(InnerDelimChar,"expected inner delimiter" );
218 assertNoWhitespaces( "after an inner delimiter");
219}
220
222{
223 assertNoWhitespaces( "before an outer delimiter");
224 assertChar(OuterDelimChar,"expected outer delimiter" );
225 assertNoWhitespaces( "after an outer delimiter");
226}
227
228#endif // #if !DOXYGEN
229
230
231// #################################################################################################
232// enumrecords::detail::bootstrap()
233// #################################################################################################
234} namespace alib::enumrecords::detail {
235
236# include "ALib.Lang.CIFunctions.H"
238{
239 #if ALIB_MONOMEM && ALIB_CONTAINERS
240 getInternalRecordMap().Reset();
241 #endif
242}
243
244} // namespace [alib::enumrecords::detail]
245# include "ALib.Lang.CIMethods.H"
246
247
#define A_CHAR(STR)
HashMap< MonoAllocator, EnumRecordKey, const void *, EnumRecordKey::Hash, EnumRecordKey::EqualTo > & getInternalRecordMap()
Definition records.cpp:89
@ 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:644
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2390
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
strings::TCString< nchar > NCString
Type alias in namespace alib.
Definition cstring.inl:512
constexpr CString DEFAULT_WHITESPACES
A zero-terminated string of default whitespace characters.
Definition cstring.inl:664
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
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).