/* * VAR.C * * Variables and Macros */ #include "defs.h" #define MACNODE struct _MACNODE MACNODE { MNODE Node; char *Name; /* variable name */ char *MacName; /* replace with.. */ short MacLen; short NameLen; short NormalEntry; }; MLIST MacList = { (MNODE *)&MacList.mlh_Tail, NULL, (MNODE *)&MacList.mlh_Head }; MLIST ColList = { (MNODE *)&ColList.mlh_Tail, NULL, (MNODE *)&ColList.mlh_Head }; /* * var points to begining, str points to the '=' */ void MacroAssign(var, str) char *var, *str; { MACNODE *node = malloc(sizeof(MACNODE)); while (str != var && (*str == '=' || *str == ' ' || *str == '\t')) --str; ++str; node->NameLen = str - var; node->Name = malloc(node->NameLen + 1); movmem(var, node->Name, node->NameLen); node->Name[node->NameLen] = 0; while (*str && *str != '=') ++str; if (*str == '=') ++str; while (*str && (*str == ' ' || *str == '\t')) ++str; node->MacLen = strlen(str); node->MacName = malloc(node->MacLen + 1); strcpy(node->MacName, str); AddHead(&MacList, node); } MacroReplace(spec, buf) register char *buf; { char *base = buf; char cext; short error = 8192; while (*buf && --error) { register short i; char *found = NULL; short falloced = 0; if ((buf[0] != '$' && buf[0] != '%') || buf[1] != '(') { ++buf; continue; } for (i = 2; buf[i] && buf[i] != ')' && buf[i] != ':'; ++i) { if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); } if (buf[i] != ')' && buf[i] != ':') { ++buf; continue; } cext = (buf[i] == ':'); { register MACNODE *node; register short len = i - 2; char *search = buf + 2; /* * Check normal macro variables */ for (node = GetHead(&MacList); node; node = GetSucc(node)) { if (node->NameLen == len && strncmp(node->Name, search, len) == 0) { found = node->MacName; break; } } percind: if (found && buf[0] == '%') { search = found; len = strlen(found); if (falloced) { free(found); falloced = 0; } node = NULL; found = NULL; } /* * Check collections */ if (!found && spec) { for (node = GetHead(&ColList); node; node = GetSucc(node)) { if (node->NameLen == len && strncmp(node->Name, search, len) == 0) { found = node->MacName; break; } } } /* * Still nothing! If it is a wildcard, try to find a match * with item(s) on the collection list. Else check the * enviroment. */ if (!found) { char c = search[len]; search[len] = 0; if (IsWildCard(search)) { for (node = GetHead(&ColList); node; node = GetSucc(node)) { if (node->NormalEntry && WildCmp(search, node->MacName)) { if (found) { char *new = malloc(strlen(found) + strlen(node->MacName) + 2); strcpy(new, found); strcat(new, " "); strcat(new, node->MacName); if (falloced) free(found); found = new; falloced = 1; } else { found = node->MacName; } } } } else { found = NULL; /* mountrequest(0); if (found = GetDEnv(search)) falloced = 1; mountrequest(1); */ } search[len] = c; if (found) goto percind; } } if (found && cext) { /* found the string & extension */ char *w1, *w2; char *xbuf = malloc(256); char *res; char *rstr = malloc(1); register char *ptr; register short len; rstr[0] = 0; ++i; if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); if (buf[i] != '\"') { printf("Quote missing: %s\n", buf); xexit(30); } ++i; w1 = buf + i; while (buf[i] && buf[i] != '\"') { if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); else ++i; } if (buf[i] != '\"') { printf("Quote missing: %s\n", buf); xexit(30); } buf[i++] = 0; if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); if (buf[i++] != ':') { printf("Colon missing: %s\n", buf); xexit(30); } if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); if (buf[i++] != '\"') { puts("QM"); xexit(30); } w2 = buf + i; while (buf[i] && buf[i] != '\"') { if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); else ++i; } if (buf[i] != '\"') { puts("QM2"); xexit(30); } buf[i++] = 0; if ((buf[i] == '$' || buf[i] == '%') && buf[i+1] == '(') MacroReplace(spec, buf + i); if (buf[i] != ')') { puts("QM3"); xexit(30); } /* * Now parse found string and call VirtuoExpand(w2, w1, file) */ for (ptr = found; *ptr;) { while (*ptr == ' ' || *ptr == '\t') ++ptr; if (!ptr[0]) break; for (len = 0; ptr[len] && ptr[len] != ' ' && ptr[len] != '\t'; ++len); movmem(ptr, xbuf, len); ptr += len; xbuf[len] = 0; /* printf("VEXT '%s' '%s' '%s'\n", w2, w1, xbuf); */ if (res = VirtuoExpand(w2, w1, xbuf)) { char *tmp = malloc(strlen(rstr) + strlen(res) + 2); strcpy(tmp, rstr); if (tmp[0]) strcat(tmp, " "); strcat(tmp, res); free(rstr); rstr = tmp; } } if (falloced) free(found); found = rstr; falloced = 1; free(xbuf); } /* * replace the area buf + 0; < buf + i + 1 (len i + 1) * with 'found' */ if (found) { register short flen = strlen(found); register short len = i + 1; movmem(buf + len, buf + flen, strlen(buf + len) + 1); movmem(found, buf, flen); } else { buf += i + 1; } if (falloced) free(found); } return(buf - base); } ResetVarCollector() { register MACNODE *node; #ifdef DEBUG2 puts("RESETVARCOL"); #endif while (node = RemHead(&ColList)) { free(node->Name); free(node->MacName); free(node); } } AddVarCollector(str, basestr, normal) char *str, *basestr; { register MACNODE *node; register char *ptr; short newlen = strlen(str); #ifdef DEBUG2 printf("ADDVARCOLLECTOR: %s += %s\n", basestr, str); #endif for (node = GetHead(&ColList); node; node = GetSucc(node)) { if (strcmp(node->Name, basestr) == 0) break; } if (!node) { node = malloc(sizeof(MACNODE)); node->NameLen = strlen(basestr); node->Name = malloc(node->NameLen+1); strcpy(node->Name, basestr); node->MacLen = 0; node->MacName = malloc(1); node->MacName[0] = 0; AddTail(&ColList, node); } node->NormalEntry = normal; ptr = malloc(node->MacLen + newlen + 2); strcpy(ptr, node->MacName); if (node->MacLen) strcat(ptr, " "); strcat(ptr, str); free(node->MacName); node->MacName = ptr; node->MacLen = strlen(ptr); }