
/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

/*	Copyright (c) 1984 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/
#ident "$Header: lib.c 1.2 90/04/20 $@(#)lib.c	1.1 89/12/01"
#include <stdio.h>
#include "xsld.h"
#include <malloc.h>
#include <string.h>

static char **libs;

extern char *gettxt();

#define INC_LIB		10

static LIB lib_free = 0;
static LIB lib_max = 0;
LIB null_lib = NULL_LIB;

LIB
add_library(name)
  char *name;
{
  if (lib_free == lib_max){
    if (lib_max == 0){
      lib_max = INC_LIB;
      if ((libs = (char **)malloc(sizeof(char *) * INC_LIB)) == 0){
        fprintf(stderr, gettxt("xsld:1","Out of memory (lib.c (1))\n"));
        fatal();
      }
    } else {
      lib_max += INC_LIB;
      if ((libs = (char **)realloc((char *)libs, sizeof(char *) * lib_max))==0){
        fprintf(stderr, gettxt("xsld:2","Out of memory (lib.c (2))\n"));
        fatal();
      }
    }
  }

  libs[lib_free] = na_store(name);  

  return lib_free++;
}

bool
is_user_lib(name)
  char *name;
{
  char *ptr = strrchr(name, '.');
  if (ptr == 0)
    return FALSE;
  return (strcmp(ptr + 1, MSG_LIB_SUFFIX) == 0);
}

bool
is_null_lib(lib)
  LIB lib;
{
  return lib == NULL_LIB;
}

/*
 * Configuration file scanning
 * format is
 * <name>:<lang>:<actual name>
 * where <name> is the library name (same convention than cc)
 *       <lang> is the natural language chosen. a null string means
 *              the default entry for the specified library
 * Config file is scanned at first call
 */

struct sys_lang {
  char *lib_name;
  char *lib_lang;
  struct sys_lang *lib_next;
};

struct sys_lib {
  char *sys_name;
  struct sys_lang *sys_lang;
  struct sys_lib *sys_next;
};

static struct sys_lib *sys_libs;

char *
system_lib(name, lang)
  char *name, *lang;
{
  struct sys_lib *sys_ptr;
  struct sys_lang *lang_ptr;
  char *default_lib = 0;
  
  if (sys_libs == 0)
    build_sys_lib();
  sys_ptr = sys_libs;
  
  while (sys_ptr != 0){
    if (strcmp(name, sys_ptr->sys_name) == 0)
      break;
    sys_ptr = sys_ptr->sys_next;
  }
  
  if (sys_ptr == 0){
    fprintf(stderr, gettxt("xsld:3","No system library %s\n"), name);
    return 0;
  }
  
  lang_ptr = sys_ptr->sys_lang;

  if (!lang)
	lang = "";
  
  while (lang_ptr != 0){
    if (!strcmp(lang, lang_ptr->lib_lang))
      return lang_ptr->lib_name;
    if (lang_ptr->lib_lang[0] == '\0')	/* remember the default */
      default_lib = lang_ptr->lib_name;
    lang_ptr = lang_ptr->lib_next;
  }
  if (!default_lib) {
    fprintf(stderr, gettxt("xsld:5","No default language library for %s\n"), name);
    return 0;
  }
  else {
    fprintf(stderr, gettxt("xsld:4","No message library for the language \"%s\", using default library\n"),lang);
    return default_lib;
  }
}
  
