1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-02 15:55:59 +00:00
oot/tools/fado/src/help.c

163 lines
5.3 KiB
C
Raw Normal View History

New relocation-generating program (#1016) * Update makefiles * git subrepo clone git@github.com:EllipticEllipsis/fado.git tools/fado subrepo: subdir: "tools/fado" merged: "46c4d751a" upstream: origin: "git@github.com:EllipticEllipsis/fado.git" branch: "master" commit: "46c4d751a" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/fado subrepo: subdir: "tools/fado" merged: "88114ebce" upstream: origin: "git@github.com:EllipticEllipsis/fado.git" branch: "master" commit: "88114ebce" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * A few ideas for computing dependencies * Remove reserved identifiers from spec.h and util.h and add required headers * Fix a couple more headers * Program for reloc prerequisites * git subrepo pull tools/fado subrepo: subdir: "tools/fado" merged: "36a905f72" upstream: origin: "git@github.com:EllipticEllipsis/fado.git" branch: "master" commit: "36a905f72" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Update makefile to make dependency files and use overlay's name * git subrepo pull tools/fado subrepo: subdir: "tools/fado" merged: "43c339a59" upstream: origin: "git@github.com:EllipticEllipsis/fado.git" branch: "master" commit: "43c339a59" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Change awk to grep, delete ZAPD files, gitignore elf * Delete all the cfg files * Fix memory leaks * Rename and add coloured errors * Makefile tweaks - preprocess spec before grep - split order prerequisites via phony target to reduce dependency edges - remove `resources` target - remove separate overlays targets - use `$(SPEC)` throughout - change to using filenames of relocs for overlay names via `$*` - Rearrange targets to better reflect their categories * Update gitignore * Review * Add a check for the reloc file name * get_segment_by_name * get_stmt_id_by_stmt_name * Cleaning up * algorithm change * function rename * Fix typos Co-authored-by: angie <angheloalf95@gmail.com>
2022-02-06 19:40:26 +00:00
/**
* Getopt-compatible printing of formatted help.
*/
/* Copyright (C) 2021 Elliptic Ellipsis */
/* SPDX-License-Identifier: AGPL-3.0-only */
#include "help.h"
#include <assert.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "macros.h"
/* Values of the variables used by Help_PrintHelp. Defaults are taken from common terminal programs like grep */
size_t helpTextWidth = 80;
size_t helpDtIndent = 2;
size_t helpDdIndent = 25;
/**
* Prints a paragraph, word wrapped to helpTextWidth, with a hanging indent. initialColumn is used to determine how wide
* the first line should be, while indentFirstLine should be true if there is no previous text on the line (an ordinary
* paragraph), and false if there is (e.g. as a description list description)
*/
void Help_PrintFlowAndIndent(const char* string, size_t initialColumn, size_t textWidth, size_t hangingIndent,
bool indentFirstLine) {
size_t column = initialColumn;
size_t index = 0;
size_t inLength = strlen(string);
size_t lookAhead;
bool shouldBreak;
assert(initialColumn < textWidth);
assert(hangingIndent < textWidth);
if (indentFirstLine) {
printf("%*s", (int)initialColumn, "");
}
for (; index <= inLength; index++) {
shouldBreak = 0;
if (column == textWidth) {
printf("%c\n%*s", string[index], (int)hangingIndent, "");
column = hangingIndent;
continue;
}
column++;
switch (string[index]) {
case '\0':
return;
case ' ':
if (column == hangingIndent) {
continue;
}
for (lookAhead = 0; lookAhead <= textWidth - column; lookAhead++) {
// printf("%c\n", src[index + lookAhead]);
if (string[index + lookAhead + 1] == ' ' || string[index + lookAhead + 1] == '\0') {
putchar(' ');
shouldBreak = 1;
break;
}
}
if (shouldBreak) { /* Damn shared keywords. */
break;
}
case '\n':
printf("\n%*s", (int)hangingIndent, "");
column = hangingIndent;
break;
default:
putchar(string[index]);
break;
}
}
}
/**
* Prints help in the form
* ```
* prologue (word wrapped)
*
* Positional arguments
* arg1 Description (word
* wrapped)
* arg2 Description (word
* wrapped)
*
* Options
* -a --long-name=ARG Description (word
* wrapped)
*
* epilogue (word wrapped)
* ```
* where the positional arguments are described using the posArgInfo array, and options are fed using the OptInfo array,
* which should both be null-terminated. posArgCount/optCount is the actual number of positional arguments/options: it
* is used to guarantee no garbage is printed even if the user has not null-terminated the array. (optCount is required
* for constructing the getopt option array anyway.)
*/
void Help_PrintHelp(const char* prologue, size_t posArgCount, const PosArgInfo* posArgInfo, size_t optCount,
const OptInfo* optInfo, const char* epilogue) {
size_t i;
size_t dtLength;
int padding;
Help_PrintFlowAndIndent(prologue, 0, helpTextWidth, 0, false);
if (posArgCount != 0) {
printf("\nPositional Argument\n");
for (i = 0; i < optCount; i++) {
if (posArgInfo[i].helpArg == 0) {
break;
}
dtLength = helpDtIndent + strlen(posArgInfo[i].helpArg);
padding = helpDdIndent - dtLength - 2;
printf("%*s%s%*s ", (int)helpDtIndent, "", posArgInfo[i].helpArg, CLAMP_MIN(padding, 0), "");
Help_PrintFlowAndIndent(posArgInfo[i].helpMsg, CLAMP_MIN(dtLength + 2, helpDdIndent), helpTextWidth,
helpDdIndent, false);
printf("\n");
}
}
if (optCount != 0) {
printf("\nOptions\n");
for (i = 0; i < optCount; i++) {
if (optInfo[i].longOpt.val == 0) {
break;
}
dtLength = helpDtIndent + 6 + strlen(optInfo[i].longOpt.name);
if (optInfo[i].helpArg == NULL) {
padding = helpDdIndent - dtLength - 2;
printf("%*s-%c, --%s%*s ", (int)helpDtIndent, "", optInfo[i].longOpt.val, optInfo[i].longOpt.name,
CLAMP_MIN(padding, 0), "");
} else {
dtLength += 1 + strlen(optInfo[i].helpArg);
padding = helpDdIndent - dtLength - 2;
printf("%*s-%c, --%s=%s%*s ", (int)helpDtIndent, "", optInfo[i].longOpt.val, optInfo[i].longOpt.name,
optInfo[i].helpArg, CLAMP_MIN(padding, 0), "");
}
Help_PrintFlowAndIndent(optInfo[i].helpMsg, CLAMP_MIN(dtLength + 2, helpDdIndent), helpTextWidth,
helpDdIndent, false);
printf("\n");
}
}
printf("\n");
Help_PrintFlowAndIndent(epilogue, 0, helpTextWidth, 0, false);
printf("\n");
}