Logo Search packages:      
Sourcecode: xa version File versions  Download package

xap.c

/* xa65 - 65xx/65816 cross-assembler and utility suite
 *
 * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

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

#include "xah.h"
#include "xah2.h"

#include "xa.h"
#include "xad.h"
#include "xal.h"
#include "xam.h"
#include "xap.h"
#include "xar.h"
#include "xat.h"

char s[MAXLINE];
Datei *filep;

static int tcompare(char *, char **, int);
static int pp_replace(char *, char *, int, int);
static int searchdef(char *);
static int fgetline(char *, int len, int *rlen, FILE *);

static int icl_open(char *), pp_ifdef(char *), pp_ifndef(char *);
static int pp_else(char *), pp_endif(char *);
static int pp_echo(char *), pp_if(char *), pp_print(char *),
pp_prdef(char *);
static int pp_ifldef(char *), pp_iflused(char *);
static int pp_undef(char *);

#define   VALBEF    6
#define   ANZBEF    13

static char *cmd[] = {
      "echo", "include", "define", "undef", "printdef", "print",
      "ifdef", "ifndef", "else", "endif",
      "ifldef", "iflused", "if"
};

static int (*func[]) (char *) = {
      pp_echo, icl_open, pp_define, pp_undef,
      pp_prdef, pp_print, pp_ifdef, pp_ifndef,
      pp_else, pp_endif, pp_ifldef, pp_iflused, pp_if
};

static char *mem;
static unsigned long memfre;
static int nlf;
static int nff;
static int hashindex[256];

static List *liste;
static unsigned int rlist;
static int fsp;
static int loopfl;
static Datei flist[MAXFILE + 1];
static char in_line[MAXLINE];

int pp_comand(char *t)
{
      int i, l, er = 1;

      i = tcompare(t, cmd, ANZBEF);

      if (i >= 0) {
            if (loopfl && (i < VALBEF))
                  er = 0;
            else {
                  l = (int)strlen(cmd[i]);
                  while (isspace(t[l]))
                        l++;

                  er = (*func[i]) (t + l);
            }
      }
      return er;
}

int pp_ifdef(char *t)
{
      loopfl = (loopfl << 1) + (searchdef(t) ? 0 : 1);

      return 0;
}

int pp_ifndef(char *t)
{
      loopfl = (loopfl << 1) + (searchdef(t) ? 1 : 0);

      return 0;
}

int pp_ifldef(char *t)
{
      loopfl = (loopfl << 1) + (ll_pdef(t) ? 1 : 0);

      return 0;
}

int pp_iflused(char *t)
{
      int n;

      loopfl = (loopfl << 1) + (ll_search(t, &n) ? 1 : 0);

      return 0;
}

int pp_echo(char *t)
{
      int er;

      if ((er = pp_replace(s, t, -1, rlist)))
            errout(er);
      else {
            logout(s);
            logout("\n");
      }

      return 0;
}

int pp_print(char *t)
{
      int f, a, er;

      logout(t);

      if ((er = pp_replace(s, t, -1, rlist))) {
            logout("\n");
            errout(er);
      } else {
            logout("=");
            logout(s);
            logout("=");
            er = b_term(s, &a, &f, pc[segment]);
            if (er) {
                  logout("\n");
                  errout(er);
            } else {
                  sprintf(s, "%d\n", a);
                  logout(s);
            }
      }

      return 0;
}

int pp_if(char *t)
{
      int a, f, l, er;

      if ((er = pp_replace(s, t, -1, rlist)))
            errout(er);
      else {
            dsb_len = 1;
            f = b_term(s, &a, &l, pc[segment]);
            dsb_len = 0;

            if ((!loopfl) && f)
                  errout(f);
            else
                  loopfl = (loopfl << 1) + (a ? 0 : 1);
      }

      return 0;
}

int pp_else(char *t)
{
      (void)t; /* quench warning */

      loopfl ^= 1;

      return 0;
}

int pp_endif(char *t)
{
      (void)t; /* quench warning */

      loopfl = loopfl >> 1;

      return 0;
}

/* pp_undef is a great hack to get it working fast... */
int pp_undef(char *t)
{
      int i;

      if ((i = searchdef(t))) {
            i += rlist;
            liste[i].s_len = 0;
      }

      return 0;
}

int pp_prdef(char *t)
{
      char *x;
      int i, j;

      if ((i = searchdef(t))) {
            i += rlist;
            x = liste[i].search;
            sprintf(s, "\n%s", x);
            if (liste[i].p_anz) {
                  sprintf(s + strlen(s), "(");
                  for (j = 0; j < liste[i].p_anz; j++) {
                        x += strlen(x) + 1;
                        sprintf(s + strlen(s), "%s%c", x,
                              (liste[i].p_anz - j -
                               1) ? ',' : ')');
                  }
            }
            sprintf(s + strlen(s), "=%s\n", liste[i].replace);
            logout(s);
      }

      return (E_OK);
}

