home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 2: PC
/
frozenfish_august_1995.bin
/
bbs
/
d07xx
/
d0770.lha
/
Uedit
/
Kienitz.LZH
/
frx
/
frx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-14
|
9KB
|
355 lines
/* frx -- like rx but different -- see frx.doc */
#include <exec/exec.h>
#include <libraries/dosextens.h>
#include <rexx/storage.h>
#include <rexx/rxslib.h>
#include <paul.h>
struct RxsLib *RexxSysBase;
struct RexxMsg * CreateRexxMsg(struct MsgPort *reply, str extension, str host);
void DeleteRexxMsg(struct RexxMsg *message);
long FillRexxMsg(struct RexxMsg *message, long count, long mask);
void ClearRexxMsg(struct RexxMsg *message, long count);
void /* ubyte */ StrcpyU(str dest, str source, long length);
short StrcmpU(str a, str b, long length);
char ToUpper(char c);
struct RexxRsrc *FindRsrcNode(struct List *list, char *name, long type);
void DeleteArgstring(str argstring);
#pragma amicall(RexxSysBase, 0x90, CreateRexxMsg(a0, a1, d0))
#pragma amicall(RexxSysBase, 0x96, DeleteRexxMsg(a0))
#pragma amicall(RexxSysBase, 0xA2, FillRexxMsg(a0, d0, d1))
#pragma amicall(RexxSysBase, 0x9C, ClearRexxMsg(a0, d0))
#pragma amicall(RexxSysBase, 0x114, StrcpyU(a0, a1, d0))
#pragma amicall(RexxSysBase, 0x102, StrcmpU(a0, a1, d0))
#pragma amicall(RexxSysBase, 0x126, ToUpper(d0))
#pragma amicall(RexxSysBase, 0xB4, FindRsrcNode(a0, a1, d0))
#pragma amicall(RexxSysBase, 0x84, DeleteArgstring(a0))
#asm
public _ErrorMsg ; glue routine
_ErrorMsg: move.l _RexxSysBase,a6
jsr -$60(a6)
move.l a0,d0
addq.l #8,d0 ; NexxStr * => str
rts
public _CVa2i ; glue routine
_CVa2i: move.l _RexxSysBase,a6
jsr -$12C(a6)
move.l d1,(a3) ; number of digits scanned
rts
#endasm
str ErrorMsg(long code);
long CVa2i(str buf, long *digits);
#pragma regcall(ErrorMsg(d0))
#pragma regcall(CVa2i(a0,a3))
typedef struct {
short argc, bargc;
char argline[600]; /* bigger than necessary */
str argv[32]; /* all we can use */
str barg[16];
ubyte bits[16];
} glob;
#define NOGOBBLE 2
#define MATCHONLY 4
#define REQUIRED 8
void spew(str s)
{
register BPTR o = ThisProcess()->pr_COS;
if (o) Write(o, s, (long) strlen(s));
}
/* This version of cliparse features handling of internal quotes BCPL-style
with *" instead of Manx "". *N and *E are supported. With all args
except argv[0] (the command name) you can see if it was quoted by looking
at whether argv[n][-1] is a double-quote or a nul. */
void cliparse(glob *g, long alen, register str ap, bool skippy)
{
register short coml, al;
bool quoted, star;
register ubyte c;
register str poik;
if (skippy) {
g->argc = 2;
coml = strlen(g->argline) + 1;
coml += strlen(g->argline + coml);
} else {
poik = bip(char, bip(struct CommandLineInterface,
ThisProcess()->pr_CLI)->cli_CommandName);
coml = *poik;
strncpy(g->argline, poik + 1, (size_t) coml);
g->argline[coml] = '\0';
*g->argv = &g->argline[0];
g->argc = 1;
}
if (al = alen) {
poik = g->argline + coml + 1;
for (;;) {
while (al && *ap <= ' ') ap++, al--;
if (!al) break;
star = false;
if (quoted = *ap == '"')
*(poik++) = *(ap++), al--;
g->argv[g->argc] = poik;
if (++g->argc > 30) break;
while (al && (c = (ubyte) *ap) &&
(quoted ? star || c != '"' : c > ' ')) {
if (star) {
if (ToUpper(c) == 'E') c = 27;
else if (ToUpper(c) == 'N') c = '\n';
star = false;
*(poik++) = c;
} else if (!(star = quoted && c == '*'))
*(poik++) = c;
ap++, al--;
}
if (*ap == '"') ap++, al--;
*(poik++) = '\0';
}
}
}
str ClipNodeVal(str name) /* why wasn't this provided? */
{
struct RexxRsrc *cn = FindRsrcNode(&RexxSysBase->rl_ClipList, name, 0);
if (cn) return (str) cn->rr_Arg1; /****** ?????? ******/
else return null; /* What about the arg's LENGTH? */
}
short WhatKeyword(str word, register str plate, glob *g)
{
short w;
bool start = true;
for (w = 0; *plate; plate++) {
if (start && !g->barg[w]) {
short l = 0;
register str p = plate;
while (*p && *p != '/' && *p != ',' && *p != '=')
p++, l++;
if (l == strlen(word) && !StrcmpU(word, plate, (long) l))
return w;
start = false;
} else if (*plate == '=')
start = true;
else if (*plate == ',')
start = true, w++;
else start = false;
}
return -1;
}
void Chew(glob *g, str plate)
{
short i, n;
str t;
bool slash = false;
for (t = plate; *t; t++)
if (*t == ',')
g->bargc++;
else if (*t == '/')
slash = true;
else if (slash) {
char tt = ToUpper(*t);
if (tt == 'S')
g->bits[g->bargc] |= NOGOBBLE | MATCHONLY;
else if (tt == 'K')
g->bits[g->bargc] |= MATCHONLY;
else if (tt == 'A')
g->bits[g->bargc] |= REQUIRED;
slash = false;
}
g->bargc++;
for (i = 2; i < g->argc; i++)
if (!g->argv[i][-1] && ~(n = WhatKeyword(g->argv[i], plate, g))) {
if (!(g->bits[n] & NOGOBBLE)) {
g->argv[i] = null;
if (!g->argv[++i]) {
g->argc = 1001;
spew("Bad arguments: no value after template keyword.\n");
return;
}
} else { /* /S */
register str a = g->argv[i];
while (*a) *(a++) = ToUpper(*a);
}
g->barg[n] = g->argv[i];
g->argv[i] = null;
}
for (i = 2; i < g->argc; i++)
if (g->argv[i]) {
for (n = 0; n < g->bargc; n++)
if (!g->barg[n] && !(g->bits[n] & MATCHONLY)) break;
if (n >= g->bargc) {
g->argc = 1002;
spew("Bad arguments: too many for template.\n");
return;
}
g->barg[n] = g->argv[i];
}
for (n = 0; n < g->bargc; n++)
if (!g->barg[n] && g->bits[n] & REQUIRED) {
g->argc = 1003;
spew("Bad arguments: required argument not given.\n");
return;
}
g->argc = g->bargc + 2;
for (n = 0; n < g->bargc; n++)
g->argv[n + 2] = g->barg[n];
g->argv[g->argc] = null;
}
long _main(long alen, str aptr)
{
struct MsgPort *duh, *zex;
struct RexxMsg *mess, *m2;
long air = 0, ret = 0;
short i;
glob g;
char clipname[300], newargline[300];
str a1, template;
memset(&g, 0, sizeof(g));
if (!(zex = FindPort("REXX")) ||
!(RexxSysBase = (adr) OpenLibrary("rexxsyslib.library", 0))) {
spew("No ARexx!\n");
air = ERROR_INVALID_RESIDENT_LIBRARY;
ret = 20;
goto quit5;
}
cliparse(&g, alen, aptr, false);
if (!g.argv[1] || (*g.argv[1] == '?' && !g.argv[1][1]
&& !g.argv[1][-1] && !g.argv[2])) {
spew("Usage: ");
spew(*g.argv);
spew(" RexxFunction [arg] [arg] ...\n");
ret = 20;
air = ERROR_LINE_TOO_LONG;
goto quit3;
}
a1 = g.argv[1];
if (!StrcmpU(a1, "REXX:", 5))
a1 += 5;
i = strlen(a1);
StrcpyU(clipname, a1, (long) i);
strcpy(clipname + i, "-TEMPLATE");
i = 0;
template = ClipNodeVal(clipname);
while (*g.argv[2] == '?' && !g.argv[2][1] && !g.argv[2][-1] && !g.argv[3]) {
if (Input()) {
if (template) {
spew(template);
spew(": ");
} else {
spew(clipname);
spew(" not found\nArguments: ");
}
alen = Read(Input(), newargline, 299);
if (alen < 0) alen = 0;
} else
alen = 0;
cliparse(&g, alen, newargline, true);
g.argv[g.argc] = null;
}
if (template)
Chew(&g, template);
/* we'll just ASSUME nobody deletes the template while we're using it */
if (g.argc > 17) {
if (g.argc < 100) spew("Fifteen function arguments maximum!\n");
air = ERROR_LINE_TOO_LONG;
ret = 20;
goto quit3;
}
if (!(duh = CreatePort(null, 0))) {
spew("Can't open message port!\n");
air = ERROR_NO_FREE_STORE;
ret = 20;
goto quit3;
}
if (!(mess = CreateRexxMsg(duh, null, null))) {
spew("Can't create RexxMsg!\n");
air = ERROR_NO_FREE_STORE;
ret = 20;
goto quit2;
}
for (i = 0; i < g.argc - 1; i++)
mess->rm_Args[i] = (adr) g.argv[i + 1];
if (!FillRexxMsg(mess, (long) g.argc - 1, 0)) {
spew("No memory!\n");
air = ERROR_NO_FREE_STORE;
ret = 20;
goto quit1;
}
mess->rm_Action = RXFUNC | RXFF_RESULT | g.argc - 1;
PutMsg(zex, (adr) mess);
WaitPort(duh);
while (!(m2 = (adr) GetMsg(duh)) || m2 != mess)
if (!m2) WaitPort(duh);
if (mess->rm_Result2)
if (mess->rm_Result1) {
str s = ErrorMsg(mess->rm_Result2);
spew("ARexx error: ");
spew((str) s);
spew(".\n");
ret = mess->rm_Result1;
if ((air = mess->rm_Result2) == 1) /* program not found */
ret = 10; /* instead of 5 */
} else {
struct RexxArg *r = (adr) ((str) mess->rm_Result2 - 8);
long l;
long x = CVa2i(r->ra_Buff, &l);
if (l == r->ra_Length)
ret = air = x;
else {
air = 47;
ret = 10;
spew("ARexx error: arithmetic conversion error.\n");
}
DeleteArgstring((str) mess->rm_Result2);
}
else
air = ret = mess->rm_Result1;
ClearRexxMsg(mess, (long) g.argc - 1);
quit1:
DeleteRexxMsg(mess);
quit2:
DeletePort(duh);
quit3:
CloseLibrary((adr) RexxSysBase);
quit5:
ThisProcess()->pr_Result2 = air;
return ret;
}