Category : C Source Code
Archive   : WTWG12B.ZIP
Filename : WFSCANFM.C

 
Output of file : WFSCANFM.C contained in archive : WTWG12B.ZIP
/* wfscanfm.c
* procedure: wfscanform(FILE *infile, WFORM *form, char *stopcode)
*
* This procedure is a file-header parser.
* Text files are read and each line is checked to see if
* it matches an item in the WFORM table. If so, the data is
* formatted and placed in the calling program's storage area
* ...as indicated by the table.
*
* The input file may be in the format:
* KEYWORDdata\r\n
* KEYWORDdata\r\n
* STOPCODE\r\n
* The KEYWORD may have a punctuation mark or whitespace at the end,
* these are ignored for the purposes of comparison.
* So the file may be in any of the following forms:
* KEYWORD: filedata\r\n
* KEYWORD:filedata\r\n
* KEYWORD filedata\r\n
* KEYWORD-filedata\r\n
* KEYWORD$ filedata\r\n
*
*
* ONLY 1 punctuation mark may be used as a delimiter,
* but it doesn't have to be the same one each time.
*
*
* in each of these cases, the data that will be returned
* will be 'filedata' without the punctuation or leading space.
*
* However, if no delimiter or space is indicated in the WFORM label,
* then any delimiter found will be included in the data.
*
* Data may continue to the next line if the last line is a + - or \
* ex: col 0123456789....
* KEYWORD: This is dat+\r\n
* a for the program\r\n
* will be read as This is data for the program.
*
*
* Open the input file in either text or binary mode,
* This routine actively ignores \n\r
* and does not depend on fgets() to remove these codes.
*
*
* If a KEYWORD is not found in the file, no values are moved to the
* calling program's data area.
*
* Input stops on FEOF or on an input line entirely contained in STOPCODE
*
* OK if you specify STOPCODE as DATA: and the input line is DATA\r\n
* or if the input line is DATA:\r\n and stopcode is just DATA
*
* ie: ok for a single punct. mark at end of stopcode or input line
* for a header record, STOPCODE might be DATA: or DATA- or DATA
*
* to display the KEYWORDdata information onscreen, use the same WFORM[]
* and call WPRINTFORM ()
* to create compatible file headers, use the same WFORM[]
* and call WFPRINTFORM[]
*
*
*
*
*/


#include "wsys.h"


#define wftype wfspecial




/* static function:
* read input from infile,
* piece together continuation lines,
* check for stopcode. RETURNS: zero if no more data to check.
*/
static int do_another( FILE *infile, char *buffer,
int buffsize, char *stopcode );





void wfscanform ( FILE *infile, WFORM *form, char *stopcode )
{
char *buffer;
WFORM *item, *firstentry;
int n, buffsize, lbl_len;
char *data_ptr,
*userend;



_NORMALIZE (form);



firstentry = form;

item = firstentry;

/* scan form, fill in data types, figure out longest data element
*/


for ( item = firstentry, buffsize = 0;
item->wflabel != NULL;
++item
)
{
_NORMALIZE (item->wfuser);
_NORMALIZE (item->wflabel);
_NORMALIZE (item->wformat);

/* find the longest piece of data (plus size of it's label
*/

n= strlen (item->wflabel) + item->wflen;
if ( buffsize < n )
{
buffsize = n;
}


/* check data type against supported types,
* move single char type into form table
*/
item->wftype = *(item->wformat +
strcspn ( item->wformat, "csidfegEGouxX") );

} /* end for... scanning table ... */




buffsize += 256; /* add enough to cover longest line */
buffer = wmalloc ( buffsize, "WFSCANFORM" );



while ( do_another ( infile, buffer, buffsize, stopcode ) )
{
for ( item = firstentry; item-> wflabel != NULL; ++item )
{
lbl_len = strlen (item->wflabel);

/* ignore punctuation marks and whitespace
* at the end of the label
*/
while( --lbl_len &&
( ispunct( item->wflabel[ lbl_len ] )
|| isspace (item->wflabel[ lbl_len ] )
)
)
{ /* empty */
}
++lbl_len;




if (memicmp ( item->wflabel, buffer, lbl_len ) ==0 )
{
/* line in file matches line in form
*/
data_ptr = buffer + lbl_len; /* pt past label */

/* skip whitespace and punctuation between label and data.
*/
while ( ispunct( *data_ptr ) || isspace ( *data_ptr ) )
{
++data_ptr;
}

if ( *data_ptr == 0 )
{
/* skip NULL entry */
}
else
if (item ->wfuser) /* not a pure label, so get data */
{
/* update user data from buffer
*/
switch ( item ->wftype )
{
case ( 'c' ):
*((char*)item->wfuser)
= *data_ptr;
break;
case ( 's' ):

memcpy(
(char*)(item->wfuser),
data_ptr,
item->wflen );

/* make sure string has a
* terminal NULL
*/
userend =((char*)item->wfuser)
+ (item->wflen)-1;

*userend = 0;


break;
default:
sscanf (data_ptr,
item->wformat,
item->wfuser);
}/* end switch */

/* end of updating */
} /* end non-NULL data */

} /* end if... data matches from line */

} /* end for... item */
} /* end while... infile */

free (buffer);

return; /* wfscanform */
}


/* do_another()
* static routine that reads one line,
* strips any DOS end-line characters,
*
* concateneates next line if last line ended with a continuation mark.
*
* RETURNS 0 if end of file or stopcode
* 1 if need to read more.
*/
static int do_another( FILE *infile, char *buffer,
int buffsize, char *stopcode )
{

int retcode;
int inlen;
int remaining;
int keep_going;
register int actual_inlen;



inlen =0;
retcode = 1;

do {

remaining = buffsize - inlen;

fgets ( buffer + inlen, remaining, infile );

if ( feof (infile) )
{
keep_going = retcode = 0; /* don't do any more */
}
else
{

/* strip any \n or \r or terminal spaces from end of string
* (there may be two of these (\n and \r)
* in either order
*/
inlen = strlen (buffer) -1;
while ( inlen >0 && isspace(buffer[inlen]) )
{
--inlen;
}

/* is this a continuation line ?
*/
switch ( buffer[inlen] )
{
case ('+'):
case ('-'):
case ('\\'):
keep_going = 1;
/* NOTE: by not advancing inlen,
* terminal NULL will be placed on the continuation mark.
*/
default:
keep_going = 0;

/* inlen now points to last letter,
* move forward to terminal NULL
*/
++inlen;
}

/* ensure that terminal NULL is in correct place.
*/
buffer[inlen] = 0;

}


}
while ( keep_going ); /* read continuation lines */

/* now look for 'stopcode'.
* allow a punct. mark after stopcode, so check for actual length to compare
*/
actual_inlen = inlen-1;
if ( ispunct ( buffer[actual_inlen] ) )
{
inlen = actual_inlen;
}


/* NOTE: must be memicmp, not stricmp, because of possibly shortened inlen
* (see check for ispunct() above)
*/
if ( memicmp( buffer, stopcode, inlen ) == 0 )
{
retcode =0;
}




return (retcode); /* do_another */
}


/*-------------------- end of wfscanform.c ----------------------*/


  3 Responses to “Category : C Source Code
Archive   : WTWG12B.ZIP
Filename : WFSCANFM.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/