Add some flags to hdoc to make it more useful.

This commit is contained in:
Jordan Bancino 2023-04-27 02:30:44 +00:00
parent 2447bb63cc
commit 3b06ab120b

View file

@ -32,6 +32,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <errno.h>
typedef struct DocDecl typedef struct DocDecl
{ {
char docs[HEADER_EXPR_MAX]; char docs[HEADER_EXPR_MAX];
@ -106,11 +108,108 @@ main(int argc, char **argv)
char comment[HEADER_EXPR_MAX]; char comment[HEADER_EXPR_MAX];
int isDocumented = 0; int isDocumented = 0;
Stream *in = NULL;
Stream *out = NULL;
int opt;
while ((opt = getopt(argc, argv, "i:o:D:")) != -1)
{
switch (opt)
{
case 'i':
if (in)
{
break;
}
if (strcmp(optarg, "-") == 0)
{
in = StreamStdin();
}
else
{
int len = strlen(optarg);
in = StreamOpen(optarg, "r");
if (!in)
{
StreamPrintf(StreamStderr(), "Error: %s:%s",
optarg, strerror(errno));
exit = EXIT_FAILURE;
goto finish;
}
while (optarg[len - 1] != '.')
{
optarg[len - 1] = '\0';
len--;
}
optarg[len - 1] = '\0';
len--;
HashMapSet(registers, "Nm", StrDuplicate(optarg));
}
break;
case 'o':
if (out)
{
break;
}
if (strcmp(optarg, "-") == 0)
{
out = StreamStdout();
}
else
{
out = StreamOpen(optarg, "w");
if (!out)
{
StreamPrintf(StreamStderr(), "Error: %s:%s",
optarg, strerror(errno));
exit = EXIT_FAILURE;
goto finish;
}
}
break;
case 'D':
val = optarg;
while (*val && *val != '=')
{
val++;
}
if (!*val || *val != '=')
{
StreamPrintf(StreamStderr(), "Bad register definition: %s",
optarg);
exit = EXIT_FAILURE;
goto finish;
}
*val = '\0';
val++;
HashMapSet(registers, optarg, StrDuplicate(val));
break;
}
}
if (!in)
{
in = StreamStdin();
}
if (!out)
{
out = StreamStdout();
}
memset(&expr, 0, sizeof(expr)); memset(&expr, 0, sizeof(expr));
while (1) while (1)
{ {
HeaderParse(StreamStdin(), &expr); HeaderParse(in, &expr);
switch (expr.type) switch (expr.type)
{ {
@ -211,54 +310,54 @@ last:
val = tsBuf; val = tsBuf;
} }
StreamPrintf(StreamStdout(), ".Dd $%s: %s $\n", "Mdocdate", val); StreamPrintf(out, ".Dd $%s: %s $\n", "Mdocdate", val);
val = HashMapGet(registers, "Os"); val = HashMapGet(registers, "Os");
if (val) if (val)
{ {
StreamPrintf(StreamStdout(), ".Os %s\n", val); StreamPrintf(out, ".Os %s\n", val);
} }
val = HashMapGet(registers, "Nm"); val = HashMapGet(registers, "Nm");
StreamPrintf(StreamStdout(), ".Dt %s 3\n", val); StreamPrintf(out, ".Dt %s 3\n", val);
StreamPrintf(StreamStdout(), ".Sh NAME\n"); StreamPrintf(out, ".Sh NAME\n");
StreamPrintf(StreamStdout(), ".Nm %s\n", val); StreamPrintf(out, ".Nm %s\n", val);
val = HashMapGet(registers, "Nd"); val = HashMapGet(registers, "Nd");
if (!val) if (!val)
{ {
val = "No Description."; val = "No Description.";
} }
StreamPrintf(StreamStdout(), ".Nd %s\n", val); StreamPrintf(out, ".Nd %s\n", val);
StreamPrintf(StreamStdout(), ".Sh SYNOPSIS\n"); StreamPrintf(out, ".Sh SYNOPSIS\n");
val = HashMapGet(registers, "Nm"); val = HashMapGet(registers, "Nm");
StreamPrintf(StreamStdout(), ".In %s.h\n", val); StreamPrintf(out, ".In %s.h\n", val);
for (i = 0; i < ArraySize(declarations); i++) for (i = 0; i < ArraySize(declarations); i++)
{ {
size_t j; size_t j;
decl = ArrayGet(declarations, i); decl = ArrayGet(declarations, i);
StreamPrintf(StreamStdout(), ".Ft %s\n", decl->decl.returnType); StreamPrintf(out, ".Ft %s\n", decl->decl.returnType);
StreamPrintf(StreamStdout(), ".Fn %s ", decl->decl.name); StreamPrintf(out, ".Fn %s ", decl->decl.name);
for (j = 0; j < ArraySize(decl->decl.args); j++) for (j = 0; j < ArraySize(decl->decl.args); j++)
{ {
StreamPrintf(StreamStdout(), "\"%s\" ", ArrayGet(decl->decl.args, j)); StreamPrintf(out, "\"%s\" ", ArrayGet(decl->decl.args, j));
} }
StreamPutc(StreamStdout(), '\n'); StreamPutc(out, '\n');
} }
if (ArraySize(typedefs)) if (ArraySize(typedefs))
{ {
StreamPrintf(StreamStdout(), ".Sh TYPE DECLARATIONS\n"); StreamPrintf(out, ".Sh TYPE DECLARATIONS\n");
for (i = 0; i < ArraySize(typedefs); i++) for (i = 0; i < ArraySize(typedefs); i++)
{ {
char *line; char *line;
type = ArrayGet(typedefs, i); type = ArrayGet(typedefs, i);
StreamPrintf(StreamStdout(), ".Bd -literal -offset indent\n"); StreamPrintf(out, ".Bd -literal -offset indent\n");
StreamPrintf(StreamStdout(), "%s\n", type->text); StreamPrintf(out, "%s\n", type->text);
StreamPrintf(StreamStdout(), ".Ed\n.Pp\n"); StreamPrintf(out, ".Ed\n.Pp\n");
line = strtok(type->docs, "\n"); line = strtok(type->docs, "\n");
while (line) while (line)
@ -270,7 +369,7 @@ last:
if (*line) if (*line)
{ {
StreamPrintf(StreamStdout(), "%s\n", line); StreamPrintf(out, "%s\n", line);
} }
line = strtok(NULL, "\n"); line = strtok(NULL, "\n");
@ -278,10 +377,10 @@ last:
} }
} }
StreamPrintf(StreamStdout(), ".Sh DESCRIPTION\n"); StreamPrintf(out, ".Sh DESCRIPTION\n");
for (i = 0; i < ArraySize(descr); i++) for (i = 0; i < ArraySize(descr); i++)
{ {
StreamPrintf(StreamStdout(), "%s\n", ArrayGet(descr, i)); StreamPrintf(out, "%s\n", ArrayGet(descr, i));
} }
for (i = 0; i < ArraySize(declarations); i++) for (i = 0; i < ArraySize(declarations); i++)
@ -290,16 +389,16 @@ last:
char *line; char *line;
decl = ArrayGet(declarations, i); decl = ArrayGet(declarations, i);
StreamPrintf(StreamStdout(), ".Ss %s %s(", StreamPrintf(out, ".Ss %s %s(",
decl->decl.returnType, decl->decl.name); decl->decl.returnType, decl->decl.name);
for (j = 0; j < ArraySize(decl->decl.args); j++) for (j = 0; j < ArraySize(decl->decl.args); j++)
{ {
StreamPrintf(StreamStdout(), "%s", ArrayGet(decl->decl.args, j)); StreamPrintf(out, "%s", ArrayGet(decl->decl.args, j));
if (j < ArraySize(decl->decl.args) - 1) if (j < ArraySize(decl->decl.args) - 1)
{ {
StreamPuts(StreamStdout(), ", "); StreamPuts(out, ", ");
} }
StreamPuts(StreamStdout(), ")\n"); StreamPuts(out, ")\n");
} }
line = strtok(decl->docs, "\n"); line = strtok(decl->docs, "\n");
@ -312,7 +411,7 @@ last:
if (*line) if (*line)
{ {
StreamPrintf(StreamStdout(), "%s\n", line); StreamPrintf(out, "%s\n", line);
} }
line = strtok(NULL, "\n"); line = strtok(NULL, "\n");
@ -324,27 +423,27 @@ last:
{ {
char *xr = strtok(val, " "); char *xr = strtok(val, " ");
StreamPrintf(StreamStdout(), ".Sh SEE ALSO\n"); StreamPrintf(out, ".Sh SEE ALSO\n");
while (xr) while (xr)
{ {
if (*xr) if (*xr)
{ {
StreamPrintf(StreamStdout(), ".Xr %s 3 ", xr); StreamPrintf(out, ".Xr %s 3 ", xr);
} }
xr = strtok(NULL, " "); xr = strtok(NULL, " ");
if (xr) if (xr)
{ {
StreamPutc(StreamStdout(), ','); StreamPutc(out, ',');
} }
StreamPutc(StreamStdout(), '\n'); StreamPutc(out, '\n');
} }
} }
finish: finish:
StreamClose(StreamStdin()); StreamClose(in);
StreamClose(StreamStdout()); StreamClose(out);
StreamClose(StreamStderr()); StreamClose(StreamStderr());
MemoryFreeAll(); MemoryFreeAll();