int searchdef(char *t)
{
      int i = 0, j, k, l = 0;

      while (t[l] != ' ' && t[l] != '\0')
            l++;

      if (rlist) {
            i = hashindex[hashcode(t, l)];
            /*for(i=0;i<rlist;i++) */
            do {
                  k = liste[i].s_len;
                  j = 0;

                  if (k && (k == l)) {
                        while ((t[j] == liste[i].search[j])
                               && j < k)
                              j++;
                        if (j == k)
                              break;
                  }

                  if (!i) {
                        i = rlist;
                        break;
                  }

                  i = liste[i].nextindex;

            } while (1);
      }

      return i - rlist;
}

int ga_pp(void)
{
      return rlist;
}

int gm_pp(void)
{
      return ANZDEF;
}

long gm_ppm(void)
{
      return MAXPP;
}

long ga_ppm(void)
{
      return MAXPP - memfre;
}

int pp_define(char *k)
{
      int i, er = E_OK, hash, rl;
      char h[MAXLINE * 2], *t;
      unsigned int j;

      t = k;

      if (rlist >= ANZDEF || memfre < MAXLINE * 2)
            return E_NOMEM;

      rl = rlist++;

      liste[rl].search = mem;

      for (i = 0; (t[i] != ' ') && (t[i] != '\0') && (t[i] != '('); i++)
            *mem++ = t[i];

      *mem++ = '\0';
      memfre -= i + 1;
      liste[rl].s_len = i;
      liste[rl].p_anz = 0;

      if (t[i] == '(') {
            while (t[i] != ')' && t[i] != '\0') {
                  i++;
                  liste[rl].p_anz++;
                  for (j = 0;
                       t[i + j] != ')' && t[i + j] != ','
                       && t[i + j] != '\0'; j++);
                  if (j < memfre) {
                        strncpy(mem, t + i, j);
                        mem += j;
                        *mem++ = '\0';
                        memfre -= j + 1;
                  }
                  i += j;
            }
            if (t[i] == ')')
                  i++;
      }
      while (t[i] == ' ')
            i++;
      t += i;

      pp_replace(h, t, -1, 0);

      t = h;

      liste[rl].replace = mem;
      strcpy(mem, t);
      mem += strlen(t) + 1;

      if (!er) {
            hash = hashcode(liste[rl].search, liste[rl].s_len);
            liste[rl].nextindex = hashindex[hash];
            hashindex[hash] = rl;
      } else
            rlist = rl;

      return er;
}

int tcompare(char s[], char *v[], int n)
{
      int i, j, l;
      static char t[MAXLINE];

      for (i = 0; s[i] != '\0'; i++)
            t[i] = tolower(s[i]);
      t[i] = '\0';

      for (i = 0; i < n; i++) {
            l = (int)strlen(v[i]);

            for (j = 0; j < l; j++) {
                  if (t[j] != v[i][j])
                        break;
            }
            if (j == l)
                  break;
      }
      return (i == n) ? -1 : i;
}

