From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  7-JUN-1989 13:53
To:	MRGATE::"ARISIA::EVERHART"
Subj:	MAINT -- Full Screen File/Directory Maintenance (Part 5 of 11)

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed,  7 JUN 89 07:01:21 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Wed, 7 Jun 89 06:57:12 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA18228; Wed, 7 Jun 89 06:43:00 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 7 Jun 89 12:46:46 GMT
From: peirce@gumby.wisc.edu  (Leonard J. Peirce)
Organization: Western Michigan University, Kalamazoo, MI
Subject: MAINT -- Full Screen File/Directory Maintenance (Part 5 of 11)
Message-Id: <740@gumby.cc.wmich.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

+-+-+-+ Beginning of part 5 +-+-+-+
X`009`009  keybd_id;`009`009/* keyboard id to read from`009      */
X`009 short`009  scr_width;`009`009/* width of screen`009`009      */
X
X`123`009/*** file_select ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister ULONG`009  status;`009`009/* return code status holder`009      */
Xregister char`009  *tptr,`009`009/* pointer to input buffer`009      */
X`009`009  *tptr2;`009`009/* pointer to output buffer`009      */
X`009 ULONG`009  status2,`009`009/* secondary return code status`009      */
X`009`009  status3;`009`009/* yet another return code holder     */
X`009 USHORT`009  term_code,`009`009/* keystroke code read in`009      */
X`009`009  finish_flag = 0,`009/* set when user wants to finish file */
X`009`009  key_flag;`009`009/* loop control flag`009`009      */
X`009 short`009  buf_cnt,`009`009/* number of chars in output buffer   */
X`009`009  temp;`009`009`009/* temporary value`009`009      */
Xstatic`009 long`009  row,`009`009`009/* current row in virtual display     */
X`009`009  end_col;`009`009/* ending column for ERASE_DISPLAY    */
Vstatic`009 UCHAR`009  pass;`009`009`009/* to make sure we initialize once`032
X   */
Xstatic`009 char`009  options[BUFSIZ],`009/* options line`009`009`009      */
X`009`009  out_buf[SCR_MAX+1];`009/* for formatting output`009      */
Vstatic`009 struct`009  FAB`009in_fab;`009`009/* input file FAB`009`009      *
X/
Vstatic`009 struct`009  RAB`009in_rab;`009`009/* input file RAB`009`009      *
X/
Vstatic $DESCRIPTOR(text_d,out_buf);`009/* output record buffer descriptor`032
X   */
Xstatic $DESCRIPTOR(opt_d,options);`009/* options descriptor`009`009      */
Vstatic $DESCRIPTOR(eof_d,"[eof]");`009/* end-of-file string descriptor      *
X/
X
X
X   if(!pass) `009`009`009`009/* first time we have been called?    */
X   `123
X      /* initialize the RMS blocks only once */
X
X      in_fab = cc$rms_fab;
X      in_rab = cc$rms_rab;
X
V      in_fab.fab$b_fac = FAB$M_GET;`009/* going to use SYS$GET() on it`009
X      */
X
X      in_rab.rab$l_fab = &in_fab;`009/* pointer to FAB`009`009      */
V      in_rab.rab$b_rac = RAB$C_SEQ;`009/* sequential access to the file  `032
X   */
V      in_rab.rab$w_usz = IN_REC_SIZE;`009/* input record buffer size`009 `032
X    */
X
X      end_col = (long) scr_width;`009/* set up for erasing the display     */
V      opt_d.dsc$w_length = scr_width;`009/* set width of options line`009`032
X     */
X      pass++;`009`009`009`009/* make sure we only do this once     */
X   `125
X
X   in_fab.fab$l_fna = filename;`009`009/* set filename & length`009      */
X   in_fab.fab$b_fns = (UCHAR) strlen(filename);
X   in_fab.fab$w_ifi = 0;`009`009/* reset just in case.......`009      */
X   in_rab.rab$l_ubf = buf;`009`009/* set where to read things into      */
X
X   /* try to open the input file */
X
X   status = SYS$OPEN(&in_fab);
X
X   if(status != RMS$_NORMAL)
X   `123
X      SYS$CLOSE(&in_fab);`009`009/* try to close it to be sure.....    */
X      return(CANT_OPEN);
X   `125
X
V   status = SYS$CONNECT(&in_rab);`009/* connect the FAB and the RAB`009  `032
X   */
X
X   if(status != RMS$_NORMAL)
X   `123
X      SYS$CLOSE(&in_fab);`009`009/* what happened....?`009`009      */
X      return(CANT_OPEN);
X   `125
X
X   /* get the first record and see if the file has anything in it; if it
X    * is empty, no sense in pasting the virtual display for doing the work
X    * and all that; just return that the file is empty
X    */
X
V   status = SYS$GET(&in_rab);`009`009/* read-ahead the first record`009  `032
X   */
X
X   if(status != RMS$_NORMAL)`009`009/* anything in the file?`009      */
X   `123
X      SYS$CLOSE(&in_fab);`009`009/* nope, close the file`009`009      */
X      return(CANT_DISPLAY);`009`009/* return that we can't look at it    */
X   `125
X
X   /* ok, we opened the file; now paste the virtual display over the main
X    * display so that we can write to it
X    */
X
X   status2 = SMG$PASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id,&WORK_BASE_ROW,
X`009`009`009`009       &WORK_BASE_COL,0);
X
X   if(status2 != SS$_NORMAL)
X      return(CANT_DISPLAY);
X
X   /* the virtual display has been pasted; create the options line to write
X    * at the bottom with the options and the filename by concatenating the
X    * the options line, the filename, and enough blank spaces to make sure
X    * that the previous filename is wiped clean
X    */
X
V   cat(options,"+(next) screen   Finish    File:  ",filename,"           `032
X   \
X                                                                            \
X       ");
X
X   options[scr_width] = '\0';`009`009/* terminate things where we want     */
X
X   status2 = SMG$PUT_CHARS(&disp_id,&opt_d,&WORK_ROWS,&1L,0,&SMG$M_REVERSE,
X`009`009`009  0,0);
X
X   if(status2 != SS$_NORMAL)
X   `123
X      /* bummer; try to salvage the situation */
X
X      status = SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X
X      if(status != SS$_NORMAL)
X`009 LIB$STOP(status);`009`009/* double dummer......`009`009      */
X
X      return(CANT_DISPLAY);
X   `125
X
X   /* now process the file, displaying it on the screen in a series of pages,
X    * until end-of-file OR until the user wants to quit looking at the file
X    */
X
X   while((status == RMS$_NORMAL) && (!finish_flag))
X   `123
X      row = 1L;`009`009`009`009/* start on first row in display      */
X
X      /* clear out the display */
X
X      SMG$ERASE_DISPLAY(&disp_id,&1L,&1L,&(WORK_ROWS-1),&end_col);
X
X      /* write a page of the file or as much as we can get if we hit
X       * end-of-file here
X       */
X
X      while((status == RMS$_NORMAL) && (row < (WORK_ROWS - 1)))
X      `123
X`009 tptr = buf;`009`009`009/* point to start of input buffer     */
V`009 buf[in_rab.rab$w_rsz] = '\0';`009/* make the input record a string     *
X/
X
X`009 do
X`009 `123
X`009    tptr2 = out_buf;`009`009/* point to beginning of output buf   */
X`009    buf_cnt = 0;`009`009/* clear number of chars in buffer    */
X
X       `009    while((buf_cnt < scr_width) && (*tptr != '\0'))
X`009    `123
X
X`009       if(*tptr >= ' ')`009`009/* is character printable?`009      */
X`009       `123
X`009`009  *tptr2++ = *tptr++;`009/* store the character`009`009      */
X`009`009  buf_cnt++;`009`009/* count the character`009`009      */
X`009       `125
X`009       else
X`009       `123
X `009`009  switch(*tptr)`009`009/* what kind of control char is it?   */
X`009`009  `123
X`009`009     case(0x9):`009`009/* control-I (tab) character`009      */
X
X`009`009`009temp = buf_cnt % 8; /* determine how many to add      */
X
X`009`009`009if(temp != 0)
X`009`009`009   buf_cnt = buf_cnt + (8 - temp);
X`009`009`009else
X`009`009`009   buf_cnt += 8;
X
X`009`009`009*tptr2++ = *tptr++; /* just use the tab as it is      */
X
X`009`009`009break;
X
X`009`009     case(10):`009`009/* control-J (linefeed) character     */
X`009`009     case(13):`009`009/* control-M (carriage return) char   */
X
V`009`009`009*tptr2++ = ' ';`009/* store a space for `094J and `094M`009  `032
X   */
X `009`009        tptr++;`009`009/* skip over the character`009      */
X`009`009`009buf_cnt++;`009/* count the character`009`009      */
X`009`009`009break;
X
X`009`009     default:`009`009/* all other control characters`009      */
X
X`009`009`009if(buf_cnt < scr_width - 2)
X`009`009`009`123
X`009`009`009   /* only do this if we have room */
X
X`009`009`009   *tptr2++ = '`094'; /* use two chars - `094<char>`009      */
X`009     `009`009   *tptr2++ = *tptr++ + 64;
X`009`009`009`125
X`009`009`009buf_cnt += 2;   /* count two characters  `009      */
X`009`009`009break;
X
X`009`009  `125 /* switch (*tptr) */
X
X`009       `125 /* if(*tptr >= ' ') */
X
X`009    `125 /* while((buf_cnt < scr_width) && (*tptr != '\0')) */
X`009   `032
X`009    *tptr2 = '\0';`009`009/* make the output buffer a string    */
X`009    text_d.dsc$w_length = (USHORT) strlen(out_buf);
X
X`009    /* write this line to the display */
X
X`009    status2 = SMG$PUT_CHARS(&disp_id,&text_d,&row,&1L,0,0,0,0);
X
X`009    if(status2 != SS$_NORMAL)`009/* were we able to write the record?  */
X`009    `123
X`009       SYS$CLOSE(&in_fab);  `009/* close the input file`009`009      */
X`009       status = SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X
X`009       if(status != SS$_NORMAL)
X`009`009  LIB$STOP(status);`009/* BIG error here....`009`009      */
X
X`009       SMG$ERASE_DISPLAY(&disp_id,&1L,&1L,&(WORK_ROWS-1),&end_col);
X
X`009       return(CANT_DISPLAY);`009/* say that something went wrong      */
X`009    `125
X
X`009    row++;`009`009`009/* move to next row in display`009      */
X`009 `125
X`009 while(*tptr != '\0' && row < (WORK_ROWS - 1));
X
X`009 if(*tptr == '\0')`009`009/* do we need another record yet?     */
X`009    status = SYS$GET(&in_rab);`009/* get the next record`009`009      */
X      `125
X
X      /* do we need to put the the "[eof]" on the screen? */
X
X      if(status != RMS$_NORMAL)
X      `123
X`009  if(SMG$PUT_CHARS(&disp_id,&eof_d,&row,&1L,0,&SMG$M_REVERSE,0,0)
X`009     != SS$_NORMAL)
X`009  `123
X`009    SYS$CLOSE(&in_fab);`009`009/* close the input file`009`009      */
X    `009    status = SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X
X`009    if(status != SS$_NORMAL)
X`009       LIB$STOP(status);`009/* BIG error here....`009`009      */
X
X`009    SMG$ERASE_DISPLAY(&disp_id,&1L,&1L,&(WORK_ROWS-1),&end_col);
X
X`009    return(CANT_DISPLAY);`009/* say that something went wrong      */
X`009  `125
X      `125
X
X      /* we are at the end of a page; wait for the user to tell us what
X       * s/he wants to do
X       */
X
X      key_flag = 0;`009`009`009/* make sure we enter the loop`009      */
X
X      while(!key_flag)`009`009`009/* loop until we get a good key`009      */
X      `123
X`009 status3 = SMG$READ_KEYSTROKE(&keybd_id,&term_code,0,0,&disp_id,0,0);
X
X`009 if((status3 != SS$_NORMAL) && (status3 != SMG$_EOF))
X`009 `123
V`009    SYS$CLOSE(&in_fab);`009     `009/* close the input file`009`009  `032
X   */
X    `009    status = SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X
X`009    if(status != SS$_NORMAL)
X`009        LIB$STOP(status); `009/* BIG error here....`009`009      */
X
X`009    /* clear out the display */
X
X`009    SMG$ERASE_DISPLAY(&disp_id,&1L,&1L,&(WORK_ROWS-1),&end_col);
X  `032
X`009    return(CANT_DISPLAY); `009/* say that something went wrong      */
X`009 `125
X
X`009 if(status3 == SMG$_EOF)`009/* user pressed control-Z; same as F  */
X`009    term_code = SMG$K_TRM_LOWERCASE_F;
X
X`009 /* ok, then, see what the keystroke was */
X
X`009 switch(term_code)
X`009 `123
X`009    case(SMG$K_TRM_EQUAL):`009/* +(next) screen`009`009      */
X`009    case(SMG$K_TRM_NEXT_SCREEN):
X`009    case(SMG$K_TRM_DOWN):
X`009    case(SMG$K_TRM_ASTERISK+1):
X`009    case(SMG$K_TRM_SPACE):
X`009    case(SMG$K_TRM_CR):
X
X`009       key_flag++;`009`009/* break out of the while() loop      */
X`009       break;`009`009`009/* just keep going`009`009      */
X
X`009    case(SMG$K_TRM_UPPERCASE_F):  /* Finish viewing file`009      */
X`009    case(SMG$K_TRM_LOWERCASE_F):
X`009    case(SMG$K_TRM_UPPERCASE_Q):
X`009    case(SMG$K_TRM_LOWERCASE_Q):
X
X`009       finish_flag++;`009`009/* set the Finish key flag`009      */
X`009       key_flag++;`009`009/* break out of the key loop`009      */
X`009       break;
X`009`009`009`009`009/* right here`009`009`009      */
X`009    default:
X
X`009       SMG$RING_BELL(&disp_id,0); /* scream and try again `009      */
X`009       break;
X
X`009 `125 /* switch(term_code) */
X
X      `125 /* while(!key_flag) */
X
X   `125 /* while(status == RMS$_NORMAL) */
X
V   status = SYS$CLOSE(&in_fab);`009`009/* close the input file`009`009      *
X/
X
X   if(status != RMS$_NORMAL)
X      LIB$STOP(status);
X
X   /* unpaste the work virtual display so that the main screen and related
X    * info is back on the screen
X    */
X
X   status = SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X
X   if(status != SS$_NORMAL)
X      LIB$STOP(status);`009`009`009/* BIG error here....`009`009      */
X
X   /* clear out the work virtual display */
X
X   SMG$ERASE_DISPLAY(&disp_id,&1L,&1L,&WORK_ROWS,&end_col);
X
X
X   return(0); `009   `009  `009`009/* everything is cool; just return    */
X
X`125`009/*** file_select ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009file_locate
X
X  Purpose:`009Get the filename prefix that is desired by the user and
X`009`009search for it.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none                                                        `032
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009  0`009`009`009no prefix string given
X`009return()`009`009return code from file_search
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic short file_locate(dirptr,disp_id,keybd_id,num_file,scr_width)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ENT_DEF  *dirptr;`009`009/* pointer to directory entry memory  */
X`009 long`009  disp_id,`009`009/* display id of where to read from   */
X`009`009  keybd_id;`009`009/* keyboard id of where to read from  */
X`009 short`009  num_file,`009`009/* number of files in directory`009      */
X`009`009  scr_width;`009`009/* width of screen`009`009      */
X
X`123`009/*** file_locate ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister short`009  i;`009`009`009/* loop and array index`009`009      */
X`009 ULONG`009  status;`009`009/* return code holder`009`009      */
X`009 long`009  end_col;`009`009/* number of columns to erase`009      */
X`009 USHORT`009  rlength;`009`009/* received string length`009      */
Vstatic`009 long`009  max_len = SPEC_MAX;`009/* maximum prefix length allowed
X      */
Vstatic`009 char`009  prefix[SPEC_MAX+1];`009/* filename prefix read in`009
X      */
Xstatic $DESCRIPTOR(buf_d,prefix);`009/* prefix string descriptor`009      */
Xstatic $DESCRIPTOR(prompt_d,"Search for: ");
X
X
X   /* position the cursor where we want it */
X
X   status = SMG$SET_CURSOR_ABS(&disp_id,&MAIN_ROWS,&1L);
X            `032
X   if(status != SS$_NORMAL)
X      return(-1);
X
X   /* prompt and ye shall receive....... */
X
X   status = SMG$READ_STRING(&keybd_id,&buf_d,&prompt_d,&max_len,0,0,0,
X`009`009`009    &rlength,0,&disp_id,0,&SMG$M_BOLD,0);
X
X   if(status != SS$_NORMAL)
X      return(-1);`009`009`009/* problems reading from keyboard     */
X
X   /* erase the prompt from the virtual display */
X
X   end_col = (long) scr_width;
X   status = SMG$ERASE_DISPLAY(&disp_id,&MAIN_ROWS,&1L,&MAIN_ROWS,&end_col);
X
X   if(status != SS$_NORMAL)
X      return(-1);
X`009      `032
X   if(!rlength)
X      return(0);`009`009`009/* no string given; just leave`009      */
X
X   prefix[rlength] = '\0';`009`009/* terminate the prefix string`009      */
X
X   /* convert the string to upper-case */
X
X   for(i = 0; i < rlength; i++)
X      prefix[i] = _toupper(prefix[i]);
X
X   /* now search for the filename prefix in the directory entries */
X
X   return(file_search(dirptr,prefix,num_file,rlength));
X
X`125`009/*** file_locate ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009file_search
X
X  Purpose:`009Search for the filename prefix specified
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009 i`009`009`009number of file in directory
X`009 -1`009`009`009file prefix not found in directory
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X                                  `032
Xstatic short file_search(dirptr,prefix,num_file,length)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister ENT_DEF  *dirptr;`009`009/* pointer to directory entries`009      */
Xregister char`009  *prefix;`009`009/* filename prefix to find`009      */
Vregister short`009  num_file;`009`009/* number of files in directory`009 `032
X    */
X`009 short`009  length;`009`009/* length of prefix string`009      */
X
X`123`009/*** file_search ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister short`009  i = 0;`009`009/* loop index and file entry counter  */
X`009 short`009  done = 0;`009`009/* loop control flag`009`009      */
X
X
X   /* search from the beginning for the filename prefix until 1) we find
X    * what we are looking for or 2) we run out of files; when we exit the
X    * loop we look at why we exited to see if we found the file or not
X    */
X
X   while((i < num_file) && (!done))
X   `123
X      if(!strncmp(dirptr->filename,prefix,length))
X`009 done++;`009`009`009/* we found it; stop searching....    */
X      else
X      `123
X`009 ++i;`009`009`009`009/* count this file entry`009      */
X`009 ++dirptr;`009`009`009/* go to next file entry`009      */
X      `125
X   `125
X
X   /* did we find what we were looking for? */
X
X   if(i == num_file)`009`009`009/* did we find the filename prefix?   */
X      i = -1;`009`009`009`009/* nope.....`009`009`009      */
X
X   return(i);`009`009`009`009/* say whether or not we found it...  */
X
X`125`009/*** file_search ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009put_help
X
X  Purpose:`009Called by LBR$OUTPUT_HELP, this routine will write a line
X`009`009of help text to the virtual display and prompt the user to
X`009`009press a key at the end of a page to give them a chance to
X`009`009read what is on the screen.  This routine is only called by
X`009`009LBR$OUTPUT_HELP.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009scr_width`009`009`009`009X
X    `009state`009`009`009   X`009  X
X`009disp4_id`009`009`009`009X
X`009keybd_id`009`009`009`009X
X`009paste_id`009`009`009`009X
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009RMS$_EOF`009`009error writing to virtual display
X`009SS$_NORMAL`009`009write to virtual display successful
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic ULONG put_help(msg_d)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Vstruct`009 dsc$descriptor  *msg_d;`009/* descriptor for message to write    *
X/
X
X`123`009/*** put_help ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xstatic`009 ULONG`009  status;`009`009/* return code status holder`009      */
Xstatic`009 long`009  row;`009`009`009/* current row in virtual display     */
Vstatic`009 USHORT`009  term_code;`009`009/* key read from keyboard`009      *
X/
Xstatic $DESCRIPTOR(prompt_d,"Press any key to continue                    \
X                                                                           \
X            ");
Xstatic $DESCRIPTOR(clear_d,"                                             \
X                                                                           \
X            ");
X
X
X   if(!state)`009`009`009`009/* set up initialization code`009      */
X   `123
X      /* we need to reset things because we are to start a new help session
X       * or a new page
X       */
X
X      row = 1L;`009`009`009`009/* reset row counter`009`009      */
X      prompt_d.dsc$a_pointer[scr_width] = '\0';
X      clear_d.dsc$a_pointer[scr_width] = '\0';
X      state++;
X      status = SMG$PUT_CHARS(&disp4_id,&clear_d,&WORK_ROWS,&1L,0,
X`009`009`009     &SMG$M_REVERSE,0,0);
X      if(status != SS$_NORMAL)
X`009 return(RMS$_EOF);
X   `125
X
X   /* before we write anything, we must check to see if the screen is
X    * full; if it is, ask the user to press a key before continuing,
X    * thus giving them a chance to read what is on the screen
X    */
X
X   if(row == (WORK_ROWS - 1))`009`009/* is the screen full?`009`009      */
X   `123
X      /* tell the user to press a key to continue */
X
X      status = SMG$PUT_CHARS(&disp4_id,&prompt_d,&WORK_ROWS,&1L,0,
X`009`009`009     &SMG$M_REVERSE,0,0);
X
X      if(status != SS$_NORMAL)
X`009 return(RMS$_EOF);`009`009/* problems writing to the screen     */
X
X      /* now get a keystroke and continue */
X
X      status = SMG$READ_KEYSTROKE(&keybd_id,&term_code,0,0,&disp4_id,0,0);
X
X      if(status != SS$_NORMAL)
X`009 return(RMS$_EOF);
X
V      SMG$ERASE_DISPLAY(&disp4_id);`009/* so NOW clear the screen....`009`032
X     */
X
X      /* .... and clear out the prompt information at the bottom */
X
X      status = SMG$PUT_CHARS(&disp4_id,&clear_d,&WORK_ROWS,&1L,0,
X`009`009`009     &SMG$M_REVERSE,0,0);
X
X      row = 1L;`009`009`009`009/* reset the row counter`009      */
X   `125
X
X   /* now write the line we were supposed to write when we entered */
X
X   row++;
X   status = SMG$PUT_CHARS(&disp4_id,msg_d,&row,&1L,&1L,0,0,0);
X
X   if(status != SS$_NORMAL)`009`009/* bummer.....`009`009`009      */
X      return(RMS$_EOF);
X
X   return(SS$_NORMAL);`009`009`009/* no problem........`009`009      */
X
X`125`009/*** put_help ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009get_help
X
X  Purpose:`009Called by LBR$OUTPUT_HELP, this routine will read a line
X`009`009of text from the virtual display and return it.  This routine
X`009`009is only called by LBR$OUTPUT_HELP.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009scr_width`009`009`009`009X
X`009state`009`009`009`009  X
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009RMS$_EOF`009`009error reading virtual display
X`009SS$_NORMAL`009`009read from virtual display successful
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic ULONG get_help(get_d,prompt_d,out_len)
X
Xstruct`009 dsc$descriptor`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009`009  *get_d,`009`009/* where to put string that is read   */
X`009`009  *prompt_d;`009`009/* prompt to use`009`009      */
X`009 USHORT`009  *out_len;`009`009/* length string in get_d`009      */
X
X`123`009/*** get_help ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xstatic`009 ULONG`009  status,`009`009/* return code status holder`009      */
X`009`009  status2;`009`009/* another return code status holder  */
Vstatic`009 long`009  max_length = STR_MAX, /* max. # of characters to be read
X    */
X`009`009  end_col;`009`009/* for erasing virtual display`009      */
Vstatic`009 char`009  *ptr;`009`009`009/* temporary character pointer`009 `032
X    */
Vstatic`009 UCHAR`009  pass;`009`009`009/* prevents multiple intialization`032
X   */
Vstatic $DESCRIPTOR(prompt2_d,"");`009/* alternate prompt descriptor`009  `032
X   */
X
X
X   if(!pass)
X   `123
V      get_d->dsc$b_dtype = DSC$K_DTYPE_T; /* set up the descriptor type`009
X      */
V      get_d->dsc$b_class = DSC$K_CLASS_S; /* set up the descriptor class `032
X    */
V      end_col= (long) scr_width;  `009/* for clearing the virtual display   *
X/
X      pass++;
X   `125
X
X   /* we have to do the prompting ourselves rather than let SMG$READ_STRING
X    * do it; for some reason, the prompt is not written to the virtual
X    * display and thus cannot be erased later; first, set up the alternate
V    * prompt descriptor so that all of the control characters at the beginnin
Xg
X    * of the prompt are ignored; then call put_help() to write the prompt
X    * <CR><LF> pair that appears at the beginning of every prompt
X    */
X
X   ptr = prompt_d->dsc$a_pointer;
X
X   while((*ptr != '\0') && (*ptr < ' '))
X      ptr++;
X
X   prompt2_d.dsc$a_pointer = ptr;
X   prompt2_d.dsc$w_length = (USHORT) strlen(ptr);
X
X   status = put_help(&prompt2_d);`009/* write the prompt`009`009      */
X
X   if(status != SS$_NORMAL)
X      return(RMS$_EOF);
X
X   get_d->dsc$w_length = STR_MAX;
X
X   status = SMG$READ_STRING(&keybd_id,get_d,0,&max_length,0,0,0,out_len,0,
X`009`009`009    &disp4_id,0,0,0);
X
V   get_d->dsc$w_length = *out_len;`009/* set length read in the descriptor  *
X/
X   get_d->dsc$a_pointer[*out_len] = '\0';
X
X   /* clear out the virtual display so that the next topic starts on a new
X    * page
X    */
X
X   status2 = SMG$ERASE_DISPLAY(&disp4_id,&1L,&1L,&(WORK_ROWS-1),&end_col);
X
X   if(status2 != SS$_NORMAL)
X      return(RMS$_EOF);`009`009`009/* bummer.....`009`009`009      */
X
X   state = 0;`009`009`009`009/* make put_help reset row counter    */
X
X   if(status != SS$_NORMAL)`009`009/* now check READ_STRING's return     */
X      return(RMS$_EOF);`009`009`009/* use the right end-of-file value    */
X
X   return(status);`009`009`009/* or just return SS$_NORMAL....      */
X
X`125`009/*** get_help ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009put_options
X
X  Purpose:`009Write the options line to the statistics/options virtual
X`009`009display.  The keystroke needed to invoke the command is written
X`009`009in bold, the rest of the command in normal.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void put_options(disp_id,scr_width)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ULONG`009  disp_id;`009`009/* display id of where to write`009      */
X`009 short`009  scr_width;`009`009/* width of screen`009`009      */
X
X`123`009/*** put_options ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister OPT_DEF  *opt_ptr;`009`009/* pointer to options array`009      */
Xregister ULONG`009  status;`009`009/* return code status holder`009      */
Xstatic`009 long`009  column;`009`009/* current column number for writing  */
Xstatic $DESCRIPTOR(text_d,"");`009`009/* descriptor for writing`009      */
Vstatic`009 OPT_DEF  options1[] =`009`009/* options array for 80-column mode
X   */
X`123
X`123"A","cl",1,2,1`125,
X`123"D","el",1,2,1`125,
X`123"R","en",1,2,1`125,
X`123"P","rot",1,3,1`125,
X`123"C","opy",1,3,1`125,
X`123"U","nmark",1,5,1`125,
X`123"+","",1,0,1`125,
X`123"-","",1,0,1`125,
X`123"S","el",1,2,1`125,
X`123"F","in",1,2,1`125,
X`123"X","ecute",1,5,1`125,
X`123"Q","uit",1,3,1`125,
X`123"T","ext",1,3,1`125,
X`123"`094P","ush",2,3,1`125,
X`123"E","xpnd",1,4,1`125,
X`123"L","ocat",1,4,1`125,
X`123"H","elp",1,3,0`125,
X`123"","",0,0,0`125
X`125,
X`009`009  options2[] =`009`009/* options array for 132-column mode  */
X`123
X`123"A","cl",1,2,3`125,
X`123"D","elete",1,5,3`125,
X`123"R","ename",1,5,3`125,
X`123"P","rotect",1,6,3`125,
X`123"C","opy",1,3,3`125,
X`123"U","nmark",1,5,3`125,
X`123"+","",1,0,3`125,
X`123"-","",1,0,3`125,
X`123"S","elect",1,5,4`125,
X`123"F","inish",1,5,4`125,
X`123"X","ecute",1,5,4`125,
X`123"Q","uit",1,3,3`125,
X`123"T","ext",1,3,3`125,
X`123"`094P","ush",2,3,3`125,
X`123"E","xpand",1,5,3`125,
X`123"L","ocate",1,5,3`125,
X`123"H","elp",1,3,0`125,
X`123"","",0,0,0`125
X`125;
X
X
X   if(scr_width == 80)`009`009`009/* set pointer to options array`009      */
X      opt_ptr = &options1[0];
X   else
X      opt_ptr = &options2[0];
X
X   column = 1L;`009`009`009`009/* make sure we start ok`009      */
X
X   while(opt_ptr->key_len != 0)`009`009/* do them ALL......`009`009      */
X   `123
X      /* write the key that activates the option in bright mode */
X
X      text_d.dsc$a_pointer = opt_ptr->keystr;
X      text_d.dsc$w_length = (USHORT) opt_ptr->key_len;
X
X      status = SMG$PUT_CHARS(&disp_id,&text_d,&2L,&column,0,&SMG$M_BOLD,
X`009`009`009     0,0);
X
X      if(status != SS$_NORMAL)
X`009 LIB$STOP(status);
X
X      /* write the rest of the command name in normal video */
X
X      column += (long) opt_ptr->key_len; /* move the column over`009      */
X
X      text_d.dsc$a_pointer = opt_ptr->remaining;
X      text_d.dsc$w_length = opt_ptr->rem_len;
X
X      status = SMG$PUT_CHARS(&disp_id,&text_d,&2L,&column,0,&SMG$M_NORMAL,
X`009`009`009     0,0);
X
X      if(status != SS$_NORMAL)
X`009 LIB$STOP(status);
X
X      /* skip the length of the remaining command name AND the number of
X       * spaces that separates this command from the next
X       */
X
X      column = column + (long) opt_ptr->spaces + (long) opt_ptr->rem_len;
X      opt_ptr++;`009`009`009/* go to next option slot`009      */
X   `125
X
X   return;
X
X`125`009/*** put_options ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009get_text_des
X
X  Purpose:`009Attempt to read in the text descriptors from the text des-
X`009`009criptor file for the current directory.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009NO_FILE`009`009`009file does not exist
X`009CANT_OPEN`009`009cannot open MAINT.TDF file
X`009BAD_FILE`009`009bad text descriptor file
X`009 0`009`009`009text descriptor file successfully read
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X `009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic short get_text_des(dirptr,curr_pool,dir_text,pool_length,num_file)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister ENT_DEF  *dirptr;`009`009/* pointer to directory entries`009      */
X`009 POOL_DEF **curr_pool;`009`009/* pointer to pointer to current pool */
X`009 char`009  **dir_text;`009`009/* directory text descriptor array    */
X`009 long`009  pool_length;`009`009/* length of pool to allocate`009      */
X`009 short`009  num_file;`009`009/* number of files in directory`009      */
X
X`123`009/*** get_text_des ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
Vstatic`009 ENT_DEF  *currptr;`009`009/* current entry for searching`009  `032
X   */
Xstatic`009 char`009  *tptr;`009`009/* temporary character pointer`009      */
Xstatic`009 struct`009  FAB`009in_fab;`009`009/* input FAB`009`009`009      */
Xstatic`009 struct`009  RAB`009in_rab;`009`009/* input RAB`009`009`009      */
Vstatic`009 char`009  pass,`009`009`009/* to prevent multiple initialization *
X/
X`009`009  text_buf[TEXT_REC_MAX+1];
X
X
X   if(!pass)`009`009`009`009/* only initialize first time thru    */
X   `123                                                           `032
X      in_fab = cc$rms_fab;
X      in_rab = cc$rms_rab;
X      in_fab.fab$b_fac = FAB$M_GET;
X      in_rab.rab$l_fab = &in_fab;
X      in_rab.rab$w_usz = TEXT_REC_MAX;
X      in_rab.rab$l_ubf = text_buf;
X      in_rab.rab$b_rac = RAB$C_SEQ;
X      in_fab.fab$l_fna = TEXT_FILE;
X      in_fab.fab$b_fns = (UCHAR) strlen(TEXT_FILE);
X      pass++;
X   `125
X
X   in_fab.fab$w_ifi = 0;`009`009/* reset this every time`009      */
X
V   status = SYS$OPEN(&in_fab);`009`009/* open the text descriptor file      *
X/
X
X   if(status == RMS$_FNF)`009`009/* no text descriptor file; oh well   */
X   `123
X      /* everything is ok; we just did not find a text descriptor file */
X
X      return(NO_FILE);
X   `125
X   else if(status != RMS$_NORMAL)
X   `123
X      *dir_text = NULL;
X      return(CANT_OPEN);
X   `125
X
X   /* connect the FAB and the RAB */
X
X   status = SYS$CONNECT(&in_rab);
X
X   if(status != RMS$_NORMAL)
X   `123
X      *dir_text = NULL;
X      SYS$CLOSE(&in_fab);
X      return(CANT_OPEN);
X   `125        `032
X
X   /* get the first record; this is the text descriptor for the directory;
X    * the format for this record is
X    *    >>><text descriptor for directory>
X    */
X
X   status = SYS$GET(&in_rab);
X
X   if(status != RMS$_NORMAL)
X   `123
X      *dir_text = NULL;
X      SYS$CLOSE(&in_fab);
X      return(CANT_OPEN);
X   `125
X
X   /* make sure this record is in the right form */
X
X   if(strindex(text_buf,">>>") != 0)
X   `123
X      SYS$CLOSE(&in_fab);
X      return(BAD_FILE);
X   `125
X
X   /* store this in the memory pools and set the dir_text pointer to point
X    * to it
X    */
X
X   text_buf[in_rab.rab$w_rsz] = '\0';`009/* make it a string`009`009      */
X            `032
X   put_pool(dir_text,curr_pool,&text_buf[3],in_rab.rab$w_rsz,pool_length);
X
X   /* skip the comment lines in the text descriptor file */
X
X   status = SYS$GET(&in_rab);
X
X   while((status == RMS$_NORMAL) && (text_buf[0] == '>'))
X      status = SYS$GET(&in_rab);
X
X   if(status == RMS$_EOF)
X   `123
X      SYS$CLOSE(&in_fab);
X      return(0);`009`009`009/* end-of-file here....`009`009      */
X   `125
X
X   if(status != RMS$_NORMAL)`009`009/* error reading the file?`009      */
X   `123
X      SYS$CLOSE(&in_fab);
X      return(BAD_FILE);`009`009`009/* yup.....`009`009`009      */
X   `125
X
X   /* now get each text descriptor record and match it up with a filename */
X
X   /* set the current file entry pointer to actually pointer to one entry
X    * BEFORE the current entry; it will be updated inside text_search to
X    * point to the correct entry; this is done so that text_search can be
X    * more general
X    */
X
V   currptr = dirptr - 1L;`009     `009/* set where we start to look`009  `032
X   */
X
X   while(status == RMS$_NORMAL)
X   `123                        `032
V      text_buf[in_rab.rab$w_rsz] = '\0'; /* make the record a string`009 `032
X    */
X
V      /* search for a match with the filename in the text descriptor record *
X/
X
X      if((tptr = text_search(dirptr,&currptr,text_buf,num_file)) != NULL)
X      `123
X`009 /* match; store the text descriptor in a memory pool */
X
X`009 put_pool(&(currptr->text),curr_pool,tptr,(long) strlen(tptr),
X`009`009  pool_length);
X      `125
X
X      status = SYS$GET(&in_rab);
X   `125
X
V   status = SYS$CLOSE(&in_fab);`009`009/* close the text descriptor file `032
X   */
X
X   if(status != RMS$_NORMAL)
X   `123
X      return(BAD_FILE);
X   `125
X
X   return(0);`009`009`009`009/* everything done`009`009      */
X
X`125`009/*** get_text_des ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009text_search
X
X  Purpose:`009Search the directory entries for a match with the current
X`009`009text descriptor record.  If one is found, return a pointer
X`009`009to the actual text of the text descriptor and update the
X`009`009current directory entry pointer to point to the NEXT entry
X`009`009to check for a text descriptor match.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009retval`009`009`009pointer to actual text of text descriptor
X`009NULL`009`009`009no match for text descriptor
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X `009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic char *text_search(dirptr,currptr,text_rec,num_file)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ENT_DEF  *dirptr,`009`009/* pointer to all directory entries   */
X`009 `009  **currptr;`009`009/* pointer to current directory entry */
X`009 char`009  *text_rec;`009`009/* current text descriptor record     */
X`009 short`009  num_file;`009`009/* number of files in directory`009      */
X
X`123`009/*** text_search ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister ENT_DEF  *ptr;`009`009`009/* current file entry pointer`009      */
Vstatic`009 ENT_DEF  *origptr;`009`009/* original directory pointer`009      *
X/
Xstatic`009 char`009  *retval;`009`009/* return value`009`009`009      */
Vstatic`009 ULONG`009  curr_index;`009`009/* index value for setting pointer
X    */
X
X
X   /* get pointer to directory that we need; this is the one following
X    * (modulo the number of files in the directory) the entry that we
X    * were on the last time through
X    */
X
X   curr_index = *currptr - dirptr;`009/* get current entry index`009      */
X   curr_index = (curr_index + 1L) % (ULONG) num_file;
X
V   ptr = dirptr + curr_index;`009`009/* get pointer to the NEW entry`009 `032
X    */
X
X   /* first check to see if we have a match with the current entry */
X
X   if((retval = text_match(ptr->filename,text_rec)) != NULL)
X   `123
X      /* we have a match; return the pointer to the beginning of the
X       * actual text of the text descriptor AND update the currptr
X       * return value to point to the next entry so that the next time
X       * this routine is called, we can start up one after where we
X       * left off here
X       */
X
X      *currptr = ptr;`009`009`009/* return pointer to current entry    */
X      return(retval);`009`009`009/* match....`009`009`009      */
X   `125
X
X   /* no match with the current entry; search the entries until 1) we find a
X    * a match, or until we have examined all of the entries
X    */
X
X   origptr = ptr;`009`009`009/* save where we are right now`009      */
X   curr_index = (curr_index + 1L) % (ULONG) num_file;
X   ptr = dirptr + curr_index;
X
X   while(ptr != origptr)`009`009/* until we are back where we started */
X   `123
X      /* check for a match */
X
X      if((retval = text_match(ptr->filename,text_rec)) != NULL)
X      `123
X`009 /* we have a match; return the pointer to the beginning of the
X`009  * actual text of the text descriptor AND update the currptr
X`009  * return value to point to the current directory entry so that
X`009  * we know where we left off last time through
X`009  */
X
X`009 *currptr = ptr;
X`009 return(retval);
X      `125
X
X      /* update the current entry pointer to point to the next entry */
X
X      curr_index = (curr_index + 1L) % (ULONG) num_file;
X      ptr = dirptr + curr_index;
X   `125
X
X   return(NULL);`009`009`009/* no match for this text descriptor  */
X
X`125`009/*** text_search ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009text_match
X
X  Purpose:`009Determine if a text descriptor record is the correct one
X`009`009for a file entry.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X
X`009NULL`009`009`009no match for text descriptor record
X`009text_rec + 1L`009`009pointer to beginning of text descriptor part
X`009`009`009`009of the record
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X `009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic char *text_match(filename,text_rec)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister char`009  *filename,`009`009/* filename to look for`009`009      */
X`009`009  *text_rec;`009`009/* current text descriptor record     */
X
X`123`009/*** text_match ***/
X
X
X   while((*filename == *text_rec) && (*filename != ';'))
X   `123
X      filename++;
X      text_rec++;
X   `125
X
X   /* now check to see if we had a match */
X
X   if(*text_rec == ' ')
X   `123
X      /* return a pointer to the beginning of the text descriptor */
X
X      return(text_rec + 1L);
X   `125
X
X   return(NULL);`009`009`009/* not correct record for file`009      */
X
X`125`009/*** text_match ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009get_sysdisk
X
X  Purpose:`009Get the value of SYS$DISK when the program is invoked so that
X`009`009we can set it back when we exit.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009return code from SYS$TRNLNM()
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void get_sysdisk(orig_disk,length)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *orig_disk;`009`009/* where to store value of SYS$DISK   */
X`009 USHORT`009  length;`009`009/* length of array orig_disk`009      */
X
X`123`009/*** get_sysdisk ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
V       `009 ULONG`009  status;`009`009/* return code status holder`009      *
X/
Vstatic`009 ITM_LST  items[] = `123`009`009/* items obtained during translatio
Xn  */
V`1230,LNM$_STRING,NULL,NULL`125,`009`009/* things are filled in below`009`032
X     */
X`1230,0,NULL,NULL`125`125;
Xstatic $DESCRIPTOR(table_d,"LNM$PROCESS");
Xstatic $DESCRIPTOR(sysdisk_d,"SYS$DISK");
X
X
X   items[0].buf_len = length;
X   items[0].buf_addr = orig_disk;
V   items[0].ret_len = &length;`009`009/* store it right back in length      *
X/
X
X   status = SYS$TRNLNM(0,&table_d,&sysdisk_d,0,items);
X
X   if(status != SS$_NORMAL)
X      LIB$STOP(status);
X
X   *(orig_disk + length) = '\0';`009/* terminate it`009`009`009      */
X
X   return;
X
X`125`009/*** get_sysdisk ***/  `032
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009screen_reset
X
X  Purpose:`009Called when something has changed the format of the screen
X`009`009and we have to make sure that the cursor still points to the
X`009`009right place.  The current file is located and the row, column,
X`009`009and screen values are reset/recalculated.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void screen_reset(nodes,dirptr,entptr,node_row,node_col,scr_file,
X`009`009`009 curr_screen,num_file,num_slot,num_screen,slot_width,
X`009`009`009 num_row,num_col)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 NODE_DEF nodes[][MAX_NODE_COL+1]; /* screen node matrix`009      */
X`009 ENT_DEF  *dirptr,`009`009/* pointer to directory information   */
X`009`009  *entptr;`009`009/* pointer to directory entry`009      */
X      `009 short`009  *node_row,`009`009/* current node array row`009      */
X`009`009  *node_col,`009`009/* current node array column`009      */
X`009`009  *scr_file,`009`009/* number of files for current screen */
X`009`009  *curr_screen,`009`009/* current screen of directory`009      */
X`009 `009  num_file,`009  `009/* number of files in current direct. */
X`009`009  num_slot,`009`009/* number of slots per screen`009      */
X`009`009  num_screen,`009`009/* number of screens in directorys    */
X`009`009  slot_width,`009`009/* width of one screen slot`009      */
X`009`009  num_row,`009`009/* number of rows on the screen`009      */
X`009`009  num_col;`009`009/* number of columns on the screen    */
X
X`123`009/*** screen_reset ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 short`009  temp,`009`009`009/* temporary variable and return code */
X`009`009  temp2,`009`009/* temporary variable number two      */
X`009`009  new_screen;`009`009/* temporary current screen number    */
X
X
X   /* find the file in memory so we can calculate what page it is supposed to
X    * be on
X    */
X
X   temp = file_search(dirptr,entptr->filename,num_file,
X`009`009      (short) strlen(entptr->filename));
X
X   if(temp >= 0)
X   `123
X      /* we should ALWAYS get here, because the directory name should not
X       * disappear from our memory, right?
X       */
X
X      new_screen = (temp / num_slot) + 1;
X
X      /* get us to the current screen */
X
X      temp2 = temp - ((new_screen - 1) * num_slot);
X      *node_col = temp2 / num_row;
X      *node_row = temp % num_row;
X                    `032
X      /* do we need to go to a new screen?  if so, make the new one now */
X
X      if(new_screen != *curr_screen)
X      `123
X`009 /* create the new screen by first putting the new page number in the
X`009  * upper-right and then rebuilding the main display
X`009  */
X
X`009 /* do we need to update the screen node pointers? */
X
X`009 if((new_screen == num_screen) `124`124 (*curr_screen == num_screen))
X`009 `123
X`009    /* set the nodes */
X                                                     `032
X`009    set_nodes(nodes,scr_file,num_screen,new_screen,num_file,
X`009`009      slot_width,num_col);
X`009 `125
X
X`009 *curr_screen = new_screen;
X      `125
X   `125
X
X   return;
X
X`125`009/*** screen_reset ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009size_qsort
X
X  Purpose:`009Sort the directory entries by size.
X
X`009`009Algorithm for quicksort from "Fundamentals of Data Structures",
X`009`009Ellis Horowitz and Sartaj Sahni, page 137.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009baseptr`009`009`009`009`009X
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void size_qsort(m,n)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister short`009  m,`009`009`009/* lower-bound of sub-array to be     */
X`009`009`009`009`009/* sorted`009`009`009      */
X`009`009  n;`009`009`009/* upper-bound of sub-array to be     */
X`009`009`009`009`009/* sorted`009`009`009      */
X
X`123`009/*** size_qsort ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister long`009  i,`009`009`009/* loop and array index`009`009      */
X`009`009  j;`009`009`009/*  "    "    "     "`009`009      */
-+-+-+-+-+ End of part 5 +-+-+-+-+-

