176 lines
5.8 KiB
C
176 lines
5.8 KiB
C
/// _
|
|
/// __ ___ _ _ __ | |_ __ ___ __
|
|
/// \ \/ / | | | '_ \| __/ _` \ \/ /
|
|
/// > <| |_| | | | | || (_| |> <
|
|
/// /_/\_\\__, |_| |_|\__\__,_/_/\_\
|
|
/// |___/
|
|
///
|
|
/// 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);
|
|
}
|