int pp_replace(char *to, char *ti, int a, int b)
{
      char *t = to, c, *x, *y, *mx, *rs;
      int i, l, n, sl, d, ld, er = E_OK, hkfl, klfl;
      char fti[MAXLINE], fto[MAXLINE];

      strcpy(t, ti);

      if (rlist) {
            while (t[0] != '\0') {
                  while (!isalpha(t[0]) && t[0] != '_') {
                        if (t[0] == '\0') {
                              break;      /*return(E_OK); */
                        } else {
                              t++;
                              ti++;
                        }
                  }

                  for (l = 0; isalnum(t[l]) || t[l] == '_'; l++)
                        /* nothing */;

                  ld = l;

                  if (a < 0) {
                        n = hashindex[hashcode(t, l)];

                        do {
                              sl = liste[n].s_len;

                              if (sl && (sl == l)) {
                                    i = 0;
                                    x = liste[n].search;
                                    while (t[i] == *x++
                                           && t[i])
                                          i++;

                                    if (i == sl) {
                                          rs = liste[n].
                                              replace;

                                          if (liste[n].p_anz) {
                                                strcpy(fti,
                                                       liste
                                                       [n].
                                                       replace);

                                                if (rlist +
                                                    liste
                                                    [n].
                                                    p_anz
                                                    >=
                                                    ANZDEF
                                                    ||
                                                    memfre
                                                    <
                                                    MAXLINE
                                                    * 2)
                                                      er = E_NOMEM;
                                                else {
                                                      y = t + sl;
                                                      x = liste[n].search + sl + 1;
                                                      if (*y != '(')
                                                            er = E_SYNTAX;
                                                      else {
                                                            mx = mem - 1;
                                                            for (i = 0; i < liste[n].p_anz; i++) {
                                                                  liste
                                                                      [rlist
                                                                       +
                                                                       i].
                                                                      search
                                                                      =
                                                                      x;
                                                                  liste
                                                                      [rlist
                                                                       +
                                                                       i].
                                                                      s_len
                                                                      =
                                                                      (int)
                                                                      strlen
                                                                      (x);
                                                                  x += strlen(x) + 1;
                                                                  liste
                                                                      [rlist
                                                                       +
                                                                       i].
                                                                      p_anz
                                                                      =
                                                                      0;
                                                                  liste
                                                                      [rlist
                                                                       +
                                                                       i].
                                                                      replace
                                                                      =
                                                                      mx
                                                                      +
                                                                      1;
                                                                  c = *(++mx) = *(++y);
                                                                  hkfl = klfl = 0;
                                                                  while
                                                                      (c
                                                                       !=
                                                                       '\0'
                                                                       &&
                                                                       ((hkfl != 0 || klfl != 0)
                                                                        ||
                                                                        (c
                                                                         !=
                                                                         ','
                                                                         &&
                                                                         c
                                                                         !=
                                                                         ')')
                                                                       )
                                                                      ) {
                                                                        if (c == '\"')
                                                                              hkfl = hkfl ^ 1;
                                                                        if (!hkfl) {
                                                                              if (c == '(')
                                                                                    klfl++;
                                                                              if (c == ')')
                                                                                    klfl--;
                                                                        }
                                                                        c = *(++mx) = *(++y);
                                                                  }
                                                                  *mx = '\0';
                                                                  if (c != ((i == liste[n].p_anz - 1) ? ')' : ',')) {
                                                                        er = E_ANZPAR;
                                                                        break;
                                                                  }
                                                            }
                                                            if (!er)
                                                                  er = pp_replace(fto, fti, rlist, rlist + i);
                                                            sl = (int)((long)y + 1L - (long)t);
                                                            rs = fto;
                                                      }
                                                }
                                                if (er)
                                                      return
                                                          (er);
                                          }

                                          d = (int)
                                              strlen(rs) -
                                              sl;

                                          if (strlen(to) +
                                              d >= MAXLINE)
                                                return
                                                    (E_NOMEM);

                                          if (d)
                                                strcpy(t +
                                                       sl +
                                                       d,
                                                       ti +
                                                       sl);

                                          i = 0;
                                          while ((c = rs[i]))
                                                t[i++] = c;
                                          l = sl + d;
                                          break;
                                    }
                              }
                              if (!n)
                                    break;

                              n = liste[n].nextindex;

                        } while (1);
                  } else {
                        for (n = b - 1; n >= a; n--) {
                              sl = liste[n].s_len;

                              if (sl && (sl == l)) {
                                    i = 0;
                                    x = liste[n].search;
                                    while (t[i] == *x++
                                           && t[i])
                                          i++;

                                    if (i == sl) {
                                          rs = liste[n].
                                              replace;
                                          d = (int)
                                              strlen(rs) -
                                              sl;

                                          if (strlen(to) +
                                              d >= MAXLINE)
                                                return
                                                    (E_NOMEM);
                                          if (d)
                                                strcpy(t +
                                                       sl +
                                                       d,
                                                       ti +
                                                       sl);

                                          i = 0;
                                          while ((c = rs[i]))
                                                t[i++] = c;
                                          l += d;
                                          break;
                                    }
                              }
                        }
                  }
                  ti += ld;
                  t += l;
            }
      }
      return E_OK;
}

int pp_init(void)
{
      int er;

      for (er = 0; er < 256; er++)
            hashindex[er] = 0;

      fsp = 0;

      er = 0;
      mem = malloc(MAXPP);

      if (!mem)
            er = E_NOMEM;

      memfre = MAXPP;
      rlist = 0;
      nlf = 1;
      nff = 1;

      if (!er) {
            liste = malloc((long)ANZDEF * sizeof (List));
            if (!liste)
                  er = E_NOMEM;
      }

      return er;
}

