home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
PRINTING
/
PSFIX.ZIP
/
STRLIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-28
|
30KB
|
1,337 lines
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * */
/* * strlib.c library of string-manipulating functions * */
/* * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * Marc A. Murison * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/*
* This software may be freely distributed under the following conditions:
* 1. It is distributed in its current form, without alterations.
* 2. No monetary profit is made, under any circumstances.
*
* Marc A. Murison
* Smithsonian Astrophysical Observatory
* 60 Garden Street, MS 63
* Cambridge, MA 02138
*
* (617) 495-7079 murison@cfacx2.harvard.edu
*/
#define global extern
#define STRLIB_C
#define KEY_CODES
#include "strlib.h"
#ifdef __TURBOC__
/*-----------------------------------------------------------------------------
* text buffer browse utility
*
* returns 0 if unable to allocate enough memory for storing current text
* screen; 1 otherwise
*---------------------------------------------------------------------------*/
Boolean browse( char *text, char *title )
{
unsigned size;
int i, top_line, bot_line, nlines;
Key_Code key;
Boolean start_text, end_text, extended;
char *old_screen, *lp_top, *lp_bot, *end_of_text;
char *info_bar = "* Quit: Q Esc * "
"Up: Enter Up PgUp Home * "
"Down: Space Dn PgDn End *";
enum colors text_fg, text_bkg, title_fg, title_bkg,
info_fg, info_bkg;
struct text_info current;
/* assign colors */
text_fg = BLACK;
text_bkg = LIGHTGRAY;
title_fg = WHITE;
title_bkg = RED;
info_fg = WHITE;
info_bkg = RED;
/* save current text screen */
gettextinfo( ¤t );
size = ((current.screenheight*current.screenwidth*2) / 1000) * 1024;
old_screen = cvector( 0, size-1 );
if( old_screen == NULL ) return FALSE;
gettext( 1, 1, current.screenwidth, current.screenheight, old_screen );
/* find the end of the input text (for use in paging down) */
end_of_text = text;
while( *end_of_text ) ++end_of_text;
/* write the title bar */
_setcursortype( _NOCURSOR );
window( 1, 1, current.screenwidth, 1 );
textcolor( title_fg );
textbackground( title_bkg );
clrscr();
i = 1 + (current.screenwidth - strlen( title )) / 2;
gotoxy( i, 1 );
while( *title ) { putchar(*title); ++title; }
/* write the info bar */
window( 1, current.screenheight, current.screenwidth, current.screenheight);
textcolor( info_fg );
textbackground( info_bkg );
clrscr();
i = 1 + (current.screenwidth - strlen( info_bar )) / 2;
gotoxy( i, 1 );
while( *info_bar ) { putchar(*info_bar); ++info_bar; }
/* side borders */
window( 1, 2, 1, current.screenheight-1 );
clrscr();
window( current.screenwidth, 2,
current.screenwidth, current.screenheight-1 );
clrscr();
/* define new window */
window( 2, 2, current.screenwidth-1, current.screenheight-1 );
textcolor( text_fg );
textbackground( text_bkg );
clrscr();
gotoxy( 1, 1 );
top_line = 1;
bot_line = current.screenheight - 2;
nlines = bot_line - top_line + 1;
/* print the first screenful of text */
lp_top = text;
lp_bot = text;
for( i=0; i < nlines; i++ ) {
gotoxy( 1, top_line+i );
cprint_line( OFF, &lp_bot );
}
start_text = TRUE;
if( *lp_bot == NULL )
end_text = TRUE;
else
end_text = FALSE;
/* interpret keystrokes */
extended = ON;
key = KEY_CR; /* dummy start value */
while( BROWSE_KEY( extended, key ) ) {
i = getch();
if( i == 0 ) {
extended = ON;
key = (Key_Code) getch();
} else {
extended = OFF;
key = (Key_Code) i;
}
/* scroll window up */
if( (key == KEY_UP && extended) || key == KEY_CR ) {
if( !start_text ) {
/* insert a blank line at the top */
gotoxy( 1, top_line );
insline();
clreol();
/* point to previous text line */
if( !prev_line( &lp_top, text ) ) start_text = TRUE;
/* print the previous text line */
cprint_line( OFF, &lp_top );
prev_line( &lp_top, text ); /* but don't advance */
end_text = FALSE;
/* update bottom line pointer */
prev_line( &lp_bot, text );
}
/* scroll window down */
} else if( (key == KEY_DN && extended) || key == KEY_SP ) {
if( !end_text ) {
/* delete the top line and scroll window contents up */
gotoxy( 1, top_line );
delline();
/* print next line of text */
gotoxy( 1, bot_line );
clreol();
cprint_line( OFF, &lp_bot );
if( *lp_bot == NULL ) end_text = TRUE;
start_text = FALSE;
/* update top line pointer */
next_line( &lp_top );
}
/* page window up */
} else if( key == KEY_PGUP && extended ) {
if( !start_text ) {
clrscr();
for( i=0; i < nlines; i++ ) prev_line( &lp_top, text );
if( lp_top <= text ) {
lp_top = text;
start_text = TRUE;
} else
start_text = FALSE;
lp_bot = lp_top;
for( i=0; i < nlines; i++ ) {
gotoxy( 1, top_line+i );
cprint_line( OFF, &lp_bot );
}
if( lp_bot >= end_of_text )
end_text = TRUE;
else
end_text = FALSE;
}
/* page window down */
} else if( key == KEY_PGDN && extended ) {
if( !end_text ) {
clrscr();
for( i=0; i < nlines; i++ ) next_line( &lp_bot );
if( lp_bot >= end_of_text ) {
lp_top = end_of_text;
for( i=0; i < nlines; i++ ) prev_line( &lp_top, text );
end_text = TRUE;
} else
for( i=0; i < nlines; i++ ) next_line( &lp_top );
start_text = FALSE;
lp_bot = lp_top;
for( i=0; i < nlines; i++ ) {
gotoxy( 1, top_line+i );
cprint_line( OFF, &lp_bot );
}
}
/* home */
} else if( key == KEY_HOME && extended ) {
if( !start_text ) {
clrscr();
lp_top = text;
lp_bot = text;
for( i=0; i < nlines; i++ ) {
gotoxy( 1, top_line+i );
cprint_line( OFF, &lp_bot );
}
start_text = TRUE;
if( *lp_bot == NULL )
end_text = TRUE;
else
end_text = FALSE;
}
/* end */
} else if( key == KEY_END && extended ) {
if( !end_text ) {
clrscr();
lp_top = end_of_text;
for( i=0; i < nlines; i++ ) prev_line( &lp_top, text );
if( lp_top <= text ) {
lp_top = text;
start_text = TRUE;
}
else
start_text = FALSE;
lp_bot = lp_top;
for( i=0; i < nlines; i++ ) {
gotoxy( 1, top_line+i );
cprint_line( OFF, &lp_bot );
}
end_text = TRUE;
}
}
}
/* restore old screen */
window( 1, 1, current.screenwidth, current.screenheight );
puttext( 1, 1, current.screenwidth, current.screenheight, old_screen );
gotoxy( current.curx, current.cury );
_setcursortype( _NORMALCURSOR );
return TRUE;
}
#endif
/*-----------------------------------------------------------------------------
* Boolean next_line( char **bp )
*
* advance buffer pointer to character after next newline character
*
* contents of bp updated to new position in buffer, which is the first
* character after the next newline
*
* returns: 1 successful
* 0 NULL encountered
*---------------------------------------------------------------------------*/
Boolean next_line( char **bp )
{
/* go to next newline character */
if( !end_line( bp ) ) return FALSE;
/* next character after that */
++(*bp);
if( **bp == NULL )
return FALSE;
else
return TRUE;
}
/*-----------------------------------------------------------------------------
* Boolean prev_line( char **bp, char *buffer )
*
* move buffer pointer to character before previous newline character
*
* contents of bp updated to new position in buffer, which is the first
* character after the newline beginning the previous line
*
* returns: 1 successful
* 0 beginning of buffer encountered
*---------------------------------------------------------------------------*/
Boolean prev_line( char **bp, char *buffer )
{
/*
* special case:
* if we're sitting on a newline, and the previous 2 chars are newlines,
* move to the middle newline
*/
if( **bp == NEWLINE && *(*bp-1) == NEWLINE && *(*bp-2) == NEWLINE ) {
--(*bp);
if( *bp <= buffer ) { *bp = buffer; return FALSE; }
return TRUE;
}
/*
* special case:
* if we're sitting on a newline, and the preceding char is a newline but the
* next preceding one isn't, move to before the newlines and then to the
* beginning of that line
*/
if( **bp == NEWLINE && *(*bp-1) == NEWLINE ) {
*bp -= 2;
if( *bp <= buffer ) { *bp = buffer; return FALSE; }
if( !beg_line( bp, buffer ) ) {
if( **bp == NEWLINE ) { /* 1st char of buffer = '\n' */
++(*bp);
return TRUE;
} else
return FALSE;
}
++(*bp);
return TRUE;
}
/*
* normal case:
*/
/* move to beginning of current line */
if( !beg_line( bp, buffer ) ) return FALSE;
/* move to beginning of previous line (1st char after newline) */
--(*bp);
if( *bp < buffer ) { *bp = buffer; return FALSE; }
if( !beg_line( bp, buffer ) ) {
if( **bp == NEWLINE ) { /* 1st char of buffer = '\n' */
++(*bp);
return TRUE;
} else
return FALSE;
}
++(*bp);
return TRUE;
}
/*-----------------------------------------------------------------------------
* Boolean beg_line( char **bp, char *buffer )
*
* move buffer pointer to preceding newline character
*
* contents of bp updated to new position in buffer, which is the
* the newline beginning the current line
*
* returns: 1 successful
* 0 beginning of buffer encountered
*---------------------------------------------------------------------------*/
Boolean beg_line( char **bp, char *buffer )
{
char *p;
p = *bp;
if( p <= buffer ) { *bp = buffer; return FALSE; }
while( *p != NEWLINE ) {
--p;
if( p <= buffer ) { *bp = buffer; return FALSE; }
}
*bp = p;
return TRUE;
}
/*-----------------------------------------------------------------------------
* Boolean end_line( char **bp )
*
* move buffer pointer to next newline character
*
* contents of bp updated to new position in buffer, which is the next
* newline
*
* returns: 1 successful
* 0 end of buffer (NULL) encountered
*---------------------------------------------------------------------------*/
Boolean end_line( char **bp )
{
char *p;
p = *bp;
if( *p == NULL ) return FALSE;
while( *p != NEWLINE ) {
++p;
if( *p == NULL ) { *bp = p; return FALSE; }
}
*bp = p;
return TRUE;
}
/*-----------------------------------------------------------------------------
*
* announce program version and date
*
*---------------------------------------------------------------------------*/
void announce( char *version_string, char *date_string )
{
#ifdef __MSDOS__
int vlength, dlength, i;
#else
int vlength, dlength, i, k;
#endif
vlength = strlen( version_string );
dlength = strlen( date_string );
#ifdef __MSDOS__
if( dlength > 0 ) {
printf( "\n\xc9" );
for( i=0; i < vlength+4; i++ ) printf( "\xcd" );
printf( "\xd1" );
for( i=0; i < dlength+4; i++ ) printf( "\xcd" );
printf( "\xbb\n\xba %s \xb3 %s \xba",
version_string, date_string );
printf( "\n\xc8" );
for( i=0; i < vlength+4; i++ ) printf( "\xcd" );
printf( "\xcf" );
for( i=0; i < dlength+4; i++ ) printf( "\xcd" );
printf( "\xbc\n" );
} else {
printf( "\n\xc9" );
for( i=0; i < vlength+4; i++ ) printf( "\xcd" );
printf( "\xbb\n\xba %s \xba", version_string );
printf( "\n\xc8" );
for( i=0; i < vlength+4; i++ ) printf( "\xcd" );
printf( "\xbc\n" );
}
#else
if( dlength > 0 ) {
k = (dlength+vlength+8+1)/2;
printf( "\n*" );
for( i=0; i < k; i++ ) printf( " *" );
if( IS_EVEN(dlength+vlength) )
printf( "\n* %s * %s *", version_string, date_string );
else
printf( "\n* %s * %s *", version_string, date_string );
printf( "\n*" );
for( i=0; i < k; i++ ) printf( " *" );
printf( "\n" );
} else {
k = (vlength+4+1)/2;
printf( "\n*" );
for( i=0; i < k; i++ ) printf( " *" );
if( IS_EVEN(vlength) )
printf( "\n* %s *", version_string );
else
printf( "\n* %s *", version_string );
printf( "\n*" );
for( i=0; i < k; i++ ) printf( " *" );
printf( "\n" );
}
#endif
return;
}
/*-----------------------------------------------------------------------------
*
* convert string buffer to upper case
*
*---------------------------------------------------------------------------*/
char *upcase( char *string )
{
char *p;
p = string;
while( *p ) { *p = UPPER( *p ); p++; }
return string;
}
/*-----------------------------------------------------------------------------
*
* convert string buffer to lower case
*
*---------------------------------------------------------------------------*/
char *dncase( char *string )
{
char *p;
p = string;
while( *p ) { *p = LOWER( *p ); p++; }
return string;
}
/*-----------------------------------------------------------------------------
* char *itoh( int i, char *string )
*
* convert an integer to a string of hex characters
*---------------------------------------------------------------------------*/
char *itoh( int i, char *string )
{
int k;
int j;
char *p;
/* load the character string with hex values */
p = string;
*p = NULL;
if( i < 0 ) return string;
k = i;
if( k == 0 ) {
*p++ = itohc( k );
*p = NULL;
} else {
while( k > 0 ) {
j = k % HEX_RADIX;
*p++ = itohc( j );
k /= HEX_RADIX;
}
*p = NULL;
/* mirror flip */
p = string;
sflip( p );
}
return string;
}
/*-----------------------------------------------------------------------------
* char *ltoh( long i, char *string )
*
* convert a long integer to a string of hex characters
*---------------------------------------------------------------------------*/
char *ltoh( long i, char *string )
{
long k;
int j;
char *p;
/* load the character string with hex values */
p = string;
*p = NULL;
if( i < 0 ) return string;
k = i;
if( k == 0 ) {
*p++ = itohc( (int)k );
*p = NULL;
} else {
while( k > 0 ) {
j = (int) (k % HEX_RADIX);
*p++ = itohc( j );
k /= HEX_RADIX;
}
*p = NULL;
/* mirror flip */
p = string;
sflip( p );
}
return string;
}
/*-----------------------------------------------------------------------------
* char itohc( int i )
*
* convert an integer in the range 0 <= i <= 15 to a hex character
*---------------------------------------------------------------------------*/
char itohc( int i )
{
char *p = "0123456789ABCDEF";
if( i < 0 || i > 15 )
return NULL;
else
return p[i];
}
/*-----------------------------------------------------------------------------
* char *sflip( char *string )
*
* mirror-flip a string of characters
*---------------------------------------------------------------------------*/
char *sflip( char *string )
{
char *p1, *p2;
/* point to first and last characters */
p1 = string;
while( *p1 ) ++p1;
p2 = p1 - 1;
p1 = string;
/* swap characters */
while( p2 > p1 ) {
SWAP( *p1, *p2 );
++p1;
--p2;
}
return string;
}
/*-----------------------------------------------------------------------------
*
* left justify a text string
*
*---------------------------------------------------------------------------*/
char *ljust( char *string )
{
char *sp, *p;
if( *string != BLANK && *string != TAB ) return string;
/* skip white */
sp = string;
while( *sp == BLANK || *sp == TAB && *sp ) ++sp;
/* move */
p = string;
while( *sp ) *p++ = *sp++;
*p = NULL;
return string;
}
/*-----------------------------------------------------------------------------
* struct tab_info expand_tabs( int n, char *in_ptr, char *out_ptr
* long maxchars )
*
* Function to expand the tabs in *in_ptr and put the result into
* *out_ptr. The number of spaces that will be put in place of tabs
* is n
*
* expand_tabs returns the number of tab substitutions performed and the
* number of spaces inserted. If the output buffer is too small, values
* of -1 are returned instead
*---------------------------------------------------------------------------*/
Tab_Info expand_tabs( int n, char *in_ptr, char *out_ptr, long maxchars )
{
int npos = 0; /* position from beginning of instring */
/* or from last '\n' */
int nfill, i;
long char_count = 0;
char c, *in, *out;
Tab_Info count;
count.ntabs = 0;
count.nspaces = 0;
in = in_ptr;
out = out_ptr;
c = *in;
while( c != NULL ) {
++npos;
++char_count;
if( char_count > maxchars ) {
count.ntabs = -1;
count.nspaces = -1;
return count;
}
if( c == TAB ) { /* found a tab */
++count.ntabs;
if( n != 0 ) { /* skip if tab = 0 spaces */
/* spaces to next tab stop */
nfill = ( ((npos-1) / n) + 1 ) * n + 1 - npos;
/* check for possible overflow */
char_count += nfill - 1;
if( char_count > maxchars ) {
count.ntabs = -1;
count.nspaces = -1;
return count;
}
c = BLANK;
for( i=0; i < nfill; i++) *out++ = c;
npos += nfill - 1;
count.nspaces += nfill;
}
} else {
if( c == NEWLINE ) npos = 0;
*out++ = *in;
}
c = *(++in);
}
*out = NULL;
return count;
}
/*-----------------------------------------------------------------------------
* Boolean next_word( char **bp, char *word, int *n )
*
* retrieve next word from a buffer
*
* A word is assumed to consist of sequential alphanumeric characters or
* an underscore. Anything else is a word delimiter
*
* entry: bp pointer to the address of the input buffer pointer
*
* exit: word contents of next word
* n number of characters in word, excluding the NULL
* *bp points to 1st char after word
*
* returns: 1 successful
* 0 NULL encountered
*---------------------------------------------------------------------------*/
Boolean next_word( char **bp, char *word, int *n )
{
char *wp;
/* skip to next word */
wp = word;
*n = 0; *wp = NULL;
while( !WORD_CHAR( **bp ) && **bp ) ++(*bp);
if( **bp == NULL ) return FALSE;
/* transfer a word */
*n = 1; *wp++ = **bp; ++(*bp); /* 1st character */
while( WORD_CHAR( **bp ) ) {
*wp++ = **bp;
++(*n);
++(*bp);
}
*wp = NULL;
return TRUE;
}
/*-----------------------------------------------------------------------------
* Boolean next_word_num( char **bp, char *word, int *n )
*
* retrieve next word from a buffer (word can also be a number)
*
* A word is assumed to consist of sequential alphanumeric characters or
* any of the following special characters: . + - _
* Anything else is a word delimiter
*
* entry: bp pointer to the address of the input buffer pointer
*
* exit: word contents of next word
* n number of characters in word, excluding the NULL
* *bp points to 1st char after word
*
* returns: 1 successful
* 0 NULL encountered
*---------------------------------------------------------------------------*/
Boolean next_word_num( char **bp, char *word, int *n )
{
char *wp;
/* skip to next word */
wp = word;
*n = 0; *wp = NULL;
while( !WORD_NUM_CHAR( **bp ) && **bp ) ++(*bp);
if( **bp == NULL ) return FALSE;
/* transfer a word */
*n = 1; *wp++ = **bp; ++(*bp); /* 1st character */
while( WORD_NUM_CHAR( **bp ) ) {
*wp++ = **bp;
++(*n);
++(*bp);
}
*wp = NULL;
return TRUE;
}
/*-----------------------------------------------------------------------------
* Boolean is_blank( char *string )
*
* test character string for emptiness
*
* returns: 1 string is empty or contains only blanks or tabs
* 0 string is not empty
*---------------------------------------------------------------------------*/
Boolean is_blank( char *string )
{
char *sp;
sp = string;
while( *sp ) {
if( *sp != BLANK && *sp != TAB ) return FALSE;
++sp;
}
return TRUE;
}
/*-----------------------------------------------------------------------------
* Write a message to stdout
*
* The line after the message is cleared
* Cursor is left at column
* If nextline = TRUE, a linefeed is printed before the message
* If lineafter = TRUE, a linefeed is printed after the message
*
*---------------------------------------------------------------------------*/
void print_msg( Boolean nextline, Boolean lineafter, int n, ... )
{
char *sp;
register int i;
int k, length;
va_list argp;
if( nextline ) putchar( NEWLINE );
length = 0;
putchar(CR);
va_start( argp, n );
for( k=0; k < n; k++ ) {
sp = va_arg( argp, char * );
printf( "%s", sp );
length += strlen(sp);
}
va_end(argp);
for( i=0; i < 79 - length; i++ ) putchar(BLANK);
putchar(CR);
if( lineafter ) putchar( NEWLINE );
fflush( stdout );
}
/*-----------------------------------------------------------------------------
* void moreprint( char *string )
*
* Function to print the message in *string to the screen, pausing every
* (TEXT_ROWS - 1) lines (similar to the Unix more utility)
*
*---------------------------------------------------------------------------*/
void moreprint( char *string )
{
register int i;
char c, *strp;
#if __TURBOC__
char *msg = "<*>Press any key (q to quit)";
#else
char *msg = "<*>Press ENTER to continue (Q ENTER to quit)";
#endif
strp = string;
#if __TURBOC__
while( *strp ) {
/* output one screenful of text */
clrscr();
for( i = 0; *strp && i < TEXT_ROWS - 1; i++ )
print_line( ON, &strp );
/* "more" */
if( i == TEXT_ROWS - 1 ) {
if( *strp == NULL ) putchar( NEWLINE );
c = moreprint_pause( msg );
if( c == 'q' || c == 'Q' ) {
putchar( NEWLINE );
return;
}
}
}
/* final pause */
while( i < TEXT_ROWS-1 ) { ++i; putchar( NEWLINE ); }
c = moreprint_pause( msg );
#else
while( *strp ) {
/* output one screenful of text */
for( i = 0; *strp && i < TEXT_ROWS - 2; i++ )
print_line( ON, &strp );
/* "more" */
if( i == TEXT_ROWS - 2 ) {
if( *strp == NULL ) putchar( NEWLINE );
c = moreprint_pause( msg );
if( c == 'q' || c == 'Q' ) {
putchar( NEWLINE );
return;
}
}
}
/* final pause */
while( i < TEXT_ROWS-2 ) { ++i; putchar( NEWLINE ); }
c = moreprint_pause( msg );
#endif
return;
}
/*-----------------------------------------------------------------------------
* char moreprint_pause( char *msg )
*
* Function to put a "press any key" message on the screen and wait for
* a keypress. Message text is in *msg, and it has to contain an asterisk
* if this is being compiled with TURBO C
*
* This function is designed for use by moreprint
*
* Returns the first character pressed
*---------------------------------------------------------------------------*/
char moreprint_pause( char *msg )
{
char c, *p;
int i1;
/* print the "pause" message */
p = msg;
while( *p ) { putchar(*p); ++p; }
putchar( CR );
/* wait for a keypress */
#if __TURBOC__
/* blink the asterisk */
i1 = (int) ( strchr( msg, '*' ) - msg + 1 );
_setcursortype( _NOCURSOR );
while( !kbhit() ) {
/* off */
gotoxy( i1, TEXT_ROWS );
putchar( BLANK );
delay( 100 );
/* on */
gotoxy( i1, TEXT_ROWS );
putchar( '*' );
delay( 100 );
}
/* erase the "pause" message */
p = msg;
putchar( CR );
while( *p++ ) putchar( BLANK );
putchar( CR );
/* quit now? */
c = (char) getch();
while( kbhit() != 0 ) getch(); /* flush extra key hits */
_setcursortype( _NORMALCURSOR );
if( c == 'q' || c == 'Q' ) {
putchar( NEWLINE );
return c;
}
#else
/* simulate kbhit() */
c = getc(stdin);
/* erase the "pause" message */
p = msg;
putchar( CR );
while( *p++ ) putchar( BLANK );
putchar( BLANK );
putchar( CR );
#endif
return c;
}
/*-----------------------------------------------------------------------------
* void print_line( int crlf, char **text_ptr )
*
* print one line of text to the stdout device (including CR+LF if crlf
* is ON)
*
* input: text_ptr Pointer to the address of a pointer in the calling
* program into the text buffer. Output starts from
* the position in the text buffer pointed to by the
* contents of text_ptr
*
* output: text_ptr The contents of text_ptr, which in turn is a
* pointer, is updated to the address of the new
* position in the text buffer after the line has
* written. This new position is the byte after a
* newline has been encountered
*---------------------------------------------------------------------------*/
void print_line( int crlf, char **text_ptr )
{
char *p;
p = *text_ptr;
while( *p != NEWLINE && *p ) putchar( *p++ );
if( *p == NEWLINE ) {
++p;
if( crlf ) {
putchar(CR);
putchar(LF);
}
}
*text_ptr = p;
return;
}
#ifdef __TURBOC__
/*-----------------------------------------------------------------------------
*
* console version of print_line
*
*---------------------------------------------------------------------------*/
void cprint_line( int crlf, char **text_ptr )
{
char *p;
p = *text_ptr;
while( *p != NEWLINE && *p ) putch( *p++ );
if( *p == NEWLINE ) {
++p;
if( crlf ) {
putch(CR);
putch(LF);
}
}
*text_ptr = p;
return;
}
#endif
/*-----------------------------------------------------------------------------
* void parse_args( char string[], int *nargs, double args[] )
*
* Function to parse (double) floating arguments from a null-terminated
* string buffer
*
* entry: string[] null-terminated string containing numbers to
* decode
*
* exit: *nargs number of numbers decoded
* args[] vector containing decoded (double) floating
* numbers
*
* function dependencies: none
* header files: ctype.h, stdio.h
*---------------------------------------------------------------------------*/
#ifndef NO_FLOAT
void parse_args( char string[], int *nargs, double args[] )
{
int i, j, k, do_flag;
char c, *tmpstr;
double fnum;
tmpstr = cvector( 0, 80 );
if( *string == NULL )
*nargs = 0;
else {
*nargs = 0; i = 0; do_flag = 1;
while( string[i] != NULL && do_flag ) {
/* skip leading white space */
while( isspace( string[i] ) ) i++;
/* put number into tmpstr */
j = 0;
while( string[i] != NULL && !isspace((c = string[i])) ) {
tmpstr[j++] = c;
i++;
}
/* decode number in tmpstr */
if( j > 0 ) {
tmpstr[j] = NULL;
fnum = atof( tmpstr );
/* valid number was returned */
if( fnum != 0.0 ) {
args[*nargs] = fnum;
(*nargs)++;
/* zero returned--check for an actual zero */
} else {
k = 0;
if( (c=tmpstr[k]) == '+' || c == '-' ) k++;
if( (c=tmpstr[k]) != '0' ) {
if( c != '.' )
do_flag = 0; /* not a number */
else { /* is a decimal point */
while( (c=tmpstr[++k]) == '0' );
if( c == NULL || isspace(c) ) {
args[*nargs] = fnum;
(*nargs)++;
} else { /* check for e- or d-floating */
if( c == 'e' || c == 'E' ||
c == 'd' || c == 'D' ) {
args[*nargs] = fnum;
(*nargs)++;
} else
do_flag = 0; /* not a number */
} /* e- or d-floating format check */
} /* is a decimal point */
} /* 1st char != 0 */
else { /* 1st char = '0' */
while( (c=tmpstr[++k]) == '0' );
if( c == NULL || isspace(c) ) {
args[*nargs] = fnum;
(*nargs)++;
} else { /* check for decimal point */
if( c == '.' ) {
while( (c=tmpstr[++k]) == '0' );
if( c == NULL || isspace(c) ) {
args[*nargs] = fnum;
(*nargs)++;
} else { /* check for e- or d-floating */
if( c == 'e' || c == 'E' ||
c == 'd' || c == 'D' ) {
args[*nargs] = fnum;
(*nargs)++;
} else
do_flag = 0; /* not a number */
} /* e- or d-floating format check */
} /* is a decimal point */
else {
if( c == 'e' || c == 'E' ||
c == 'd' || c == 'D' ) {
args[*nargs] = fnum;
(*nargs)++;
} else
do_flag = 0; /* not a number */
} /* not a d.p., e- or d-floating check */
} /* decimal point check */
} /* 1st char = '0' */
} /* check for actual zero */
} /* j > 0 (input string not empty) */
} /* decoding loop */
} /* input string not NULL */
free_cvector( tmpstr, 0 );
return;
}
#endif