mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 21:25:11 +00:00
261 lines
4.4 KiB
C
261 lines
4.4 KiB
C
#include <StringSplit.h>
|
|
|
|
#include <Cytoplasm/Memory.h>
|
|
#include <Cytoplasm/Str.h>
|
|
#include <Cytoplasm/Log.h>
|
|
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
|
|
char **
|
|
StrSplitLines(char *text)
|
|
{
|
|
char **ret = NULL;
|
|
size_t lines = 0;
|
|
|
|
char *next = text, *ptr = text;
|
|
bool done = false;
|
|
if (!text)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
while (!done)
|
|
{
|
|
size_t bytes;
|
|
char *line;
|
|
|
|
next = strchr(ptr, '\n');
|
|
if (!next)
|
|
{
|
|
next = text + strlen(text);
|
|
done = true;
|
|
}
|
|
|
|
/* Take the chunk from ptr to [text] */
|
|
bytes = next - ptr;
|
|
line = Malloc(bytes + 1);
|
|
memcpy(line, ptr, bytes);
|
|
line[bytes] = '\0';
|
|
|
|
ret = Realloc(ret, sizeof(char *) * ++lines);
|
|
ret[lines - 1] = line;
|
|
|
|
ptr = *next ? next + 1 : next;
|
|
}
|
|
|
|
ret = Realloc(ret, sizeof(char *) * ++lines);
|
|
ret[lines - 1] = NULL;
|
|
return ret;
|
|
}
|
|
void
|
|
StrFreeLines(char **split)
|
|
{
|
|
char *line, **orig;
|
|
if (!split)
|
|
{
|
|
return;
|
|
}
|
|
|
|
orig = split;
|
|
while ((line = *split++))
|
|
{
|
|
Free(line);
|
|
}
|
|
|
|
Free(orig);
|
|
}
|
|
|
|
size_t
|
|
StrLines(char **split)
|
|
{
|
|
size_t i;
|
|
if (!split)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; *split++; i++)
|
|
{
|
|
/* Left blank */
|
|
}
|
|
return i;
|
|
}
|
|
static size_t
|
|
StrMaxLine(char **split)
|
|
{
|
|
size_t max = 0;
|
|
if (!split)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
while (*split)
|
|
{
|
|
size_t len = strlen(*split++);
|
|
if (len > max)
|
|
{
|
|
max = len;
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
|
|
StringRect
|
|
StrFullRect(char **split)
|
|
{
|
|
return ((StringRect) {
|
|
.start_line = 0, .start_char = 0,
|
|
.end_line = StrLines(split),
|
|
.end_char = StrMaxLine(split),
|
|
.source_lines = split
|
|
});
|
|
}
|
|
|
|
char
|
|
StrGet(StringRect *rect, int line, int col)
|
|
{
|
|
size_t actual_line, actual_col;
|
|
char *linep;
|
|
if (!rect || !rect->source_lines)
|
|
{
|
|
return '\0';
|
|
}
|
|
|
|
actual_line = rect->start_line + line;
|
|
actual_col = rect->start_char + col;
|
|
|
|
if (actual_line > rect->end_line)
|
|
{
|
|
return '\0';
|
|
}
|
|
if (actual_line >= StrLines(rect->source_lines))
|
|
{
|
|
return '\0';
|
|
}
|
|
|
|
if (!(linep = rect->source_lines[actual_line]))
|
|
{
|
|
return '\0';
|
|
}
|
|
if (actual_col > strlen(linep))
|
|
{
|
|
return '\0';
|
|
}
|
|
|
|
return linep[actual_col];
|
|
}
|
|
size_t
|
|
StrViewChars(StringRect rect, int line)
|
|
{
|
|
size_t actual_line;
|
|
char *linep;
|
|
if (!rect.source_lines)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
actual_line = rect.start_line + line;
|
|
|
|
if (actual_line > rect.end_line)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!(linep = rect.source_lines[actual_line]))
|
|
{
|
|
return 0;
|
|
}
|
|
return rect.end_char - rect.start_char;
|
|
}
|
|
|
|
StringRect
|
|
StrGetl(StringRect *rect, int line, bool extend)
|
|
{
|
|
size_t actual_line;
|
|
StringRect ret;
|
|
if (!rect->source_lines)
|
|
{
|
|
return StrFullRect(NULL);
|
|
}
|
|
|
|
ret = *rect;
|
|
|
|
actual_line = rect->start_line + line;
|
|
|
|
if (actual_line > rect->end_line)
|
|
{
|
|
return StrFullRect(NULL);
|
|
}
|
|
if (actual_line >= StrLines(rect->source_lines))
|
|
{
|
|
return StrFullRect(NULL);
|
|
}
|
|
|
|
ret.start_line = actual_line;
|
|
if (!extend)
|
|
{
|
|
ret.end_line = actual_line;
|
|
}
|
|
return ret;
|
|
}
|
|
StringRect
|
|
StrShift(StringRect rect, int n)
|
|
{
|
|
size_t new = rect.start_char + n;
|
|
if (new > rect.end_char)
|
|
{
|
|
new = rect.end_char;
|
|
}
|
|
rect.start_char = new;
|
|
|
|
return rect;
|
|
}
|
|
|
|
size_t
|
|
StrViewLines(StringRect view)
|
|
{
|
|
if (view.start_line > view.end_line)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return view.end_line - view.start_line + 1;
|
|
}
|
|
|
|
char *
|
|
StrViewToStr(StringRect rect)
|
|
{
|
|
size_t i;
|
|
char *ret = NULL, *rtmp;
|
|
if (!rect.source_lines)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 0; i < StrViewLines(rect); i++)
|
|
{
|
|
char *line = NULL, *tmp;
|
|
char cbuf[2] = { 0, '\0' };
|
|
size_t chi = 0;
|
|
bool last = i == StrViewLines(rect) - 1;
|
|
|
|
while ((*cbuf = StrGet(&rect, i, chi)) != '\0' &&
|
|
chi++ <= StrViewChars(rect, i))
|
|
{
|
|
rtmp = line;
|
|
line = StrConcat(2, line, cbuf);
|
|
Free(rtmp);
|
|
}
|
|
|
|
tmp = ret;
|
|
ret = StrConcat(3, ret, line, last ? "\n" : "\n");
|
|
Free(tmp);
|
|
|
|
Free(line);
|
|
}
|
|
|
|
return ret;
|
|
}
|