constructor.i (17540B)
1 /* -*- C++ -*- vim:set syntax=cpp: 2 * (C) 2005-2015 Frank-Rene Schaefer 3 * ABSOLUTELY NO WARRANTY */ 4 #ifndef __QUEX_INCLUDE_GUARD__ANALYZER__STRUCT__CONSTRUCTOR_I 5 #define __QUEX_INCLUDE_GUARD__ANALYZER__STRUCT__CONSTRUCTOR_I 6 7 #include "Buffer.i" 8 #include "LexatomLoader.i" 9 #include "analyzerInclude-stack" 10 11 QUEX_NAMESPACE_MAIN_OPEN 12 13 QUEX_INLINE void QUEX_NAME(Asserts_user_memory)(QUEX_TYPE_ANALYZER* me, 14 QUEX_TYPE_LEXATOM* BufferMemoryBegin, 15 size_t BufferMemorySize, 16 QUEX_TYPE_LEXATOM* BufferEndOfContentP /* = 0x0 */); 17 QUEX_INLINE void QUEX_NAME(Asserts_construct)(const char* CodecName); 18 QUEX_INLINE void QUEX_NAME(Tokens_construct)(QUEX_TYPE_ANALYZER* me); 19 QUEX_INLINE void QUEX_NAME(Tokens_reset)(QUEX_TYPE_ANALYZER* me); 20 QUEX_INLINE void QUEX_NAME(Tokens_destruct)(QUEX_TYPE_ANALYZER* me); 21 QUEX_INLINE void QUEX_NAME(ModeStack_construct)(QUEX_TYPE_ANALYZER* me); 22 23 24 /* Level (1) __________________________________________________________________ 25 * */ 26 QUEX_INLINE void 27 QUEX_MEMBER_FUNCTION2(from, file_name, 28 const char* FileName, 29 const char* CodecName) 30 { 31 QUEX_NAME(ByteLoader)* byte_loader; 32 33 byte_loader = QUEX_NAME(ByteLoader_FILE_new_from_file_name)(FileName); 34 /* NOT: Abort/return if byte_loader == 0 !! 35 * Incomplete construction => propper destruction IMPOSSIBLE! */ 36 if( byte_loader ) { 37 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 38 } 39 QUEX_MEMBER_FUNCTION_CALL2(from, ByteLoader, byte_loader, CodecName); 40 } 41 42 /* Level (2) __________________________________________________________________ 43 * */ 44 QUEX_INLINE void 45 QUEX_MEMBER_FUNCTION3(from, FILE, 46 __QUEX_STD_FILE* fh, 47 const char* CodecName /* = 0x0 */, 48 bool BinaryModeF /* = false */) 49 /* 'BinaryModeF' tells whether the file has been opened in 'binary mode'. */ 50 { 51 QUEX_NAME(ByteLoader)* byte_loader; 52 __quex_assert( fh ); 53 54 /* At the time of this writing 'stdin' as located in the C++ global 55 * namespace. This seemed suspicous to the author. To avoid compilation 56 * errors in the future the test for the standard input is only active in 57 * 'C'. It is only about user information anyway. So better no risks taken. 58 * <fschaef 2010y02m06d> */ 59 setbuf(fh, 0); /* turn off system based buffering! 60 ** ** this is essential to profit from the quex buffer! */ 61 byte_loader = QUEX_NAME(ByteLoader_FILE_new)(fh, BinaryModeF); 62 /* NOT: Abort/return if byte_loader == 0 !! 63 * Incomplete construction => propper destruction IMPOSSIBLE! */ 64 if( byte_loader ) { 65 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 66 } 67 QUEX_MEMBER_FUNCTION_CALL2(from, ByteLoader, byte_loader, CodecName); 68 } 69 70 #ifndef __QUEX_OPTION_PLAIN_C 71 QUEX_INLINE void 72 QUEX_MEMBER_FUNCTION3(from, istream, 73 std::istream* istream_p, 74 const char* CodecName /* = 0x0 */, 75 bool BinaryModeF /* = false */) 76 { 77 QUEX_NAME(ByteLoader)* byte_loader; 78 __quex_assert( istream_p ); 79 80 byte_loader = QUEX_NAME(ByteLoader_stream_new)(istream_p); 81 byte_loader->binary_mode_f = BinaryModeF; 82 83 /* NOT: Abort/return if byte_loader == 0 !! 84 * Incomplete construction => propper destruction IMPOSSIBLE! */ 85 if( byte_loader ) { 86 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 87 } 88 QUEX_MEMBER_FUNCTION_CALL2(from, ByteLoader, byte_loader, CodecName); 89 } 90 #endif 91 92 93 #if defined(__QUEX_OPTION_WCHAR_T) && ! defined(__QUEX_OPTION_PLAIN_C) 94 QUEX_INLINE void 95 QUEX_MEMBER_FUNCTION3(from, wistream, 96 std::wistream* istream_p, 97 const char* CodecName /* = 0x0 */, 98 bool BinaryModeF /* = false */) 99 { 100 QUEX_NAME(ByteLoader)* byte_loader; 101 __quex_assert( istream_p ); 102 103 byte_loader = QUEX_NAME(ByteLoader_stream_new)(istream_p); 104 byte_loader->binary_mode_f = BinaryModeF; 105 106 /* NOT: Abort/return if byte_loader == 0 !! 107 * Incomplete construction => propper destruction IMPOSSIBLE! */ 108 if( byte_loader ) { 109 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 110 } 111 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 112 QUEX_MEMBER_FUNCTION_CALL2(from, ByteLoader, byte_loader, CodecName); 113 } 114 #endif 115 116 #if defined(__QUEX_OPTION_UNIT_TEST) && ! defined (__QUEX_OPTION_PLAIN_C) 117 /* StrangeStreams are not for C-language stuff */ 118 template<class UnderlyingStreamT> QUEX_INLINE void 119 QUEX_MEMBER_FUNCTION2(from_StrangeStream, strange_stream, 120 quex::StrangeStream<UnderlyingStreamT>* istream_p, 121 const char* CodecName /* = 0x0 */) 122 { 123 QUEX_NAME(ByteLoader)* byte_loader; 124 __quex_assert( istream_p ); 125 126 byte_loader = QUEX_NAME(ByteLoader_stream_new)(istream_p); 127 byte_loader->binary_mode_f = false; 128 129 /* NOT: Abort/return if byte_loader == 0 !! 130 * Incomplete construction => propper destruction IMPOSSIBLE! */ 131 if( byte_loader ) { 132 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 133 } 134 135 byte_loader->ownership = E_Ownership_LEXICAL_ANALYZER; 136 QUEX_MEMBER_FUNCTION_CALL2(from, ByteLoader, byte_loader, CodecName); 137 } 138 #endif 139 140 141 /* Level (3) __________________________________________________________________ 142 * */ 143 QUEX_INLINE void 144 QUEX_MEMBER_FUNCTION2(from, ByteLoader, 145 QUEX_NAME(ByteLoader)* byte_loader, 146 const char* CodecName) 147 { 148 QUEX_NAME(LexatomLoader)* filler; 149 QUEX_NAME(Asserts_construct)(CodecName); 150 151 filler = QUEX_NAME(LexatomLoader_new_DEFAULT)(byte_loader, CodecName); 152 /* NOT: Abort/return if filler == 0 !! 153 * Incomplete construction => propper destruction IMPOSSIBLE! */ 154 if( filler ) { 155 filler->ownership = E_Ownership_LEXICAL_ANALYZER; 156 } 157 158 QUEX_MEMBER_FUNCTION_CALL1(from, LexatomLoader, filler); 159 } 160 161 /* Level (4) __________________________________________________________________ 162 * */ 163 QUEX_INLINE void 164 QUEX_MEMBER_FUNCTION1(from, LexatomLoader, 165 QUEX_NAME(LexatomLoader)* filler) 166 { 167 QUEX_MAP_THIS_TO_ME(QUEX_TYPE_ANALYZER) 168 QUEX_TYPE_LEXATOM* memory; 169 170 memory = (QUEX_TYPE_LEXATOM*)QUEXED(MemoryManager_allocate)( 171 QUEX_SETTING_BUFFER_SIZE * sizeof(QUEX_TYPE_LEXATOM), 172 E_MemoryObjectType_BUFFER_MEMORY); 173 /* NOT: Abort/return if memory == 0 !! 174 * Incomplete construction => propper destruction IMPOSSIBLE! */ 175 176 QUEX_NAME(Buffer_construct)(&me->buffer, filler, 177 memory, QUEX_SETTING_BUFFER_SIZE, 178 (QUEX_TYPE_LEXATOM*)0, 179 E_Ownership_LEXICAL_ANALYZER); 180 QUEX_MEMBER_FUNCTION_CALLO1(basic_constructor, (const char*)"<unknown>"); 181 } 182 183 /* Level (5) __________________________________________________________________ 184 * */ 185 QUEX_INLINE void 186 QUEX_MEMBER_FUNCTION3(from, memory, 187 QUEX_TYPE_LEXATOM* Memory, 188 const size_t MemorySize, 189 QUEX_TYPE_LEXATOM* EndOfFileP) 190 191 /* When memory is provided from extern, the 'external entity' is responsible 192 * for filling it. There is no 'file/stream handle', no 'byte loader', and 'no 193 * buffer filler'. */ 194 { 195 QUEX_MAP_THIS_TO_ME(QUEX_TYPE_ANALYZER) 196 QUEX_ASSERT_MEMORY(Memory, MemorySize, EndOfFileP); 197 198 QUEX_NAME(Buffer_construct)(&me->buffer, 199 (QUEX_NAME(LexatomLoader)*)0, 200 Memory, MemorySize, EndOfFileP, 201 E_Ownership_EXTERNAL); 202 QUEX_MEMBER_FUNCTION_CALLO1(basic_constructor, (const char*)"<memory>"); 203 } 204 205 QUEX_INLINE void 206 QUEX_MEMBER_FUNCTIONO1(basic_constructor, const char* InputNameP) 207 { 208 QUEX_MAP_THIS_TO_ME(QUEX_TYPE_ANALYZER) 209 QUEX_NAME(Tokens_construct)(me); 210 QUEX_NAME(ModeStack_construct)(me); 211 __QUEX_IF_INCLUDE_STACK( me->_parent_memento = (QUEX_NAME(Memento)*)0); 212 __QUEX_IF_STRING_ACCUMULATOR(QUEX_NAME(Accumulator_construct)(&me->accumulator, me)); 213 __QUEX_IF_POST_CATEGORIZER( QUEX_NAME(PostCategorizer_construct)(&me->post_categorizer)); 214 __QUEX_IF_COUNT( QUEX_NAME(Counter_construct)(&me->counter); ) 215 216 /* A user's mode change callbacks may be called as a consequence of the 217 * call to 'set_mode_brutally_by_id()'. The current mode must be set to '0' 218 * so that the user may detect whether this is the first mode transition.*/ 219 me->__current_mode_p = (QUEX_NAME(Mode)*)0; 220 QUEX_NAME(set_mode_brutally_by_id)(me, __QUEX_SETTING_INITIAL_LEXER_MODE_ID); 221 222 me->__input_name = (char*)0; 223 (void)QUEX_MEMBER_FUNCTION_CALLO1(input_name_set, InputNameP); 224 225 QUEX_MEMBER_FUNCTION_CALLO(user_constructor); 226 } 227 228 QUEX_INLINE 229 QUEX_DESTRUCTOR() 230 { 231 QUEX_MAP_THIS_TO_ME(QUEX_TYPE_ANALYZER) 232 QUEX_NAME(Tokens_destruct)(me); 233 234 __QUEX_IF_INCLUDE_STACK(QUEX_MEMBER_FUNCTION_CALLO(include_stack_delete)); 235 /* IMPORTANT: THE ACCUMULATOR CAN ONLY BE DESTRUCTED AFTER THE INCLUDE 236 * STACK HAS BEEN DELETED. OTHERWISE, THERE MIGHT BE LEAKS. 237 * TODO: Why? I cannot see a reason <fschaef 15y08m03d> */ 238 __QUEX_IF_STRING_ACCUMULATOR( QUEX_NAME(Accumulator_destruct)(&me->accumulator)); 239 __QUEX_IF_POST_CATEGORIZER( QUEX_NAME(PostCategorizer_destruct)(&me->post_categorizer)); 240 241 QUEX_NAME(Buffer_destruct)(&me->buffer); 242 243 if( me->__input_name ) { 244 QUEXED(MemoryManager_free)(me->__input_name, E_MemoryObjectType_BUFFER_MEMORY); 245 } 246 } 247 248 QUEX_INLINE void 249 QUEX_NAME(Asserts_user_memory)(QUEX_TYPE_ANALYZER* me, 250 QUEX_TYPE_LEXATOM* BufferMemoryBegin, 251 size_t BufferMemorySize, 252 QUEX_TYPE_LEXATOM* BufferEndOfContentP /* = 0x0 */) 253 { 254 # ifdef QUEX_OPTION_ASSERTS 255 size_t memory_size = BufferMemoryBegin ? BufferMemorySize 256 : QUEX_SETTING_BUFFER_SIZE; 257 QUEX_TYPE_LEXATOM* iterator = 0x0; 258 259 __quex_assert(memory_size == 0 || memory_size > 2); 260 if( BufferMemoryBegin ) { 261 /* End of File must be inside the buffer, because we assume that the buffer 262 * contains all that is required. */ 263 if( BufferMemorySize <= QUEX_SETTING_BUFFER_MIN_FALLBACK_N + 2) { 264 QUEX_ERROR_EXIT("\nConstructor: Provided memory size must be more than 2 greater than\n" 265 "Constructor: QUEX_SETTING_BUFFER_MIN_FALLBACK_N. If in doubt, specify\n" 266 "Constructor: -DQUEX_SETTING_BUFFER_MIN_FALLBACK_N=0 as compile option.\n"); 267 } 268 if( BufferEndOfContentP < BufferMemoryBegin 269 || BufferEndOfContentP > (BufferMemoryBegin + BufferMemorySize - 1)) { 270 QUEX_ERROR_EXIT("\nConstructor: Argument 'BufferEndOfContentP' must be inside the provided memory\n" 271 "Constructor: buffer (speficied by 'BufferMemoryBegin' and 'BufferMemorySize').\n" 272 "Constructor: Note, that the last element of the buffer is to be filled with\n" 273 "Constructor: the buffer limit code character.\n"); 274 } 275 } 276 if( BufferEndOfContentP ) { 277 __quex_assert(BufferEndOfContentP > BufferMemoryBegin); 278 __quex_assert(BufferEndOfContentP <= BufferMemoryBegin + memory_size - 1); 279 280 /* The memory provided must be initialized. If it is not, then that's wrong. 281 * Try to detect me by searching for BLC and PTC. */ 282 for(iterator = BufferMemoryBegin + 1; iterator != BufferEndOfContentP; ++iterator) { 283 if( *iterator == QUEX_SETTING_BUFFER_LIMIT_CODE 284 || *iterator == QUEX_SETTING_PATH_TERMINATION_CODE ) { 285 QUEX_ERROR_EXIT("\nConstructor: Buffer limit code and/or path termination code appeared in buffer\n" 286 "Constructor: when pointed to user memory. Note, that the memory pointed to must\n" 287 "Constructor: be initialized! You might redefine QUEX_SETTING_PATH_TERMINATION_CODE\n" 288 "Constructor: and/or QUEX_SETTING_PATH_TERMINATION_CODE; or use command line arguments\n" 289 "Constructor: '--buffer-limit' and '--path-termination'."); 290 } 291 } 292 } 293 # endif 294 295 /* NOT: before ifdef, otherwise c90 issue: mixed declarations and code */ 296 (void)me; (void)BufferMemoryBegin; (void)BufferMemorySize; (void)BufferEndOfContentP; 297 } 298 299 /* AUXILIARY FUNCTIONS FOR CONSTRUCTION _______________________________________ 300 * */ 301 302 QUEX_INLINE void 303 QUEX_NAME(Asserts_construct)(const char* CodecName) 304 { 305 (void)CodecName; 306 307 # if defined(QUEX_OPTION_ASSERTS) \ 308 && ! defined(QUEX_OPTION_ASSERTS_WARNING_MESSAGE_DISABLED) 309 __QUEX_STD_printf(__QUEX_MESSAGE_ASSERTS_INFO); 310 # endif 311 312 # if defined(QUEX_OPTION_ASSERTS) 313 if( QUEX_SETTING_BUFFER_LIMIT_CODE == QUEX_SETTING_PATH_TERMINATION_CODE ) { 314 QUEX_ERROR_EXIT("Path termination code (PTC) and buffer limit code (BLC) must be different.\n"); 315 } 316 # endif 317 318 # if defined(__QUEX_OPTION_ENGINE_RUNNING_ON_CODEC) 319 if( CodecName ) { 320 __QUEX_STD_printf(__QUEX_MESSAGE_CHARACTER_ENCODING_SPECIFIED_WITHOUT_CONVERTER, CodecName); 321 } 322 # endif 323 } 324 325 #if ! defined(QUEX_TYPE_TOKEN) 326 # error "QUEX_TYPE_TOKEN must be defined before inclusion of this file." 327 #endif 328 QUEX_INLINE void 329 QUEX_NAME(Tokens_construct)(QUEX_TYPE_ANALYZER* me) 330 { 331 #if defined(QUEX_OPTION_TOKEN_POLICY_QUEUE) 332 # if defined(QUEX_OPTION_USER_MANAGED_TOKEN_MEMORY) 333 /* Assume that the user will pass us a constructed token queue */ 334 QUEX_NAME(TokenQueue_disfunctionality_set)(&me->_token_queue); 335 # else 336 QUEX_NAME(TokenQueue_construct)(&me->_token_queue, 337 (QUEX_TYPE_TOKEN*)&me->__memory_token_queue, 338 QUEX_SETTING_TOKEN_QUEUE_SIZE); 339 # endif 340 #elif defined(QUEX_OPTION_USER_MANAGED_TOKEN_MEMORY) 341 /* Assume that the user will pass us a constructed token */ 342 me->token = (QUEX_TYPE_TOKEN*)0x0; 343 # else 344 me->token = &me->__memory_token; 345 # ifdef __QUEX_OPTION_PLAIN_C 346 QUEX_NAME_TOKEN(construct)(me->token); 347 # endif 348 #endif 349 } 350 351 QUEX_INLINE void 352 QUEX_NAME(Tokens_destruct)(QUEX_TYPE_ANALYZER* me) 353 { 354 /* Even if the token memory is user managed, the destruction (not the 355 * freeing of memory) must happen at this place. */ 356 #ifdef QUEX_OPTION_TOKEN_POLICY_QUEUE 357 QUEX_NAME(TokenQueue_destruct)(&me->_token_queue); 358 #else 359 # if defined(__QUEX_OPTION_PLAIN_C) \ 360 && ! defined(QUEX_OPTION_USER_MANAGED_TOKEN_MEMORY) 361 QUEX_NAME_TOKEN(destruct)(me->token); 362 # endif 363 #endif 364 } 365 366 QUEX_INLINE void 367 QUEX_NAME(Tokens_reset)(QUEX_TYPE_ANALYZER* me) 368 { 369 #ifdef QUEX_OPTION_TOKEN_POLICY_QUEUE 370 QUEX_NAME(TokenQueue_reset)(&me->_token_queue); 371 #else 372 QUEX_NAME(Tokens_destruct(me)); 373 QUEX_NAME(Tokens_construct(me)); 374 #endif 375 } 376 377 QUEX_INLINE void 378 QUEX_NAME(ModeStack_construct)(QUEX_TYPE_ANALYZER* me) 379 { 380 me->_mode_stack.end = me->_mode_stack.begin; 381 me->_mode_stack.memory_end = &me->_mode_stack.begin[QUEX_SETTING_MODE_STACK_SIZE]; 382 } 383 384 QUEX_INLINE const char* 385 QUEX_MEMBER_FUNCTIONO(input_name) 386 { QUEX_MAP_THIS_TO_ME(QUEX_TYPE_ANALYZER) return me->__input_name; } 387 388 QUEX_INLINE bool 389 QUEX_MEMBER_FUNCTIONO1(input_name_set, const char* InputNameP) 390 { 391 QUEX_MAP_THIS_TO_ME(QUEX_TYPE_ANALYZER) 392 393 if( me->__input_name ) { 394 QUEXED(MemoryManager_free)(me->__input_name, E_MemoryObjectType_BUFFER_MEMORY); 395 } 396 me->__input_name = (char*)QUEXED(MemoryManager_allocate)( 397 sizeof(char)*(__QUEX_STD_strlen(InputNameP)+1), 398 E_MemoryObjectType_BUFFER_MEMORY); 399 if( me->__input_name ) { 400 __QUEX_STD_strcpy(me->__input_name, InputNameP); 401 return true; 402 } 403 return false; 404 } 405 406 407 QUEX_NAMESPACE_MAIN_CLOSE 408 409 #endif /* __QUEX_INCLUDE_GUARD__ANALYZER__STRUCT__CONSTRUCTOR_I */