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:
Mark Pizzolato 2014-02-10 17:25:07 -08:00
parent b1fb809210
commit 545aa85677

166
scp.c
View file

@ -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 = &top;
@ -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;