Metropoli BBS
VIEWER: gentab.c MODE: TEXT (ASCII)
/**
	Reference table generator, HP48 Utility
	Borland C++ 3.0
	Detlef Mueller, 24.04.1992
	Q&D hack - Usage: GENTAB <[entries file] >[table file]

	The sequence
	    GENTAB <entries.a >tab.a
	    SASM -E -N -H -o tab tab.a
	should generate the downloadable file tab.

	0.000 24.04.1992 DM	coded
	  100 25.08.1992 DM	mofified output to feed it into sasm only
**/

#include	<stdio.h>
#include	<stdlib.h>
#include	<stdarg.h>
#include	<string.h>
#include	<ctype.h>

#include	<alloc.h>
#include	<errno.h>
#include	<io.h>				/* MesS-DOS */
#include	<fcntl.h>			/* MesS-DOS */


#define	MAJVER		0
#define	MINVER		0
#define	REVER		0

#define	WRKFILE		"________.TMP"
#define	STARTCH		' '


typedef enum
	{
	    ERROR,
	    WARNING
	}
	ERRTYPE ;

typedef	struct
	{
	    char
		name[13] ;
	    long
		addr ;
	}
	ENTRY ;


static ENTRY
	**table = NULL ;

static unsigned int
	entries = 0,
	hash[128 - STARTCH] = { 0 } ;


void  Error ( ERRTYPE messt, char *msg, ... )
{
    va_list
	argptr ;
    char
	*tstr,
	str[81] ;

    va_start( argptr, msg ) ;
    vsprintf( str, msg, argptr ) ;

    switch ( messt )
    {
	case ERROR :
	    tstr = "\nError: %s " ;
	    break ;

	case WARNING :
	    tstr = "\nWarning: %s " ;
	    break ;

	default :
	    tstr = "Unknown error: %s " ;
    }

    fprintf( stderr, tstr, str ) ;

    if ( errno != EZERO )
	perror( "" ) ;
    else
	fputc( '\n', stderr ) ;

    va_end( argptr ) ;

    if ( messt == ERROR )
	exit( -1 ) ;
}

static int compare ( const void *s1, const void *s2 )
{
    register char
	*s_1, *s_2 ;

    for ( s_1 = (*(ENTRY **)s1)->name, s_2 = (*(ENTRY **)s2)->name ;
	  *s_1 || *s_2 ; ++s_1, ++s_2 )
	if ( *s_1 != *s_2 )
	    return ( *s_1 - *s_2 ) ;

    return ( 0 ) ;
}

static void Work ( void )
{
    static char
	image[] = "\\|/-" ;
    static int
	i = 0 ;

    fputc( '\b', stderr ) ;
    fputc( image[i = (i + 1) & 3], stderr ) ;
}

static void WriteTab ( FILE *fout )
{
    unsigned int
	i, *h ;
    char
	ch = '\0' ;
    ENTRY
	**entry ;

    fputs( "\nWriting hash table ...", stderr ) ;

    fputs( "\tNIBASC\t`HPHP48-E`\n"
	   "\tCON(5)\t#02A2C\t\t=DOCSTR\n"
	   "\tREL(5)\tTabEnd\n"
	   "\tNIBASC\t`\\00\\n`\n", fout ) ;

    for ( i = 0, h = hash ; i < (sizeof( hash ) / sizeof( *hash )) - 1 ; ++i )
	if ( *h++ )
	    fprintf( fout, "\tREL(5)\t_%c_\n", i + STARTCH ) ;
	else
	    fprintf( fout, "\tCON(5)\t0\n" ) ;

    fprintf( fout, "\tREL(5)\tTabEnd\n" ) ;

    fputs( "\nWriting reference table ...  ", stderr ) ;

    for ( i = 0, entry = table ; i < entries ; ++i, ++entry )
    {
	if ( *(*entry)->name != ch )
	    fprintf( fout, "_%c_\n", ch = *(*entry)->name ) ;

	fprintf( fout,
		 "\tCON(6)\t#%lX\n"
		 "\tNIBASC\t`%s`\n",
		 (*entry)->addr | ((long)strlen( (*entry)->name ) << 20),
		 (*entry)->name ) ;

	free( *entry ) ;

	if ( ! (i % 100) )
	    Work() ;
    }

    fputs( "TabEnd\n", fout ) ;

    free( table ) ;

    fputs( "\b ", stderr ) ;
}

