slweb

Једноставни генератор статичких веб страна
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување b85f2039375ad83274e2ca3797f85cbab6e563de
родитељ 4bb45aee9855be6fdc9d61e01a7c2501bcb284c2
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Fri, 25 Dec 2020 13:37:35 +0100

Added include processing; small optimizations

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
MTODO | 3++-
Mindex.html | 2+-
Mslweb.c | 171++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
измењених датотека: 3, додавања: 115(+), брисања: 61(-)

diff --git a/TODO b/TODO @@ -7,10 +7,11 @@ Migration to C checklist [x] Add {=macro} parsing [x] Add [=command Link](link) form of links [x] Add [(Link)](link) form of links - [ ] Add {include} processing + [x] Add {include} processing [x] Add {.class} processing [x] Add {#id} processing [x] Convert strncat token processing to individual token-based + [ ] -d support (determine real pathname in links) [ ] Add {lsdir} [x] Add title: processing [ ] Update manpage diff --git a/index.html b/index.html @@ -114,7 +114,7 @@ this program. If not, see &lt;https://www.gnu.org/licenses/&gt;. </p> <div id="git-log"> Previous commit: -index.slw 2f07a15 2020-12-24 13:05:16 +0100 (Страхиња Радић) (HEAD -> master, origin/master, origin/HEAD) +index.slw 4bb45ae 2020-12-24 19:49:04 +0100 (Страхиња Радић) (HEAD -> master, origin/master, origin/HEAD) </div><!--git-log--> diff --git a/slweb.c b/slweb.c @@ -22,6 +22,7 @@ static size_t lineno = 0; static size_t colno = 1; static uint8_t* filename = NULL; +static char* arg_zero = NULL; #define CHECKEXITNOMEM(ptr) if (!ptr) exit(error(ENOMEM, \ (uint8_t*)"Memory allocation failed (out of memory?)\n")) @@ -150,14 +151,14 @@ process_tag(uint8_t* token, FILE* output, KeyValue** macros, return warning(1, (uint8_t*)"Empty tag name\n"); if (!strcmp((char*)token, "git-log") - && !read_yaml_macros_and_links) + && !read_yaml_macros_and_links) /* {git-log} */ { if (!filename) - return warning(1, (uint8_t*)"Cannot use git-log in stdin\n"); + return warning(1, (uint8_t*)"Cannot use 'git-log' in stdin\n"); uint8_t* basename = NULL; CALLOC(basename, uint8_t, u8_strlen(filename)) - uint8_t* slash = u8_strrchr(filename, '/'); + uint8_t* slash = u8_strrchr(filename, (ucs4_t)'/'); if (slash) u8_strncpy(basename, slash+1, u8_strlen(slash+1)); else @@ -175,7 +176,7 @@ process_tag(uint8_t* token, FILE* output, KeyValue** macros, { fprintf(output, "</div><!--git-log-->\n"); perror(PROGRAMNAME); - return warning(1, (uint8_t*)"Cannot popen\n"); + return warning(1, (uint8_t*)"git-log: Cannot popen\n"); } uint8_t* cmd_output_line = NULL; CALLOC(cmd_output_line, uint8_t, BUFSIZE) @@ -200,7 +201,7 @@ process_tag(uint8_t* token, FILE* output, KeyValue** macros, } else if (!strcmp((char*)token, "made-by") - && !read_yaml_macros_and_links) + && !read_yaml_macros_and_links) /* {made-by} */ { fprintf(output, "<div id=\"made-by\">\n" "Generated by <a href=\"https://github.com/Strahinja/slweb\">" @@ -208,7 +209,84 @@ process_tag(uint8_t* token, FILE* output, KeyValue** macros, "© 2020 Strahinya Radich.\n" "</div><!--made-by-->\n"); } - else if (*token == '=') + else if (!strcmp(substr((char*)token, 0, strlen("include")), "include")) + /* {include} */ + { + if (!arg_zero) + exit(error(EINVAL, (uint8_t*)"Invalid argument zero\n")); + + if (!filename) + return warning(1, (uint8_t*)"Cannot use 'include' in stdin\n"); + + if (!read_yaml_macros_and_links) + { + uint8_t* command = NULL; + uint8_t* slash = u8_strrchr(filename, (ucs4_t)'/'); + uint8_t* ptoken = u8_strchr(token, (ucs4_t)' '); + uint8_t* include_filename = NULL; + uint8_t* pinclude_filename = NULL; + uint8_t* include_basedir = NULL; + uint8_t* pinclude_basedir = NULL; + size_t include_basedir_len = 0; + uint8_t* pfilename = filename; + if (!ptoken) + { + *skip_eol = TRUE; + return warning(1, (uint8_t*)"Directive 'include' requires" + " an argument\n"); + } + ptoken++; + CALLOC(include_filename, uint8_t, BUFSIZE) + CALLOC(include_basedir, uint8_t, BUFSIZE) + pinclude_basedir = include_basedir; + if (slash) + while (pfilename && *pfilename && pfilename != slash) + *pinclude_basedir++ = *pfilename++; + else + *pinclude_basedir++ = '.'; + *pinclude_basedir = '\0'; + include_basedir_len = u8_strlen(include_basedir); + u8_strncpy(include_filename, include_basedir, include_basedir_len); + *(include_filename + include_basedir_len) = '/'; + pinclude_filename = include_filename + include_basedir_len + 1; + while (ptoken && *ptoken) + if (*ptoken != '"') + *pinclude_filename++ = *ptoken++; + else + ptoken++; + CALLOC(command, uint8_t, BUFSIZE) + u8_snprintf(command, BUFSIZE, "%s -b %s.slw", arg_zero, include_filename); + + FILE* cmd_output = popen((char*)command, "r"); + if (!cmd_output) + { + perror(PROGRAMNAME); + return warning(1, (uint8_t*)"include: Cannot popen\n"); + } + uint8_t* cmd_output_line = NULL; + CALLOC(cmd_output_line, uint8_t, BUFSIZE) + while (!feof(cmd_output)) + { + if (!fgets((char*)cmd_output_line, BUFSIZE, cmd_output)) + continue; + + char* eol = strchr((char*)cmd_output_line, '\n'); + if (eol) + *eol = '\0'; + + fprintf(output, "%s\n", cmd_output_line); + + } + pclose(cmd_output); + + free(cmd_output_line); + free(include_basedir); + free(include_filename); + free(command); + } + *skip_eol = TRUE; + } + else if (*token == '=') /* {=macro} */ { *skip_eol = TRUE; if (!end_tag) @@ -255,7 +333,7 @@ process_tag(uint8_t* token, FILE* output, KeyValue** macros, *skip_eol = TRUE; } } - else if (!read_yaml_macros_and_links) + else if (!read_yaml_macros_and_links) /* general tags */ { fprintf(output, "<"); if (end_tag) @@ -1008,13 +1086,8 @@ slweb_parse(uint8_t* buffer, FILE* output, break; } - if (state & ST_TAG) - { - if (*(pline-1) != '{') - return error(1, (uint8_t*)"Character '/' not allowed here"); - + if ((state & ST_TAG) && pline-1 && *(pline-1) == '{') end_tag = TRUE; - } else *ptoken++ = *pline; @@ -1156,14 +1229,9 @@ slweb_parse(uint8_t* buffer, FILE* output, break; case '(': - if (state & (ST_MACRO_BODY | ST_PRE | ST_CODE)) - { - *ptoken++ = *pline++; - colno++; - break; - } - - if (state & ST_LINK) + if (state & (ST_MACRO_BODY | ST_PRE | ST_CODE | ST_HEADING)) + *ptoken++ = *pline; + else if (state & ST_LINK) { uint8_t* tag = (uint8_t*)"<span>"; size_t tag_len = u8_strlen(tag); @@ -1179,23 +1247,14 @@ slweb_parse(uint8_t* buffer, FILE* output, } state |= ST_LINK_SPAN; - pline++; } - else { - *ptoken++ = *pline++; - } - + else + *ptoken++ = *pline; + pline++; colno++; break; case ')': - if (state & (ST_MACRO_BODY | ST_PRE | ST_CODE)) - { - *ptoken++ = *pline++; - colno++; - break; - } - if (state & ST_LINK_SPAN) { if (u8_strlen(pline) > 1 @@ -1215,40 +1274,32 @@ slweb_parse(uint8_t* buffer, FILE* output, } state &= ~ST_LINK_SPAN; } - - pline++; - colno++; - break; - } - - if (!(state & (ST_LINK_SECOND_ARG | ST_IMAGE_SECOND_ARG))) - { - *ptoken++ = *pline++; - colno++; - break; } - - *ptoken = '\0'; - if (!read_yaml_macros_and_links) + else if (state & (ST_LINK_SECOND_ARG | ST_IMAGE_SECOND_ARG)) { - if (state & ST_LINK_SECOND_ARG) - process_inline_link(link_text, - get_value(*macros, *macros_count, link_macro, NULL), - token, output); - else - process_inline_image(link_text, token, output); + *ptoken = '\0'; + if (!read_yaml_macros_and_links) + { + if (state & ST_LINK_SECOND_ARG) + process_inline_link(link_text, + get_value(*macros, *macros_count, link_macro, NULL), + token, output); + else + process_inline_image(link_text, token, output); + } + *token = '\0'; + ptoken = token; + state &= ~(ST_LINK | ST_LINK_SECOND_ARG + | ST_IMAGE | ST_IMAGE_SECOND_ARG); } - *token = '\0'; - ptoken = token; - state &= ~(ST_LINK | ST_LINK_SECOND_ARG - | ST_IMAGE | ST_IMAGE_SECOND_ARG); + else + *ptoken++ = *pline; pline++; colno++; break; case ']': - if (!(state & (ST_MACRO_BODY | ST_LINK | ST_IMAGE | ST_PRE - | ST_CODE))) + if (state & (ST_MACRO_BODY | ST_PRE | ST_CODE)) { *ptoken++ = *pline++; colno++; @@ -1495,6 +1546,8 @@ main(int argc, char** argv) CALLOC(basedir, char, 2) *basedir = '.'; + arg_zero = *argv; + while ((arg = *++argv)) { if (*arg == '-')