Blame localized/util/mkcatdefs.c

Packit b099d7
/* $TOG: mkcatdefs.c /main/4 1997/03/31 13:43:31 dbl $ */
Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 * 
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * HISTORY
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * COMPONENT_NAME: (CMDMSG) Message Catalogue Facilities
Packit b099d7
 *
Packit b099d7
 * FUNCTIONS: main, mkcatdefs, incl, chkcontin, insert, nsearch, hash
Packit b099d7
 *
Packit b099d7
 * ORIGINS: 27, 18
Packit b099d7
 *
Packit b099d7
 * IBM CONFIDENTIAL -- (IBM Confidential Restricted when
Packit b099d7
 * combined with the aggregated modules for this product)
Packit b099d7
 * OBJECT CODE ONLY SOURCE MATERIALS
Packit b099d7
 * (C) COPYRIGHT International Business Machines Corp. 1988, 1989, 1991
Packit b099d7
 * All Rights Reserved
Packit b099d7
 *
Packit b099d7
 * US Government Users Restricted Rights - Use, duplication or
Packit b099d7
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * @OPENGROUP_COPYRIGHT@
Packit b099d7
 */
Packit b099d7
Packit b099d7
#include <stdio.h>
Packit b099d7
#include <stdlib.h>
Packit b099d7
#include <unistd.h>
Packit b099d7
#include <locale.h>
Packit b099d7
#include <ctype.h>
Packit b099d7
Packit b099d7
#ifdef aix
Packit b099d7
#include <sys/dir.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#ifdef hpux
Packit b099d7
#ifndef _XPG2
Packit b099d7
#define _XPG2
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#include <limits.h>
Packit b099d7
#include <string.h>
Packit b099d7
Packit b099d7
#ifndef PATH_MAX
Packit b099d7
#define PATH_MAX 1024
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#define MAXLINELEN 8192
Packit b099d7
#define KEY_START '$'
Packit b099d7
#define MAXIDLEN 64
Packit b099d7
#ifdef _D_NAME_MAX
Packit b099d7
#define MDIRSIZ _D_NAME_MAX
Packit b099d7
#else
Packit b099d7
#define MDIRSIZ 14
Packit b099d7
#endif
Packit b099d7
Packit b099d7
static int errflg = 0;
Packit b099d7
static int setno = 1;
Packit b099d7
static int msgno = 1;
Packit b099d7
static int symbflg = 0;
Packit b099d7
static int inclfile = 1;
Packit b099d7
static FILE *outfp;
Packit b099d7
static FILE *msgfp;
Packit b099d7
static FILE *descfile;
Packit b099d7
static char inname [PATH_MAX];
Packit b099d7
static char outname [PATH_MAX];
Packit b099d7
static char catname [PATH_MAX];
Packit b099d7
static char *mname;
Packit b099d7
static void mkcatdefs(char *);
Packit b099d7
static int chkcontin(char *);
Packit b099d7
static int insert(char *, int);
Packit b099d7
static int nsearch(char *);
Packit b099d7
static int hash(char *);
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * NAME: main
Packit b099d7
 *
Packit b099d7
 * FUNCTION: Make message catalog defines.
Packit b099d7
 *
Packit b099d7
 * EXECUTION ENVIRONMENT:
Packit b099d7
 *  	User mode.
Packit b099d7
 *
Packit b099d7
 * NOTES:  Invoked by:
Packit b099d7
 *         mkcatdefs <name> <msg_file>
Packit b099d7
 *
Packit b099d7
 *  	Results are 1) Creates header file <name>.h.
Packit b099d7
 *                  2) Displays message file to stdout. The message file is 
Packit b099d7
 *                     ready to be used as input to gencat.
Packit b099d7
 *
Packit b099d7
 *   	mkcatdefs takes a message definition file and produces
Packit b099d7
 *  	a header file containing #defines for the message catalog,
Packit b099d7
 * 	the message sets and the messages themselves.  It also
Packit b099d7
 *  	produces a new message file which has the symbolic message set and