static void ReadTab ( FILE *fin )
{
    static char
	line[80], buffer[256] ;
    char
	*pl, *pa ;
    unsigned int
	i ;
    long
	addr ;
    ENTRY
	entry, **tab ;
    FILE
	*ftmp ;

    if ( ! (ftmp = fopen( WRKFILE, "wb" )) )
	Error( ERROR, "Can't create <%s>", WRKFILE ) ;

    fprintf( stderr, "\nReading and converting input ...  " ) ;

    while ( fgets( line, 80, fin ) )
	if ( strlen( line ) && *line != '\n' )
	{
	    pl = strcpy( buffer, line ) ;

	    if (    ! (pl = strtok( *pl == '=' ? pl + 1 : pl, "\n\r\t " ))
		 || strlen( pl ) > 12
		 || *pl == '*'
		 || *pl == '~'
		 || ! strtok( NULL, "\n\r\t " )
		 || ! (pa = strtok( NULL, "\n\r\t " ))
		 || ! (i = sscanf( *pa == '#' ? pa + 1 : pa, "%lX", &addr ))
		 || i == EOF
		 || (addr & 0xFFF00000L) )
		continue ;

	    hash[*pl - STARTCH] = 1 ;
	    strcpy( entry.name, pl ) ;
	    entry.addr = addr ;

	    if ( ! fwrite( &entry, sizeof( ENTRY ), 1, ftmp ) )
		Error( ERROR, "Write error on <%s>", WRKFILE ) ;

	    if ( ! (++entries % 100) )
		Work() ;
	}

    fclose( ftmp ) ;

    if ( ! entries )
	Error( ERROR, "Sorry, no entries found" ) ;

    fputs( "\b ", stderr ) ;
    fprintf( stderr, "\nFound %u symbols\nGenerating table ...  ",
	     entries ) ;

    if ( ! (ftmp = fopen( WRKFILE, "rb" )) )
	Error( ERROR, "Can't reopen <%s>", WRKFILE ) ;

    if ( ! (table = (ENTRY **)malloc( entries * sizeof( ENTRY *) )) )
	Error( ERROR, "Can't alloc room for %u entries", entries ) ;

    for ( i = 0, tab = table ; i < entries ; ++i, ++tab )
    {
	if ( ! (*tab = (ENTRY *)malloc( sizeof( ENTRY ) )) )
	    Error( ERROR, "Can't alloc %d bytes room for %uth entry",
		   sizeof( ENTRY ), i ) ;

	if ( ! fread( *tab, sizeof( ENTRY ), 1, ftmp ) )
	    Error( ERROR, "Can't read %uth entry from <%s>", i, WRKFILE ) ;

	if ( ! (i % 100) )
	    Work() ;
    }

    fputs( "\b ", stderr ) ;

    fclose( ftmp ) ;
    unlink( WRKFILE ) ;
}

void  main ( int argc, char *argv[] )
{
    fprintf( stderr,
	     "\n%s, Version %d.%d.%d, %s  %s  BC %X.%X, (c) 1992 DM.\n",
	     argv[0], MAJVER, MINVER, REVER, __DATE__, __TIME__,
	     __TURBOC__ >> 8, __TURBOC__ & 0x00FF ) ;	/* MesS-DOS */

    setmode( fileno( stdout ), O_BINARY ) ;		/* MesS-DOS */
    setmode( fileno( stdin ), O_BINARY ) ;		/* MesS-DOS */

    ReadTab( stdin ) ;
    fprintf( stderr, "\nSorting (by name)..." ) ;
    qsort( table, entries, sizeof( ENTRY * ), compare ) ;
    WriteTab( stdout ) ;

    fprintf( stderr, "\n\nNow:	SASM -E -N -H -o tab tab.a" ) ;

    exit( 0 ) ;
}
[ RETURN TO DIRECTORY ]