чување 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:
| M | TODO | | | 3 | ++- |
| M | index.html | | | 2 | +- |
| M | slweb.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 <https://www.gnu.org/licenses/>. </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 == '-')