JiscMail Logo
Email discussion lists for the UK Education and Research communities

Help for STARDEV Archives


STARDEV Archives

STARDEV Archives


STARDEV@JISCMAIL.AC.UK


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

STARDEV Home

STARDEV Home

STARDEV  June 2008

STARDEV June 2008

Options

Subscribe or Unsubscribe

Subscribe or Unsubscribe

Log In

Log In

Get Password

Get Password

Subject:

Re: KAPHELP crash

From:

Patrick Wallace <[log in to unmask]>

Reply-To:

Starlink development <[log in to unmask]>

Date:

Wed, 11 Jun 2008 18:59:40 +0100

Content-Type:

MULTIPART/MIXED

Parts/Attachments:

Parts/Attachments

TEXT/PLAIN (23 lines) , help.c (1 lines)

> >>  Tracked this down to the "cue" variable definition on line 190 of
> >>  help.c and the actual overrun to:
> >>
> >>    strcpy ( cue, ( levcur < 1 ) ? "Topic? " : "Subtopic? " );
> >>
> >>  cue was defined with size 9 and needs 11 chars. Fixed that.
> >>
> >
> > Pat may want to know about that one.

Cripes!  What an abject bug.  It took its time surfacing.

FWIW the latest help.c is attached, with that bug corrected.


Patrick Wallace
____________________________________________________________________________
Space Science & Technology Department                    +44-1235-445372 tel
STFC / Rutherford Appleton Laboratory                    +44-1235-446362 fax
Harwell Science and Innovation Campus                      [log in to unmask]
Didcot, Oxfordshire, OX11 0QX, United Kingdom           [log in to unmask]
____________________________________________________________________________


