#include "prefs.h"
#ifdef LATTICE
#include <dos.h>
#endif
#ifdef DICE
#include <libraries/dos.h>
#endif



Prototype void ReadAliasList(void);
Prototype void FreeAliasList(struct AliasItem **);
Prototype char *GetAlias(struct AliasItem *, char *);
Prototype void PutAlias(struct AliasItem **, char *, char *);
Prototype struct AliasItem *AdrsToAList(char *);
Prototype char *delete_wspaces_begin(char *);
Prototype char *delete_wspaces_end(char *);



void ReadAliasList(void)
{
    FILE *fp;
    char *a,*r,*p;
    char line[MAX_LINELENGTH];
    struct AliasItem *list,*l;

    strcpy(line,UULIB);
    strcat(line,UserName);
    strcat(line,ELM_ALIASES);
    if (!(fp=fopen(line,"r"))) {
      strcpy(line,UULIB);
      strcat(line,ELM_ALIASES);
      if (!(fp=fopen(line,"r"))) {
        return;
      }
    }

    while(fgets(line,MAX_LINELENGTH-1,fp)) {
      removeCR(line);

      if (*line!='#' && (r = strchr(line,'='))) {
        *r = '\0';
        a = delete_wspaces_begin(line);
        p = r-1;
        while (p>=a && (*p==' ' || *p=='\t'))
          p--;
        p++;
        *p = '\0';

        r = delete_wspaces_begin(r+1);
        delete_wspaces_end(r);

        if (a && r && strlen(a) && strlen(r)) {

          l = list = AdrsToAList(a);

          while (l) {
            if (GetAlias(AliasList,l->alias))
              fprintf(stderr,"elm: alias %s defined twice\n",l->alias);
            else
              PutAlias(&AliasList,l->alias,r);

            l = l->next;
          }

          FreeAliasList(&list);

        }
      }
    }

    fclose(fp);
}



void FreeAliasList(struct AliasItem **list)
{
  struct AliasItem *i;

  while (*list) {
    i = *list;
    *list = (*list)->next;
    free(i->alias);
    free(i->real);
    free(i);
  }

  *list = NULL;
}



void PutAlias(struct AliasItem **list, char *alias, char *real)
{
  struct AliasItem *i,*l;

  if (i=malloc(sizeof(struct AliasItem))) {

    if (alias)
      i->alias = strdup(alias);
    else
      i->alias = NULL;

    if (real)
      i->real = strdup(real);
    else
      i->real = NULL;

    i->next = NULL;

    if (*list) {
      for (l = *list ; l->next ; l=l->next )
        ;
      l->next = i;
    }
    else {
      *list = i;
    }
    /*printf("Alias: %s -> %s\n",i->alias,i->real);*/
  }
}



char *GetAlias(struct AliasItem *list, char *alias)
{
  struct AliasItem *i;

  if (alias && strlen(alias)) {
    for (i=list;i;i=i->next)
      if (!strcmp(i->alias,alias))
        return(i->real);
  }

  return(NULL);
}



char *delete_wspaces_begin(char *str)
{
  if (str)
    while (*str==' ' || *str=='\t')
      str++;

  return(str);
}



char *delete_wspaces_end(char *str)
{
  char *p;

  if (str) {
    for (p = str+strlen(str)-1 ; p>=str && (*p==' ' || *p=='\t') ; p--)
      *p = '\0';
  }

  return(str);
}



/* Addresses to Alias List */
struct AliasItem *AdrsToAList(char *adrs)
{
  char *p,*ptr;
  long klammer=0L;
  BOOL gans = FALSE;
  struct AliasItem *list = NULL;

  if (adrs && strlen(adrs) && (ptr = malloc(strlen(adrs)+2))) {

    strcpy(ptr,adrs);
    ptr[strlen(ptr)+1] = '\0';    /* TWO null bytes !!!! */

    p = ptr;

    while (*p) {
      if (*p=='\t') {
        *p = ' ';
        p++;
      }
      else if (*p=='\r'  || *p=='\n') {
        char *c=p;
        while(*c) {
          *c = *(c+1);
          c++;
        }
      }
      else
        p++;
    }

    p = ptr;

    while (*p || *(p-1)) {
      if (*p=='\0' || (*p==',' && !klammer && !gans)) {
        char *ptrend = p-1;
        while (ptrend>=ptr && *ptrend==' ')
          ptrend--;
        ptrend++;
        *ptrend='\0';
        while(*ptr==' ')
          ptr++;
        if (strlen(ptr))
          PutAlias(&list,ptr,GetAlias(AliasList,ptr));
        /*printf("adr: %s, %s\n",ptr,GetAlias(AliasList,ptr));*/
        /*printf("adr: -> %s <-\n",strlen(ptr)?ptr:"(leer)");*/
        ptr=p+1;
      }
      else if (*p=='(' || *p=='<' || *p=='[' || *p=='{')
        klammer++;
      else if (*p==')' || *p=='>' || *p==']' || *p=='}')
        klammer--;
      else if (*p=='\"')
        gans=!gans;
      p++;
    }
  }

  return(list);
}

