[AYA] See alsos, live-alongs, more documentation

I need to work on _actual_ Parsee, now
This commit is contained in:
LDA 2024-08-05 15:23:33 +02:00
commit aa71c5cfeb
10 changed files with 302 additions and 45 deletions

View file

@ -13,6 +13,7 @@
#include <Cytoplasm/Args.h>
#include <Cytoplasm/Log.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Uri.h>
#include <stdlib.h>
#include <string.h>
@ -88,6 +89,7 @@ ParseAyadoc(char *raw)
}
}
line_content = StrDuplicate("");
for (index_ptr = start; index_ptr < line_break; index_ptr++)
{
char char_buffer[2] = { *index_ptr, '\0' };
@ -97,11 +99,6 @@ ParseAyadoc(char *raw)
Free(temporary);
}
if (!line_content)
{
break;
}
if (!strncmp(line_content, "---", 3))
{
parsing_notes = true;
@ -140,18 +137,133 @@ line_end:
}
static void
GenerateReturns(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl, char *val)
HandleReturnValue(Stream *out, AyadocComment *aya, HeaderDeclaration d, char *field)
{
if (StrEquals(val, "NOTHING"))
char *tag_del = NULL;
if (StrEquals(field, "NOTHING"))
{
StreamPrintf(out, "<span class='rets-none'>Nothing.</span>");
StreamPrintf(out, "<span class='rets-none'>nothing</span>");
return;
}
else if (StrEquals(field, "NORETURN"))
{
StreamPrintf(out, "<span class='rets-exit'>doesn't return in the thread</span>");
return;
}
/* TODO: Split all arguments by the '|', and handle them automatically
* (with live-alongs, special capped params, ... */
StreamPrintf(out, " <span class='rets-span'>%s</span>", val);
if ((tag_del = strchr(field, '[')))
{
/* We're free to edit field, as it is in the heap */
*tag_del = '\0';
}
/* Already write the field */
StreamPrintf(out, " <span class='rets-span'>%s</span>", field);
if (tag_del)
{
/* Locate the last ]. */
char *end_tags = strrchr(++tag_del, ']');
if (!end_tags)
{
end_tags = tag_del + strlen(tag_del);
}
*end_tags = '\0';
if (StrEquals(tag_del, "LA:HEAP") ||
StrEquals(tag_del, "HEAP"))
{
StreamPrintf(out, " <span class='rets-la'>(stored in the heap)</span>");
return;
}
else if (!strncmp(tag_del, "LA:", 3))
{
tag_del += 3;
}
StreamPrintf(out, " <span class='rets-la'>(stored along %s)</span>", tag_del);
}
}
static void
HandleSeeValue(Stream *out, AyadocComment *aya, HeaderDeclaration d, char *field)
{
Uri *uri = UriParse(field);
if (uri)
{
StreamPrintf(out,
"<a class='aya-see-field' href='%s'>%s</a>",
field, uri->host
);
UriFree(uri);
return;
}
StreamPrintf(out,
"<a href='#fdiv-%s' class='aya-see-field'>%s</a>",
field, field
);
}
#define SplitBy(sym, cb, del_str) \
char *start_of_arg = val, *separator = NULL; \
bool end_of_field = false; \
\
while (!end_of_field) \
{ \
char *temporary, *field = NULL, *index; \
char *last_char; \
while (*start_of_arg && isspace(*start_of_arg)) \
{ \
start_of_arg++; \
} \
if (!(separator = strchr(start_of_arg, sym))) \
{ \
end_of_field = true; \
separator = start_of_arg + strlen(start_of_arg); \
} \
if (start_of_arg >= separator) \
{ \
break; \
} \
\
/* Trim out spaces */ \
last_char = separator - 1; \
while (*last_char && isspace(*last_char)) \
{ \
last_char--; \
} \
\
field = StrDuplicate(""); \
for (index = start_of_arg; index <= last_char; index++) \
{ \
char buffer[2] = { *index, '\0' }; \
\
temporary = field; \
field = StrConcat(2, field, buffer); \
Free(temporary); \
} \
\
/* Process the field */ \
cb(out, ayadoc, decl, field); \
\
if (!end_of_field) \
{ \
StreamPrintf(out, del_str); \
} \
\
Free(field); \
start_of_arg = separator + 1; \
}
static void
GenerateReturns(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl, char *val)
{
SplitBy('|', HandleReturnValue, " <strong>or</strong> ");
}
static void
GenerateSee(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl, char *val)
{
SplitBy(',', HandleSeeValue, ", ");
}
#undef SplitBy
static void
GenerateHTML(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl)
{
@ -225,6 +337,26 @@ GenerateHTML(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl)
StreamFlush(out);
continue;
}
else if (StrEquals(attr, "See-Also"))
{
/* TODO: Be a little more advanced. */
StreamPrintf(out, "<div class='aya-see' id='see-%s'>", decl.name);
StreamPrintf(out, "<h2>See also</h2>");
GenerateSee(out, ayadoc, decl, value);
StreamPrintf(out, "</div>");
StreamFlush(out);
continue;
}
else if (StrEquals(attr, "Thrasher"))
{
/* TODO: Be a little more advanced. */
StreamPrintf(out, "<p class='aya-free' id='free-%s'>", decl.name);
StreamPrintf(out, "<strong>This function may be destroyed with ");
StreamPrintf(out, "<code><a href='#fdiv-%s'>%s</a></code>", value, value);
StreamPrintf(out, "</strong></p>");
StreamFlush(out);
continue;
}
}
}
@ -241,10 +373,12 @@ Main(Array *args, HashMap *env)
int flag;
char *header = NULL, *xhtml = NULL, *css = NULL;
char *project = "Ayaya!";
Stream *input, *output;
bool help = false;
ArgParseStateInit(&state);
while ((flag = ArgParse(&state, args, "i:o:C:")) != -1)
while ((flag = ArgParse(&state, args, "i:o:p:C:h")) != -1)
{
switch (flag)
{
@ -257,13 +391,23 @@ Main(Array *args, HashMap *env)
case 'C':
css = state.optArg;
break;
case 'p':
project = state.optArg;
break;
case 'h':
help = true;
break;
}
}
if (!header || !xhtml)
if (!header || !xhtml || help)
{
Log(LOG_ERR,
"Usage: %s -i [C header file] -o [Generated Aya HTML]",
Log(help ? LOG_INFO : LOG_ERR,
"Usage: %s "
"-i [C header file] "
"-o [Generated Aya HTML] "
"-p {project name} "
"-C {CSS stylefile}",
ArrayGet(args, 0)
);
return EXIT_FAILURE;
@ -286,7 +430,7 @@ Main(Array *args, HashMap *env)
StreamPrintf(output, "</head>");
StreamPrintf(output, "<body>");
StreamPrintf(output, "<center><h1>Ayaya!: %s</h1></center>", header);
StreamPrintf(output, "<center><h1>%s: %s</h1></center>", project, header);
StreamPrintf(output, "<br/>");
/* TODO */
{
@ -295,6 +439,7 @@ Main(Array *args, HashMap *env)
while (true)
{
HeaderDeclaration decl;
bool raw_put = false;
HeaderParse(input, &expression);
if (expression.type == HP_EOF)
@ -305,15 +450,29 @@ Main(Array *args, HashMap *env)
switch (expression.type)
{
case HP_COMMENT:
if (strncmp(expression.data.text, "*", 1))
if (strncmp(expression.data.text, "*", 1) &&
strncmp(expression.data.text, "-*", 2))
{
break;
}
if (!strncmp(expression.data.text, "-*", 2))
{
raw_put = true;
}
if (comm)
{
FreeAyadoc(comm);
}
comm = ParseAyadoc(expression.data.text);
comm = ParseAyadoc(expression.data.text + !!raw_put);
if (raw_put)
{
StreamPrintf(output, "<p>");
StreamPrintf(output, comm->description);
StreamPrintf(output, "</p>");
FreeAyadoc(comm);
comm = NULL;
}
break;
case HP_DECLARATION:
if (!comm)