SCP: Cleaned up the hierarchical help APIs to follow the same indentation style used in the rest of scp.c. Fixed the help prompt to avoid adding an extra level to the prompt when the current level has no children.
This commit is contained in:
parent
b1fb809210
commit
545aa85677
1 changed files with 590 additions and 592 deletions
166
scp.c
166
scp.c
|
@ -7945,11 +7945,12 @@ jmp_buf (help_env);
|
|||
* Expands text buffer as necessary.
|
||||
*/
|
||||
|
||||
static void appendText (TOPIC *topic, const char *text, size_t len) {
|
||||
static void appendText (TOPIC *topic, const char *text, size_t len)
|
||||
{
|
||||
char *newt;
|
||||
if (!len) {
|
||||
|
||||
if (!len)
|
||||
return;
|
||||
}
|
||||
|
||||
newt = (char *)realloc (topic->text, topic->len + len +1);
|
||||
if (!newt) {
|
||||
|
@ -7964,7 +7965,8 @@ static void appendText (TOPIC *topic, const char *text, size_t len) {
|
|||
|
||||
/* Release memory held by a topic and its children.
|
||||
*/
|
||||
static void cleanHelp (TOPIC *topic) {
|
||||
static void cleanHelp (TOPIC *topic)
|
||||
{
|
||||
TOPIC *child;
|
||||
size_t i;
|
||||
|
||||
|
@ -7984,7 +7986,8 @@ static void cleanHelp (TOPIC *topic) {
|
|||
* Handles substitutions, formatting.
|
||||
*/
|
||||
static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
||||
struct sim_unit *uptr, const char *htext, va_list ap) {
|
||||
struct sim_unit *uptr, const char *htext, va_list ap)
|
||||
{
|
||||
char *end;
|
||||
size_t n, ilvl;
|
||||
#define VSMAX 100
|
||||
|
@ -8015,9 +8018,8 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
help_where.line++;
|
||||
if (isspace (*htext) || *htext == '+') {/* Topic text, indented topic text */
|
||||
if (excluded) { /* Excluded topic text */
|
||||
while (*htext && *htext != '\n') {
|
||||
while (*htext && *htext != '\n')
|
||||
htext++;
|
||||
}
|
||||
if (*htext)
|
||||
++htext;
|
||||
continue;
|
||||
|
@ -8031,12 +8033,10 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
htext++;
|
||||
}
|
||||
}
|
||||
while (*htext && *htext != '\n' && isspace (*htext)) {
|
||||
while (*htext && *htext != '\n' && isspace (*htext))
|
||||
htext++;
|
||||
}
|
||||
if (!*htext) { /* Empty after removing leading spaces */
|
||||
if (!*htext) /* Empty after removing leading spaces */
|
||||
break;
|
||||
}
|
||||
start = htext;
|
||||
while (*htext) { /* Process line for substitutions */
|
||||
if (*htext == '%') {
|
||||
|
@ -8067,15 +8067,13 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
default: /* Check for vararg # */
|
||||
if (isdigit (*htext)) {
|
||||
n = 0;
|
||||
while (isdigit (*htext)) {
|
||||
while (isdigit (*htext))
|
||||
n += (n * 10) + (*htext++ - '0');
|
||||
}
|
||||
if (( *htext != 'H' && *htext != 's') ||
|
||||
n == 0 || n >= VSMAX)
|
||||
FAIL (SCPE_ARG, Invalid escape, htext);
|
||||
while (n > vsnum) { /* Get arg pointer if not cached */
|
||||
while (n > vsnum) /* Get arg pointer if not cached */
|
||||
vstrings[vsnum++] = va_arg (ap, char *);
|
||||
}
|
||||
start = vstrings[n-1]; /* Insert selected string */
|
||||
if (*htext == 'H') { /* Append as more input */
|
||||
if (asnum >= VSMAX) {
|
||||
|
@ -8091,14 +8089,13 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
appendText (topic, start, ep - start);
|
||||
if (*ep) { /* More past \n, indent */
|
||||
size_t i;
|
||||
for (i = 0; i < ilvl; i++) {
|
||||
for (i = 0; i < ilvl; i++)
|
||||
appendText (topic, " ", 4);
|
||||
}
|
||||
}
|
||||
start = ep;
|
||||
} else {
|
||||
ep++;
|
||||
}
|
||||
else
|
||||
ep++;
|
||||
}
|
||||
appendText (topic, start, ep-start);
|
||||
break;
|
||||
|
@ -8124,31 +8121,28 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
|
||||
n = 0;
|
||||
start = htext;
|
||||
while (isdigit (*htext)) {
|
||||
while (isdigit (*htext))
|
||||
n += (n * 10) + (*htext++ - '0');
|
||||
}
|
||||
if ((htext == start) || !n) {
|
||||
FAIL (SCPE_ARG, Invalid topic heading, htext);
|
||||
}
|
||||
if (n <= topic->level) { /* Find level for new topic */
|
||||
while (n <= topic->level) {
|
||||
while (n <= topic->level)
|
||||
topic = topic->parent;
|
||||
}
|
||||
} else {
|
||||
else {
|
||||
if (n > topic->level +1) { /* Skipping down more than 1 */
|
||||
FAIL (SCPE_ARG, Level not contiguous, htext); /* E.g. 1 3, not reasonable */
|
||||
}
|
||||
}
|
||||
while (*htext && (*htext != '\n') && isspace (*htext)) {
|
||||
while (*htext && (*htext != '\n') && isspace (*htext))
|
||||
htext++;
|
||||
}
|
||||
if (!*htext || (*htext == '\n')) { /* Name missing */
|
||||
FAIL (SCPE_ARG, Missing topic name, htext);
|
||||
}
|
||||
start = htext;
|
||||
while (*htext && (*htext != '\n')) {
|
||||
while (*htext && (*htext != '\n'))
|
||||
htext++;
|
||||
}
|
||||
if (start == htext) { /* Name NULL */
|
||||
FAIL (SCPE_ARG, Null topic name, htext);
|
||||
}
|
||||
|
@ -8156,14 +8150,12 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
if (*start == '?') { /* Conditional topic? */
|
||||
size_t n = 0;
|
||||
start++;
|
||||
while (isdigit (*start)) { /* Get param # */
|
||||
while (isdigit (*start)) /* Get param # */
|
||||
n += (n * 10) + (*start++ - '0');
|
||||
}
|
||||
if (!*start || *start == '\n'|| n == 0 || n >= VSMAX)
|
||||
FAIL (SCPE_ARG, Invalid parameter number, start);
|
||||
while (n > vsnum) { /* Get arg pointer if not cached */
|
||||
while (n > vsnum) /* Get arg pointer if not cached */
|
||||
vstrings[vsnum++] = va_arg (ap, char *);
|
||||
}
|
||||
end = vstrings[n-1]; /* Check for True */
|
||||
if (!end || !(toupper (*end) == 'T' || *end == '1')) {
|
||||
excluded = TRUE; /* False, skip topic this time */
|
||||
|
@ -8186,9 +8178,8 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
if (*htext)
|
||||
htext++;
|
||||
|
||||
if (newt->title[0] == '$') {
|
||||
if (newt->title[0] == '$')
|
||||
newt->flags |= HLP_MAGIC_TOPIC;
|
||||
}
|
||||
|
||||
children = (TOPIC **) realloc (topic->children,
|
||||
(topic->kids +1) * sizeof (TOPIC *));
|
||||
|
@ -8202,9 +8193,8 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
newt->level = n;
|
||||
newt->parent = topic;
|
||||
n = strlen (newt->title);
|
||||
if (n > topic->kidwid) {
|
||||
if (n > topic->kidwid)
|
||||
topic->kidwid = n;
|
||||
}
|
||||
sprintf (nbuf, ".%u", topic->kids);
|
||||
n = strlen (topic->label) + strlen (nbuf) + 1;
|
||||
newt->label = (char *) malloc (n);
|
||||
|
@ -8235,7 +8225,8 @@ static TOPIC *buildHelp (TOPIC *topic, struct sim_device *dptr,
|
|||
/* Create prompt string - top thru current topic
|
||||
* Add prompt at end.
|
||||
*/
|
||||
static char *helpPrompt ( TOPIC *topic, const char *pstring, t_bool oneword ) {
|
||||
static char *helpPrompt ( TOPIC *topic, const char *pstring, t_bool oneword )
|
||||
{
|
||||
char *prefix;
|
||||
char *newp, *newt;
|
||||
|
||||
|
@ -8245,9 +8236,9 @@ static char *helpPrompt ( TOPIC *topic, const char *pstring, t_bool oneword ) {
|
|||
FAIL (SCPE_MEM, No memory, NULL);
|
||||
}
|
||||
prefix[0] = '\n';
|
||||
} else {
|
||||
prefix = helpPrompt (topic->parent, "", oneword);
|
||||
}
|
||||
else
|
||||
prefix = helpPrompt (topic->parent, "", oneword);
|
||||
|
||||
newp = (char *) malloc (strlen (prefix) + 1 + strlen (topic->title) + 1 +
|
||||
strlen (pstring) +1);
|
||||
|
@ -8256,6 +8247,7 @@ static char *helpPrompt ( TOPIC *topic, const char *pstring, t_bool oneword ) {
|
|||
FAIL (SCPE_MEM, No memory, NULL);
|
||||
}
|
||||
strcpy (newp, prefix);
|
||||
if (topic->children) {
|
||||
if (topic->level != 0)
|
||||
strcat (newp, " ");
|
||||
newt = (topic->flags & HLP_MAGIC_TOPIC)?
|
||||
|
@ -8267,22 +8259,25 @@ static char *helpPrompt ( TOPIC *topic, const char *pstring, t_bool oneword ) {
|
|||
newt++;
|
||||
}
|
||||
*np = '\0';
|
||||
} else {
|
||||
strcat (newp, newt);
|
||||
}
|
||||
else
|
||||
strcat (newp, newt);
|
||||
if (*pstring && *pstring != '?')
|
||||
strcat (newp, " ");
|
||||
}
|
||||
strcat (newp, pstring);
|
||||
free (prefix);
|
||||
return newp;
|
||||
}
|
||||
|
||||
static void displayMagicTopic (FILE *st, struct sim_device *dptr, TOPIC *topic) {
|
||||
static void displayMagicTopic (FILE *st, struct sim_device *dptr, TOPIC *topic)
|
||||
{
|
||||
char tbuf[CBUFSIZE];
|
||||
size_t i, skiplines;
|
||||
#ifdef _WIN32
|
||||
FILE *tmp;
|
||||
char *tmpnam;
|
||||
|
||||
do {
|
||||
int fd;
|
||||
tmpnam = _tempnam (NULL, "simh");
|
||||
|
@ -8308,10 +8303,14 @@ static void displayMagicTopic (FILE *st, struct sim_device *dptr, TOPIC *topic)
|
|||
if (!strcmp (topic->title+1, "Registers")) {
|
||||
fprint_reg_help (tmp, dptr) ;
|
||||
skiplines = 1;
|
||||
} else if (!strcmp (topic->title+1, "Set commands")) {
|
||||
}
|
||||
else
|
||||
if (!strcmp (topic->title+1, "Set commands")) {
|
||||
fprint_set_help (tmp, dptr);
|
||||
skiplines = 3;
|
||||
} else if (!strcmp (topic->title+1, "Show commands")) {
|
||||
}
|
||||
else
|
||||
if (!strcmp (topic->title+1, "Show commands")) {
|
||||
fprint_show_help (tmp, dptr);
|
||||
skiplines = 3;
|
||||
}
|
||||
|
@ -8319,14 +8318,12 @@ static void displayMagicTopic (FILE *st, struct sim_device *dptr, TOPIC *topic)
|
|||
|
||||
/* Discard leading blank lines/redundant titles */
|
||||
|
||||
for (i =0; i < skiplines; i++) {
|
||||
for (i =0; i < skiplines; i++)
|
||||
fgets (tbuf, sizeof (tbuf), tmp);
|
||||
}
|
||||
|
||||
while (fgets (tbuf, sizeof (tbuf), tmp)) {
|
||||
if (tbuf[0] != '\n') {
|
||||
if (tbuf[0] != '\n')
|
||||
fputs (" ", st);
|
||||
}
|
||||
fputs (tbuf, st);
|
||||
}
|
||||
fclose (tmp);
|
||||
|
@ -8341,15 +8338,16 @@ static void displayMagicTopic (FILE *st, struct sim_device *dptr, TOPIC *topic)
|
|||
|
||||
static t_stat displayFlatHelp (FILE *st, struct sim_device *dptr,
|
||||
struct sim_unit *uptr, int32 flag,
|
||||
TOPIC *topic, va_list ap ) {
|
||||
TOPIC *topic, va_list ap )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (topic->flags & HLP_MAGIC_TOPIC) {
|
||||
fprintf (st, "\n%s ", topic->label);
|
||||
displayMagicTopic (st, dptr, topic);
|
||||
} else {
|
||||
fprintf (st, "\n%s %s\n", topic->label, topic->title);
|
||||
}
|
||||
else
|
||||
fprintf (st, "\n%s %s\n", topic->label, topic->title);
|
||||
|
||||
/* Topic text (for magic topics, follows for explanations)
|
||||
* It's possible/reasonable for a magic topic to have no text.
|
||||
|
@ -8358,9 +8356,8 @@ static t_stat displayFlatHelp (FILE *st, struct sim_device *dptr,
|
|||
if (topic->text)
|
||||
fputs (topic->text, st);
|
||||
|
||||
for (i = 0; i < topic->kids; i++) {
|
||||
for (i = 0; i < topic->kids; i++)
|
||||
displayFlatHelp (st, dptr, uptr, flag, topic->children[i], ap);
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -8368,13 +8365,14 @@ static t_stat displayFlatHelp (FILE *st, struct sim_device *dptr,
|
|||
#define HLP_MATCH_AMBIGUOUS (~0u)
|
||||
#define HLP_MATCH_WILDCARD (~1U)
|
||||
#define HLP_MATCH_NONE 0
|
||||
static int matchHelpTopicName (TOPIC *topic, const char *token) {
|
||||
static int matchHelpTopicName (TOPIC *topic, const char *token)
|
||||
{
|
||||
size_t i, match;
|
||||
char cbuf[CBUFSIZE], *cptr;
|
||||
|
||||
if (!strcmp (token, "*")) {
|
||||
if (!strcmp (token, "*"))
|
||||
return HLP_MATCH_WILDCARD;
|
||||
}
|
||||
|
||||
match = 0;
|
||||
for (i = 0; i < topic->kids; i++) {
|
||||
strcpy (cbuf,topic->children[i]->title +
|
||||
|
@ -8383,15 +8381,15 @@ static int matchHelpTopicName (TOPIC *topic, const char *token) {
|
|||
while (*cptr) {
|
||||
if (blankch (*cptr)) {
|
||||
*cptr++ = '_';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*cptr = toupper (*cptr);
|
||||
cptr++;
|
||||
}
|
||||
}
|
||||
if (!strncmp (cbuf, token, strlen (token))) {
|
||||
if (match) {
|
||||
if (match)
|
||||
return HLP_MATCH_AMBIGUOUS;
|
||||
}
|
||||
match = i+1;
|
||||
}
|
||||
}
|
||||
|
@ -8404,7 +8402,8 @@ static int matchHelpTopicName (TOPIC *topic, const char *token) {
|
|||
|
||||
t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
||||
struct sim_unit *uptr, int32 flag,
|
||||
const char *help, const char *cptr, va_list ap) {
|
||||
const char *help, const char *cptr, va_list ap)
|
||||
{
|
||||
|
||||
TOPIC top = { 0, NULL, NULL, &top, NULL, 0, NULL, 0, 0};
|
||||
TOPIC *topic = ⊤
|
||||
|
@ -8419,6 +8418,7 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
static const char brief_help[] = { "%s help. Type <CR> to exit, HELP for navigation help" };
|
||||
static const char onecmd_help[] = { "%s help." };
|
||||
static const char help_help[] = {
|
||||
|
||||
/****|***********************80 column width guide********************************/
|
||||
" This help command provides hierarchical help. To see more information,\n"
|
||||
" type an offered subtopic name. To move back a level, just type <CR>.\n"
|
||||
|
@ -8448,17 +8448,15 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
if (dptr) {
|
||||
p = dptr->name;
|
||||
flat_help = (dptr->flags & DEV_FLATHELP) != 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
p = sim_name;
|
||||
}
|
||||
top.title = (char *) malloc (strlen (p) + ((flag & SCP_HELP_ATTACH)? sizeof (attach_help)-1: 0) +1);
|
||||
for (i = 0; p[i]; i++ ) {
|
||||
for (i = 0; p[i]; i++ )
|
||||
top.title[i] = toupper (p[i]);
|
||||
}
|
||||
top.title[i] = '\0';
|
||||
if (flag & SCP_HELP_ATTACH) {
|
||||
if (flag & SCP_HELP_ATTACH)
|
||||
strcpy (top.title+i, attach_help);
|
||||
}
|
||||
|
||||
top.label = (char *) malloc (sizeof ("1"));
|
||||
strcpy (top.label, "1");
|
||||
|
@ -8467,14 +8465,13 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
|
||||
if (flat_help) {
|
||||
flag |= SCP_HELP_FLAT;
|
||||
if (sim_ttisatty()) {
|
||||
if (sim_ttisatty())
|
||||
fprintf (st, "%s help.\nThis help is also available in hierarchical form.\n", top.title);
|
||||
} else {
|
||||
else
|
||||
fprintf (st, "%s help.\n", top.title);
|
||||
}
|
||||
} else {
|
||||
else
|
||||
fprintf (st, ((flag & SCP_HELP_ONECMD)? onecmd_help: brief_help), top.title);
|
||||
}
|
||||
|
||||
/* Add text and subtopics */
|
||||
|
||||
|
@ -8484,9 +8481,8 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
|
||||
while (cptr && *cptr) {
|
||||
cptr = get_glyph (cptr, gbuf, 0);
|
||||
if (!gbuf[0]) {
|
||||
if (!gbuf[0])
|
||||
break;
|
||||
}
|
||||
if (!strcmp (gbuf, "HELP")) { /* HELP (about help) */
|
||||
fprintf (st, "\n");
|
||||
fputs (help_help, st);
|
||||
|
@ -8527,9 +8523,9 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
if (topic->flags & HLP_MAGIC_TOPIC) {
|
||||
fputc ('\n', st);
|
||||
displayMagicTopic (st, dptr, topic);
|
||||
} else {
|
||||
fprintf (st, "\n%s\n", topic->title);
|
||||
}
|
||||
else
|
||||
fprintf (st, "\n%s\n", topic->title);
|
||||
|
||||
/* Topic text (for magic topics, follows for explanations)
|
||||
* It's possible/reasonable for a magic topic to have no text.
|
||||
|
@ -8592,16 +8588,14 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
topic = topic->parent;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (gbuf, "?")) { /* ?, repaint current topic */
|
||||
if (!strcmp (gbuf, "?")) /* ?, repaint current topic */
|
||||
continue;
|
||||
}
|
||||
if (!strcmp (gbuf, "HELP")) { /* HELP (about help) */
|
||||
fputs (help_help, st);
|
||||
goto reprompt;
|
||||
}
|
||||
if (!strcmp (gbuf, "EXIT") || !strcmp (gbuf, "QUIT")) { /* EXIT (help) */
|
||||
if (!strcmp (gbuf, "EXIT") || !strcmp (gbuf, "QUIT")) /* EXIT (help) */
|
||||
break;
|
||||
}
|
||||
|
||||
/* String - look for that topic */
|
||||
|
||||
|
@ -8639,7 +8633,8 @@ t_stat scp_vhelp (FILE *st, struct sim_device *dptr,
|
|||
|
||||
t_stat scp_help (FILE *st, struct sim_device *dptr,
|
||||
struct sim_unit *uptr, int32 flag,
|
||||
const char *help, const char *cptr, ...) {
|
||||
const char *help, const char *cptr, ...)
|
||||
{
|
||||
t_stat r;
|
||||
va_list ap;
|
||||
|
||||
|
@ -8661,7 +8656,8 @@ t_stat scp_help (FILE *st, struct sim_device *dptr,
|
|||
t_stat scp_vhelpFromFile (FILE *st, struct sim_device *dptr,
|
||||
struct sim_unit *uptr, int32 flag,
|
||||
const char *helpfile,
|
||||
const char *cptr, va_list ap) {
|
||||
const char *cptr, va_list ap)
|
||||
{
|
||||
FILE *fp;
|
||||
char *help, *p;
|
||||
t_offset size, n;
|
||||
|
@ -8682,18 +8678,19 @@ t_stat scp_vhelpFromFile (FILE *st, struct sim_device *dptr,
|
|||
* of the executable. Failing that, we're out of luck.
|
||||
*/
|
||||
strncpy (fbuf, sim_argv[0], sizeof (fbuf));
|
||||
if ((p = match_ext (fbuf, "EXE"))) {
|
||||
if ((p = match_ext (fbuf, "EXE")))
|
||||
*p = '\0';
|
||||
}
|
||||
if ((p = strrchr (fbuf, '\\'))) {
|
||||
p[1] = '\0';
|
||||
d = "%s\\";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ((p = strrchr (fbuf, '/'))) {
|
||||
p[1] = '\0';
|
||||
d = "%s/";
|
||||
#ifdef VMS
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ((p = strrchr (fbuf, ']'))) {
|
||||
p[1] = '\0';
|
||||
d = "[%s]";
|
||||
|
@ -8755,7 +8752,8 @@ t_stat scp_vhelpFromFile (FILE *st, struct sim_device *dptr,
|
|||
|
||||
t_stat scp_helpFromFile (FILE *st, struct sim_device *dptr,
|
||||
struct sim_unit *uptr, int32 flag,
|
||||
const char *helpfile, const char *cptr, ...) {
|
||||
const char *helpfile, const char *cptr, ...)
|
||||
{
|
||||
t_stat r;
|
||||
va_list ap;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue