56 lines
2.6 KiB
C
56 lines
2.6 KiB
C
#ifndef TERRACE_PARSER_H
|
|
#define TERRACE_PARSER_H
|
|
|
|
// Holds the parsed information from each line.
|
|
typedef struct terrace_linedata_s {
|
|
// Which character is being used for indentation. Avoids having to specify it on each terrace_parse_line call.
|
|
char indent;
|
|
// How many indent characters are present in the current line before the first non-indent character.
|
|
unsigned int level;
|
|
// The number of characters before the start of the line's "head" section.
|
|
// (Normally the same as `level`)
|
|
unsigned int offsetHead;
|
|
// The number of characters before the start of the line's "tail" section.
|
|
unsigned int offsetTail;
|
|
} terrace_linedata_t;
|
|
|
|
/**
|
|
* Initialize a terrace_linedata struct with default values to pass to terrace_parse_line()
|
|
* @param {const char} indent The character to use for indenting lines. ONLY ONE CHARACTER IS CURRENTLY PERMITTED.
|
|
* @returns {terrace_linedata_t} A linedata struct with the specified indent character and all other values initialized to 0.
|
|
*/
|
|
terrace_linedata_t terrace_create_linedata(const char indent) {
|
|
terrace_linedata_t line_data = { .indent = indent, .level = 0, .offsetHead = 0, .offsetTail = 0 };
|
|
return line_data;
|
|
}
|
|
|
|
/**
|
|
* Core Terrace parser function, sets level, offsetHead, and offsetTail in a terrace_linedata struct based on the current line.
|
|
* @param char* line A pointer to the line to parse as a C-style string. Shouldn't end with a newline.
|
|
* @param terrace_linedata_t* lineData A pointer to the terrace_linedata_t struct to store information about the current line in.
|
|
*/
|
|
void terrace_parse_line(const char* line, terrace_linedata_t* lineData) {
|
|
// Empty lines are nullptr/0 as they have no characters. (The newline character should be stripped off.)
|
|
// Special case handling for these allows them to be parsed extra quickly.
|
|
if (!line) {
|
|
// Empty lines are treated as having the same level as the previous line, so lineData->line is not updated.
|
|
lineData->offsetHead = 0;
|
|
lineData->offsetTail = 0;
|
|
} else {
|
|
// Count the number of indent characters in the current line.
|
|
unsigned int level = 0;
|
|
while (line[level] == lineData->indent) ++level;
|
|
lineData->level = level;
|
|
|
|
// Set offsetHead and offsetTail to level to start with.
|
|
// offsetHead should always be equal to level, and offsetTail will always be equal to or greater than level.
|
|
lineData->offsetHead = level;
|
|
lineData->offsetTail = level;
|
|
|
|
// Increment offsetTail until we encounter a space character (start of tail) or reach EOL (no tail present).
|
|
while (line[lineData->offsetTail] && line[lineData->offsetTail] != ' ') ++lineData->offsetTail;
|
|
}
|
|
}
|
|
|
|
#endif
|