home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- INDEMO.C -- Driver for testing and debugging INCON.
-
- Compiler: Borland Turbo C 2.01
-
- INCON source files and the object and library files created from
- them are:
- Copyright (c) 1993-94, Richard Zigler.
- You may freely distribute unmodified source, object, and library
- files, and incorporate them into your own non-commercial software,
- provided that this paragraph and the program name and copyright
- strings defined in INCON.C are included in all copies.
- *************************************************************************/
-
- #include <bios.h> /* for keyboard routines */
- #include <conio.h> /* for console i/o routines */
- #include <dos.h> /* for FP_SEG and FP_OFF */
- #include <math.h> /* for sin() */
- #include <stdio.h> /* for scanf() */
- #include <stdlib.h> /* for exit() and ato?() */
- #include <string.h> /* for string operations */
- #include "indefs.h" /* declarations and definitions */
- #include "indecl.h" /* function prototypes */
-
- /****
- Set UPPER_LOWER to 0 if you want the flags on the menu to appear
- in uppercase only.
- ****/
-
- #define UPPER_LOWER 1
-
- #define FULL_SCREEN 1,1,80,25 /* full screen coordinates */
- #define MENU_ITEMS 19 /* number of items in menu */
- #define MSG_BLK_SIZ 8 /* message block size (words) */
- #define RADIX 10 /* radix for itoa() */
- #define ALPHA_WIDTH 120 /* width of alpha prompt */
- #define ALPHA_PREC 0 /* alpha fields optional */
- #define ALPHA_FILL 250 /* small bullet for text fill */
- #define NUMER_WIDTH 3 /* width of numeric prompts */
- #define NUMER_PREC 1 /* numeric fields mandatory */
- #define NUMER_FILL 32 /* numeric field fill char */
- #define LOGIC_WIDTH 1 /* width of yes/no prompts */
- #define VISIBLE_LEN 0 /* scroll field visible length */
- #define FIELD_ATTR 0 /* invert current attribute */
- #define FIELD_PAD NUMER_FILL /* pad return with spaces */
-
- #define HUGE_PTR(x) ((char huge *)(x)) /* far pointer arithmetic */
-
- /**** Main Menu ****/
-
- static char *MainMenu =
- {
- "\r\n"
- "═══════════════════════════════════════╦════════════════════════════════════════"
- " Field Parameters ║ Field Flags\r\n"
- " ──────────────────────────╫──────────────────────────\r\n"
- " Width ║ Strip [ ]\r\n"
- " Precision ║ Message [ ]\r\n"
- " Visible ║ Sign [ ]\r\n"
- " ║ Display [ ]\r\n"
- " Attribute ║ Confirm [ ]\r\n"
- " Fill ║ Delimit [ ]\r\n"
- " Pad ║ xKeys [ ]\r\n"
- " ║ Scroll [ ]\r\n"
- " Type [ ] ║ Hide [ ]\r\n"
- " Justify [ ] ║ Template [ ]\r\n"
- };
-
- /**** Field Coordinates ****/
-
- static int Field[MENU_ITEMS][2] =
- {
- { 1, 1 }, /* Default input string */
- { 32, 5 }, /* Width */
- { 32, 6 }, /* Prec */
- { 32, 7 }, /* Visible */
- { 32, 9 }, /* Attr */
- { 32, 10 }, /* Fill */
- { 32, 11 }, /* Pad */
- { 32, 13 }, /* Input Type */
- { 32, 14 }, /* Justify */
- { 59, 5 }, /* Strip */
- { 59, 6 }, /* Message */
- { 59, 7 }, /* Sign */
- { 59, 8 }, /* Display */
- { 59, 9 }, /* Confirm */
- { 59, 10 }, /* Delimit */
- { 59, 11 }, /* xKeys */
- { 59, 12 }, /* Scroll */
- { 59, 13 }, /* Hide */
- { 59, 14 }, /* Template */
- };
-
- /**** Menu Info Strings ****/
-
- static char *MenuInfo[MENU_ITEMS] =
- {
- "Enter default input string, or press [Enter], [Tab], or [Shift+Tab] for none.",
- "Maximum field width.",
- "Minimum input required or float field decimals.",
- "Scrolling field visible length.",
- "Input field video attribute; 0 for inverse of current screen attribute.",
- "Decimal ASCII character in unoccupied positions of the input field.",
- "Decimal ASCII character in leading and trailing spaces of justified output.",
- "May be Alpha, Upper, Integer, Float, or Mixed.",
- "May be None, Left, Center, or Right.",
- "Strip delimiters from template fields.",
- "Display run-time error messages.",
- "Allow sign in numeric fields.",
- "Display default input string.",
- "Require confirmation of input.",
- "Display field between delimiters.",
- "Trap extended keys.",
- "Allow alpha fields to scroll.",
- "Do not display input in field.",
- "Treat default input string as input template.",
- };
-
- #define INFO_LINE 1,24 /* put info line here */
- #define INFO_AT 1,25 /* put info string here */
-
- /****
- dPrompt holds the default input string between calls to InCon, so
- that the string doesn't have to be reinitialized between calls.
- dPrompt is copied to ioBuf, the working version of the input
- string that is passed to InCon. ioBuf is modified or not,
- depending on whether InCon detects an entry error or whether
- the user presses an extended key in xKeyList.
- ****/
-
- static char dPrompt [INCON_BUFFER + 1];
- static char ioBuf [INCON_BUFFER + 1];
-
- extern char Copyright[]; /* defined in INCON.C */
- static char ProgName[] = "INDEMO 3.1";
- const char StatsFlags[] = "B BBB BB B B B B B B B B B B";
-
- #if (UPPER_LOWER)
- static char TypeStr[] = "aAuUiIfFmM"; /* input type options */
- static char JustStr[] = "nNlLcCrR"; /* input justification */
- static char NoYes[] = "nNyY"; /* yes/no flags options */
- #else
- static char TypeStr[] = "AUIFM";
- static char JustStr[] = "NLCR";
- static char NoYes[] = "NY";
- #endif
-
- /****
- The extended-key list passes codes for [Tab], [Shift+Tab],
- and the unshifted function keys. InCon treats the list as
- a C string; it must be terminated by a null byte.
- ****/
-
- const BYTE xKeyList[] =
- { 9, 15, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 0 };
-
- /**** Menu Navigation and Help ****/
-
- static int pascal DemoMenu ( int, int, int, MBLOCK far *, char * );
- extern int pascal InHelp ( int );
-
- /************************************************************************/
- /* main() */
- /* */
- /* The message block passed to InCon is declared as a union. */
- /* In the input loop, it is addressed as an array of integers; */
- /* in the output loop, it is addressed as a structure. */
-
- void main( void )
- {
- register int i; /* loop counter, utility */
- register int incon_ret; /* return code from InCon */
- int yn; /* yes/no loop-control flag */
- int attr; /* current video attribute */
- int help_attr; /* normal attr for help screen */
- WORD work; /* working storage */
- BIT_FLAGS * flags; /* flags from user message block */
- union
- {
- long user_long; /* integer field value */
- double user_dbl; /* float field value */
- } user_val; /* value of user input */
-
- /* message blocks used by INDEMO */
- static MBLOCK a_block; /* alpha field block */
- static MBLOCK n_block; /* numeric field block */
- static MBLOCK l_block; /* logical (yes/no) field block */
- static MBLOCK u_block; /* user message block */
-
- MBLOCK far * block_ptr; /* message block pointer */
-
- char * work_buf; /* pointer to scratch buffer */
- char * str_ptr_1; /* working pointers to strings */
- char * str_ptr_2;
-
- #if defined( __TURBOC__ )
- extern char _video; /* Turbo C internal table */
- *((char *)&_video + 10) = '\0'; /* disable CGA snow control */
- #endif
-
- /****
- Force loading of the floating-point library. This is a kludge
- recommended by Borland, though there is no bug of course.
- ****/
-
- user_val.user_dbl = sin( 1 );
-
- work_buf = malloc( INCON_BUFFER + 1 );
- if ( work_buf == NULL )
- {
- cputs( "\n\aInsufficient memory..." );
- exit( 1 );
- }
-
- clrscr();
-
- attr = GetVideoAttr(); /* get current video attribute */
- help_attr = ((attr & 0x07) << 4) | /* and invert for help window */
- ((attr & 0x70) >> 4) |
- ( attr & 0x08) ;
-
- InHelp( help_attr | 0x8000 ); /* init help screen */
-
- /****
- Set up INDEMO's message blocks.
- Note that, when addressing the message block as an array of
- integers, the value that is stored at the higher address must
- be shifted into the high byte for the assignment.
- ****/
-
- a_block.iblock[0] = FP_OFF( dPrompt ); /* default input string field */
- a_block.iblock[1] = FP_SEG( dPrompt );
- a_block.iblock[2] = FP_OFF( xKeyList );
- a_block.iblock[3] = FP_SEG( xKeyList );
- a_block.iblock[4] = FLAG_ALPHA |
- FLAG_CONFIRM|
- FLAG_XKEYS ;
- a_block.iblock[5] = ALPHA_WIDTH | (ALPHA_PREC << 8);
- a_block.iblock[6] = VISIBLE_LEN | (FIELD_ATTR << 8);
- a_block.iblock[7] = ALPHA_FILL | (FIELD_PAD << 8);
-
- n_block.iblock[0] = FP_OFF( work_buf ); /* numeric fields */
- n_block.iblock[1] = FP_SEG( work_buf );
- n_block.iblock[2] = FP_OFF( xKeyList );
- n_block.iblock[3] = FP_SEG( xKeyList );
- n_block.iblock[4] = FLAG_INTGR |
- FLAG_RJUST |
- FLAG_DISPLAY|
- FLAG_CONFIRM|
- FLAG_XKEYS ;
- n_block.iblock[5] = NUMER_WIDTH | (NUMER_PREC << 8);
- n_block.iblock[6] = VISIBLE_LEN | (FIELD_ATTR << 8);
- n_block.iblock[7] = NUMER_FILL | (FIELD_PAD << 8);
-
- l_block.iblock[0] = FP_OFF( work_buf ); /* logical (yes/no) fields */
- l_block.iblock[1] = FP_SEG( work_buf );
- l_block.iblock[2] = FP_OFF( xKeyList );
- l_block.iblock[3] = FP_SEG( xKeyList );
- #if (UPPER_LOWER)
- l_block.iblock[4] = FLAG_DELIMIT|
- FLAG_XKEYS ;
- #else
- l_block.iblock[4] = FLAG_UPPER |
- FLAG_DELIMIT|
- FLAG_XKEYS ;
- #endif
- l_block.iblock[5] = LOGIC_WIDTH | (NUMER_PREC << 8);
- l_block.iblock[6] = VISIBLE_LEN | (attr << 8);
- l_block.iblock[7] = NUMER_FILL | (FIELD_PAD << 8);
-
- /****
- Set up user message block values that are common to all calls.
- The message blocks defined above are those used by InDemo itself.
- The following message block is for testing and debugging InCon;
- it gets filled in the input loop below.
- ****/
-
- u_block.iblock[0] = FP_OFF( ioBuf );
- u_block.iblock[1] = FP_SEG( ioBuf );
- u_block.iblock[2] = FP_OFF( xKeyList );
- u_block.iblock[3] = FP_SEG( xKeyList );
-
-
- cputs( MainMenu ); /* display menu */
- do /**** begin input loop ****/
- {
- window( FULL_SCREEN );
- gotoxy( INFO_LINE );
- WriteMany( '─', attr, MAXCOL );
- for ( i = 0 ; i < MENU_ITEMS ; i++ )
- {
- gotoxy( INFO_AT );
- WriteMany( ' ', attr, MAXCOL );
- cprintf( "%-.*s", MAXCOL - 1, MenuInfo[i] );
- gotoxy( Field[i][0], Field[i][1] );
- if ( i > 6 )
- block_ptr = &l_block;
- else if ( i )
- block_ptr = &n_block;
- else
- block_ptr = &a_block;
-
- /****
- In the following switch block, work receives values entered
- into the menu. Since work is unsigned, the tests of those
- values need only check the upper bound of the valid range
- (the lower bound is 0 in each case). If work is changed
- to a signed quantity, the tests would have to check both
- upper and lower bounds (work < 0 || work > 255).
- ****/
-
- switch ( i )
- {
-
- case 0 : /* default input string */
-
- incon_ret = InCon( block_ptr );
- if ( incon_ret != 0 ) /* if entry error */
- strcpy( work_buf, dPrompt ); /* reload default */
- break;
-
- case 1 : /* field width */
- case 2 : /* field precision */
-
- work = i == 1 ?
- LOBYTE(u_block.iblock[5]) :
- LOBYTE(u_block.iblock[5] >> 8) ;
- itoa( work, work_buf, RADIX );
- incon_ret = InCon( block_ptr );
- work = atoi( work_buf );
- incon_ret |= (work > 255); /* <---- work unsigned */
- if ( incon_ret == 0 )
- {
- cputs( work_buf );
- u_block.iblock[5] =
- i == 1 ?
- HIBYTE(u_block.iblock[5]) | LOBYTE(work) :
- LOBYTE(u_block.iblock[5]) | (work << 8) ;
- }
- break;
-
- case 3 : /* scroll field visible length */
- case 4 : /* field attribute */
-
- work = i == 3 ?
- LOBYTE(u_block.iblock[6]) :
- LOBYTE(u_block.iblock[6] >> 8) ;
- itoa( work, work_buf, RADIX );
- incon_ret = InCon( block_ptr );
- work = atoi( work_buf );
- incon_ret |= (work > 255);
- if ( incon_ret == 0 )
- {
- cputs( work_buf );
- u_block.iblock[6] =
- i == 3 ?
- HIBYTE(u_block.iblock[6]) | LOBYTE(work) :
- LOBYTE(u_block.iblock[6]) | (work << 8) ;
- }
- break;
-
- case 5 : /* field fill char */
- case 6 : /* return string pad character */
-
- work = i == 5 ?
- LOBYTE(u_block.iblock[7]) :
- LOBYTE(u_block.iblock[7] >> 8) ;
- itoa( work, work_buf, RADIX );
- incon_ret = InCon( block_ptr );
- work = atoi( work_buf );
- incon_ret |= (work > 255);
- if ( incon_ret == 0 )
- {
- WriteMany( ' ', attr, 3 );
- if ( work == 32 || work == 255 )
- cprintf( "%3s", work == 32 ? "Sp" : "PSp" );
- else
- cprintf( "%2c", (BYTE) work );
- u_block.iblock[7] =
- i == 5 ?
- HIBYTE(u_block.iblock[7]) | LOBYTE(work) :
- LOBYTE(u_block.iblock[7]) | (work << 8) ;
- }
- break;
-
- case 7 : /* input type */
- case 8 : /* output justify */
-
- /****
- This block and the default block that follows first
- get the current value of the flag and use it to index
- the relevant string. The indexed character is handed
- to InCon for display as default input. The return
- value from InCon is then used to set the new value.
- ****/
-
- str_ptr_2 = (i == 7) ? TypeStr : JustStr ;
- work = u_block.iblock[4];
- if ( i == 7 )
- {
- work &= MASK_TYPE;
- work >>= SHIFT_TYPE;
- }
- else
- {
- work &= MASK_JUSTIFY;
- work >>= SHIFT_JUSTIFY;
- }
-
- #if (UPPER_LOWER)
- work <<= 1; /* index TypeStr or JustStr */
- work++;
- #endif
- *((WORD *) work_buf) = str_ptr_2[work]; /* put char and 0 */
- incon_ret = InCon( block_ptr );
- str_ptr_1 = strchr( str_ptr_2, (int) *work_buf );
- incon_ret |= (str_ptr_1 == NULL);
- if ( incon_ret == 0 )
- {
- work = str_ptr_1 - str_ptr_2; /* convert ptr to index */
-
- #if (UPPER_LOWER)
- work >>= 1; /* and index to flag */
- #endif
- /****
- Clear current value of flag, shift new value into
- position, and store new value.
- ****/
-
- if ( i == 7 )
- {
- u_block.iblock[4] &= ~MASK_TYPE;
- work <<= SHIFT_TYPE;
- }
- else
- {
- u_block.iblock[4] &= ~MASK_JUSTIFY;
- work <<= SHIFT_JUSTIFY;
- }
- u_block.iblock[4] |= work;
- } /* if (incon_ret) */
- break;
-
- default : /* all yes/no flags */
-
- work = u_block.iblock[4]; /* isolate flag */
- work >>= (MENU_ITEMS - i - 1);
- work &= 1;
-
- #if (UPPER_LOWER)
- work <<= 1; /* index NoYes */
- work++;
- #endif
- *((WORD *) work_buf) = NoYes[work];
- incon_ret = InCon( block_ptr );
- str_ptr_1 = strchr( NoYes, (int) *work_buf );
- incon_ret |= (str_ptr_1 == NULL);
- if ( incon_ret == 0 )
- {
- work = str_ptr_1 - NoYes; /* convert ptr to index */
-
- #if (UPPER_LOWER)
- work >>= 1; /* make yes/no flag */
- #endif
- /****
- First turn off each flag. Then, at the end
- of the switch block, shift the value of the
- answer from above into position and combine
- it with the flags already in place.
- ****/
-
- switch ( i )
- {
- case 9 : /* strip template */
- u_block.iblock[4] &= ~MASK_STRIP;
- break;
- case 10 : /* run-time messages */
- u_block.iblock[4] &= ~MASK_MESSAGE;
- break;
- case 11 : /* signed input */
- u_block.iblock[4] &= ~MASK_SIGN;
- break;
- case 12 : /* display default */
- u_block.iblock[4] &= ~MASK_DISPLAY;
- break;
- case 13 : /* confirm input */
- u_block.iblock[4] &= ~MASK_CONFIRM;
- break;
- case 14 : /* field delimiters */
- u_block.iblock[4] &= ~MASK_DELIMIT;
- break;
- case 15 : /* trap xKeys */
- u_block.iblock[4] &= ~MASK_XKEYS;
- break;
- case 16 : /* scroll field */
- u_block.iblock[4] &= ~MASK_SCROLL;
- break;
- case 17 : /* hidden input */
- u_block.iblock[4] &= ~MASK_HIDE;
- break;
- case 18 : /* template field */
- u_block.iblock[4] &= ~MASK_TEMPLATE;
- break;
- } /* switch() */
- work <<= (MENU_ITEMS - i - 1);
- u_block.iblock[4] |= work; /* store the flag */
- } /* if (incon_ret) */
- break;
- } /* switch() */
-
- /****
- If InCon returned the F1 key, put up the help window.
- If it returned [Tab], [Shift+Tab], one of the other
- keys from xKeyList, or a value invalid for the current
- field, do the menu-handling. The return from DemoMenu()
- must be decremented because i is incremented at the
- bottom of the for() loop.
- ****/
-
- if ( incon_ret != 0 )
- {
- if ( incon_ret == 59 )
- InHelp( help_attr );
- i = DemoMenu( i, incon_ret, attr, block_ptr, work_buf );
- --i;
- }
- } /* for (i) */
-
- /************************************************************************/
- /* Display the data that is being passed to InCon. From this point on */
- /* the message block is addressed as a structure. */
-
- #define TEXT_WINDOW1 1, 16, 80, 25 /* text window coordinates */
- #define TEXT_WINDOW2 1, 17, 80, 25
-
- window( TEXT_WINDOW1 );
- clrscr();
-
- block_ptr = &u_block; /* load user message block */
- strcpy( ioBuf, dPrompt ); /* load default string */
-
- flags = (BIT_FLAGS *)&block_ptr->sblock.Flags.bflags;
-
- /* extract pointer to i/o buffer from message block as further test */
-
- str_ptr_1 = (char *)MK_FP(
- block_ptr->sblock.BufSeg, block_ptr->sblock.BufOff );
-
- cprintf( "\r\n%s", str_ptr_1 ); /* print default string, using */
- /* far pointer from above */
-
- /**** Display window layout.
-
- Test Field___________________
- User Input___________________
- _____________________________
- _____________________________
- _____________________________
- ┌────────────────────────────────────────────────────────────────────────────┐
- │ INDEMO 3.1 Copyright (c) 1993-94, Richard Zigler │
- │ ioBuf segment:offset = XXXX:XXXX xKeyList segment:offset = XXXX:XXXX │
- │ Width: XX Prec: XX Visible: XX Attr: XX Fill: XX Pad: XX │
- │ Flags: B BBB BB B B B B B B B B B B Use [Numpad 5] to toggle Stat Box │
- └────────────────────────────────────────────────────────────────────────────┘
-
- ****/
-
-
- /****
- Build string of flags bit-values. incon_ret is used as
- an index here because it is free for the time being, and
- it is a register variable.
- ****/
-
- work = block_ptr->sblock.Flags.iflags;
- for ( i = 0x8000, incon_ret = 0 ; StatsFlags[incon_ret] ; incon_ret++ )
- {
- if ( StatsFlags[incon_ret] == 'B' )
- {
- work_buf[incon_ret] = work & i ? '1' : '0' ;
- (WORD) i >>= 1; /* need unsigned shift */
- }
- else
- work_buf[incon_ret] = ' ';
- }
- work_buf[incon_ret] = '\0';
- Cursor( OFF );
- gotoxy( 1, 5 );
- cprintf /* print stat box */
- (
- " ┌──────────────────────────────────────"
- "──────────────────────────────────────┐ "
- " │ %-37s%s │ "
- " │ ioBuf segment:offset = %.4X:%.4X"
- " xKeyList segment:offset = %.4X:%.4X │ "
- " │ Width: %.2X Prec: %.2X Visible: %.2X"
- " Attr: %.2X Fill: %.2X Pad: %.2X │ "
- " │ Flags: %-33sUse [Numpad 5] to toggle Stat Box │ "
- " └──────────────────────────────────────"
- "──────────────────────────────────────┘"
- , ProgName , Copyright
- , block_ptr->sblock.BufSeg , block_ptr->sblock.BufOff
- , block_ptr->sblock.KeySeg , block_ptr->sblock.KeyOff
- , block_ptr->sblock.Width , block_ptr->sblock.Prec
- , block_ptr->sblock.Visible , block_ptr->sblock.Attr
- , block_ptr->sblock.Fill , block_ptr->sblock.Pad
- , work_buf
- );
- Cursor( ON );
-
- /****
- Enable INCON Stat Box, which shows changes made to
- flags and parameters by field initialization. INCON
- displays its Stat Box only if INCON_STATS is non-zero
- when INCON.C is compiled and the Debug flag is set.
- ****/
-
- flags->Debug = YES;
-
- /************************************************************************/
- do /**** begin output loop ****/
- {
- int l; /* return string length */
-
- /****
- Call InCon with far pointer to message block. Put
- the cursor where the input field is to appear; InCon
- will determine the absolute cursor position for itself.
- Turn off Debug flag when InCon returns so that repeated
- calls to InCon from within this do...while block don't
- trigger display of the Stat Box each time. The __emit__
- statement sets a breakpoint for the debugger; it has no
- effect when the program is run from the command line.
- While InCon returns the F1 key code, display help screen.
- ****/
-
- window( TEXT_WINDOW1 );
- __emit__( 0xCC ); /* Int 03h */
-
- while ( (incon_ret = InCon( block_ptr )) == 59 )
- InHelp( help_attr );
- flags->Debug = NO;
- window( TEXT_WINDOW2 );
- clrscr();
-
- /****
- Print the contents of the i/o buffer, using the far pointer
- created above. The buffer now contains either the user's
- input (if there was no input error), or the original default
- string.
- ****/
-
- cputs( str_ptr_1 );
- gotoxy( 1, 5 ); /* print InCon return code and */
- cprintf /* length of input string */
- (
- "InCon returned: %d (%04Xh)\r\n"
- " Input length: %d\r\n"
- " Input value: "
- , incon_ret, incon_ret, l = strlen( str_ptr_1 )
- );
-
- /****
- Determine whether or not field type is float, and print
- value of return string. InCon may convert an integer
- field to float or an unsigned integer field to signed
- (see INCON.DOC), so check for '.' or '-' in ioBuf.
- ****/
-
- if ( !flags->Template && flags->Type & INTGR )
- {
- if ( strchr( ioBuf, '.' ) )
- {
- int p = block_ptr->sblock.Prec; /* p may be 0 if integer */
- /* converted to float */
- user_val.user_dbl = atof( ioBuf );
- cprintf( "%.*lf", p ? p : l, user_val.user_dbl );
- }
- else
- {
- user_val.user_long = strtol( ioBuf, (char **) 0, RADIX );
- cprintf( "%ld", user_val.user_long );
- }
- }
- else
- {
- user_val.user_long = strtoul( ioBuf, (char **) 0, RADIX );
- cprintf( "%lu", user_val.user_long );
- }
- strcpy( ioBuf, dPrompt ); /* reload default input string */
- gotoxy( 1, 9 );
- cputs( "Quit this test (y/n)? " );
- yn = LOBYTE(KEYREAD);
- }
- while ( yn != 'y' && yn != 'Y' ); /**** end output loop ****/
- /************************************************************************/
- window( TEXT_WINDOW1 );
- clrscr();
- gotoxy( 1, 10 );
- cputs( "Quit all tests (y/n)? " );
- yn = LOBYTE(KEYREAD);
- clrscr();
- }
- while ( yn != 'y' && yn != 'Y' ); /**** end input loop ****/
- free( work_buf );
- }
-
- /************************************************************************/
- /* DemoMenu() -- menu-handling for main(). */
-
- static int pascal DemoMenu( int MenuItem, int InconRet,
- int Attr, MBLOCK far * Block, char * String )
- {
- register int i = MenuItem,
- work,
- field_width,
- delimit;
-
- delimit = Block->sblock.Flags.bflags.Delimit;
- field_width = Block->sblock.Width + (delimit ? 2 : 0);
-
- switch( i ) /* reprint current field value */
- {
- case 0: /* default input string */
- clreol();
- cprintf( "%-.*s", MAXCOL, String );
- break;
- case 1: /* numeric fields */
- case 2:
- case 3:
- case 4:
- cprintf( "%*s", field_width, String );
- break;
- case 5: /* fill character */
- case 6: /* pad character */
- work = atoi( String );
- WriteMany( ' ', Attr, 3 );
- if ( work == 32 || work == 255 )
- cprintf( "%*s", field_width, work == 32 ? "Sp" : "PSp" );
- else
- cprintf( "%2c", (BYTE)work );
- break;
- default: /* Type, Justify, yes/no flags */
- if ( delimit )
- cprintf( "[%c]", *String );
- else
- cprintf( "%*s", field_width, String );
- break;
- }
-
- /****
- Now tell main() where to go. Invalid entries stay
- with current menu item.
- ****/
-
- if ( InconRet == 9 ) /* [Tab] -- go ahead */
- {
- if ( ++i >= MENU_ITEMS ) /* at last item */
- i = 0; /* go to first */
- }
- else if ( InconRet == 15 ) /* [Shift+Tab] -- back up */
- {
- if ( --i < 0 ) /* at first item */
- i += MENU_ITEMS; /* go to last */
- }
- return ( i );
- }
-
- /**** EOF: INDEMO.C ****/