static
build_sys_lib()
{
  FILE *fd;
  char buf[BUFSIZ];
  char *lang, *name, *actname;
  struct sys_lib *sys_ptr1, *sys_ptr2;
  struct sys_lang *lang_ptr1, *lang_ptr2;
  
  if ((fd = fopen(CONFIG_FILE, "r")) == NULL){
    perror(CONFIG_FILE);
    return;
  }
  
  name = buf;
  while (fgets(buf, BUFSIZ, fd) != 0){
    if ((lang = strchr(buf, ':')) == 0)
      continue;
    *lang = '\0';
    lang++;
    if ((actname = strchr(lang, ':')) == 0)
      continue;
    *actname = '\0';
    actname++;
    actname[strlen(actname) - 1] = '\0';
    
    sys_ptr1 = sys_ptr2 = sys_libs;
    while (sys_ptr1 != 0){
      if (strcmp(sys_ptr1->sys_name, name) == 0)
        break;
      sys_ptr2 = sys_ptr1;
      sys_ptr1 = sys_ptr1->sys_next;
    }
    if (sys_ptr1 == 0){
      if ((sys_ptr1 = (struct sys_lib *)malloc(sizeof(struct sys_lib))) == 0){
        fprintf(stderr, gettxt("xsld:6","Out of memory (lib.c (4))\n"));
        fatal();
      }
      if ((sys_ptr1->sys_name = malloc(lang - name)) == 0){
        fprintf(stderr, gettxt("xsld:7","Out of memory (lib.c (5))\n"));
        fatal();
      }
      strcpy(sys_ptr1->sys_name, name);
      sys_ptr1->sys_lang = 0;
      sys_ptr1->sys_next = 0;
      if (sys_ptr2 != 0)
        sys_ptr2->sys_next = sys_ptr1;
      else
        sys_libs = sys_ptr1;
    }
    if (lang[0] == '\0'){
      /*
       * Default library
       */
      lang_ptr1 = lang_ptr2 = sys_ptr1->sys_lang;
      while (lang_ptr1 != 0){
        if (lang_ptr1->lib_lang[0] == '\0'){
          fprintf(stderr, gettxt("xsld:8","Too many default libraries (%s)\n"), name);
          goto next_entry;
        }
        lang_ptr2 = lang_ptr1;
        lang_ptr1 = lang_ptr1->lib_next;
      }
      if ((lang_ptr1 = (struct sys_lang *)malloc(sizeof(struct sys_lang))) == 0){
        fprintf(stderr, gettxt("xsld:9","Out of memory (lib.c (6))\n"));
        fatal();
      }
      if ((lang_ptr1->lib_name = malloc(strlen(actname) + 1)) == 0){
        fprintf(stderr, gettxt("xsld:10","Out of memory (lib.c (7))\n"));
        fatal();
      }
      strcpy(lang_ptr1->lib_name, actname);
      lang_ptr1->lib_next = 0;
      lang_ptr1->lib_lang = "";
      if (lang_ptr2 == 0)
        sys_ptr1->sys_lang = lang_ptr1;
      else
        lang_ptr2->lib_next = lang_ptr1;
    } else {
      lang_ptr1 = lang_ptr2 = sys_ptr1->sys_lang;
      while (lang_ptr1 != 0){
        if (strcmp(lang_ptr1->lib_lang, lang) == 0){
          fprintf(stderr, gettxt("xsld:11","Too many %s libraries (%s)\n"), lang, name);
          goto next_entry;
        }
        lang_ptr2 = lang_ptr1;
        lang_ptr1 = lang_ptr1->lib_next;
      }
      if ((lang_ptr1 = (struct sys_lang *)malloc(sizeof(struct sys_lang))) == 0){
        fprintf(stderr, gettxt("xsld:12","Out of memory (lib.c (8))\n"));
        fatal();
      }
      if ((lang_ptr1->lib_name = malloc(strlen(actname) + 1)) == 0){
        fprintf(stderr, gettxt("xsld:13","Out of memory (lib.c (9))\n"));
        fatal();
      }
      if ((lang_ptr1->lib_lang = malloc(actname - lang)) == 0){
        fprintf(stderr, gettxt("xsld:14","Out of memory (lib.c (10))\n"));
        fatal();
      }
      strcpy(lang_ptr1->lib_name, actname);
      lang_ptr1->lib_next = 0;
      strcpy(lang_ptr1->lib_lang, lang);
      if (lang_ptr2 == 0)
        sys_ptr1->sys_lang = lang_ptr1;
      else
        lang_ptr2->lib_next = lang_ptr1;
    }
next_entry:
;
  }
}

void
lib_print(lib)
  LIB lib;
{
  if (lib != NULL_LIB)
    fprintf(stdout, "(%s)", libs[lib]);
}

char *
lib_name(lib)
  LIB lib;
{
  return libs[lib];
}