int pp_open(char *name)
{
      FILE *fp;

      fp = xfopen(name, "r");

      /* we have to alloc it dynamically to make the name survive another
         pp_open - it's used in the cross-reference list */
      flist[0].fname = malloc(strlen(name) + 1);
      if (!flist[0].fname) {
            fprintf(stderr, "Oops, no more memory!\n");
            exit(1);
      }
      strcpy(flist[0].fname, name);
      flist[0].fline = 0;
      flist[0].bdepth = b_depth();
      flist[0].filep = fp;
      flist[0].flinep = NULL;

      return (long)fp == 0l;
}

void pp_close(void)
{
      if (flist[fsp].bdepth != b_depth()) {
            fprintf(stderr,
                  "Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
                  flist[fsp].fname, flist[fsp].bdepth, b_depth());
      }
      fclose(flist[fsp].filep);
}

void pp_end(void)
{
      /* return */
}

Datei *pp_getidat(void)
{
      return &flist[fsp];
}

int icl_close(int *c)
{
      if (!fsp)
            return E_EOF;

      if (flist[fsp].bdepth != b_depth()) {
            fprintf(stderr,
                  "Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
                  flist[fsp].fname, flist[fsp].bdepth, b_depth());
      }

      fclose(flist[fsp--].filep);
      nff = 1;
      *c = '\n';

      return E_OK;
}

int icl_open(char *tt)
{
      FILE *fp2;
      int j, i = 0;

      pp_replace(s, tt, -1, rlist);

      if (fsp >= MAXFILE)
            return -1;

      if (s[i] == '<' || s[i] == '"')
            i++;

      for (j = i; s[j]; j++)
            if (s[j] == '>' || s[j] == '"')
                  s[j] = '\0';

      fp2 = xfopen(s + i, "r");

      if (!fp2)
            return E_FNF;

      setvbuf(fp2, NULL, _IOFBF, BUFSIZE);

      fsp++;

      /* we have to alloc it dynamically to make the name survive another
         pp_open - it's used in the cross-reference list */
      flist[fsp].fname = malloc(strlen(s + i) + 1);
      if (!flist[fsp].fname) {
            fprintf(stderr, "Oops, no more memory!\n");
            exit(1);
      }
      strcpy(flist[fsp].fname, s + i);
      flist[fsp].fline = 0;
      flist[fsp].bdepth = b_depth();
      flist[fsp].flinep = NULL;
      flist[fsp].filep = fp2;
      nff = 1;

      return 0;
}

int pgetline(char *t)
{
      int c, er = E_OK;
      int rlen, tlen;

      loopfl = 0;

      filep = flist + fsp;

      do {
            c = fgetline(in_line, MAXLINE, &rlen, flist[fsp].filep);
            /* continuation lines */
            tlen = rlen;
            while (c == '\n' && tlen && in_line[tlen - 1] == '\\') {
                  c = fgetline(in_line + tlen - 1, MAXLINE - tlen,
                             &rlen, flist[fsp].filep);
                  tlen += rlen - 1;
            }
            if (in_line[0] == '#') {
                  if ((er = pp_comand(in_line + 1))) {
                        if (er != 1) {
                              logout(in_line);
                              logout("\n");
                        }
                  }
            } else
                  er = 1;

            if (c == EOF)
                  er = icl_close(&c);

      } while (!er || (loopfl && er != E_EOF));

      if (!er || loopfl)
            in_line[0] = '\0';
      er = (er == 1) ? E_OK : er;

      if (!er)
            er = pp_replace(t, in_line, -1, rlist);

      if (!er && nff)
            er = E_NEWFILE;
      if (!er && nlf)
            er = E_NEWLINE;
      nlf = nff = 0;

      filep = flist + fsp;
      filep->flinep = in_line;

      return er;
}

int rgetc(FILE *fp)
{
      static int c, d, fl;

      fl = 0;

      do {
            /* remove ^M for unices */
            while ((c = getc(fp)) == 13);

            if (fl && (c == '*')) {
                  if ((d = getc(fp)) != '/')
                        ungetc(d, fp);
                  else {
                        fl--;
                        while ((c = getc(fp)) == 13);
                  }
            }

            if (c == '\n') {
                  flist[fsp].fline++;
                  nlf = 1;
            } else if (c == '/') {
                  if ((d = getc(fp)) != '*')
                        ungetc(d, fp);
                  else
                        fl++;
            }

      } while (fl && (c != EOF));

      return (c - '\t') ? c : ' ';
}

int fgetline(char *t, int len, int *rlen, FILE *fp)
{
      static int c, i;

      i = 0;

      do {
            c = rgetc(fp);

            if (c == EOF || c == '\n') {
                  t[i] = '\0';
                  break;
            }
            t[i] = c;
            i = (i < len - 1) ? i + 1 : len - 1;
      } while (1);

      *rlen = i;

      return c;
}

Generated by  Doxygen 1.6.0   Back to index