#include <string.h> #include "help.h" #include "hlpsys.h" int hlpRepsub ( int ( * ) ( int, char*, int, char* ), int ( * ) ( char* ), int, int, char*, char*, char*, char* ); int hlpHelp ( int ( * outsub ) ( char* ), int lout, char *ipline, char *lib, int jflags, int ( * insub ) ( char*, char*, int* ), int ( * nametr ) ( int, char*, int, char* ) ) /* ** - - - - - - - - ** h l p H e l p ** - - - - - - - - ** ** Perform a HELP enquiry and, optionally, carry out an interactive ** HELP session. ** ** Given: ** *outsub func user-supplied output subroutine (note 2) ** lout int maximum record length accepted by outsub ** *ipline char string specifying required HELP text (note 3) ** *lib char name of HELP library (note 4) ** jflags int flags (note 5) ** *insub func user-supplied interactive input routine (note 6) ** *nametr func user-supplied name translation routine (note 7) ** ** Returned (function value): ** int status: +1 = OK ** hlp_ILLEGAL_LEVEL = illegal current level ** hlp_LINE_OUTPUT_BAD = outsub reported error ** hlp_LINE_INPUT_BAD = insub reported error ** hlp_STRING_OVERFLOW = string overflowed ** hlp_TRANSLATE_ERROR = other errors ** ** The error codes are defined in the header file hlpsys.h. ** ** Notes: ** ** 1) This routine is similar, though not identical, in its arguments ** and function to the Digital Equipment Corporation VAX/VMS ** LBR$OUTPUT_HELP routine. ** ** 2) The user-supplied outsub routine is an int function which ** accepts one argument, the string to be output, and returns a ** status of +1 if OK. outsub is responsible for knowing where to ** write the information, how to handle pagination, and so on. ** ** 3) The ipline string contains the series of HELP keywords, ** separated by spaces. It may contain leading as well as ** embedded and trailing spaces. The applications help command ** itself (for example "help"), is not included in this string, ** nor any command qualifiers. A maximum of LEVMAX (defined below) ** keywords is accepted; any more are ignored. Keywords longer ** than LKWMAX (defined below) are truncated. ** ** 4) The library specified by lib is in a special format, produced by ** the crehlp program. The hlp routines are not compatible with ** VMS .HLB files, though the source form of the library is very ** similar. The name is subject to environment-dependent ** translation at open time via the user-supplied nametr routine. ** ** 5) At present, jflags consists of one flag only, though more options ** may be added in the future. An odd jflags value, the usual case, ** means that once the topic specified in the ipline string has been ** reported, an interactive session ensues, with prompted input and ** the opportunity to explore the help tree. If jflags is even the ** output is unaffected, but control is passed back to the caller ** immediately the topic specified in the ipline string has been ** reported, without any ensuing interactive phase. ** ** 6) The user-supplied interactive input routine insub is an int ** function which has arguments string, prompt, *l, where string ** receives the line input, prompt is the string to output prior to ** reading the line, and l the number of characters input. If the ** call is successful, a function value of +1 is returned. (Note ** that insub is never called if jflags is even.) ** ** 7) The user-supplied name translation routine nametr is an int ** function. It has arguments command, string1, lstring2 and ** string2, and returns a status value. command (given) is an ** int which the HELP system always sets to zero; the application ** may use other values of command, for example to perform ** initializations or enquiries. string1 (given) is, for command=0, ** the HELP library name to be translated; this name can be the ** value of the lib argument to the present routine (identifying the ** root library) or the name following the '@' symbol in a HELP ** source file (identifying another library grafted onto the current ** library). string2 (returned, length lstring2) is, for command=0, ** the translation of string1 into a filename for use in fopen ** statements. The status returned as the function value is zero to ** show success and various -ve values to report failure. The status ** values may be translated into text by means of the hlpErrmes ** routine. ** ** Called: hlpHinit, hlpHopenr, hlpHtellx, hlpHreadx, hlpHchkl, ** hlpHseekx, hlpSplit, hlpHleap, hlpLength, hlpUpcase, ** hlpComstr, hlpLinout, hlpHreadd, hlpRepsub, hlpHclose, ** hlpCopyn ** ** Last revision: 11 June 2008 ** ** Copyright P.T.Wallace. All rights reserved. */ #define TRUE 1 #define FALSE 0 /* Wildcard and ellipsis codes. */ #define WILDN "*" #define ELLIPS "..." /* Maximum length of a keyword. */ #define LKWMAX 64 /* Length of HELP text output buffer. */ #define LOBUF 132 /* Length of HELP library file input buffer. */ #define LHBUF 132 /* Length of command-line input buffer. */ #define LIBUF 132 /* Maximum level number. */ #define LEVMAX 9 /* Maximum length of filenames. */ #define LFILE 100 { /* Certain larger arrays are declared static to avoid stack */ /* overflow on some small systems. The static specifier can */ /* be removed for systems where stack overflow is not a problem. */ /* HELP text output buffer. */ char outbuf [ LOBUF ]; /* HELP library file input buffer. */ char hlpbuf [ LHBUF ]; /* Command-line input buffer. */ char inbuf [ LIBUF ]; /* Level numbers: the top of the hierarchy is level zero; deeper */ /* levels are 1 to LEVMAX inclusive. levcur is the current level */ /* in the tree-walk. level is temporary storage for a level number. */ int levcur, level; /* The tree-walk context: HELP library names, index address, logical */ /* level number, keyword for the latest match at each level, and a flag */ /* which shows if a perfect match has yet been found at this level (in */ /* which case any further matches are ignored). Apart from the keyword */ /* and exact-match entries, each entry is double, because the given point */ /* in the HELP tree may be where a subsidiary HELP library has been */ /* grafted on, thereby requiring two sets of information. The first */ /* value refers to the host and the second to the graft; in the most */ /* common case, where no graft exists, both sets of information are the */ /* same. Note that although the possibility exists that the keyword may */ /* differ across a graft this does not yield useful results and should */ /* be avoided when preparing the source files. */ static char hlname [ LEVMAX + 1 ] [ 2 ] [ LFILE ]; long levpos [ LEVMAX + 1 ] [ 2 ]; int loglev [ LEVMAX + 1 ] [ 2 ]; static char levels [ LEVMAX + 1 ] [ LKWMAX + 1 ]; int exact [ LEVMAX + 1 ]; /* Scratch entries for temporary storage of context. */ static char fname [ LFILE ]; long iadr; int logl; /* Number of entries completely satisfying the latest input. */ int nfound; /* Work strings for containing level names. */ static char name1 [ LKWMAX ], name2 [ LKWMAX ]; /* List of keywords supplied and how many (note space for '?' endmark) */ static char pars [ LEVMAX + 1 ] [ LKWMAX ]; int npars; /* Status: <0 = fatal error */ /* 0 = proceeding normally */ /* +1 = no more HELP at this level */ int jstat; int i, nc, ic, j, i1, i2, lipsis, ip, maxbuf, iactiv, output, wild, eos, found, subtop; char name [LKWMAX], cue[11]; /* ** Preliminaries ** ------------- */ /* Extract flags. */ iactiv = jflags & 1; /* Initialize the HELP system and open the top-level HELP library. */ hlpHinit( lib ); if ( ( jstat = hlpHopenr ( nametr ) ) ) return jstat; /* Initialize the context. */ /* Reset the "exact match" flags. */ for ( levcur = 0; levcur <= LEVMAX; exact[levcur++] = FALSE ); /* Level 0 topic has just been read: note the library name and the */ /* address. */ for ( i = 0; i <= 1; i++ ) hlpHtellx ( hlname[0][i], & levpos[0][i], & loglev[0][i] ); /* Read the index entry to get the top-level topic name and check that */ /* the level is zero. */ if ( ( jstat = hlpHreadx ( nametr, 'd', LHBUF, hlpbuf, &nc ) ) ) return jstat; hlpHchkl ( hlpbuf, &levcur, levels[0] ); /* Copy the command string, substituting '?' if null. */ strncpy ( inbuf, ( ( hlpLength ( ipline ) ) ? ipline : "?" ), LIBUF ); /* ** Main loop: respond to input until we run out of levels ** ------------------------------------------------------ */ while ( levcur >= 0 ) { /* Any response? */ if ( hlpLength ( inbuf ) ) { /* Yes: enable output. */ output = TRUE; } else { /* No: disable output and up a level. */ output= FALSE; levcur--; } /* Position the HELP file index at the last match at this level. */ hlpHseekx ( hlname[levcur][1], levpos[levcur][1], loglev[levcur][1] ); /* Skip the already-matched record. Leave the file pointing to */ /* the next entry down the branch. */ if ( ( jstat = hlpHreadx ( nametr, 'd', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; /* Split the input line into separate, uppercase parameters. */ /* Initialize the string and parameter pointers, and the */ /* parameter count. */ ic = 0; i = 0; npars = 0; /* Copy the parameters one by one. */ while ( i >= 0 && npars < LEVMAX ) { /* Find the start and end of the next parameter. */ hlpSplit ( inbuf, ic, &i, &j ); /* Was there a parameter? */ if ( i >= 0 ) { /* Yes: increment the count. */ npars++; /* Update the inbuf pointer. */ ic = j + 1; /* Copy the keyword and fold to uppercase. */ j = ( j < LIBUF ) ? j : LIBUF - 1 ; i1 = j - i + 1; i2 = LKWMAX - 1; hlpUpcase ( hlpCopyn ( pars[npars-1], inbuf + i, ( i1 < i2 ) ? i1 : i2 ) ); } /* Next parameter. */ } /* Endmark the list with a question mark. */ strcpy ( pars[npars], "?" ); /* Reset the wildcard/ellipsis flag. */ wild = FALSE; /* Point to the first parameter. */ npars = 0; /* Loop until we reach the end marker. */ while ( strcmp ( pars[npars], "?" ) ) { /* Pick up the current parameter. */ strncpy ( name, pars[npars], LKWMAX ); /* Wildcard? */ if ( ! strncmp ( name, WILDN, 3 ) ) { /* Yes: set the wildcard/ellipsis flag. */ wild = TRUE; /* Next parameter. */ npars++; } else { /* Not a wildcard: ellipsis? */ i = hlpLength ( name ); if ( i >= 3 && ! strncmp ( name + i - 3, ELLIPS, 3 ) ) { /* Yes: set the wildcard/ellipsis flag. */ wild = TRUE; /* Is the ellipsis tagged onto the previous parameter? */ if ( i > 3 ) { /* Yes: remove it and make it the next parameter. */ hlpCopyn ( pars[npars], name, i-3 ); npars++; strcpy ( pars[npars], ELLIPS ); } /* Make the next parameter the end marker. */ npars++; strcpy ( pars[npars], "?" ); } else { /* Neither a wildcard nor an ellipsis: next parameter. */ npars++; } } } /* Initialize the ellipsis flag (the level at which the ellipsis */ /* was first detected). */ lipsis = -1; /* Reset the count of topics output as a result of the latest input. */ nfound = 0; /* Initialize the pointer to the list of nominated topics. */ ip = 0; /* Loop until the whole subtree from the existing unique match at */ /* the level one above the current starting level has been searched. */ while ( ip >= 0 ) { /* Pick up the name of the topic (uppercase) and check for */ /* ellipsis. */ if ( ! strcmp ( strcpy ( name, pars[ip] ), ELLIPS ) ) { /* Yes: has it already been seen? */ if ( lipsis < 0 ) { /* No: note the current level, and interpret the ellipsis */ /* on this first occasion as if it were the question mark */ /* which follows it. */ lipsis = levcur; ip++; strcpy ( name, "?" ); } else { /* We are already handling the ellipsis: interpret it as a */ /* wildcard. */ strcpy ( name, WILDN ); } /* Not an ellipsis: if it isn't the question mark, switch off */ /* any ellipsis handling. */ } else if ( strcmp ( name, "?" ) ) { lipsis = -1; } /* Question mark? */ if ( strcmp ( name, "?" ) ) { /* No: search for the requested topic at the next level down. */ /* Down a level. */ ip++; if ( levcur >= LEVMAX ) return hlp_ILLEGAL_LEVEL; levcur++; /* Reset the "perfect match" flag. */ exact[levcur] = FALSE; /* Initialize the "end of subtree" and "subtopic found" flags. */ eos = FALSE; found = FALSE; while ( ! found && ! eos ) { /* Satisfy any pending switch to another HELP library. */ if ( ( jstat = hlpHleap ( nametr, LHBUF, hlpbuf, hlname[levcur][1], & levpos[levcur][1], & loglev[levcur][1] ) ) ) return jstat; /* Save the context. */ hlpHtellx ( fname, &iadr, &logl ); /* Read the next HELP library index entry, leaving the file */ /* positioned at the next entry for the current level. */ if ( ( jstat = hlpHreadx ( nametr, 'a', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; eos = jstat; /* Unless we have reached end-of-subtree, get the level and */ /* name for the latest index entry. */ if ( ! eos ) { hlpHchkl ( hlpbuf, &level, name1 ); /* Examine the level just encountered. */ if ( level < levcur ) { /* Higher level: stop looking. */ eos = TRUE; } else if ( level == levcur ) { /* Check if the name of the level matches the */ /* requested name, ignoring any further matches */ /* once a perfect match has been detected. */ hlpUpcase ( strcpy ( name2, name1 ) ); if ( ( ! exact[levcur] ) && hlpComstr ( name2, name ) ) { /* Match: if perfect, set the flag. */ if ( ! strcmp ( name2, name ) ) exact[levcur] = TRUE; /* Store the context for this level. */ for ( i = 0; i <= 1; i++ ) { strcpy ( hlname[levcur][i], fname ); levpos[levcur][i] = iadr; loglev[levcur][i] = logl; } strcpy ( levels[levcur], name1 ); /* Set flag to show we found the topic. */ found = TRUE; } } } } /* If the topic has not been found, up two levels, */ /* resetting the most recent "exact match" flag. */ if ( ! found ) { exact[levcur] = FALSE; ip -= 2; levcur -= 2; /* Unless about to terminate, reposition the file. */ if ( levcur >= 0 ) hlpHseekx ( hlname[levcur+1][0], levpos[levcur+1][0], loglev[levcur+1][0] ); /* Skip the already-matched record, leaving the file */ /* positioned at the next entry at the current level. */ if ( ( jstat = hlpHreadx ( nametr, 'a', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; /* If we are handling an ellipsis, and if we have not yet */ /* finished doing so, correct the parameter pointer so that */ /* the search continues. */ if ( lipsis >= 0 && levcur >= lipsis ) ip++; } else { /* We have found the topic, but the index is now positioned */ /* at the start of the next subtree. Reposition the index */ /* one entry down from the latest find, with the data */ /* pointer set to the keyword record for the latest find. */ hlpHseekx ( hlname[levcur][1], levpos[levcur][1], loglev[levcur][1] ); if ( ( jstat = hlpHreadx (nametr, 'd', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; /* Satisfy any pending switch to another HELP library. */ if ( ( jstat = hlpHleap ( nametr, LHBUF, hlpbuf, hlname[levcur][1], & levpos[levcur][1], & loglev[levcur][1] ) ) ) return jstat; } } else { /* We have a match to report. */ /* Increment the count of topics/subtopics output. */ nfound++; /* If output is enabled, display the topic. */ if ( output ) { /* Output the heading (n.b. level 0 only at the very start). */ for ( level = 0; level <= levcur; level++ ) { if ( level || ! levcur ) { if ( outsub ( "\0 " ) != 1 ) return hlp_LINE_OUTPUT_BAD; if ( hlpLinout ( outsub, lout, 2 *(level-1), strncpy ( outbuf, levels[level], LOBUF ) ) != 1 ) return hlp_LINE_OUTPUT_BAD; } } if ( outsub ( "\0 " ) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Display the current level's text and subtopics. */ /* The next record to be read from the data section of the */ /* HELP library is the keyword record for the current level: */ /* skip it. */ if ( ( jstat = hlpHreadd ( LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; /* Reset the "there were subtopics" flag. */ subtop = FALSE; /* Now read from the data section of the HELP library and */ /* output until we come across a new level (or end of text */ /* at this level). */ eos = FALSE; level = -1; while ( ! eos && level < 0 ) { /* Read the current line from the HELP library. */ if ( ( jstat = hlpHreadd ( LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; /* If not EOF, start of new level? */ if ( ! jstat ) { hlpHchkl ( hlpbuf, &level, name1 ); if ( level >= 0 ) { /* Yes: examine the level. */ if ( level <= levcur ) { /* Same or higher level: finished outputting */ /* text. */ eos = TRUE; } else { /* Deeper: set the "there are subtopics" flag. */ subtop = TRUE; } } else { /* Not a new level: output the line. */ if ( hlpLinout ( outsub, lout, 2 * ( ( levcur >= 1 ) ? levcur : 1 ), hlpbuf ) != 1 ) return hlp_LINE_OUTPUT_BAD; } } else { /* EOF: counts as end of text at this level. */ eos = TRUE; } /* Read the next record. */ } /* Unless wildcarding or handling an ellipsis, list any */ /* subtopics. */ strcpy ( name, pars[( ip > 1 ) ? ip - 1 : 0] ); if ( strcmp ( name, WILDN ) && strcmp ( name, ELLIPS ) && subtop) if ( ( jstat = hlpRepsub ( nametr, outsub, lout, levcur, fname, name1, outbuf, hlpbuf ) ) < 0 ) return jstat; /* If EOF, flag no more to be found. */ found = ( jstat == 0 ); /* Position the HELP library index at the last match at */ /* this level. */ hlpHseekx ( hlname[levcur][0], levpos[levcur][0], loglev[levcur][0] ); /* Ellipsis? */ if ( lipsis < 0 ) { /* No: skip the already-matched record, leaving the file */ /* pointing to the next entry for the current level. */ if ( ( jstat = hlpHreadx ( nametr, 'a', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; } else { /* Yes: skip the already-matched record, leaving the file */ /* pointing to the next entry down the branch. */ if ( ( jstat = hlpHreadx ( nametr, 'd', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; } } else { /* Output is disabled. This means that we are returning */ /* through successively higher levels, and so we know there */ /* are subtopics. */ subtop = TRUE; } /* Output a blank line. */ if ( outsub ( "\0" ) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Point to the previous parameter. */ ip--; /* Unless we are handling an ellipsis, up one level. */ if ( lipsis < 0 ) levcur--; } } /* The current level is now one above where it was when the last */ /* input line was supplied; down a level to where it was. */ levcur++; /* React to how many matches were found. */ if ( nfound < 1 ) { /* Nothing found: issue error report. */ /* Output the heading. */ for ( level = 1; level <= levcur; level++ ) { if ( outsub ( "\0" ) != 1 ) return hlp_LINE_OUTPUT_BAD; if ( hlpLinout ( outsub, lout, 2 * ( level - 1 ), strncpy ( outbuf, levels[level], LOBUF ) ) != 1 ) return hlp_LINE_OUTPUT_BAD; } if ( outsub ( "\0" ) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Load the output record with the level names. */ maxbuf = LOBUF - hlpLength ( name ) - 1; strcpy ( outbuf, "Sorry, no documentation on" ); ic = hlpLength ( outbuf ) + 2; outbuf[ic-2] = (char) ' '; /* First batch of level names from the HELP library. */ i = 1; while ( i <= levcur && ic <= maxbuf ) { /* Is there room for the level name? */ if ( ( ic + hlpLength ( levels[i] ) ) <= maxbuf ) { /* There is: load it and convert it to uppercase. */ outbuf[ic-2] = (char) ' '; hlpUpcase ( hlpCopyn ( outbuf + ic - 1, levels[i], LOBUF - ic - 1 ) ); /* Advance the pointer. */ ic = hlpLength ( outbuf ) + 2; } /* Do the next level. */ i++; } /* Second batch of level names as supplied in input line. */ i = 1; while ( i <= npars && ic <= maxbuf ) { /* Is there room for the level name? */ if ( ( ic + hlpLength ( pars[i-1] ) ) <= maxbuf ) { /* There is: load it and convert it to uppercase. */ outbuf[ic-2] = (char) ' '; hlpUpcase ( hlpCopyn ( outbuf + ic - 1, pars[i-1], LOBUF - ic - 1 ) ); /* Advance the pointer. */ ic = hlpLength ( outbuf ) + 2; } /* Do the next level. */ i++; } /* Output the warning. */ if ( hlpLinout ( outsub, lout, 2 * ( ( levcur > 1 ) ? levcur : 1 ), outbuf) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Position the HELP file index at the first subtopic. */ hlpHseekx ( hlname[levcur][1], levpos[levcur][1], loglev[levcur][1] ); if ( ( jstat = hlpHreadx ( nametr, 'd', LHBUF, hlpbuf, &nc ) ) ) return jstat; /* List subtopics at the prompt level. */ if ( ( jstat = hlpRepsub ( nametr, outsub, lout, levcur, fname, name1, outbuf, hlpbuf ) ) < 0 ) return jstat; if ( outsub ( "\0" ) != 1) return hlp_LINE_OUTPUT_BAD; /* Single match (except as the result of wildcard)? */ } else if ( nfound == 1 && ! wild ) { /* Yes: adjust the current level to that of the match. */ levcur += npars; /* Up a level if no subtopics found. */ if ( ! subtop ) levcur--; } /* Interactive prompting in effect? */ if ( iactiv ) { /* Yes: get next input. */ /* Load the output buffer with the level names. */ i = 1; ic = 0; while ( i <= levcur && ic < LOBUF ) { /* Is there room for the level name? */ if ( ( ic + hlpLength ( levels[i] ) ) < LOBUF ) { /* There is: load it. */ if ( ic > 0 ) outbuf[ic-1] = (char) ' '; hlpCopyn ( outbuf + ic, levels[i], LOBUF - ic - 1 ); } else { /* There isn't: overflow to stop the loop. */ i = LOBUF; } /* Place for next level name. */ ic = hlpLength ( outbuf ) + 1; /* Do the next level. */ i++; } /* Complete the prompt string. */ strcpy ( cue, ( levcur < 1 ) ? "Topic? " : "Subtopic? " ); i = (int) strlen ( cue ); if ( ic + i >= LOBUF ) ic = 0; hlpCopyn ( outbuf + ic, cue, i ); /* Eliminate any included nulls. */ for ( i += ic - 1; i >= 0; i-- ) { if ( ! outbuf[i] ) outbuf[i] = (char) ' '; } /* Ask for the next topic. */ if ( insub ( inbuf, outbuf, &nc ) != 1) return hlp_LINE_INPUT_BAD; /* If we are about to search from the top, terminate instead. */ if ( levcur <= 0 && ! hlpLength ( inbuf ) ) levcur = -1; } else { /* Interactive prompting not in effect: trigger termination. */ levcur = -1; } /* Handle the latest input line if any. */ } /* OK return. */ return 1; } int hlpRepsub ( int ( * nametr ) ( int, char*, int, char* ), int ( * outsub ) ( char* ), int lout, int levcur, char *fname, char *name, char *outbuf, char *hlpbuf ) /* ** - - - - - - - - - - ** h l p R e p s u b ** - - - - - - - - - - ** ** Report subtopic names. ** ** Given: ** *nametr func user-supplied name translation routine ** *outsub func user-supplied output routine ** lout int maximum record length accepted by outsub ** levcur int current level number ** ** Workspace: ** *fname char filename ** *name char keyword ** *outbuf char output buffer ** *hlpbuf char input buffer ** ** Returned (function value): ** int status: 0 = OK ** hlp_LINE_OUTPUT_BAD = outsub error ** else = HELP file I/O status ** ** Notes: ** ** 1) See the hlpHelp source for information on the nametr and ** outsub functions. ** ** 2) Prior to calling the present routine, the HELP file index must be ** positioned so that the index entry for the first subtopic will be ** input next. On leaving the routine, the HELP file index is ** positioned so that the next record to be input is the first index ** entry that is not part of the current subtree. ** ** Last revision: 14 January 2008 ** ** Copyright P.T.Wallace. All rights reserved. */ /* Increment between topic names on the output line. */ #define IPITCH 11 { int jstat, indent, maxind, nc, level, levsub, ic, logl; long iadr; /* Output a heading for the subtopics. */ if ( outsub ( "\0" ) != 1 ) return hlp_LINE_OUTPUT_BAD; indent = 2 * ( ( levcur > 1 ) ? levcur : 1 ); maxind = ( ( lout < LOBUF ) ? lout : LOBUF ) - indent; if ( hlpLinout ( outsub, lout, indent, strcpy(outbuf, "Additional information available:") ) != 1 ) return hlp_LINE_OUTPUT_BAD; if ( outsub ( "" ) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Read the first subtopic name from the index and get its name. Set */ /* the file pointer so that the next item to be read will be the next */ /* index entry at the current level. */ if ( ( jstat = hlpHreadx ( nametr, 'a', LHBUF, hlpbuf, &nc ) ) ) return jstat; hlpHchkl ( hlpbuf, & level, name ); /* Continue reading the HELP library index entries for the current level */ /* and for the current subtree until we are returned to a higher level */ /* or reach end-of-index. */ levsub = levcur + 1; level = levsub; for ( ic = 0; ic < LOBUF - 1; outbuf[ic++] = (char) ' ' ); outbuf[LOBUF-1] = (char) '\0'; ic = 0; while ( jstat == 0 && level >= levsub ) { /* Is the current subtopic at the right level? */ if ( level == levsub ) { /* Yes: load the output buffer with the current subtopic's name. */ /* First check if there will be room for it. */ if ( ic + hlpLength ( name ) > maxind ) { /* There is not: display the current contents of the buffer. */ if ( hlpLinout ( outsub, lout, indent, hlpTrim ( outbuf ) ) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Reset the buffer to spaces. */ for ( ic = 0; ic < LOBUF - 1; outbuf[ic++] = (char) ' ' ); outbuf[LOBUF-1] = (char) '\0'; ic = 0; } /* Now load the current name into the buffer. */ strncpy ( outbuf + ic, name, hlpLength ( name ) ); /* Work out where the next name is to go. */ ic = hlpLength ( outbuf ) + 2; if ( ic % IPITCH ) ic = ( ic / IPITCH + 1 ) * IPITCH; } /* Read the next index record, leaving the file pointer set so that */ /* the next item to be read is at the current level or is the first */ /* item of the next subtree. */ hlpHtellx ( fname, &iadr, &logl ); if ( ( jstat = hlpHreadx ( nametr, 'a', LHBUF, hlpbuf, &nc ) ) < 0 ) return jstat; /* If not EOF get the keyword name and level. */ if ( ! jstat ) hlpHchkl ( hlpbuf, &level, name ); /* Load the new level's name (if any). */ } /* Output. */ if ( hlpLinout ( outsub, lout, indent, hlpTrim ( outbuf ) ) != 1 ) return hlp_LINE_OUTPUT_BAD; /* Reposition the file so that the next index record to be read is the */ /* first one that is nothing to do with the topic just reported. */ hlpHseekx ( fname, iadr, logl ); return 0; }

Top of Message | Previous Page | Permalink

JiscMail Tools


RSS Feeds and Sharing


Advanced Options


Archives

December 2023
January 2023
December 2022
July 2022
June 2022
April 2022
March 2022
December 2021
October 2021
July 2021
April 2021
January 2021
October 2020
September 2020
August 2020
May 2020
November 2019
October 2019
July 2019
June 2019
February 2019
January 2019
December 2018
November 2018
August 2018
July 2018
May 2018
April 2018
March 2018
February 2018
December 2017
October 2017
August 2017
July 2017
May 2017
April 2017
February 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
October 2015
September 2015
August 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
2004
April 2003
2003


JiscMail is a Jisc service.

View our service policies at https://www.jiscmail.ac.uk/policyandsecurity/ and Jisc's privacy policy at https://www.jisc.ac.uk/website/privacy-notice

For help and support help@jisc.ac.uk

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager