/* 
 * $RCSfile: initrom.c,v $
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * $Log: initrom.c,v $
 * Revision 1.2  1996/01/29 20:06:53  slm
 * Updated copyright and version.
 *
 * Revision 1.1  1995/07/28  21:50:49  slm
 * Initial revision
 *
 * Revision 1.3.2.1  1994/11/03  00:15:26  hkaram
 * New branch
 *
 * Revision 1.3  1994/08/05  00:16:30  menze
 *   [ 1994/06/08          menze ]
 *   Protected file-accesses with ! XK_KERNEL, so even in-kernel
 *   implementations can use this to get at the compose-generated rom
 *   entries.
 *
 *   [ 1994/05/05          menze ]
 *   savestr wasn't copying last char
 *   Fixed problem in support for compose-generated rom entries
 *
 *   [ 1994/03/10          menze ]
 *   Added support for rom entries generated by compose
 *
 * Revision 1.2  1994/02/05  00:09:14  menze
 *   [ 1994/01/14          menze ]
 *   Added inclusion of xk_debug.h
 *
 * Revision 1.1  1994/01/13  03:53:29  menze
 * Initial revision
 *
 */

#include <ctype.h>
#include "xk_debug.h"
#include "platform.h"
#include "x_stdio.h"
#include "x_libc.h"
#include "x_util.h"
#include "rom.h"
#include "compose.h"


#ifdef __STDC__

static void	addEntry( char * );
static char *	savestr( char * );

#endif


char *rom[ROM_MAX_LINES + 1][ROM_MAX_FIELDS + 1];  

/* 
 * Save all but the last character (the newline)
 */
static char *
savestr( s )
    char *s;
{
    char 	*r;

    r = (char *) xMalloc(strlen(s) + 1);
    strcpy(r, s);
    return r;
}


#define ROM_LEN	200

static void
addEntry( buf )
    char	*buf;
{
    static int	i=0;
    char	*p;
    int		j;

    if ( i > ROM_MAX_LINES  ) {
	sprintf(errBuf, "ROM file has too many lines (max %d)",
		ROM_MAX_LINES);
	Kabort(errBuf);
    }
    if ( strlen(buf) > ROM_LEN ) {
	sprintf(errBuf, "ROM entry in line %d is too long (max %d chars)",
		i, ROM_LEN);
	Kabort(errBuf);
    }
    p = savestr(buf);
    /* 
     * Clear out initial white space
     */
    while ( *p && isspace(*p) ) {
	p++;
    }
    if ( strlen(p) == 0 ) {
	rom[i][0] = "";
    } else {
	/* 
	 * Put a '\0' after each field and set the rom array to these
	 * fields 
	 */
	for ( j=0; *p; j++ ) {
	    if ( j >= ROM_MAX_FIELDS ) {
		sprintf(errBuf,
			"ROM entry on line %d has too many fields (max %d)",
			i, ROM_MAX_FIELDS);
		Kabort(errBuf);
	    }
	    if ( *p == '#' ) {
		/* 
		 * Comments follow until end of line.  Make sure this
		 * doesn't look like the final line.
		 */
		if ( j == 0 ) {
		    rom[i][0] = p;	/* bogus, but non-null */
		    rom[i][1] = 0;
		} else {
		    rom[i][j] = 0;
		}
		break;
	    }
	    rom[i][j] = p;
	    /* 
	     * Find and mark the end of this field
	     */
	    while ( *p && ! isspace(*p) ) {
		p++;
	    }
	    if ( *p ) {
		*p++ = 0;
		/* 
		 * Find the start of the next field
		 */
		while ( *p && isspace(*p) ) {
		    p++;
		}
	    }
	}
    }
    i++;
}


void
initRom()
{
    char **e;
    
    for ( e = composeRomEntries; *e != 0; e++ ) {
	addEntry(*e);
    }
#if ! defined(XK_KERNEL)
    {
	FILE *f;
	char buf[ROM_LEN + 2];

	if ((f = fopen("rom", "r")) == NULL) {
	    xTrace0(init, TR_MAJOR_EVENTS, "not loading ROM file");
	    return;
	} else {
	    xTrace0(init, TR_MAJOR_EVENTS, "loading ROM file");
	}
	while ( fgets(buf, ROM_LEN + 2, f) ) {
	    addEntry(buf);
	}
	fclose(f);
    }
#endif /* ! XK_KERNEL */
}
