home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include "defs.h"
- #include "externs.h"
-
- int mopt;
- int in_macro;
- int expand_macro;
- char marg[8][10][80];
- int midx;
- int mcounter, mcntmax;
- int mcntstack[8];
- struct t_line *mstack[8];
- struct t_line *mlptr;
- struct t_macro *macro_tbl[256];
- struct t_macro *mptr;
-
- /* .macro pseudo */
-
- do_macro(int *ip)
- {
- if (pass == LAST_PASS)
- println();
- else {
- if (expand_macro) {
- error("Can not nest macro definitions!");
- return;
- }
- if (lablptr == NULL) {
- error("No name for the macro!");
- return;
- }
- if (!stremove())
- return;
- if (!check_eol(ip))
- return;
- if (!macro_install())
- return;
- }
- in_macro = 1;
- }
-
- /* .endm pseudo */
-
- do_endm(int *ip)
- {
- error("Unexpected ENDM!");
- return;
- }
-
- /* search for a macro */
-
- macro_look(int idx)
- {
- char name[32];
- char c;
- int hash;
- int i;
-
- i = 0;
- hash = 0;
- while(c = prlnbuf[idx]) {
- if (c == ' ' || c == '\t' || c == ';')
- break;
- if (!isalnum(c) && c != '_')
- return (0);
- if (isdigit(c) && i == 0)
- return (0);
- name[i++] = c;
- hash += c;
- hash = (hash << 3) + (hash >> 5) + c;
- idx++;
- if (i > 31)
- return (0);
- }
-
- name[i] = '\0';
- hash &= 0xFF;
- mptr = macro_tbl[hash];
- while (mptr) {
- if (!strcmp(name, mptr->name))
- break;
- mptr = mptr->next;
- }
- if (mptr)
- return (macro_extract(idx));
- else
- return (0);
- }
-
- /* extract macro arguments */
-
- macro_extract(int idx)
- {
- char *ptr;
- char c, t;
- int i, j, f, arg;
-
- if (midx == 7) {
- error("Too many nested macro calls!");
- return (-1);
- }
- mcntstack[midx] = mcounter;
- mstack[midx++] = mlptr;
- arg = 0;
- ptr = marg[midx][0];
- for (i = 0; i < 9; i++) {
- *ptr = '\0';
- ptr += 80;
- }
- ptr = marg[midx][0];
- for (;;) {
- while (c = prlnbuf[idx]) {
- if (c != ' ' && c != '\t')
- break;
- idx++;
- }
- switch (c) {
- case ',':
- arg++;
- idx++;
- ptr += 80;
- if (arg == 9) {
- error("Too many arguments for a macro!");
- return (-1);
- }
- break;
-
- case '{':
- idx++;
- case '\"':
- i = 0;
- if (c == '{')
- t = '}';
- else
- t = '\"';
- while (c = prlnbuf[idx]) {
- ptr[i++] = c;
- if (i == 80) {
- error("Invalid macro argument length!");
- return (-1);
- }
- if (c == t)
- break;
- idx++;
- }
- switch (c) {
- case '\0':
- error("Unterminated ASCII string!");
- return (-1);
- case '}':
- i--;
- break;
- }
- while (c = prlnbuf[++idx]) {
- if (c != ' ' && c != '\t')
- break;
- }
- if (c != ',' && c != ';') {
- error("Syntax error!");
- return (-1);
- }
- ptr[i] = '\0';
- break;
-
- case ';':
- case '\0':
- return (1);
-
- default:
- i = 0;
- j = 0;
- f = 0;
- while (c = prlnbuf[idx]) {
- if (c == ',' || c == ';')
- break;
- if (f) {
- if (c != ' ') {
- for (;i < j; i++)
- ptr[i++] = ' ';
- ptr[i++] = c;
- f = 0;
- }
- }
- else if (c == ' ')
- f = 1;
- else
- ptr[i++] = c;
- if (i == 80) {
- error("Invalid macro argument length!");
- return (-1);
- }
- idx++;
- j++;
- }
- ptr[i] = '\0';
- break;
- }
- }
- }
-
- /* install a macro in the hash table */
-
- macro_install()
- {
- char c;
- int hash;
- int i;
-
- hash = 0;
- for (i = 1; i <= symbol[0]; i ++) {
- c = symbol[i];
- if (!isalnum(c) && c != '_') {
- error("Invalid macro name!");
- return (0);
- }
- hash += c;
- hash = (hash << 3) + (hash >> 5) + c;
- }
- hash &= 0xFF;
- mptr = macro_tbl[hash];
- while (mptr) {
- if (!strcmp(mptr->name, &symbol[1]))
- break;
- mptr = mptr->next;
- }
- if (mptr) {
- error("Macro defined twice!");
- return (0);
- }
- if ((mptr = (void *)malloc(sizeof(struct t_macro))) == NULL) {
- error("Out of memory!");
- return (0);
- }
- strcpy(mptr->name, &symbol[1]);
- mptr->line = NULL;
- mptr->next = macro_tbl[hash];
- macro_tbl[hash] = mptr;
- mlptr = NULL;
- return (1);
- }
-
-