#include "prims.h"
#include "externs.h"
#include "version.h"
#include "mush.h"
#include <fcntl.h>
#include <sys/stat.h>
/* private globals */
extern inst *p_oper1, *p_oper2, *p_oper3, *p_oper4;
static inst temp1, temp2;
extern int p_result;
extern char p_buf[BUFFER_LEN];
static char *string;
extern int p_nargs;
void prims_stringcmp (__P_PROTO)
{
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING || p_oper2->type != PROG_STRING)
abort_interp("Non-string argument.");
p_result = string_compare(p_oper2->data.string ? p_oper2->data.string : "",
p_oper1->data.string ? p_oper1->data.string : "");
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_stringncmp (__P_PROTO)
{
CHECKOP(3);
p_oper1 = POP();
p_oper2 = POP();
p_oper3 = POP();
if (p_oper1->type != PROG_INTEGER) abort_interp("Non-integer argument.");
if (p_oper2->type != PROG_STRING || p_oper3->type != PROG_STRING)
abort_interp("Non-string argument.");
p_result = stringn_compare(p_oper3->data.string ? p_oper3->data.string : "",
p_oper2->data.string ? p_oper2->data.string : "", p_oper1->data.number);
CLEAR(p_oper1);
CLEAR(p_oper2);
CLEAR(p_oper3);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_strcmp(__P_PROTO)
{
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING || p_oper2->type != PROG_STRING)
abort_interp("Non-string argument.");
p_result = strcmp(p_oper2->data.string ? p_oper2->data.string : "",
p_oper1->data.string ? p_oper1->data.string : "");
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_strncmp(__P_PROTO)
{
p_oper1 = POP();
p_oper2 = POP();
p_oper3 = POP();
if (p_oper1->type != PROG_INTEGER) abort_interp("Non-integer argument.");
if (p_oper2->type != PROG_STRING || p_oper3->type != PROG_STRING)
abort_interp("Non-string argument.");
p_result = strncmp(p_oper3->data.string ? p_oper3->data.string : "",
p_oper2->data.string ? p_oper2->data.string : "", p_oper1->data.number);
CLEAR(p_oper1);
CLEAR(p_oper2);
CLEAR(p_oper3);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_strcut (__P_PROTO)
{
CHECKOP(2);
temp1 = *(p_oper1 = POP());
temp2 = *(p_oper2 = POP());
if (temp1.type != PROG_INTEGER) abort_interp("Non-integer argument (2)");
if (temp1.data.number < 0)
abort_interp("Argument must be a positive integer.");
if (temp2.type != PROG_STRING) abort_interp("Non-string argument (1)");
if (!temp2.data.string)
{
push(arg, top, PROG_STRING, 0);
push(arg, top, PROG_STRING, 0);
}
else
{
if (temp1.data.number > strlen(temp2.data.string))
{
push(arg, top, PROG_STRING, MIPSCAST dup_string(temp2.data.string));
push(arg, top, PROG_STRING, 0);
}
else
{
strncpy(p_buf, temp2.data.string, temp1.data.number);
p_buf[temp1.data.number] = '\0';
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
if (strlen(temp2.data.string) > temp1.data.number)
{
strncpy(p_buf, temp2.data.string + temp1.data.number,
strlen(temp2.data.string) - temp1.data.number + 1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
else
{
push(arg, top, PROG_STRING, 0);
}
}
}
CLEAR(&temp2);
}
void prims_strlen (__P_PROTO)
{
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (!p_oper1->data.string) p_result = 0;
else p_result = strlen(p_oper1->data.string);
CLEAR(p_oper1);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_strcat (__P_PROTO)
{
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING || p_oper2->type != PROG_STRING)
abort_interp("Non-string argument.");
if (!p_oper1->data.string && !p_oper2->data.string) string = NULL;
else if (!p_oper2->data.string) string = dup_string(p_oper1->data.string);
else if (!p_oper1->data.string) string = dup_string(p_oper2->data.string);
else if (strlen(p_oper1->data.string) + strlen(p_oper2->data.string)
> (BUFFER_LEN) - 1)
{
abort_interp("Operation would p_result in overflow.");
}
else
{
strncpy(p_buf, p_oper2->data.string, strlen(p_oper2->data.string));
strncpy(p_buf + strlen(p_oper2->data.string), p_oper1->data.string,
strlen(p_oper1->data.string) + 1);
string = dup_string(p_buf);
}
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_STRING, MIPSCAST string);
}
void prims_explode (__P_PROTO)
{
int i;
char *delimit;
CHECKOP(2);
temp1 = *(p_oper1 = POP());
temp2 = *(p_oper2 = POP());
if (temp1.type != PROG_STRING) abort_interp("Non-string argument (2)");
if (temp2.type != PROG_STRING) abort_interp("Non-string argument (1)");
if (!temp1.data.string) abort_interp("Empty string argument (2)");
delimit = temp1.data.string;
if (!temp2.data.string)
{
p_result = 1;
CLEAR(&temp1);
CLEAR(&temp2);
push(arg, top, PROG_STRING, 0);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
return;
}
else
{
p_result = 0;
strncpy(p_buf, temp2.data.string, strlen(temp2.data.string) + 1);
for (i = strlen(temp2.data.string) - 1; i >= 0; i--)
{
if (!strncmp(p_buf + i, delimit, strlen(temp1.data.string)))
{
p_buf[i] = '\0';
if (*top >= STACK_SIZE) abort_interp("Stack Overflow.");
push(arg, top, PROG_STRING,
MIPSCAST dup_string(p_buf + i + strlen(temp1.data.string)));
p_result++;
}
}
if (*top >= STACK_SIZE) abort_interp("Stack Overflow.");
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
p_result++;
}
if (*top >= STACK_SIZE) abort_interp("Stack Overflow.");
CLEAR(&temp1);
CLEAR(&temp2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_subst (__P_PROTO)
{
int i = 0, j = 0;
char *match, *replacement;
char xp_buf[BUFFER_LEN];
CHECKOP(3);
p_oper1 = POP();
p_oper2 = POP();
p_oper3 = POP();
if (!p_oper1->data.string) abort_interp("Empty string argument (3)");
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (3)");
if (p_oper2->type != PROG_STRING) abort_interp("Non-string argument (2)");
if (p_oper3->type != PROG_STRING) abort_interp("Non-string argument (1)");
p_buf[0] = '\0';
if (p_oper3->data.string)
{
strncpy(xp_buf, p_oper3->data.string, strlen(p_oper3->data.string) + 1);
match = p_oper1->data.string;
replacement = DoNullInd(p_oper2->data.string);
while (xp_buf[i])
{
if (!strncmp(xp_buf + i, match, strlen(p_oper1->data.string)))
{
strcat(p_buf, replacement);
i += strlen(p_oper1->data.string);
j += *replacement ? strlen(p_oper2->data.string) : 0;
}
else
{
p_buf[j++] = xp_buf[i++];
p_buf[j] = '\0';
}
}
}
CLEAR(p_oper1);
CLEAR(p_oper2);
CLEAR(p_oper3);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_instr (__P_PROTO)
{
char *remaining, *match;
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument type (2)");
if(!(p_oper1->data.string)) abort_interp("Empty string argument (2)");
if (p_oper2->type != PROG_STRING) abort_interp("Non-string argument (1)");
if (!p_oper2->data.string) p_result = 0;
else
{
remaining = p_oper2->data.string;
match = p_oper1->data.string;
p_result = 0;
do
{
if (!strncmp(remaining, match, strlen(p_oper1->data.string)))
{
p_result = remaining - p_oper2->data.string + 1;
break;
}
remaining++;
}
while (remaining >= p_oper2->data.string && *remaining);
}
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_rinstr (__P_PROTO)
{
char *remaining, *match;
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument type (2)");
if(!(p_oper1->data.string)) abort_interp("Empty string argument (2)");
if (p_oper2->type != PROG_STRING) abort_interp("Non-string argument (1)");
if (!p_oper2->data.string)
p_result = 0;
else
{
remaining = p_oper2->data.string + strlen(p_oper2->data.string) - 1;
match = p_oper1->data.string;
p_result = 0;
do
{
if (!strncmp(remaining, match, strlen(p_oper1->data.string)))
{
p_result = remaining - p_oper2->data.string + 1;
break;
}
remaining--;
}
while (remaining >= p_oper2->data.string && *remaining);
}
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_pronoun_sub (__P_PROTO)
{
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP(); /* p_oper1 is a string, p_oper2 a dbref */
if (!valid_object(p_oper2)) abort_interp("Invalid argument (1)");
if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument (2)");
if(p_oper1->data.string) strcpy(p_buf, p_oper1->data.string);
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_STRING, (p_oper1->data.string) ?
MIPSCAST dup_string(pronoun_substitute(p_oper2->data.objref,
p_buf)) : 0);
}
void prims_toupper (__P_PROTO)
{
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (p_oper1->data.string)
{
strncpy(p_buf, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
upperstring(p_buf);
} else { p_buf[0] = '\0'; }
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_tolower (__P_PROTO)
{
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (p_oper1->data.string)
{
strncpy(p_buf, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
lowerstring(p_buf);
} else { p_buf[0] = '\0'; }
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_flagstr (__P_PROTO)
{
dbref object;
CHECKOP(1);
p_oper1 = POP();
if (!valid_object(p_oper1)) abort_interp("Non-object argument.");
object = p_oper1->data.objref;
strcpy(p_buf, (unparse_flags(object)));
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_caps (__P_PROTO)
{
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (!p_oper1->data.string) abort_interp("NULL string argument.");
strncpy(p_buf, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
lowerstring(p_buf);
p_buf[0]= toupper(p_buf[0]);
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_unparse_lock(__P_PROTO)
{
CHECKOP(1);
p_oper1 = POP();
if (!valid_object(p_oper1)) abort_interp("Non-object argument.");
sprintf(p_buf, "%s", unparse_boolexp(player, DBFETCH(p_oper1->data.objref)->key));
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_unparse_flags(__P_PROTO)
{
dbref object;
CHECKOP(1);
p_oper1 = POP();
if (!valid_object(p_oper1)) abort_interp("Non-object argument.");
object = p_oper1->data.objref;
strcpy(p_buf, (flag_description(object)));
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_wstrcmp(__P_PROTO)
{
char buf2[BUFFER_LEN];
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (p_oper2->type != PROG_STRING) abort_interp("Non-string argument.");
if((!p_oper1->data.string) || (!p_oper2->data.string))
abort_interp("NULL string argument.");
strncpy(p_buf, p_oper2->data.string, strlen(p_oper2->data.string) + 1);
strncpy(buf2, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
p_result=(wild_match(buf2,p_buf));
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_spitfile(__P_PROTO)
{
FILE *f; /* OK, this one is easy. Taken from spitfile in help.c */
char buf2[BUFFER_LEN], filename[BUFFER_LEN];;
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (!p_oper1->data.string) abort_interp("NULL string argument.");
strncpy(filename, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
if(file_ok(filename)==0)
abort_interp("Sorry, you may not access MUF text files with a '.' or '~'.");
sprintf(buf2, "%s%s", MUF_DIR, filename);
if((f = fopen(buf2, "r")) == NULL) {
fclose(f);
abort_interp("Non-existant text file."); }
if((filesize_ok(buf2)) == 0) {
fclose(f);
abort_interp("File size is larger then MAX_OUTPUT"); }
while(fgets(p_buf, sizeof p_buf, f)) {
p_buf[(strlen(p_buf)-1)] = '\0';
notify(player, player, p_buf);
}
fclose(f);
CLEAR(p_oper1);
}
void prims_notifyfile(__P_PROTO)
{
FILE *f;
char buf2[BUFFER_LEN], filename[BUFFER_LEN];
CHECKOP(3);
p_oper1 = POP();
p_oper2 = POP();
p_oper3 = POP();
if (!valid_object(p_oper3) || Typeof(p_oper3->data.number) != TYPE_ROOM)
abort_interp("Non-room argument (1)");
if (p_oper2->type != PROG_OBJECT) abort_interp("Invalid object argument (2)");
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (3)");
if (!p_oper1->data.string) abort_interp("NULL string argument.");
strncpy(filename, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
if(file_ok(filename)==0)
abort_interp("Sorry, you may not access MUF text files with a '.' or '~'.");
sprintf(buf2, "%s%s", MUF_DIR, filename);
if((f = fopen(buf2, "r")) == NULL) {
fclose(f);
abort_interp("Non-existant text file."); }
if((filesize_ok(buf2)) == 0) {
fclose(f);
abort_interp("File size is larger then MAX_OUTPUT"); }
while(fgets(p_buf, sizeof p_buf, f)) {
p_buf[(strlen(p_buf)-1)] = '\0';
notify_except(player, p_oper3->data.objref, p_oper2->data.objref, p_buf);
}
fclose(f);
CLEAR(p_oper1);
CLEAR(p_oper2);
CLEAR(p_oper3);
}
void prims_touchfile(__P_PROTO)
{
FILE *f;
char filename[BUFFER_LEN];
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if (!p_oper1->data.string) abort_interp("NULL string argument.");
strncpy(filename, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
if(file_ok(filename)==0)
abort_interp("Sorry, you may not access MUF text files with a '.' or '~'.");
sprintf(p_buf, "%s%s", MUF_DIR, filename);
if((f = fopen(p_buf, "r")) != NULL) p_result=1;
else p_result=0;
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
fclose(f);
CLEAR(p_oper1);
}
int file_ok(char *string)
{
if (index(string,'.') == NULL && index(string,'~') == NULL) return (1);
else return (0);
}
int filesize_ok(char *filename)
{
int desn;
struct stat stats;
if((desn = open(filename, O_RDONLY )) < 0) {
close(desn);
return (0); }
fstat(desn,&stats);
close(desn);
if(stats.st_size > (MAX_OUTPUT - 350)) return (0);
else return (1);
}
void prims_mushfunctions(__P_PROTO)
{
#ifdef MUSH
char tbuf[BUFFER_LEN];
char *t;
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
if(!p_oper1->data.string) abort_interp("NULL string argument.");
strncpy(tbuf, p_oper1->data.string, strlen(p_oper1->data.string) + 1);
t = exec(fr->euid, tbuf, player, EV_STRIP | EV_FCHECK);
strcpy(p_buf, t);
CLEAR(p_oper1);
if(t) free(t);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
#else
abort_interp("THIS FUNCTION WAS NOT ENABLED BY YOUR GAME ADMIN.");
#endif
}
void prims_re_compile (__P_PROTO)
{
#ifndef REGEXP
abort_interp("This prim not enabled.");
#else
regexp *re;
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
re = m_regcomp(DoNullInd(p_oper1->data.string));
if (! re) abort_interp(m_regerror());
CLEAR(p_oper1);
push(arg, top, PROG_RE,MIPSCAST re);
#endif
}
void prims_re_match (__P_PROTO)
{
#ifndef REGEXP
abort_interp("This prim not enabled.");
#else
regexp *re;
char *str;
int rv;
char *err;
int i;
CHECKOP(2);
temp2 = *(p_oper2 = POP());
temp1 = *(p_oper1 = POP());
if (temp1.type != PROG_STRING) abort_interp("Non-string argument (1).");
if (temp2.type != PROG_RE) abort_interp("Non-regexp argument (2).");
str = (char *) DoNullInd(temp1.data.string);
re = temp2.data.re;
rv = m_regexec(re,str);
err = m_regerror();
if (err) abort_interp(err);
if (rv)
{ for (i=0;i<re->nsubexp;i++)
{ if (re->startp[i])
{ rv = re->endp[i] - re->startp[i];
if (rv == 0)
push(arg, top, PROG_STRING, 0);
else
{ bcopy(re->startp[i],&buf[0],rv);
buf[rv] = '\0';
push(arg, top, PROG_STRING, dup_string(&buf[0]));
}
}
else
{ rv = 0;
push(arg, top, PROG_INTEGER, MIPSCAST &rv);
}
}
rv = re->nsubexp;
push(arg, top, PROG_INTEGER, MIPSCAST &rv);
}
else
{ rv = 0;
push(arg, top, PROG_INTEGER, MIPSCAST &rv);
}
CLEAR(&temp1);
CLEAR(&temp2);
#endif
}
void prims_stringpfx(__P_PROTO)
{
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING || p_oper2->type != PROG_STRING)
abort_interp("Non-string argument.");
if (!p_oper1->data.string || !p_oper2->data.string)
abort_interp("NULL string argument.");
if (p_oper1->data.string == p_oper2->data.string) p_result = 0;
else if (!(p_oper2->data.string && p_oper1->data.string))
p_result = p_oper1->data.string ? -1 : 1;
else
p_result = string_prefix(p_oper2->data.string, p_oper1->data.string);
CLEAR(p_oper1);
CLEAR(p_oper2);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_striplead(__P_PROTO)
{ /* string -- string' */
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Not a string argument.");
if (*top >= STACK_SIZE) abort_interp("Stack Overflow.");
strcpy(p_buf, DoNullInd(p_oper1->data.string));
for (string = p_buf; *string && isspace(*string); string++);
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(string));
}
void prims_striptail(__P_PROTO)
{ /* string -- string' */
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_STRING) abort_interp("Not a string argument.");
if (*top >= STACK_SIZE) abort_interp("Stack Overflow.");
strcpy(p_buf, DoNullInd(p_oper1->data.string));
p_result = strlen(p_buf);
while ((p_result-- > 0) && isspace(p_buf[p_result])) p_buf[p_result] = '\0';
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_smatch(__P_PROTO)
{
char xbuf[BUFFER_LEN];
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_STRING || p_oper2->type != PROG_STRING)
abort_interp("Non-string argument.");
if (!p_oper1->data.string || !p_oper2->data.string)
abort_interp("Null string argument.");
strcpy(p_buf, p_oper1->data.string);
strcpy(xbuf, p_oper2->data.string);
CLEAR(p_oper1);
CLEAR(p_oper2);
p_result = equalstr(p_buf, xbuf);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_version(__P_PROTO)
{
push(arg, top, PROG_STRING, MIPSCAST dup_string(VERSION));
if (*top >= STACK_SIZE) abort_interp("Stack Overflow.");
}
void prims_unparseobj(__P_PROTO)
{
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_OBJECT) abort_interp("Non-object argument.");
p_result = p_oper1->data.objref;
switch (p_result) {
case NOTHING:
sprintf(p_buf, "*NOTHING*");
break;
case HOME:
sprintf(p_buf, "*HOME*");
break;
default:
if (p_result < 0 || p_result > db_top)
sprintf(p_buf, "*INVALID*");
else
sprintf(p_buf, "%s", unparse_object(fr->euid, p_result));
}
CLEAR(p_oper1);
push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf));
}
void prims_spitline(__P_PROTO)
{
FILE *f;
char buf2[BUFFER_LEN], filename[BUFFER_LEN];
int i = 1;
CHECKOP(2);
p_oper1 = POP();
p_oper2 = POP();
if (p_oper1->type != PROG_INTEGER) abort_interp("Non-integer argument.");
if (p_oper1->data.number < 1) abort_interp("Invalid line number.");
if (p_oper2->type != PROG_STRING) abort_interp("Non-string argument.");
if (!p_oper2->data.string) abort_interp("NULL argument.");
strncpy(filename, p_oper2->data.string, strlen(p_oper2->data.string) + 1);
if(file_ok(filename)==0)
abort_interp("Sorry, you may not access MUF text files with a '.' or '~'.");
sprintf(buf2, "%s%s", MUF_DIR, filename);
if((f = fopen(buf2, "r")) == NULL) {
fclose(f);
abort_interp("Non-existant text file.");
}
while(fgets(p_buf, sizeof p_buf, f)) {
fprintf(stderr, "TOKE:%s", p_buf);
if( p_oper1->data.number == i) {
fprintf(stderr, "STRING:%s", p_buf);
p_buf[(strlen(p_buf)-1)] = '\0';
i = 0;
break;
}
i++;
}
fclose(f);
fprintf(stderr, "PRE:%s\n", p_buf);
if (i)
string = NULL;
else
string = dup_string(p_buf);
fprintf(stderr, "POST:%s\n", p_buf);
push(arg, top, PROG_STRING, MIPSCAST string);
CLEAR(p_oper2);
}