1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
/* xlsubr - xlisp builtin function support routines */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
/* CHANGE LOG
* --------------------------------------------------------------------
* 28Apr03 dm eliminate some compiler warnings
*/
#include "string.h"
#include "xlisp.h"
/* external variables */
extern LVAL k_test,k_tnot,s_eql;
/* xlsubr - define a builtin function */
LVAL xlsubr(const char *sname, int type, LVAL (*fcn)(void), int offset)
{
LVAL sym;
sym = xlenter(sname);
setfunction(sym,cvsubr(fcn,type,offset));
return (sym);
}
/* xlgetkeyarg - get a keyword argument */
int xlgetkeyarg(LVAL key, LVAL *pval)
{
LVAL *argv=xlargv;
int argc=xlargc;
for (argv = xlargv, argc = xlargc; (argc -= 2) >= 0; argv += 2) {
if (*argv == key) {
*pval = *++argv;
return (TRUE);
}
}
return (FALSE);
}
/* xlgkfixnum - get a fixnum keyword argument */
int xlgkfixnum(LVAL key, LVAL *pval)
{
if (xlgetkeyarg(key,pval)) {
if (!fixp(*pval))
xlbadtype(*pval);
return (TRUE);
}
return (FALSE);
}
/* xltest - get the :test or :test-not keyword argument */
void xltest(LVAL *pfcn, int *ptresult)
{
if (xlgetkeyarg(k_test,pfcn)) /* :test */
*ptresult = TRUE;
else if (xlgetkeyarg(k_tnot,pfcn)) /* :test-not */
*ptresult = FALSE;
else {
*pfcn = getfunction(s_eql);
*ptresult = TRUE;
}
}
/* xlgetfile - get a file or stream */
LVAL xlgetfile(void)
{
LVAL arg;
/* get a file or stream (cons) or nil */
if ((arg = xlgetarg())) {
if (streamp(arg)) {
if (getfile(arg) == NULL)
xlfail("file not open");
}
else if (!ustreamp(arg))
xlerror("bad argument type",arg);
}
return (arg);
}
/* xlgetfname - get a filename */
LVAL xlgetfname(void)
{
LVAL name;
/* get the next argument */
name = xlgetarg();
/* get the filename string */
if (symbolp(name))
name = getpname(name);
else if (!stringp(name))
xlerror("bad argument type",name);
/* return the name */
return (name);
}
/* needsextension - check if a filename needs an extension */
int needsextension(const char *name)
{
const char *p;
/* check for an extension */
for (p = &name[strlen(name)]; --p >= &name[0]; )
if (*p == '.')
return (FALSE);
else if (!islower(*p) && !isupper(*p) && !isdigit(*p))
return (TRUE);
/* no extension found */
return (TRUE);
}
/* the next three functions must be declared as LVAL because they
* are used in LVAL expressions, but they do not return anything
* warning 4035 is "no return value"
*/
/* #pragma warning(disable: 4035) */
/* xlbadtype - report a "bad argument type" error */
LVAL xlbadtype(LVAL arg)
{
xlerror("bad argument type",arg);
return NIL; /* never happens */
}
/* xltoofew - report a "too few arguments" error */
LVAL xltoofew(void)
{
xlfail("too few arguments");
return NIL; /* never happens */
}
/* xltoomany - report a "too many arguments" error */
LVAL xltoomany(void)
{
xlfail("too many arguments");
return NIL; /* never happens */
}
/* eq - internal eq function */
int eq(LVAL arg1, LVAL arg2)
{
return (arg1 == arg2);
}
/* eql - internal eql function */
int eql(LVAL arg1, LVAL arg2)
{
/* compare the arguments */
if (arg1 == arg2)
return (TRUE);
else if (arg1) {
switch (ntype(arg1)) {
case FIXNUM:
return (fixp(arg2) ? getfixnum(arg1)==getfixnum(arg2) : FALSE);
case FLONUM:
return (floatp(arg2) ? getflonum(arg1)==getflonum(arg2) : FALSE);
default:
return (FALSE);
}
}
else
return (FALSE);
}
/* lval_equal - internal equal function */
int lval_equal(LVAL arg1, LVAL arg2)
{
/* compare the arguments */
if (arg1 == arg2)
return (TRUE);
else if (arg1) {
switch (ntype(arg1)) {
case FIXNUM:
return (fixp(arg2) ? getfixnum(arg1)==getfixnum(arg2) : FALSE);
case FLONUM:
return (floatp(arg2) ? getflonum(arg1)==getflonum(arg2) : FALSE);
case STRING:
return (stringp(arg2) ? strcmp((char *) getstring(arg1),
(char *) getstring(arg2)) == 0 : FALSE);
case CONS:
return (consp(arg2) ? lval_equal(car(arg1),car(arg2))
&& lval_equal(cdr(arg1),cdr(arg2)) : FALSE);
default:
return (FALSE);
}
}
else
return (FALSE);
}
|