/// _ /// __ ___ _ _ __ | |_ __ ___ __ /// \ \/ / | | | '_ \| __/ _` \ \/ / /// > <| |_| | | | | || (_| |> < /// /_/\_\\__, |_| |_|\__\__,_/_/\_\ /// |___/ /// /// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic /// /// xolatile@chud.cyou - xyntax - Tiny, unsafe and somewhat insane unity header for generic syntax definition. /// /// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU /// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish... /// /// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied /// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License /// for more details, if you dare, it is a lot of text that nobody wants to read... typedef struct { natural count; natural limit; boolean * enrange; boolean * derange; character * * begin; character * * end; character * escape; natural * colour; natural * effect; } syntax_structure; static syntax_structure * syntax_initialize (natural limit) { syntax_structure * syntax = allocate (sizeof (* syntax)); syntax->limit = limit; if (limit != 0) { syntax->enrange = allocate (syntax->limit * sizeof (* syntax->enrange)); syntax->derange = allocate (syntax->limit * sizeof (* syntax->derange)); syntax->begin = allocate (syntax->limit * sizeof (* syntax->begin)); syntax->end = allocate (syntax->limit * sizeof (* syntax->end)); syntax->escape = allocate (syntax->limit * sizeof (* syntax->escape)); syntax->colour = allocate (syntax->limit * sizeof (* syntax->colour)); syntax->effect = allocate (syntax->limit * sizeof (* syntax->effect)); } return (syntax); } static syntax_structure * syntax_deinitialize (syntax_structure * syntax) { for (natural index = 0; index < syntax->count; ++index) { syntax->begin [index] = deallocate (syntax->begin [index]); syntax->end [index] = deallocate (syntax->end [index]); } syntax->enrange = deallocate (syntax->enrange); syntax->derange = deallocate (syntax->derange); syntax->begin = deallocate (syntax->begin); syntax->end = deallocate (syntax->end); syntax->escape = deallocate (syntax->escape); syntax->colour = deallocate (syntax->colour); syntax->effect = deallocate (syntax->effect); return (deallocate (syntax)); } static natural syntax_define (syntax_structure * syntax, boolean enrange, boolean derange, character * begin, character * end, character escape, natural colour, natural effect) { ++syntax->count; natural current = syntax->count - 1; fatal_failure (begin == null, "syntax_define: Begin string is null pointer."); fatal_failure (end == null, "syntax_define: End string is null pointer."); fatal_failure (syntax->count >= syntax->limit, "syntax_define: Reached the hardcoded limit."); if (syntax->limit == 0) { syntax->enrange = reallocate (syntax->enrange, syntax->count * sizeof (* syntax->enrange)); syntax->derange = reallocate (syntax->derange, syntax->count * sizeof (* syntax->derange)); syntax->begin = reallocate (syntax->begin, syntax->count * sizeof (* syntax->begin)); syntax->end = reallocate (syntax->end, syntax->count * sizeof (* syntax->end)); syntax->escape = reallocate (syntax->escape, syntax->count * sizeof (* syntax->escape)); syntax->colour = reallocate (syntax->colour, syntax->count * sizeof (* syntax->colour)); syntax->effect = reallocate (syntax->effect, syntax->count * sizeof (* syntax->effect)); } syntax->begin [current] = allocate ((string_length (begin) + 1) * sizeof (* * syntax->begin)); syntax->end [current] = allocate ((string_length (end) + 1) * sizeof (* * syntax->end)); syntax->enrange [current] = enrange; syntax->derange [current] = derange; syntax->escape [current] = escape; syntax->colour [current] = colour; syntax->effect [current] = effect; string_copy (syntax->begin [current], begin); string_copy (syntax->end [current], end); return (current); } static natural syntax_select (syntax_structure * syntax, character * string, natural * length) { natural offset = 0; natural subset = 0; natural select = 0; natural_64 begin_length = 0; natural_64 end_length = 0; for (; select != syntax->count; ++select) { begin_length = string_length (syntax->begin [select]); if (! syntax->enrange [select]) { if (! syntax->derange [select]) { if (string_compare_limit (string, syntax->begin [select], begin_length)) { break; } } else { if ((string_compare_limit (string, syntax->begin [select], begin_length)) && (character_compare_array (string [offset + begin_length], syntax->end [select]))) { break; } } } else { for (subset = 0; subset != begin_length; ++subset) { if (string [offset] == syntax->begin [select] [subset]) { goto selected; } } } } selected: if (select >= syntax->count) { * length = 1; return (syntax->count); } end_length = string_length (syntax->end [select]); for (offset = 1; string [offset - 1] != character_null; ++offset) { if (string [offset] == syntax->escape [select]) { ++offset; continue; } if (syntax->derange [select]) { subset = 0; if (end_length == 0) { break; } do { if (string [offset] == syntax->end [select] [subset]) { * length = offset; goto finished; } } while (++subset != end_length); } else { if (end_length != 0) { if (string_compare_limit (& string [offset], syntax->end [select], end_length)) { * length = offset + end_length; return (select); } } else { * length = 1; return (select); } } } finished: return (select); }