xighlight/xyntax.h
2025-04-20 10:07:41 +00:00

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);
}