mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 13:45:10 +00:00
[AYA] See alsos, live-alongs, more documentation
I need to work on _actual_ Parsee, now
This commit is contained in:
parent
4fbdf05176
commit
aa71c5cfeb
10 changed files with 302 additions and 45 deletions
4
Makefile
4
Makefile
|
|
@ -23,7 +23,7 @@ INCLUDES=src/include
|
||||||
CC=cc
|
CC=cc
|
||||||
CFLAGS=-I$(SOURCE) -I$(INCLUDES) -I$(CYTO_INC) -DNAME="\"$(NAME)\"" -DVERSION="\"$(VERSION)\"" -DREPOSITORY=\"$(REPOSITORY)\" -g -ggdb -Wall -Werror
|
CFLAGS=-I$(SOURCE) -I$(INCLUDES) -I$(CYTO_INC) -DNAME="\"$(NAME)\"" -DVERSION="\"$(VERSION)\"" -DREPOSITORY=\"$(REPOSITORY)\" -g -ggdb -Wall -Werror
|
||||||
LDFLAGS=-L $(CYTO_LIB) -lCytoplasm -g -ggdb
|
LDFLAGS=-L $(CYTO_LIB) -lCytoplasm -g -ggdb
|
||||||
AFLAGS=-C "$(ETC)/ayadoc/style.css"
|
AFLAGS=-C "$(ETC)/ayadoc/style.css" -p "$(NAME)"
|
||||||
BINARY=parsee
|
BINARY=parsee
|
||||||
# ============================ Compilation =================================
|
# ============================ Compilation =================================
|
||||||
SRC_FILES:=$(shell find $(SOURCE) -name '*.c')
|
SRC_FILES:=$(shell find $(SOURCE) -name '*.c')
|
||||||
|
|
@ -52,3 +52,5 @@ ayadoc: utils $(AYA_FILES)
|
||||||
$(AYAS)/%.html: $(INCLUDES)/%.h
|
$(AYAS)/%.html: $(INCLUDES)/%.h
|
||||||
@mkdir -p $(shell dirname "$@")
|
@mkdir -p $(shell dirname "$@")
|
||||||
tools/out/aya $(AFLAGS) -i $< -o $@
|
tools/out/aya $(AFLAGS) -i $< -o $@
|
||||||
|
|
||||||
|
# TODO: a install rule that reads prefix for software packagers?
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ a:link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- AYADOC-SPECIFIC STYLING ----------*/
|
/* ---------- AYADOC-SPECIFIC STYLING ----------
|
||||||
|
* Colors taken from Gruvbox. */
|
||||||
.aya-return
|
.aya-return
|
||||||
{
|
{
|
||||||
color: #fe8019;
|
color: #fe8019;
|
||||||
|
|
@ -45,3 +46,7 @@ a:link
|
||||||
{
|
{
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
.rets-span
|
||||||
|
{
|
||||||
|
color: #b16286;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
#ifndef PARSEE_AS_H
|
#ifndef PARSEE_AS_H
|
||||||
#define PARSEE_AS_H
|
#define PARSEE_AS_H
|
||||||
|
/*-*
|
||||||
|
* Functions used to communicate with a Matrix server and execute actions
|
||||||
|
* over HTTP(S)+JSON. This effectively serves as Parsee's Matrix SDK.
|
||||||
|
* TODO: Write my own RanSDK for KappaChat.
|
||||||
|
* --------
|
||||||
|
* Writren-By: LDA */
|
||||||
|
|
||||||
#include <Cytoplasm/HttpClient.h>
|
#include <Cytoplasm/HttpClient.h>
|
||||||
#include <Cytoplasm/Json.h>
|
#include <Cytoplasm/Json.h>
|
||||||
|
|
@ -7,9 +13,11 @@
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
#include <Routes.h>
|
#include <Routes.h>
|
||||||
|
|
||||||
/* Verifies a request from the homeserver to match the
|
/** Verifies a request from the homeserver to match the {hs_token}.
|
||||||
* hs_token. */
|
* ----------------
|
||||||
extern HashMap * ASVerifyRequest(ParseeHttpArg *);
|
* Returns: A JSON error message[HEAP] | NULL on success
|
||||||
|
* Thrasher: JsonFree */
|
||||||
|
extern HashMap * ASVerifyRequest(ParseeHttpArg *arg);
|
||||||
|
|
||||||
/* Authenticates a request with the correct as_token.
|
/* Authenticates a request with the correct as_token.
|
||||||
* It does not send the request, however. */
|
* It does not send the request, however. */
|
||||||
|
|
@ -49,8 +57,19 @@ extern void ASRedact(const ParseeConfig *, char *room, char *user, char *e_id);
|
||||||
/* Sets a state event with a specific type and body */
|
/* Sets a state event with a specific type and body */
|
||||||
extern void ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *event);
|
extern void ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *event);
|
||||||
|
|
||||||
/* Gets/Sets the content for a PL event */
|
/** Gets the content for a PL event in the room pointed by {id}
|
||||||
|
* ------------------------
|
||||||
|
* Returns: A valid JSON object[HEAP] | NULL
|
||||||
|
* Thrasher: JsonFree
|
||||||
|
* See-Also: ASSetPL */
|
||||||
extern HashMap *ASGetPL(const ParseeConfig *conf, char *id);
|
extern HashMap *ASGetPL(const ParseeConfig *conf, char *id);
|
||||||
|
|
||||||
|
/** Sets the content for a PL event in the room pointed by {id} if
|
||||||
|
* possible.
|
||||||
|
* ------------------------
|
||||||
|
* Returns: NOTHING
|
||||||
|
* Modifies: the room pointed by {id}
|
||||||
|
* See-Also: ASGetPL */
|
||||||
extern void ASSetPL(const ParseeConfig *conf, char *id, HashMap *m);
|
extern void ASSetPL(const ParseeConfig *conf, char *id, HashMap *m);
|
||||||
|
|
||||||
/* Creates a room, with a masquerade user as its creator. This function
|
/* Creates a room, with a masquerade user as its creator. This function
|
||||||
|
|
@ -62,14 +81,14 @@ extern char * ASCreateDM(const ParseeConfig *c, char *by, char *with);
|
||||||
/** Sets the user's global display{name}
|
/** Sets the user's global display{name}
|
||||||
* --------
|
* --------
|
||||||
* Returns: NOTHING
|
* Returns: NOTHING
|
||||||
* Modifies: [EXT:User status]
|
* Modifies: the users' status in Matrix
|
||||||
* See-Also: ASGetName, ASSetStatus, ASSetAvatar */
|
* See-Also: ASGetName, ASSetStatus, ASSetAvatar */
|
||||||
extern void ASSetName(const ParseeConfig *c, char *user, char *name);
|
extern void ASSetName(const ParseeConfig *c, char *user, char *name);
|
||||||
|
|
||||||
/** Sets the {user}'s global avatar, as an {mxc} URI
|
/** Sets the {user}'s global avatar, as an {mxc} URI
|
||||||
* --------
|
* --------
|
||||||
* Returns: NOTHING
|
* Returns: NOTHING
|
||||||
* Modifies: [EXT:User status]
|
* Modifies: the users' status in Matrix
|
||||||
* See-Also: ASGetName, ASSetStatus */
|
* See-Also: ASGetName, ASSetStatus */
|
||||||
extern void ASSetAvatar(const ParseeConfig *c, char *user, char *mxc);
|
extern void ASSetAvatar(const ParseeConfig *c, char *user, char *mxc);
|
||||||
|
|
||||||
|
|
@ -81,18 +100,32 @@ typedef enum UserStatus {
|
||||||
/** Sets the user's status and message, to be seen by other clients.
|
/** Sets the user's status and message, to be seen by other clients.
|
||||||
* --------
|
* --------
|
||||||
* Returns: NOTHING
|
* Returns: NOTHING
|
||||||
* Modifies: [EXT:User status]
|
* Modifies: the users' status in Matrix
|
||||||
* See-Also: https://spec.matrix.org/v1.11/client-server-api/#put_matrixclientv3presenceuseridstatus, ASSetName, ASSetAvatar */
|
* See-Also: https://spec.matrix.org/v1.11/client-server-api/#put_matrixclientv3presenceuseridstatus, ASSetName, ASSetAvatar */
|
||||||
extern void ASSetStatus(const ParseeConfig *c, char *user, UserStatus status, char *msg);
|
extern void ASSetStatus(const ParseeConfig *c, char *user, UserStatus status, char *msg);
|
||||||
|
|
||||||
/* Returns the user's name in a room, or a copy of the MXID itself, to be
|
/** Returns the user's name in a room, or a copy of the MXID itself, to be
|
||||||
* Free'd. */
|
* Free'd
|
||||||
|
* -------------
|
||||||
|
* Returns: The user's name in the room[HEAP] | A copy of {user}[HEAP]
|
||||||
|
* Thrasher: Free
|
||||||
|
* Modifies: NOTHING */
|
||||||
extern char * ASGetName(const ParseeConfig *c, char *room, char *user);
|
extern char * ASGetName(const ParseeConfig *c, char *room, char *user);
|
||||||
|
|
||||||
/* Uploads data to Matrix to be used later */
|
/** Uploads data to Matrix to be used later
|
||||||
|
* ----------------
|
||||||
|
* Returns: A valid MXC URI[HEAP] | NULL
|
||||||
|
* Thrasher: Free
|
||||||
|
* Modifies: the internal Matrix homeserver's media repository
|
||||||
|
* See-Also: ASReupload */
|
||||||
extern char * ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime);
|
extern char * ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime);
|
||||||
|
|
||||||
/* Reuploads a HTTP URL to Matrix, with an optional MIME type returned. */
|
/** Reuploads a HTTP URL to Matrix, with an optional MIME type returned.
|
||||||
|
* ----------------
|
||||||
|
* Returns: A valid MXC URI[HEAP] | NULL
|
||||||
|
* Thrasher: Free
|
||||||
|
* Modifies: the internal Matrix homeserver's media repository, {from}s server
|
||||||
|
* See-Also: ASUpload */
|
||||||
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);
|
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);
|
||||||
|
|
||||||
extern HashMap * ASGetUserConfig(const ParseeConfig *c, char *user, char *key);
|
extern HashMap * ASGetUserConfig(const ParseeConfig *c, char *user, char *key);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
#ifndef PARSEE_COMMAND_H
|
#ifndef PARSEE_COMMAND_H
|
||||||
#define PARSEE_COMMAND_H
|
#define PARSEE_COMMAND_H
|
||||||
|
/*-*
|
||||||
|
* A Matrix command manager (with a JCL/dd-style format).
|
||||||
|
* -----------
|
||||||
|
* Written-By: LDA */
|
||||||
|
|
||||||
#include <Cytoplasm/HashMap.h>
|
#include <Cytoplasm/HashMap.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,17 @@
|
||||||
#ifndef PARSEE_GLOB_H
|
#ifndef PARSEE_GLOB_H
|
||||||
#define PARSEE_GLOB_H
|
#define PARSEE_GLOB_H
|
||||||
|
/*-*
|
||||||
|
* A simple Matrix globrule matcher.
|
||||||
|
* -----------------
|
||||||
|
* Written-By: LDA */
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* Verifies if a string matches a rule, as specified in
|
/** Verifies if a string matches a rule, as specified in the Matrix
|
||||||
* https://spec.matrix.org/v1.11/appendices/#glob-style-matching. */
|
* specification on globrules.
|
||||||
|
* -----------------
|
||||||
|
* Returns: true if it does match, otherwise false
|
||||||
|
* See-Also https://spec.matrix.org/v1.11/appendices/#glob-style-matching */
|
||||||
extern bool GlobMatches(char *rule, char *string);
|
extern bool GlobMatches(char *rule, char *string);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#ifndef PARSEE_PARSEE_H
|
#ifndef PARSEE_PARSEE_H
|
||||||
#define PARSEE_PARSEE_H
|
#define PARSEE_PARSEE_H
|
||||||
|
|
||||||
|
/*-* <p>Some fields used as Parsee-specific functions/structures.</p>
|
||||||
|
* <p>TODO: Consider separating some declarations here...</p>
|
||||||
|
* --------
|
||||||
|
* Writren-By: LDA */
|
||||||
|
|
||||||
#include <Cytoplasm/HttpServer.h>
|
#include <Cytoplasm/HttpServer.h>
|
||||||
#include <Cytoplasm/HttpRouter.h>
|
#include <Cytoplasm/HttpRouter.h>
|
||||||
#include <Cytoplasm/HttpClient.h>
|
#include <Cytoplasm/HttpClient.h>
|
||||||
|
|
@ -107,7 +112,11 @@ extern char * ParseeEncodeMXID(char *);
|
||||||
extern char * ParseeDecodeMXID(char *);
|
extern char * ParseeDecodeMXID(char *);
|
||||||
|
|
||||||
|
|
||||||
/* HTTP server handler for Parsee, takes in a config. */
|
/** Callback function for the Parsee HTTP handler, to be used by
|
||||||
|
* the HTTP thread itself.
|
||||||
|
* --------
|
||||||
|
* UB-If: not used as the HTTP callback function
|
||||||
|
* Returns: NOTHING */
|
||||||
extern void ParseeRequest(HttpServerContext *, void *);
|
extern void ParseeRequest(HttpServerContext *, void *);
|
||||||
|
|
||||||
/* A pthread callback used for listening to a component */
|
/* A pthread callback used for listening to a component */
|
||||||
|
|
@ -219,38 +228,61 @@ extern void ParseePushHeadTable(char *room, char *id);
|
||||||
extern char *ParseeLookupHead(char *room);
|
extern char *ParseeLookupHead(char *room);
|
||||||
extern void ParseeDestroyHeadTable(void);
|
extern void ParseeDestroyHeadTable(void);
|
||||||
|
|
||||||
/* Globally bans a Matrix user from ever interacting with Parsee, and bans
|
/* Disables a user/room/MUC's ability to interact from Parsee, and attempts
|
||||||
* them from bridged rooms where the bot has administrator. */
|
* to ban them from rooms where Parsee has the ability to do so ("noflying").
|
||||||
|
* ---------------
|
||||||
|
* Returns: NOTHING
|
||||||
|
* See-Also: ParseeManageBan
|
||||||
|
* Modifies: the database */
|
||||||
extern void ParseeGlobalBan(ParseeData *, char *user, char *reason);
|
extern void ParseeGlobalBan(ParseeData *, char *user, char *reason);
|
||||||
|
|
||||||
/* Verifies if a user was globally banned. If so, then apply actions to the
|
/* Verifies if a user was banned globally. If so (and if {room} is set),
|
||||||
* room ID */
|
* tries to ban the user from it.
|
||||||
|
* ---------------
|
||||||
|
* Returns: NOTHING
|
||||||
|
* See-Also: ParseeManageBan
|
||||||
|
* Modifies: the database */
|
||||||
extern bool ParseeManageBan(ParseeData *, char *user, char *room);
|
extern bool ParseeManageBan(ParseeData *, char *user, char *room);
|
||||||
|
|
||||||
/* Same as ParseeVerifyStanza, but DMs */
|
/* Same as ParseeVerifyStanza, but DMs */
|
||||||
extern bool ParseeVerifyDMStanza(ParseeData *data, char *room_id, char *id);
|
extern bool ParseeVerifyDMStanza(ParseeData *data, char *room_id, char *id);
|
||||||
|
|
||||||
|
|
||||||
/* Checks if any user is an admin */
|
/** Checks if a Matrix/XMPP user is considered as "administrator" by Parsee.
|
||||||
|
* ----------------------
|
||||||
|
* Returns: (whenever the user is an admin)
|
||||||
|
* Modifies: NOTHING */
|
||||||
extern bool ParseeIsAdmin(ParseeData *data, char *user);
|
extern bool ParseeIsAdmin(ParseeData *data, char *user);
|
||||||
|
|
||||||
/* Measures Parsee's overall uptime */
|
/* Measures Parsee's overall uptime.
|
||||||
|
* ----------------
|
||||||
|
* Returns: uptime since the call to Main in milliseconds.
|
||||||
|
* Modifies: NOTHING */
|
||||||
extern uint64_t ParseeUptime(void);
|
extern uint64_t ParseeUptime(void);
|
||||||
|
|
||||||
/** Turns a duration into a nice "X minutes, Y seconds" string
|
/** Turns a duration into a nice <code>"X minutes, Y seconds"</code>
|
||||||
|
* string.
|
||||||
* ---------
|
* ---------
|
||||||
* Returns: A human-readable string showing the duration[LA:HEAP]
|
* Returns: A human-readable string showing the duration[LA:HEAP]
|
||||||
* Modifies: NOTHING */
|
* Modifies: NOTHING */
|
||||||
extern char * ParseeStringifyDate(uint64_t millis);
|
extern char * ParseeStringifyDate(uint64_t millis);
|
||||||
|
|
||||||
/* Generates the JID of the Parsee bridge user. */
|
/** Generates the Jabber ID of the main Parsee user available.
|
||||||
|
* ----------------------
|
||||||
|
* Returns: An XMPP JID[LA:HEAP]
|
||||||
|
* Thrasher: Free */
|
||||||
extern char * ParseeJID(ParseeData *data);
|
extern char * ParseeJID(ParseeData *data);
|
||||||
|
|
||||||
|
/** Generates the MXID of the main Parsee user available.
|
||||||
|
* ----------------------
|
||||||
|
* Returns: A Matrix ID[LA:HEAP]
|
||||||
|
* Thrasher: Free */
|
||||||
extern char * ParseeMXID(ParseeData *data);
|
extern char * ParseeMXID(ParseeData *data);
|
||||||
|
|
||||||
/** Prints an _fatal_ and _strange_, error message, then congratulates
|
/** Prints an _fatal_ and _strange_, error message, then congratulates
|
||||||
* the user for it(an "achievement").
|
* the user for it(an "achievement").<br/>
|
||||||
* Use this for errors that have _no business_ happening, at all.
|
* Use this for errors that have <i>no business</i> happening, at all.
|
||||||
* NOTE to users: If you see this, _*OPEN AN ISSUE*_.
|
* NOTE to users: If you see this, <u><i>OPEN AN ISSUE</i></u>.
|
||||||
* ---------------------------------------------------
|
* ---------------------------------------------------
|
||||||
* Returns: NOTHING | NORETURN */
|
* Returns: NOTHING | NORETURN */
|
||||||
extern void ParseeAchievement(const char *func, const char *msg, bool die);
|
extern void ParseeAchievement(const char *func, const char *msg, bool die);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#ifndef PARSEE_ROUTES_H
|
#ifndef PARSEE_ROUTES_H
|
||||||
#define PARSEE_ROUTES_H
|
#define PARSEE_ROUTES_H
|
||||||
|
|
||||||
|
/*-*
|
||||||
|
* The HTTP routes and Matrix bot endpoints for Parser
|
||||||
|
* -----------
|
||||||
|
* Written-By: LDA */
|
||||||
|
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
typedef struct ParseeHttpArg {
|
typedef struct ParseeHttpArg {
|
||||||
ParseeData *data;
|
ParseeData *data;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#ifndef PARSEE_XEP393_H
|
#ifndef PARSEE_XEP393_H
|
||||||
#define PARSEE_XEP393_H
|
#define PARSEE_XEP393_H
|
||||||
|
|
||||||
|
/*-*
|
||||||
|
* A basic XEP-0393 parser and XHTML-iser.
|
||||||
|
* --------
|
||||||
|
* Writren-By: LDA */
|
||||||
|
|
||||||
#include <Cytoplasm/Array.h>
|
#include <Cytoplasm/Array.h>
|
||||||
|
|
||||||
typedef enum XEP393Type {
|
typedef enum XEP393Type {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#ifndef PARSEE_XMPP_H
|
#ifndef PARSEE_XMPP_H
|
||||||
#define PARSEE_XMPP_H
|
#define PARSEE_XMPP_H
|
||||||
|
|
||||||
|
/*-*
|
||||||
|
* Functions used to communicate with an XMPP server over an JCP stream.
|
||||||
|
* --------
|
||||||
|
* Writren-By: LDA */
|
||||||
|
|
||||||
#include <Cytoplasm/Stream.h>
|
#include <Cytoplasm/Stream.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
|
||||||
195
tools/aya.c
195
tools/aya.c
|
|
@ -13,6 +13,7 @@
|
||||||
#include <Cytoplasm/Args.h>
|
#include <Cytoplasm/Args.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Uri.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -88,6 +89,7 @@ ParseAyadoc(char *raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
line_content = StrDuplicate("");
|
||||||
for (index_ptr = start; index_ptr < line_break; index_ptr++)
|
for (index_ptr = start; index_ptr < line_break; index_ptr++)
|
||||||
{
|
{
|
||||||
char char_buffer[2] = { *index_ptr, '\0' };
|
char char_buffer[2] = { *index_ptr, '\0' };
|
||||||
|
|
@ -97,11 +99,6 @@ ParseAyadoc(char *raw)
|
||||||
Free(temporary);
|
Free(temporary);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!line_content)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(line_content, "---", 3))
|
if (!strncmp(line_content, "---", 3))
|
||||||
{
|
{
|
||||||
parsing_notes = true;
|
parsing_notes = true;
|
||||||
|
|
@ -140,18 +137,133 @@ line_end:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Split all arguments by the '|', and handle them automatically
|
if ((tag_del = strchr(field, '[')))
|
||||||
* (with live-alongs, special capped params, ... */
|
{
|
||||||
StreamPrintf(out, " <span class='rets-span'>%s</span>", val);
|
/* 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
|
static void
|
||||||
GenerateHTML(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl)
|
GenerateHTML(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl)
|
||||||
{
|
{
|
||||||
|
|
@ -225,6 +337,26 @@ GenerateHTML(Stream *out, AyadocComment *ayadoc, HeaderDeclaration decl)
|
||||||
StreamFlush(out);
|
StreamFlush(out);
|
||||||
continue;
|
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;
|
int flag;
|
||||||
|
|
||||||
char *header = NULL, *xhtml = NULL, *css = NULL;
|
char *header = NULL, *xhtml = NULL, *css = NULL;
|
||||||
|
char *project = "Ayaya!";
|
||||||
Stream *input, *output;
|
Stream *input, *output;
|
||||||
|
bool help = false;
|
||||||
|
|
||||||
ArgParseStateInit(&state);
|
ArgParseStateInit(&state);
|
||||||
while ((flag = ArgParse(&state, args, "i:o:C:")) != -1)
|
while ((flag = ArgParse(&state, args, "i:o:p:C:h")) != -1)
|
||||||
{
|
{
|
||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
|
|
@ -257,13 +391,23 @@ Main(Array *args, HashMap *env)
|
||||||
case 'C':
|
case 'C':
|
||||||
css = state.optArg;
|
css = state.optArg;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
project = state.optArg;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
help = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!header || !xhtml)
|
if (!header || !xhtml || help)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR,
|
Log(help ? LOG_INFO : LOG_ERR,
|
||||||
"Usage: %s -i [C header file] -o [Generated Aya HTML]",
|
"Usage: %s "
|
||||||
|
"-i [C header file] "
|
||||||
|
"-o [Generated Aya HTML] "
|
||||||
|
"-p {project name} "
|
||||||
|
"-C {CSS stylefile}",
|
||||||
ArrayGet(args, 0)
|
ArrayGet(args, 0)
|
||||||
);
|
);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
@ -286,7 +430,7 @@ Main(Array *args, HashMap *env)
|
||||||
StreamPrintf(output, "</head>");
|
StreamPrintf(output, "</head>");
|
||||||
|
|
||||||
StreamPrintf(output, "<body>");
|
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/>");
|
StreamPrintf(output, "<br/>");
|
||||||
/* TODO */
|
/* TODO */
|
||||||
{
|
{
|
||||||
|
|
@ -295,6 +439,7 @@ Main(Array *args, HashMap *env)
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
HeaderDeclaration decl;
|
HeaderDeclaration decl;
|
||||||
|
bool raw_put = false;
|
||||||
|
|
||||||
HeaderParse(input, &expression);
|
HeaderParse(input, &expression);
|
||||||
if (expression.type == HP_EOF)
|
if (expression.type == HP_EOF)
|
||||||
|
|
@ -305,15 +450,29 @@ Main(Array *args, HashMap *env)
|
||||||
switch (expression.type)
|
switch (expression.type)
|
||||||
{
|
{
|
||||||
case HP_COMMENT:
|
case HP_COMMENT:
|
||||||
if (strncmp(expression.data.text, "*", 1))
|
if (strncmp(expression.data.text, "*", 1) &&
|
||||||
|
strncmp(expression.data.text, "-*", 2))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!strncmp(expression.data.text, "-*", 2))
|
||||||
|
{
|
||||||
|
raw_put = true;
|
||||||
|
}
|
||||||
if (comm)
|
if (comm)
|
||||||
{
|
{
|
||||||
FreeAyadoc(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;
|
break;
|
||||||
case HP_DECLARATION:
|
case HP_DECLARATION:
|
||||||
if (!comm)
|
if (!comm)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue