/*
 * File trans.c - scan TRANS.TBL file
 *
 * Written by Frank Munkert (1994).
 *
 */

/*

  TRANS.TBL contains lines of the kind
  
  	amigafilename->isofilename

  amigafilename: any sequence of characters; special characters may be
  	escaped with `\`
	
  dosfilename: "8.3" style iso file name; only letters, digits and
        underscore are allowed.

  All tabs and spaces will be ignored, unless they are escaped.
			
  Examples:
  
  	drivers->DRIVERS
	drivers  ->   DRIVERS.
	file.c -> FILE.C
	dow\ jones.txt -> DOWJONES.TXT

*/

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

#include "trans.h"
#include "unix/unixlib.h"

#ifdef LATTICE
#include <proto/utility.h>
#endif
#if defined(__GNUC__) || defined(AZTEC_C)
#include <clib/utility_protos.h>
#endif


void scan_trans_tbl (struct transtbl* tbl, const char *dir_name)
{
  char *tbl_file_name;
  FILE *in;
  static char buf[160];
  char *cp;
  char amiga_name[33];
  char iso_name[13];
  int i;
  char *tmp;
  struct translation* new;
  int line = 0;
  struct stat sbuf;

  tbl->number_of_entries = 0;
  tbl->entries = NULL;

  tbl_file_name = malloc (strlen (dir_name) + strlen ("TRANS.TBL") + 2);
  if (!tbl_file_name) {
    fprintf (stderr, "out of memory!\n");
    exit (1);
  }

  strcpy (tbl_file_name, dir_name);
  if (dir_name[strlen(dir_name)-1] != ':')
    strcat (tbl_file_name, "/");

  strcat (tbl_file_name, "TRANS.TBL");
  in = fopen (tbl_file_name, "r");
  if (!in) {
    free (tbl_file_name);
    return;
  }
  
  for (;;) {

    line++;
    
    cp = fgets (buf, sizeof (buf), in);
    if (!cp)
      break;
    if (!(cp = strchr (buf, '\n'))) {
      fprintf (stderr, "WARNING: line too long in line %d in file %s\n",
      	       line, tbl_file_name);
      free (tbl_file_name);
      return;
    }
    *cp = 0;
    
    /* skip blank lines: */
    if (strspn (buf, " \t") == strlen (buf))
      continue;
      
    /* read AmigaDOS name: */
    for (cp=buf; isspace (*cp); cp++) ;
    i=0;
    while (!(cp[0] == '-' && cp[1] == '>')) {
      if (*cp == 0) {
        fprintf (stderr, "WARNING: missing '->' in line %d file %s\n",
	         line, tbl_file_name);
	free (tbl_file_name);
	return;
      }
      if (isspace (*cp)) {
        cp++;
      } else {
        if (*cp == '\\')
          cp++;

        if (i == 32)
	  break;
        amiga_name[i++] = *cp++;
      }
    }
    cp += 2;
    amiga_name[i] = 0;
    
    /* read ISO name: */
    for (; isspace (*cp); cp++) ;
    i=0;
    while (*cp) {
      if (isspace (*cp)) {
        cp++;
      } else {
        if (i == 12)
	  break;
        iso_name[i++] = *cp++;
      }
    }
    iso_name[i] = 0;

    /* check if the Amiga file really exists: */
    tmp = malloc (strlen (dir_name) + strlen (amiga_name) + 2);
    if (!tmp) {
      fprintf (stderr, "out of memory!\n");
      exit (1);
    }
    strcpy (tmp, dir_name);
    if (dir_name[strlen(dir_name)-1] != ':')
      strcat (tmp, "/");
    strcat (tmp, amiga_name);
    if (stat (tmp, &sbuf) == -1) {
      fprintf (stderr, "WARNING: file %s (from %s) not found\n",
      	       tmp, tbl_file_name);
    }
    free (tmp);

    /* convert iso name to uppercase: */
    for (cp=iso_name; *cp; cp++)
      *cp = toupper (*cp);

    /* check if the iso name is valid: */
    if (strspn (iso_name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.")
        != strlen (iso_name)) {
      fprintf (stderr, "ERROR: invalid name '%s' in file %s\n",
      	       iso_name, tbl_file_name);
      continue;
    }
    cp = strchr (iso_name, '.');
    if ((cp && strchr (cp+1, '.')) ||
    	(!cp && strlen (iso_name) > 8) ||
	(cp && cp-iso_name > 8) ||
	(cp && strlen (iso_name) - (cp-iso_name+1) > 3) ||
	(S_ISDIR(sbuf.st_mode) && cp) ||
	(!S_ISDIR(sbuf.st_mode) && !cp)) {
      fprintf (stderr, "ERROR: invalid name '%s' in file %s\n",
      	       iso_name, tbl_file_name);
    }

    /* create table entry: */
    new = (struct translation*) malloc (sizeof (*new));
    if (!new) {
      fprintf (stderr, "out of memory!\n");
      exit (1);
    }
    strcpy (new->from, amiga_name);
    strcpy (new->to, iso_name);
    new->next = tbl->entries;
    tbl->entries = new;
    tbl->number_of_entries++;
  }
  
  fclose (in);
  free (tbl_file_name);
}

void free_trans_tbl (struct transtbl* tbl)
{
  struct translation *ptr, *next;
  
  for (ptr = tbl->entries; ptr; ptr = next) {
    next = ptr->next;
    free (ptr);
  }

  tbl->number_of_entries = 0;
}

const char* translate (struct transtbl* tbl, const char* name)
{
  struct translation *ptr;
  
  for (ptr = tbl->entries; ptr; ptr = ptr->next) {
    if (Stricmp ((UBYTE*) name, (UBYTE*) ptr->from) == 0) {
      return ptr->to;
    }
  }
  return NULL;
}