Packit b099d7
 *  	message identifiers replaced by their numeric values (in the form
Packit b099d7
 *  	required by gencat).
Packit b099d7
 *
Packit b099d7
 * DATA STRUCTURES: Effects on global data structures -- none.
Packit b099d7
 *
Packit b099d7
 * RETURNS: 1 - error condition
Packit b099d7
 */
Packit b099d7
Packit b099d7
int
Packit b099d7
main (int argc, 
Packit b099d7
      char *argv[]) 
Packit b099d7
{
Packit b099d7
  register int i;
Packit b099d7
  register char *cp;
Packit b099d7
  int count;
Packit b099d7
  char *t;
Packit b099d7
  
Packit b099d7
  setlocale (LC_ALL,"");
Packit b099d7
  
Packit b099d7
  /* usage: handle multiple files; -h option has to be at the end */
Packit b099d7
  if (argc < 3) {
Packit b099d7
    fprintf (stderr, 
Packit b099d7
	     "mkcatdefs: Usage: %s header_file msg_file [msg_file...] [-h]\n", 
Packit b099d7
	     argv [0]);	
Packit b099d7
    exit (0);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  /* check if  include file should be created; -h is the last argument */
Packit b099d7
  if (argv[argc-1][0] == '-' && argv[argc-1][1] == 'h') 
Packit b099d7
    inclfile = 0;
Packit b099d7
  
Packit b099d7
  /* open header output file */
Packit b099d7
  if (inclfile) {
Packit b099d7
    mname = argv [1];
Packit b099d7
    if ((int)strlen((t = strrchr(mname,'/')) ? t + 1 : mname) > MDIRSIZ) {
Packit b099d7
      fprintf (stderr, "mkcatdefs: header file name too long\n");
Packit b099d7
      exit (1);
Packit b099d7
    }
Packit b099d7
    sprintf (outname, "%s", mname);
Packit b099d7
    if (strrchr(mname,'/'))
Packit b099d7
      mname = strrchr(mname,'/') + 1;
Packit b099d7
    if ((outfp = fopen (outname, "w")) == NULL) {
Packit b099d7
      fprintf (stderr, "mkcatdefs: Cannot open %s\n", outname);
Packit b099d7
      exit (1);
Packit b099d7
    } else  {
Packit b099d7
      /* convert name to upper case */
Packit b099d7
      for (cp=mname; *cp; cp+=i) {
Packit b099d7
	i = mblen(cp, MB_CUR_MAX);
Packit b099d7
	if (i < 0) {
Packit b099d7
	  fprintf (stderr, "mkcatdefs: filename contains invalid character\n");
Packit b099d7
	  exit (1);
Packit b099d7
	}
Packit b099d7
	if (i == 1) {
Packit b099d7
	  if (islower(*cp) != 0)
Packit b099d7
	    *cp = toupper(*cp);
Packit b099d7
	  else if (!isupper(*cp) && !isdigit(*cp))
Packit b099d7
	    *cp = '_';
Packit b099d7
	}
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  } else sprintf (outname, "msg.h");
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  /* open new msg output file */
Packit b099d7
  msgfp = stdout;
Packit b099d7
  
Packit b099d7
  /* if message descriptor files were specified then process each one in turn 
Packit b099d7
   */
Packit b099d7
  
Packit b099d7
  if (inclfile == 0 )
Packit b099d7
    count = argc - 1;
Packit b099d7
  else
Packit b099d7
    count = argc;
Packit b099d7
  for (i = 2; i < count; i++) {
Packit b099d7
    /* open input file */
Packit b099d7
    sprintf (inname, "%s", argv[i]);
Packit b099d7
    if (strcmp(inname,"-") == 0) {
Packit b099d7
      strcpy(inname,"stdin");
Packit b099d7
      descfile = stdin;       /* input from stdin if no source files */
Packit b099d7
      mkcatdefs(inname);
Packit b099d7
    } else	{
Packit b099d7
      if ((descfile = fopen(inname,"r")) == NULL) {
Packit b099d7
	fprintf (stderr, "mkcatdefs: Cannot open %s\n", inname);
Packit b099d7
	errflg = 1;
Packit b099d7
      } else  {
Packit b099d7
	mkcatdefs (inname);
Packit b099d7
	fclose(descfile);
Packit b099d7
	descfile = NULL;
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (inclfile) {
Packit b099d7
    fflush (outfp);
Packit b099d7
    if (ferror (outfp)) {
Packit b099d7
      fprintf (stderr, "mkcatdefs: There were write errors on file %s\n", 
Packit b099d7
	       outname);
Packit b099d7
      errflg = 1;
Packit b099d7
    }
Packit b099d7
    fclose (outfp);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (errflg) {
Packit b099d7
    fprintf (stderr, "mkcatdefs: Errors found: no %s created\n", outname);
Packit b099d7
    if (inclfile)  unlink(outname);
Packit b099d7
  } else {
Packit b099d7
    if (inclfile) {
Packit b099d7
      if (symbflg)
Packit b099d7
	fprintf (stderr, "mkcatdefs: %s created\n", outname);
Packit b099d7
      else {
Packit b099d7
	fprintf (stderr, "mkcatdefs: No symbolic identifiers; no %s created\n",
Packit b099d7
		 outname);
Packit b099d7
	unlink (outname);
Packit b099d7
      }
Packit b099d7
    } 
Packit b099d7
    else 
Packit b099d7
      fprintf(stderr, "mkcatdefs: no %s created\n", outname);
Packit b099d7
  }
Packit b099d7
  exit (errflg);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * NAME: mkcatdefs
Packit b099d7
 *
Packit b099d7
 * FUNCTION: Make message catalog definitions.
Packit b099d7
 *
Packit b099d7
 * EXECUTION ENVIRONMENT:
Packit b099d7
 *  	User mode.
Packit b099d7
 *
Packit b099d7
 * RETURNS: None
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
mkcatdefs(char *fname)
Packit b099d7
     /*---- fname: message descriptor file name ----*/
Packit b099d7
{
Packit b099d7
  char msgname [PATH_MAX];
Packit b099d7
  char line [MAXLINELEN];
Packit b099d7
  register char *cp;
Packit b099d7
  register char *cpt;
Packit b099d7
  register int m;
Packit b099d7
  register int n;
Packit b099d7
  int contin = 0;
Packit b099d7
  int len;		/* # bytes in a character */
Packit b099d7
  
Packit b099d7
  
Packit b099d7
  /* put out header for include file */
Packit b099d7
  if (inclfile)
Packit b099d7
    {
Packit b099d7
      fprintf (outfp, "/* $%s$ */\n", "XConsortium");
Packit b099d7
      fprintf (outfp, "\n\n/* The following was generated from %s. */\n\n", 
Packit b099d7
	       fname);
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
  /* process the message file */
Packit b099d7
  while (fgets(line, MAXLINELEN, descfile)) {
Packit b099d7
    line[MAXLINELEN-1] = '\0'; /* terminate in case length exceeded */
Packit b099d7
    /* find first nonblank character */
Packit b099d7
    for (cp=line; *cp; cp+=len) {
Packit b099d7
      len = mblen(cp, MB_CUR_MAX);
Packit b099d7
      if (len < 0) {
Packit b099d7
	fprintf (stderr, 
Packit b099d7
		 "mkcatdefs: sourcefile contains invalid character:\n\t%s", 
Packit b099d7
		 line);
Packit b099d7
	errflg = 1;
Packit b099d7
	return;
Packit b099d7
      }
Packit b099d7
      if (len == 1 && isspace(*cp) == 0)
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    if (*cp == KEY_START) {
Packit b099d7
      cp++;
Packit b099d7
      for (cpt = cp; *cp; cp += len) {
Packit b099d7
	len = mblen(cp, MB_CUR_MAX);
Packit b099d7
	if (len < 0) {
Packit b099d7
	  fprintf (stderr, 
Packit b099d7
		   "mkcatdefs: sourcefile contains invalid character:\n\t%s",
Packit b099d7
		   line);
Packit b099d7
	  errflg = 1;
Packit b099d7
	  return;
Packit b099d7
	}
Packit b099d7
	if (len == 1 && isspace(*cp) == 0)
Packit b099d7
	  break;
Packit b099d7
      }
Packit b099d7
      if (cp != cpt) {
Packit b099d7
	sscanf (cp, "%s", msgname);
Packit b099d7
	if ((m = nsearch(msgname)) > 0) {
Packit b099d7
	  fprintf (msgfp, "$ %d", m);
Packit b099d7
	  cp += strlen(msgname);
Packit b099d7
	  fprintf (msgfp, "%s", cp);
Packit b099d7
	} else
Packit b099d7
	  fputs (line, msgfp);
Packit b099d7
	continue; /* line is a comment */
Packit b099d7
      }
Packit b099d7
      if ((strncmp (cp, "set", 3) == 0) && 
Packit b099d7
	  ((len = mblen(&(cp[3]), MB_CUR_MAX)) == 1) && 
Packit b099d7
	  (isspace(cp[3]) != 0)) {
Packit b099d7
	char setname [MAXIDLEN];
Packit b099d7
	
Packit b099d7
	sscanf (cp+3+len, "%s", setname);
Packit b099d7
	if (inclfile) 
Packit b099d7
	  fprintf (outfp, "\n/* definitions for set %s */\n", setname);
Packit b099d7
	if (isdigit(setname[0])) {
Packit b099d7
	  cpt = setname;
Packit b099d7
	  do  {
Packit b099d7
	    if (!isdigit(*cpt)) {
Packit b099d7
	      fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", 
Packit b099d7
		      setname);
Packit b099d7
	      errflg = 1;
Packit b099d7
	      return;
Packit b099d7
	    }
Packit b099d7
	  }   while (*++cpt);
Packit b099d7
	  n = atoi (setname);
Packit b099d7
	  if (n >= setno)
Packit b099d7
	    setno = n;
Packit b099d7
	  else {
Packit b099d7
	    if (n == 0)
Packit b099d7
	      fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", 
Packit b099d7
		      setname);	
Packit b099d7
	    else
Packit b099d7
	      fprintf(stderr, 
Packit b099d7
		      "mkcatdefs: set # %d already assigned or sets not in ascending sequence\n", 
Packit b099d7
		      n);
Packit b099d7
	    errflg = 1;
Packit b099d7
	    return;
Packit b099d7
	  }
Packit b099d7
	} else  {
Packit b099d7
	  cpt = setname;
Packit b099d7
	  do  {
Packit b099d7
	    len = mblen(cpt, MB_CUR_MAX);
Packit b099d7
	    if (len <= 0) {
Packit b099d7
	      fprintf (stderr, 
Packit b099d7
		       "mkcatdefs: sourcefile contains invalid character:\n\t%s",
Packit b099d7
		       line);
Packit b099d7
	      errflg = 1;
Packit b099d7
	      return;
Packit b099d7
	    }
Packit b099d7
	    if (len == 1 && (isalnum(*cpt) == 0) && (*cpt != '_')) {
Packit b099d7
	      fprintf(stderr, 
Packit b099d7
		      "mkcatdefs: %s is an invalid identifier\n", 
Packit b099d7
		      setname);
Packit b099d7
	      errflg = 1;
Packit b099d7
	      return;
Packit b099d7
	    }
Packit b099d7
	  } while (*(cpt += len));
Packit b099d7
	  if (inclfile)
Packit b099d7
	    fprintf (outfp, "#define %s %d\n\n", setname, setno);
Packit b099d7
	  symbflg = 1;
Packit b099d7
	}
Packit b099d7
#ifdef aix
Packit b099d7
	fprintf (msgfp,"$delset");
Packit b099d7
	fprintf (msgfp," %d\n", setno);
Packit b099d7
#endif
Packit b099d7
	fprintf (msgfp,"%.4s", line);
Packit b099d7
	fprintf (msgfp," %d\n", setno++);
Packit b099d7
	msgno = 1;
Packit b099d7
	continue;
Packit b099d7
      } else {
Packit b099d7
	/* !!!other command */
Packit b099d7
      }
Packit b099d7
    } else
Packit b099d7
      if (contin) {
Packit b099d7
	if (!chkcontin(line))
Packit b099d7
	  contin = 0;
Packit b099d7
      } else if (setno > 1) { /* set must have been seen first */
Packit b099d7
	char msgname [MAXIDLEN];
Packit b099d7
	
Packit b099d7
	msgname [0] = '\0';
Packit b099d7
	if (sscanf (cp, "%s", msgname) && msgname[0]) {
Packit b099d7
	  len = mblen(cp, MB_CUR_MAX);
Packit b099d7
	  if (len < 0) {
Packit b099d7
	    fprintf (stderr, 
Packit b099d7
		     "mkcatdefs: sourcefile contains invalid character:\n\t%s",
Packit b099d7
		     line);
Packit b099d7
	    errflg = 1;
Packit b099d7
	    return;
Packit b099d7
	  }
Packit b099d7
	  if (len == 1 && isalpha(*cp) != 0) {
Packit b099d7
	    cpt = msgname;
Packit b099d7
	    do  {
Packit b099d7
	      len = mblen(cpt, MB_CUR_MAX);
Packit b099d7
	      if (len < 0) {
Packit b099d7
		fprintf (stderr, 
Packit b099d7
			 "mkcatdefs: sourcefile contains invalid character:\n\t%s",
Packit b099d7
			 line);
Packit b099d7
		errflg = 1;
Packit b099d7
		return;
Packit b099d7
	      }
Packit b099d7
	      if (len == 1 && (isalnum(*cpt) == 0) && (*cpt != '_')) {
Packit b099d7
		fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", 
Packit b099d7
			msgname);	
Packit b099d7
		errflg = 1;
Packit b099d7
		return;
Packit b099d7
	      }
Packit b099d7
	    }   while (*(cpt += len));
Packit b099d7
	    cp += strlen(msgname);
Packit b099d7
	    fprintf (msgfp,"%d%s", msgno,cp);
Packit b099d7
	    if (inclfile)
Packit b099d7
	      fprintf (outfp, "#define %s %d\n", msgname, msgno);
Packit b099d7
	    symbflg = 1;
Packit b099d7
	    if (chkcontin(line))
Packit b099d7
	      contin = 1;
Packit b099d7
	    if(insert(msgname,msgno++) < 0) {
Packit b099d7
	      fprintf(stderr, "mkcatdefs: name %s used more than once\n", 
Packit b099d7
		      msgname); 
Packit b099d7
	      errflg = 1;
Packit b099d7
	      return;
Packit b099d7
	    }
Packit b099d7
	    continue;
Packit b099d7
	  } else if (isdigit (msgname[0])){
Packit b099d7
	    cpt = msgname;
Packit b099d7
	    do  {
Packit b099d7
	      if (!isdigit(*cpt)) {
Packit b099d7
		fprintf(stderr, "mkcatdefs: invalid syntax in %s\n", line);
Packit b099d7
		errflg = 1;
Packit b099d7
		return;
Packit b099d7
	      }
Packit b099d7
	    }   while (*++cpt);
Packit b099d7
	    n = atoi (msgname);
Packit b099d7
	    if ((n >= msgno) || (n == 0 && msgno == 1))
Packit b099d7
	      msgno = n + 1;
Packit b099d7
	    else {
Packit b099d7
	      errflg = 1;
Packit b099d7
	      if (n == 0)
Packit b099d7
		fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", 
Packit b099d7
			msgname);
Packit b099d7
	      else if (n == msgno) 
Packit b099d7
		fprintf(stderr,
Packit b099d7
			"mkcatdefs: message id %s already assigned to identifier\n", 
Packit b099d7
			msgname);
Packit b099d7
	      else
Packit b099d7
		fprintf(stderr,
Packit b099d7
			"mkcatdefs: source messages not in ascending sequence\n");
Packit b099d7
	      return;
Packit b099d7
	    }
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
	if (chkcontin(line))
Packit b099d7
	  contin = 1;
Packit b099d7
      }
Packit b099d7
    fputs (line, msgfp);
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  /* make sure the operations read/write operations were successful */
Packit b099d7
  if (ferror(descfile)) {
Packit b099d7
    fprintf (stderr, "mkcatdefs: There were read errors on file %s\n", inname);
Packit b099d7
    errflg = 1;
Packit b099d7
  }
Packit b099d7
  return;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * NAME: chkcontin
Packit b099d7
 *
Packit b099d7
 * FUNCTION: Check for continuation line.
Packit b099d7
 *
Packit b099d7
 * EXECUTION ENVIRONMENT:
Packit b099d7
 *  	User mode.
Packit b099d7
 *
Packit b099d7
 * RETURNS: 0 - not a continuation line.
Packit b099d7
 *          1 - continuation line.
Packit b099d7
 */
Packit b099d7
static int
Packit b099d7
chkcontin(char *line) 
Packit b099d7
{
Packit b099d7
  int	len;		/* # bytes in character */
Packit b099d7
  wchar_t	wc;		/* process code of current character in line */
Packit b099d7
  wchar_t	wcprev;		/* process code of previous character in line */
Packit b099d7
  
Packit b099d7
  for (wc=0; *line; line+=len) {
Packit b099d7
    wcprev = wc;
Packit b099d7
    len = mbtowc(&wc, line, MB_CUR_MAX);
Packit b099d7
    if (len < 0) {
Packit b099d7
      fprintf (stderr, 
Packit b099d7
	       "mkcatdefs: sourcefile contains invalid character:\n\t%s",
Packit b099d7
	       line);
Packit b099d7
      errflg = 1;
Packit b099d7
      return (0);
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
  if (wcprev == '\\' && wc == '\n')
Packit b099d7
    return (1);
Packit b099d7
  return (0);
Packit b099d7
}
Packit b099d7
Packit b099d7
#define HASHSIZE 256			/* must be a power of 2 */
Packit b099d7
#define HASHMAX HASHSIZE - 1
Packit b099d7
Packit b099d7
struct name {
Packit b099d7
  char *regname;
Packit b099d7
  int   regnr;
Packit b099d7
  struct name *left;
Packit b099d7
  struct name *right;
Packit b099d7
};
Packit b099d7
Packit b099d7
static struct name *symtab[HASHSIZE];	/* hashed pointers to binary trees */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * NAME: insert
Packit b099d7
 *
Packit b099d7
 * FUNCTION: Insert symbol
Packit b099d7
 *
Packit b099d7
 * EXECUTION ENVIRONMENT: 
Packit b099d7
 *  	User mode.
Packit b099d7
 * 
Packit b099d7
 * NOTES: These routines manipulate a symbol table for the mkcatdefs program.
Packit b099d7
 *  	  The symbol table is organized as a hashed set of binary trees. If the
Packit b099d7
 *  	  symbol being passed in is found then a -1 is returned, otherwise the
Packit b099d7
 *  	  symbol is placed in the symbol table and a 0 is returned. The purpose
Packit b099d7
 *  	  of the symbol table is to keep mkcatdefs from assigning two different
Packit b099d7
 *  	  message set / message numbers to the same symbol.
Packit b099d7
 *        Read the next line from the open message catalog descriptor file.
Packit b099d7
 *
Packit b099d7
 * RETURNS: 0 - symbol inserted.
Packit b099d7
 *         -1 - symbol exists.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static int 
Packit b099d7
insert(char *tname,
Packit b099d7
       int seqno)
Packit b099d7
     /*
Packit b099d7
       tname - pointer to symbol
Packit b099d7
       seqno - integer value of symbol
Packit b099d7
       */
Packit b099d7
     
Packit b099d7
{
Packit b099d7
  register struct name *ptr,*optr;
Packit b099d7
  int rslt = -1,i,hashval;
Packit b099d7
  
Packit b099d7
  hashval = hash(tname);
Packit b099d7
  ptr = symtab[hashval];
Packit b099d7
  
Packit b099d7
  /* search the binary tree for specified symbol */
Packit b099d7
  while (ptr && (rslt = strcmp(tname,ptr->regname))) {
Packit b099d7
    optr=ptr;  
Packit b099d7
    if (rslt<0)
Packit b099d7
      ptr = ptr->left;
Packit b099d7
    else
Packit b099d7
      ptr = ptr->right;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (rslt == 0)  /* found the symbol already defined */
Packit b099d7
    return (-1);
Packit b099d7
  else {          /* symbol not defined yet so put it into symbol table */    
Packit b099d7
    ptr = (struct name *)calloc(sizeof(struct name), 1);
Packit b099d7
    ptr->regname = malloc(strlen(tname) + 1);
Packit b099d7
    strcpy (ptr->regname, tname);
Packit b099d7
    ptr->regnr = seqno;
Packit b099d7
    
Packit b099d7
    /* not first entry in tree so update branch pointer */
Packit b099d7
    if (symtab[hashval]) {
Packit b099d7
      if (rslt < 0)
Packit b099d7
	optr->left = ptr;
Packit b099d7
      else
Packit b099d7
	optr->right = ptr;
Packit b099d7
      
Packit b099d7
      /* first entry in tree so set the root pointer */
Packit b099d7
    } else
Packit b099d7
      symtab[hashval] = ptr;
Packit b099d7
    
Packit b099d7
    return (0);
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * NAME: nsearch
Packit b099d7
 *
Packit b099d7
 * FUNCTION: Search for symbol
Packit b099d7
 *
Packit b099d7
 * EXECUTION ENVIRONMENT: 
Packit b099d7
 *  	User mode.
Packit b099d7
 * 
Packit b099d7
 * NOTES: Searches for specific identifier. If found, return allocated number.
Packit b099d7
 * 	  If not found, return -1.
Packit b099d7
 *
Packit b099d7
 * RETURNS: Symbol sequence number if symbol is found.
Packit b099d7
 *          -1 if symbol is not found.
Packit b099d7
 */
Packit b099d7
static int 
Packit b099d7
nsearch (char *tname)
Packit b099d7
     /*
Packit b099d7
       tname - pointer to symbol
Packit b099d7
       */
Packit b099d7
     
Packit b099d7
{
Packit b099d7
  register struct name *ptr,*optr;
Packit b099d7
  int rslt = -1,i,hashval;
Packit b099d7
  
Packit b099d7
  hashval = hash(tname);
Packit b099d7
  ptr = symtab[hashval];
Packit b099d7
  
Packit b099d7
  /* search the binary tree for specified symbol */
Packit b099d7
  while (ptr && (rslt = strcmp(tname,ptr->regname))) {
Packit b099d7
    optr=ptr;  
Packit b099d7
    if (rslt<0)
Packit b099d7
      ptr = ptr->left;
Packit b099d7
    else
Packit b099d7
      ptr = ptr->right;
Packit b099d7
  }
Packit b099d7
  
Packit b099d7
  if (rslt == 0)		/* found the symbol already defined */
Packit b099d7
    return(ptr->regnr);
Packit b099d7
  else
Packit b099d7
    return (-1);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * NAME: hash
Packit b099d7
 *
Packit b099d7
 * FUNCTION: Create hash value from symbol name.
Packit b099d7
 *
Packit b099d7
 * EXECUTION ENVIRONMENT: 
Packit b099d7
 *  	User mode.
Packit b099d7
 * 
Packit b099d7
 * NOTES: Hash the symbol name using simple addition algorithm.
Packit b099d7
 * 	  Make sure that the hash value is in range when it is returned.
Packit b099d7
 *
Packit b099d7
 * RETURNS: A hash value.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static int 
Packit b099d7
hash (char *name) /* pointer to symbol */
Packit b099d7
{
Packit b099d7
  register int hashval = 0;
Packit b099d7
  
Packit b099d7
  while (*name)
Packit b099d7
    hashval += *name++;
Packit b099d7
  
Packit b099d7
  return (hashval & HASHMAX);
Packit b099d7
}