slw2gmi

Конвертор из slweb-а у Џемини
git clone https://git.sr.ht/~strahinja/slw2gmi
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 7bced84c78f0917cec6c1893f618ec5e68ffc298
родитељ f5cae78b13acf4aff0ba622843818c0be8fdc77a
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sat,  4 May 2024 20:57:10 +0200

Convert manpage to mdoc(7); sync changes from slweb

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

Diffstat:
Mdefs.h | 7++++---
Mslw2gmi.1.in | 163++++++++++++++++++++++++++++---------------------------------------------------
Mslw2gmi.c | 229++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
измењених датотека: 3, додавања: 213(+), брисања: 186(-)

diff --git a/defs.h b/defs.h @@ -20,10 +20,10 @@ #include <unistd.h> #ifndef strlcpy -size_t strlcpy(char *dst, const char *src, size_t dsize); +size_t strlcpy(char* dst, const char* src, size_t dsize); #endif #ifndef strlcat -size_t strlcat(char *dst, const char *src, size_t dsize); +size_t strlcat(char* dst, const char* src, size_t dsize); #endif #include "version.h" @@ -60,7 +60,8 @@ typedef enum { CMD_BASEDIR, CMD_HELP, CMD_LINK_PREFIX, - CMD_VERSION + CMD_VERSION, + CMD_FULL_VERSION } Command; typedef struct { diff --git a/slw2gmi.1.in b/slw2gmi.1.in @@ -1,108 +1,59 @@ -'\" -.\" Manpage for slweb(1) -.\" vim: set filetype=groff: -. -.mso an-ext.tmac -.de CDS -.EX -.RS \\$1 -.sp 1 -.. -.de CDE -.sp 1 -.RE -.EE -.. -. -.TH SLW2GMI "1" "%DATE%" "slw2gmi %VERSION%" "General Commands Manual" -.SH NAME -slw2gmi \- slweb to Gemini converter -. -.SH SYNOPSIS -. -.SY slw2gmi -.OP "\-h \fR|\fP \-\-help" -.YS -. -.SY slw2gmi -.OP "\-v \fR|\fP \-\-version" -.YS -. -.SY slw2gmi -.OP "\-d \fR|\fP \-\-basedir" directory -.OP "\-p \fR|\fP \-\-global-link-prefix" URL -.RI [ filename ] -.YS -. -.SH COPYRIGHT -slw2gmi Copyright \(co 2021\-2024 Strahinya Radich. -.br -This program is licensed under GNU GPL v3 or later. See the file -.I LICENSE -in the slweb repository for details. -. -.SH DESCRIPTION -.B slw2gmi -is a converter from -.BR slweb (1) -to Gemini format. Although both are -similar to Markdown, the two formats differ enough to warrant a full converter. -. -.SH OPTIONS -. -.TP -.BI \-d " directory" -.TQ -.BI \-\-basedir " directory" -.br -Set the base directory as a reference point to normalize paths in includes (the -argument to -.B --relative-to -option for the -.BR realpath (1) -command). Defaults to the current directory. -. -.TP -.B \-h -.TQ -.B \-\-help -.br -Print this usage information screen. -. -.TP -.BI \-p " URL" -.TQ -.BI \-\-global-link-prefix " URL" -.br -Set -.I URL -as a global prefix for relative links. For example, this can be useful when -generating Gemini code which needs to keep relative links pointing to web URLs. -. -.TP -.B \-v -.TQ -.B \-\-version -.br -Print program version and exit. -. -.SH REFERENCE -. -.LP +.\" This program is licensed under the terms of GNU GPL v3 or (at your option) +.\" any later version. Copyright (C) 2021-2024 Страхиња Радић. +.\" See the file LICENSE for exact copyright and license details. +.Dd %DATE% +.Dt SLW2GMI 1 +.Os +.Sh NAME +.Nm slw2gmi +.Nd slweb to Gemini converter +.Sh SYNOPSIS +.Nm +.Fl h | Fl \-help | Fl V | Fl \-full\-version | Fl v | Fl \-version +.Nm +.Oo Fl d Ar directory | Fl \-basedir Ar directory Oc +.Oo Fl p Ar URL | Fl \-global\-link\-prefix Ar URL Oc +.Op Ar filename +.Sh DESCRIPTION +.Nm +is a converter from +.Xr slweb 1 +to Gemini format. +Although both are similar to Markdown, the two formats differ enough to warrant +a full converter. +. +.Bl -tag -width Ds +.It Fl d Ar directory | Fl \-basedir Ar directory +Set the base directory for includes +.Pf "(" Ql {include} +and +.Ql {incdir} Ns +). +Defaults to the current directory. +.It Fl h | Fl \-help +Print the usage information screen. +.It Fl p Ar URL | Fl \-global\-link\-prefix Ar URL +Set +.Ar URL +as a global prefix for relative links. +For example, this can be useful when generating Gemini code which needs to keep +relative links pointing to web URLs. +.It Fl V | Fl \-full\-version +Print full version (like +.Fl v Ns +), followed by copyright notice, and exit. +.It Fl v | Fl \-version +Print program version and commit date, and exit. +.El +.Pp Refer to -.BR slweb (1) -manual for the description of .slw file format. -. -.SH AUTHOR -. -Strahinya Radich, -.UR https://\:strahinja.org -.UE -. -.SH BUGS -. -.LP +.Xr slweb 1 +manual for the description of +.Pa .slw +file format. +.Sh AUTHORS +.An "Strahinya Radich" Aq contact@strahinja.org , +2021\-2024 +.Sh BUGS Bugs can be reported using the ticket tracker at: -.UR https://\:todo.sr.ht/\:~strahinja/\:slw2gmi - -.UE +.Lk https://\:todo.sr.ht/\:~strahinja/\:slw2gmi diff --git a/slw2gmi.c b/slw2gmi.c @@ -45,27 +45,36 @@ static long tsv_iter = 0; static ULLONG state = ST_NONE; static int incdir_only_summary = 0; -#define CHECKEXITNOMEM(ptr) \ - do \ - { \ - if (!ptr) \ - exit(error(ENOMEM, \ - (u8*)"Memory allocation failed (out of " \ - "memory?)")); \ +#define COPYRIGHT \ + (" This program is licensed under the terms of GNU GPL v3" \ + " or (at your option)\n" \ + " any later version. Copyright (C) 2021-2024 Strahinya Radich.\n" \ + " See the file LICENSE for exact copyright and license " \ + "details.") + +#define CHECKEXITNOMEM(ptr, func) \ + do \ + { \ + if (!ptr) \ + exit(error(ENOMEM, \ + (u8*)"" #func \ + ":%d: Memory allocation failed (out of " \ + "memory?)", \ + __LINE__)); \ } while (0) #define CALLOC(ptr, ptrtype, nmemb) \ do \ { \ ptr = calloc(nmemb, sizeof(ptrtype)); \ - CHECKEXITNOMEM(ptr); \ + CHECKEXITNOMEM(ptr, calloc); \ } while (0) #define REALLOC(ptr, ptrtype, newsize) \ do \ { \ ptrtype* newptr = realloc(ptr, newsize); \ - CHECKEXITNOMEM(newptr); \ + CHECKEXITNOMEM(newptr, realloc); \ ptr = newptr; \ } while (0) @@ -96,22 +105,24 @@ static int incdir_only_summary = 0; int slweb_cleanup(void); int usage(void); -int version(void); +int version(const int full); int -version(void) +version(const int full) { printf("%s %s, committed on %s\n", PROGRAMNAME, VERSION, DATE); + if (full) + puts(COPYRIGHT); return 0; } int usage(void) { - printf("Usage: %s [-d|--basedir <dir>]" - " [-p|--global-link-prefix <URL>] [-h|--help]" - " [-v|--version] [filename]\n", - PROGRAMNAME); + printf("Usage:\t%s -h | --help | -V | --full-version | -v | --version\n" + "\t%s [-d directory | --basedir directory]" + " [-p URL | --global-link-prefix URL] [filename]\n", + PROGRAMNAME, PROGRAMNAME); return 0; } @@ -270,7 +281,7 @@ set_basedir(char** basedir, size_t* basedir_size, const char* arg) size_t arg_len = strlen(arg); if (arg_len < 1) - exit(error(1, (u8*)"--basedir: Argument required")); + exit(error(1, (u8*)"set_basedir: Argument required")); if (arg_len + 1 > *basedir_size) { @@ -294,7 +305,7 @@ set_global_link_prefix(char** global_link_prefix, size_t arg_len = strlen(arg); if (arg_len < 1) - exit(error(1, (u8*)"--global-link-prefix: Argument required")); + exit(error(1, (u8*)"set_global_link_prefix: Argument required")); if (arg_len + 1 > *global_link_prefix_size) { @@ -447,7 +458,7 @@ print_command(FILE* output, const char* command, const u8* pass_arguments[], exit(1); } else if (pid < 0) - exit(error(errno, (u8*)"Fork failed")); + exit(error(errno, (u8*)"print_command: fork failed")); /* Parent */ close(arg_pipe_fds[PIPE_READ_INDEX]); @@ -456,7 +467,10 @@ print_command(FILE* output, const char* command, const u8* pass_arguments[], FILE* cmd_output = fdopen(output_pipe_fds[PIPE_READ_INDEX], "r"); if (!cmd_input || !cmd_output) - exit(error(1, (u8*)"Cannot fdopen")); + { + perror("fdopen"); + exit(error(1, (u8*)"print_command: fdopen failed")); + } if (pipe_arguments) { @@ -512,9 +526,19 @@ read_file_into_buffer(FILE** input, u8** buffer, size_t* buffer_size, *input = fopen(input_filename, "r"); if (!*input) - return error(ENOENT, (u8*)"No such file: %s", input_filename); + { + perror("fopen"); + return error(ENOENT, + (u8*)"read_file_into_buffer: fopen failed: %s", + input_filename); + } fstat(fileno(*input), &fs); + if (S_ISDIR(fs.st_mode)) + return error(EISDIR, + (u8*)"read_file_into_buffer: Is a directory: %s", + input_filename); + free(*buffer); *buffer_size = fs.st_size + 1; CALLOC(*buffer, u8, *buffer_size); @@ -659,7 +683,9 @@ tsv_template_start: case '#': if (IN(tsv_state, ST_CS_HEADER)) { - error(1, (u8*)"tsv: Invalid header register mark"); + error(1, + (u8*)"print_tsv_row: Invalid header register" + " mark"); tsv_state &= ~(ST_CS_REGISTER | ST_CS_HEADER); } else if (IN(tsv_state, ST_CS_REGISTER)) @@ -674,7 +700,9 @@ tsv_template_start: case '?': if (IN(tsv_state, ST_CS_COND)) { - error(1, (u8*)"tsv: Invalid conditional mark"); + error(1, + (u8*)"print_tsv_row: Invalid conditional" + " mark"); tsv_state &= ~ST_CS_COND; } else if (IN(tsv_state, ST_CS_REGISTER)) @@ -695,8 +723,8 @@ tsv_template_start: else if (IN(tsv_state, ST_CS_COND)) { error(1, - (u8*)"Empty conditional before/without nonempty" - " conditional"); + (u8*)"print_tsv_row: Empty conditional" + " before/without nonempty conditional"); tsv_state &= ~(ST_CS_COND | ST_CS_COND_EMPTY); } else @@ -746,12 +774,14 @@ tsv_template_start: default: if (IN(tsv_state, ST_CS_HEADER)) { - error(1, (u8*)"tsv: Invalid header register mark"); + error(1, + (u8*)"print_tsv_row: Invalid header register" + " mark"); tsv_state &= ~ST_CS_HEADER; } else if (IN(tsv_state, ST_CS_REGISTER)) { - error(1, (u8*)"tsv: Invalid register mark"); + error(1, (u8*)"print_tsv_row: Invalid register mark"); tsv_state &= ~ST_CS_REGISTER; } else @@ -782,7 +812,10 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback) UBYTE current_register = 0; if (!(tsv = fopen(filename, "rt"))) - exit(error(ENOENT, (u8*)"tsv: No such file: %s", filename)); + { + perror("fopen"); + exit(error(ENOENT, (u8*)"read_tsv: fopen failed: %s", filename)); + } CALLOC(bufline, u8, BUFSIZE); token_size = BUFSIZE; @@ -908,7 +941,9 @@ process_tsv(FILE* output, const u8* arg_token, else { if (ANY(state, ST_CSV_BODY | ST_TSV_BODY)) - exit(error(1, (u8*)"Can't nest csv/tsv directives")); + exit(error(1, + (u8*)"process_tsv: Can't nest csv/tsv " + "directives")); state |= ST_TSV_BODY; @@ -921,11 +956,13 @@ process_tsv(FILE* output, const u8* arg_token, (char**)&saveptr); args = (u8*)strtok_r(NULL, " ", (char**)&saveptr); if (!args) - exit(error(EINVAL, (u8*)"tsv: Arguments required")); + exit(error(EINVAL, + (u8*)"process_tsv: Arguments required")); size_t args_len = strlen((char*)args); if (*args != '"' || *(args + args_len - 1) != '"') exit(error(EINVAL, - (u8*)"tsv: First argument must be a string")); + (u8*)"process_tsv: First argument must be a " + "string")); if (!tsv_filename) CALLOC(tsv_filename, u8, BUFSIZE); u8* args_base = (u8*)strdup((char*)args + 1); @@ -940,7 +977,8 @@ process_tsv(FILE* output, const u8* arg_token, tsv_iter = strtol((char*)args, NULL, 10); if (errno) exit(error(errno, - (u8*)"tsv: Invalid argument '%s'", + (u8*)"process_tsv: Invalid argument " + "'%s'", args)); } } @@ -1000,7 +1038,7 @@ csv_template_start: case '#': if (IN(csv_state, ST_CS_HEADER)) { - error(1, (u8*)"csv: Invalid header register mark"); + error(1, (u8*)"print_csv_row: Invalid header register mark"); csv_state &= ~(ST_CS_REGISTER | ST_CS_HEADER); } else if (IN(csv_state, ST_CS_REGISTER)) @@ -1015,7 +1053,7 @@ csv_template_start: case '?': if (IN(csv_state, ST_CS_COND)) { - error(1, (u8*)"csv: Invalid conditional mark"); + error(1, (u8*)"print_csv_row: Invalid conditional mark"); csv_state &= ~ST_CS_COND; } else if (IN(csv_state, ST_CS_REGISTER)) @@ -1036,7 +1074,8 @@ csv_template_start: else if (IN(csv_state, ST_CS_COND)) { error(1, - (u8*)"Empty conditional before/without nonempty" + (u8*)"print_csv_row: Empty conditional " + "before/without nonempty" " conditional"); csv_state &= ~(ST_CS_COND | ST_CS_COND_EMPTY); } @@ -1087,12 +1126,12 @@ csv_template_start: default: if (IN(csv_state, ST_CS_HEADER)) { - error(1, (u8*)"csv: Invalid header register mark"); + error(1, (u8*)"print_csv_row: Invalid header register mark"); csv_state &= ~ST_CS_HEADER; } else if (IN(csv_state, ST_CS_REGISTER)) { - error(1, (u8*)"csv: Invalid register mark"); + error(1, (u8*)"print_csv_row: Invalid register mark"); csv_state &= ~ST_CS_REGISTER; } else @@ -1126,7 +1165,10 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback) = get_value(vars, vars_count, (u8*)"csv-delimiter", NULL); if (!(csv = fopen(filename, "rt"))) - exit(error(ENOENT, (u8*)"csv: No such file: %s", filename)); + { + perror("fopen"); + exit(error(ENOENT, (u8*)"read_csv: fopen failed: %s", filename)); + } CALLOC(bufline, u8, BUFSIZE); token_size = BUFSIZE; @@ -1296,7 +1338,9 @@ process_csv(FILE* output, const u8* arg_token, else { if (ANY(state, ST_CSV_BODY | ST_TSV_BODY)) - exit(error(1, (u8*)"Can't nest csv/tsv directives")); + exit(error(1, + (u8*)"read_csv: Can't nest csv/tsv" + " directives")); state |= ST_CSV_BODY; @@ -1309,11 +1353,12 @@ process_csv(FILE* output, const u8* arg_token, (char**)&saveptr); args = (u8*)strtok_r(NULL, " ", (char**)&saveptr); if (!args) - exit(error(EINVAL, (u8*)"csv: Arguments required")); + exit(error(EINVAL, (u8*)"read_csv: Arguments required")); size_t args_len = strlen((char*)args); if (*args != '"' || *(args + args_len - 1) != '"') exit(error(EINVAL, - (u8*)"csv: First argument must be a string")); + (u8*)"read_csv: First argument must be a " + "string")); if (!csv_filename) CALLOC(csv_filename, u8, BUFSIZE); u8* args_base = (u8*)strdup((char*)args + 1); @@ -1328,7 +1373,7 @@ process_csv(FILE* output, const u8* arg_token, csv_iter = strtol((char*)args, NULL, 10); if (errno) exit(error(errno, - (u8*)"csv: Invalid argument '%s'", + (u8*)"read_csv: Invalid argument '%s'", args)); } } @@ -1355,7 +1400,7 @@ process_include(FILE* output, const u8* token, if (!ptoken) exit(error(1, - (u8*)"Directive 'include' requires" + (u8*)"process_include: Directive 'include' requires" " an argument")); fflush(output); @@ -1373,7 +1418,8 @@ process_include(FILE* output, const u8* token, = fdopen(output_pipe_fds[PIPE_READ_INDEX], "r"))) { wait(&pstatus); - exit(error(1, (u8*)"Cannot fdopen")); + perror("fdopen"); + exit(error(1, (u8*)"process_include: fdopen failed")); } CALLOC(child_output_line, u8, BUFSIZE); @@ -1410,7 +1456,10 @@ process_include(FILE* output, const u8* token, close(output_pipe_fds[PIPE_READ_INDEX]); if (!(child_output = fdopen(output_pipe_fds[PIPE_WRITE_INDEX], "w"))) - exit(error(1, (u8*)"Cannot fdopen")); + { + perror("fdopen"); + exit(error(1, (u8*)"process_include: fdopen failed")); + } CALLOC(include_filename, char, BUFSIZE); pinclude_filename = include_filename; @@ -1478,7 +1527,7 @@ process_include(FILE* output, const u8* token, exit(result); } else - exit(error(1, (u8*)"Fork failed")); + exit(error(1, (u8*)"process_include: fork failed")); return 0; } @@ -1609,7 +1658,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, < 0) { perror("scandir"); - exit(error(errno, (u8*)"incdir_subdir: scandir '%s' error", + exit(error(errno, + (u8*)"process_incdir_subdir: scandir '%s' failed", abs_subdirname)); } @@ -1633,7 +1683,7 @@ process_incdir_subdir(FILE* output, const char* subdirname, int result = 0; ULLONG saved_state = ST_NONE; char* filename = NULL; - char* abs_filename = NULL; + char* abs_filename = NULL; char* link = NULL; u8* title = NULL; u8* date = NULL; @@ -1685,7 +1735,9 @@ process_incdir_subdir(FILE* output, const char* subdirname, result = slweb_parse(output, abs_filename, buffer, 1); if (result) { - warning(1, (u8*)"slweb_parse error"); + warning(1, + (u8*)"process_incdir_subdir:" + " slweb_parse error"); goto incdir_subdir_child_cleanup; } @@ -1711,7 +1763,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, exit(result); } else - exit(error(1, (u8*)"Fork failed")); + exit(error(1, + (u8*)"process_incdir_subdir: fork failed")); /*if (!list_only) print_output(output, "</article>\n");*/ @@ -1760,12 +1813,12 @@ process_incdir(FILE* output, const u8* token, const u8* link_prefix, arg = (u8*)strtok_r((char*)token, " ", (char**)&saveptr); arg = (u8*)strtok_r(NULL, " ", (char**)&saveptr); if (!arg) - exit(error(1, (u8*)"incdir: Arguments required")); + exit(error(1, (u8*)"process_incdir: Arguments required")); arg_len = strlen((char*)arg); if (*arg != '"' || *(arg + arg_len - 1) != '"') - exit(error(1, (u8*)"incdir: First argument not string")); + exit(error(1, (u8*)"process_incdir: First argument not string")); incdir = strdup((char*)(arg + 1)); *(incdir + strlen(incdir) - 1) = 0; /* trim ending " */ @@ -1787,14 +1840,17 @@ incdir_next_arg: while (parg && *parg) { if (*parg < '0' || *parg > '9') - exit(error(1, (u8*)"incdir: Invalid argument")); + exit(error(1, + (u8*)"process_incdir: Invalid " + "argument")); parg++; } errno = 0; num = strtol((char*)arg, NULL, 10); if (errno) exit(error(errno, - (u8*)"incdir: Invalid parameter 'num'")); + (u8*)"process_incdir: Invalid parameter " + "'num'")); } pass++; if (pass < 3) @@ -1808,7 +1864,8 @@ incdir_done_args: < 0) { perror("scandir"); - exit(error(errno, (u8*)"incdir: scandir '%s' error", incdir)); + exit(error(errno, (u8*)"process_incdir: scandir '%s' failed", + incdir)); } pnamelist = namelist; @@ -1951,7 +2008,8 @@ process_macro_def(FILE* output, const u8* token, } if (IN(state, ST_MACRO_BODY)) - exit(error(1, (u8*)"Cannot nest definitions")); + exit(error(1, + (u8*)"process_macro_def: Cannot nest definitions")); if (read_yaml_macros_and_links) { @@ -1990,7 +2048,8 @@ process_macro(FILE* output, const u8* token, const int end_tag) macro_body = get_value(macros, macros_count, token + 1, NULL); if (!macro_body) - exit(error(1, (u8*)"Macro '%s' undefined", token + 1)); + exit(error(1, (u8*)"process_macro: Macro '%s' undefined", + token + 1)); eol = (u8*)strrchr((char*)macro_body, '\n'); macro_body_len = strlen((char*)macro_body); @@ -2573,7 +2632,8 @@ simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, var_key = (u8*)strdup((char*)token); if (!var_key) exit(error(ENOMEM, - (u8*)"Memory allocation failed (out of " + (u8*)"simple_parse_yaml_line: strdup " + "failed (out of " "memory?)")); ptoken = token; *ptoken = 0; @@ -2683,7 +2743,7 @@ slweb_parse(FILE* output, const char* source_filename, const u8* buffer, u8* eol = NULL; if (!buffer) - exit(error(1, (u8*)"Empty buffer")); + exit(error(1, (u8*)"slweb_parse: Empty buffer")); title = get_value(vars, vars_count, (u8*)"title", NULL); title_heading_level @@ -4324,7 +4384,7 @@ do_line: NULL); if (!url) exit(error(EINVAL, - (u8*)"get_" + (u8*)"slweb_parse: get_" "value: " "Invalid " "argumen" @@ -4380,7 +4440,7 @@ do_line: NULL); if (!url) exit(error(EINVAL, - (u8*)"get_" + (u8*)"slweb_parse: get_" "value: " "Invalid " "argumen" @@ -4606,7 +4666,8 @@ do_line: { if (IN(state, ST_FORMULA)) exit(error(1, - (u8*)"Display formula within an" + (u8*)"slweb_parse: Display formula " + "within an" " open formula")); if (!(IN(state, ST_DISPLAY_FORMULA))) @@ -4643,7 +4704,8 @@ do_line: { if (IN(state, ST_DISPLAY_FORMULA)) exit(error(1, - (u8*)"Formula within an open" + (u8*)"slweb_parse: Formula within an " + "open" " display formula")); if (!(IN(state, ST_FORMULA))) @@ -5191,8 +5253,12 @@ int main(const int argc, const char** argv) { const char* arg; - Command cmd = CMD_NONE; - int result = 0; + Command cmd = CMD_NONE; + int result = 0; + FILE* input = NULL; + FILE* output = stdout; + u8* buffer = NULL; + size_t buffer_size = 0; basedir_size = 2; CALLOC(basedir, char, basedir_size); @@ -5208,7 +5274,9 @@ main(const int argc, const char** argv) if (c == '-') { - if (!strcmp(arg, "version")) + if (!strcmp(arg, "full-version")) + cmd = CMD_FULL_VERSION; + else if (!strcmp(arg, "version")) cmd = CMD_VERSION; else if (startswith(arg, "basedir")) { @@ -5232,7 +5300,7 @@ main(const int argc, const char** argv) else { error(EINVAL, - (u8*)"Invalid " + (u8*)"main: Invalid " "argument: --%s", arg); return usage(); @@ -5251,12 +5319,15 @@ main(const int argc, const char** argv) case 'p': cmd = CMD_LINK_PREFIX; break; + case 'V': + cmd = CMD_FULL_VERSION; + break; case 'v': cmd = CMD_VERSION; break; default: error(EINVAL, - (u8*)"Invalid " + (u8*)"main: Invalid " "argument: -%c", c); return usage(); @@ -5288,19 +5359,20 @@ main(const int argc, const char** argv) } if (cmd == CMD_BASEDIR) - return error(1, (u8*)"-d: Argument required"); - - if (cmd == CMD_VERSION) - return version(); + return error(1, (u8*)"main: set_basedir: Argument required"); - FILE* input = NULL; - FILE* output = stdout; - u8* buffer = NULL; - size_t buffer_size = 0; + if (cmd == CMD_FULL_VERSION) + return version(1); + else if (cmd == CMD_VERSION) + return version(0); if (input_filename) - read_file_into_buffer(&input, &buffer, &buffer_size, - input_filename, &input_dirname); + { + int result = read_file_into_buffer(&input, &buffer, + &buffer_size, input_filename, &input_dirname); + if (result) + exit(result); + } else { u8* bufline = NULL; @@ -5310,6 +5382,9 @@ main(const int argc, const char** argv) input = stdin; + CALLOC(input_dirname, char, 2); + *input_dirname = '.'; + CALLOC(bufline, u8, BUFSIZE); buffer_size = BUFSIZE; CALLOC(buffer, u8, buffer_size);