|
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 |
}
|