home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-10 | 44.3 KB | 1,489 lines |
- Newsgroups: comp.sources.misc
- From: dfs@doe.carleton.ca (David F. Skoll)
- Subject: v33i063: remind - A replacement for calendar, Part06/12
- Message-ID: <1992Nov10.041917.1064@sparky.imd.sterling.com>
- X-Md4-Signature: 44ec5de29413cf93f680f62e5958684d
- Date: Tue, 10 Nov 1992 04:19:17 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: dfs@doe.carleton.ca (David F. Skoll)
- Posting-number: Volume 33, Issue 63
- Archive-name: remind/part06
- Environment: UNIX, MS-DOS
- Supersedes: remind: Volume 17, Issue 3-6
-
- #!/bin/sh
- # This is part 06 of Remind 03.00.00
- if touch 2>&1 | fgrep 'amc' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= funcs.c ==============
- if test X"$1" != X"-c" -a -f 'funcs.c'; then
- echo "File already exists: skipping 'funcs.c'"
- else
- echo "x - extracting funcs.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > funcs.c &&
- X/***************************************************************/
- X/* */
- X/* FUNCS.C */
- X/* */
- X/* This file contains the built-in functions used in */
- X/* expressions. */
- X/* */
- X/* This file is part of REMIND. */
- X/* Copyright (C) 1991 by David F. Skoll. */
- X/* */
- X/***************************************************************/
- X#include <stdio.h>
- X#include "config.h"
- X#ifdef HAVE_STDLIB_H
- X#include <stdlib.h>
- X#endif
- X#ifdef HAVE_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#include <string.h>
- X#include <ctype.h>
- X#ifdef UNIX
- X#ifdef HAVE_UNISTD
- X#include <unistd.h>
- X#else
- X#include <sys/file.h>
- X#endif
- X#endif
- X/* May have to change previous line to <sys/file.h> for some unixes */
- X#ifdef __MSDOS__
- X#include <io.h>
- X#define R_OK 4
- X#define W_OK 2
- X#define X_OK 1
- X#endif
- X#ifndef R_OK
- X#define R_OK 4
- X#define W_OK 2
- X#define X_OK 1
- X#endif
- X#include "types.h"
- X#include "globals.h"
- X#include "protos.h"
- X#include "err.h"
- X#include "expr.h"
- X#include "version.h"
- X
- X/* Function prototypes */
- XPRIVATE int FAbs ARGS ((void));
- XPRIVATE int FAccess ARGS ((void));
- XPRIVATE int FAsc ARGS ((void));
- XPRIVATE int FBaseyr ARGS ((void));
- XPRIVATE int FChar ARGS ((void));
- XPRIVATE int FChoose ARGS ((void));
- XPRIVATE int FCoerce ARGS ((void));
- XPRIVATE int FDate ARGS ((void));
- XPRIVATE int FDay ARGS ((void));
- XPRIVATE int FDaysinmon ARGS ((void));
- XPRIVATE int FDefined ARGS ((void));
- XPRIVATE int FFilename ARGS ((void));
- XPRIVATE int FGetenv ARGS ((void));
- XPRIVATE int FHour ARGS ((void));
- XPRIVATE int FIif ARGS ((void));
- XPRIVATE int FIndex ARGS ((void));
- XPRIVATE int FIsomitted ARGS ((void));
- XPRIVATE int FMax ARGS ((void));
- XPRIVATE int FMin ARGS ((void));
- XPRIVATE int FMinute ARGS ((void));
- XPRIVATE int FMon ARGS ((void));
- XPRIVATE int FMonnum ARGS ((void));
- XPRIVATE int FOrd ARGS ((void));
- XPRIVATE int FOstype ARGS ((void));
- XPRIVATE int FPlural ARGS ((void));
- XPRIVATE int FSgn ARGS ((void));
- XPRIVATE int FShell ARGS ((void));
- XPRIVATE int FStrlen ARGS ((void));
- XPRIVATE int FSubstr ARGS ((void));
- XPRIVATE int FTime ARGS ((void));
- XPRIVATE int FTrigdate ARGS ((void));
- XPRIVATE int FTrigtime ARGS ((void));
- XPRIVATE int FTrigvalid ARGS ((void));
- XPRIVATE int FTypeof ARGS ((void));
- XPRIVATE int FUpper ARGS ((void));
- XPRIVATE int FValue ARGS ((void));
- XPRIVATE int FVersion ARGS ((void));
- XPRIVATE int FWkday ARGS ((void));
- XPRIVATE int FWkdaynum ARGS ((void));
- XPRIVATE int FYear ARGS ((void));
- XPRIVATE int FIsleap ARGS ((void));
- XPRIVATE int FLower ARGS ((void));
- XPRIVATE int FNow ARGS ((void));
- XPRIVATE int FRealtoday ARGS ((void));
- XPRIVATE int FToday ARGS ((void));
- XPRIVATE int FTrigger ARGS ((void));
- XPRIVATE int CheckArgs ARGS ((Operator *f, int nargs));
- XPRIVATE int CleanUpAfterFunc ARGS ((void));
- X
- X#ifdef __MSDOS__
- XPRIVATE FILE *popen ARGS((char *cmd, char *mode));
- XPRIVATE int pclose ARGS((FILE *fp));
- X#endif
- X
- X/* "Overload" the struct Operator definition */
- X#define NO_MAX 127
- X#define MINARGS prec
- X#define MAXARGS type
- X
- X/* Sigh - we use a global var. to hold the number of args supplied to
- X function being called */
- Xstatic int Nargs;
- X
- X/* Use a global var. to hold function return value */
- Xstatic Value RetVal;
- X
- X/* Temp string buffer */
- Xstatic char Buffer[32];
- X
- X/* We need access to the value stack */
- Xextern Value ValStack[];
- Xextern int ValStackPtr;
- X
- X/* Macro for accessing arguments from the value stack - args are numbered
- X from 0 to (Nargs - 1) */
- X#define ARG(x) (ValStack[ValStackPtr - Nargs + (x)])
- X
- X/* Macro for copying a value while destroying original copy */
- X#define DCOPYVAL(x, y) ( (x) = (y), (y).type = ERR_TYPE )
- X
- X/* Convenience macros */
- X#define UPPER(c) ( ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c) )
- X#define LOWER(c) ( ((c) >= 'A' && (c) <= 'Z') ? (c) + 'a' - 'A' : (c) )
- X
- X/* The array holding the built-in functions. */
- XOperator Func[] = {
- X/* Name minargs maxargs func */
- X
- X { "abs", 1, 1, FAbs },
- X { "access", 2, 2, FAccess },
- X { "asc", 1, 1, FAsc },
- X { "baseyr", 0, 0, FBaseyr },
- X { "char", 1, NO_MAX, FChar },
- X { "choose", 2, NO_MAX, FChoose },
- X { "coerce", 2, 2, FCoerce },
- X { "date", 3, 3, FDate },
- X { "day", 1, 1, FDay },
- X { "daysinmon", 2, 2, FDaysinmon },
- X { "defined", 1, 1, FDefined },
- X { "filename", 0, 0, FFilename },
- X { "getenv", 1, 1, FGetenv },
- X { "hour", 1, 1, FHour },
- X { "iif", 3, 3, FIif },
- X { "index", 2, 3, FIndex },
- X { "isleap", 1, 1, FIsleap },
- X { "isomitted", 1, 1, FIsomitted },
- X { "lower", 1, 1, FLower },
- X { "max", 1, NO_MAX, FMax },
- X { "min", 1, NO_MAX, FMin },
- X { "minute", 1, 1, FMinute },
- X { "mon", 1, 1, FMon },
- X { "monnum", 1, 1, FMonnum },
- X { "now", 0, 0, FNow },
- X { "ord", 1, 1, FOrd },
- X { "ostype", 0, 0, FOstype },
- X { "plural", 1, 3, FPlural },
- X { "realtoday", 0, 0, FRealtoday },
- X { "sgn", 1, 1, FSgn },
- X { "shell", 1, 1, FShell },
- X { "strlen", 1, 1, FStrlen },
- X { "substr", 2, 3, FSubstr },
- X { "time", 2, 2, FTime },
- X { "today", 0, 0, FToday },
- X { "trigdate", 0, 0, FTrigdate },
- X { "trigger", 1, 1, FTrigger },
- X { "trigtime", 0, 0, FTrigtime },
- X { "trigvalid", 0, 0, FTrigvalid },
- X { "typeof", 1, 1, FTypeof },
- X { "upper", 1, 1, FUpper },
- X { "value", 1, 2, FValue },
- X { "version", 0, 0, FVersion },
- X { "wkday", 1, 1, FWkday },
- X { "wkdaynum", 1, 1, FWkdaynum },
- X { "year", 1, 1, FYear }
- X};
- X
- X/* Need a variable here - Func[] array not really visible to outside. */
- Xint NumFuncs = sizeof(Func) / sizeof(Operator) ;
- X
- X/***************************************************************/
- X/* */
- X/* CallFunc */
- X/* */
- X/* Call a function given a pointer to it, and the number */
- X/* of arguments supplied. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPUBLIC int CallFunc(Operator *f, int nargs)
- X#else
- Xint CallFunc(f, nargs)
- XOperator *f;
- Xint nargs;
- X#endif
- X{
- X register int r = CheckArgs(f, nargs);
- X int i;
- X
- X Nargs = nargs;
- X
- X RetVal.type = ERR_TYPE;
- X if (DebugFlag & DB_PRTEXPR) {
- X fprintf(ErrFp, "%s(", f->name);
- X for (i=0; i<nargs; i++) {
- X PrintValue(&ARG(i), ErrFp);
- X if (i<nargs-1) fprintf(ErrFp, ", ");
- X }
- X fprintf(ErrFp, ") => ");
- X if (r) {
- X fprintf(ErrFp, "%s\n", ErrMsg[r]);
- X return r;
- X }
- X }
- X if (r) {
- X Eprint("%s(): %s", f->name, ErrMsg[r]);
- X return r;
- X }
- X
- X r = (*(f->func))();
- X if (r) {
- X DestroyValue(&RetVal);
- X if (DebugFlag & DB_PRTEXPR)
- X fprintf(ErrFp, "%s\n", ErrMsg[r]);
- X else
- X Eprint("%s(): %s", f->name, ErrMsg[r]);
- X return r;
- X }
- X if (DebugFlag & DB_PRTEXPR) {
- X PrintValue(&RetVal, ErrFp);
- X fprintf(ErrFp, "\n");
- X }
- X r = CleanUpAfterFunc();
- X return r;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* CheckArgs */
- X/* */
- X/* Check that the right number of args have been supplied */
- X/* for a function. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int CheckArgs(Operator *f, int nargs)
- X#else
- Xstatic int CheckArgs(f, nargs)
- XOperator *f;
- Xint nargs;
- X#endif
- X{
- X if (nargs < f->MINARGS) return E_2FEW_ARGS;
- X if (nargs > f->MAXARGS && f->MAXARGS != NO_MAX) return E_2MANY_ARGS;
- X return OK;
- X}
- X/***************************************************************/
- X/* */
- X/* CleanUpAfterFunc */
- X/* */
- X/* Clean up the stack after a function call - remove */
- X/* args and push the new value. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int CleanUpAfterFunc(void)
- X#else
- Xstatic int CleanUpAfterFunc()
- X#endif
- X{
- X Value v;
- X int i, r;
- X
- X for (i=0; i<Nargs; i++) {
- X r = PopValStack(&v);
- X if (r) return r;
- X DestroyValue(&v);
- X }
- X PushValStack(&RetVal);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* RetStrVal */
- X/* */
- X/* Return a string value from a function. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int RetStrVal(const char *s)
- X#else
- Xstatic int RetStrVal(s)
- Xchar *s;
- X#endif
- X{
- X RetVal.type = STR_TYPE;
- X if (!s) {
- X RetVal.v.str = (char *) malloc(1);
- X if (RetVal.v.str) *RetVal.v.str = 0;
- X } else
- X RetVal.v.str = StrDup(s);
- X
- X if (!RetVal.v.str) {
- X RetVal.type = ERR_TYPE;
- X return E_NO_MEM;
- X }
- X return OK;
- X}
- X
- X
- X/***************************************************************/
- X/* */
- X/* FStrlen - string length */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FStrlen(void)
- X#else
- Xstatic int FStrlen()
- X#endif
- X{
- X Value *v = &ARG(0);
- X if (v->type != STR_TYPE) return E_BAD_TYPE;
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = strlen(v->v.str);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FBaseyr - system base year */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FBaseyr(void)
- X#else
- Xstatic int FBaseyr()
- X#endif
- X{
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = BASE;
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FDate - make a date from year, month, day. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FDate(void)
- X#else
- Xstatic int FDate()
- X#endif
- X{
- X int y, m, d;
- X if (ARG(0).type != INT_TYPE ||
- X ARG(1).type != INT_TYPE ||
- X ARG(2).type != INT_TYPE) return E_BAD_TYPE;
- X y = ARG(0).v.val;
- X m = ARG(1).v.val - 1;
- X d = ARG(2).v.val;
- X
- X if (y < BASE || y > BASE+YR_RANGE || m < 0 || m > 11 || d < 1 ||
- X d > DaysInMonth(m, y)) return E_BAD_DATE;
- X
- X RetVal.type = DATE_TYPE;
- X RetVal.v.val = Julian(y, m, d);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FCoerce - type coercion function. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FCoerce(void)
- X#else
- Xstatic int FCoerce()
- X#endif
- X{
- X char *s;
- X
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X s = ARG(0).v.str;
- X
- X /* Copy the value of ARG(1) into RetVal, and make ARG(1) invalid so
- X it won't be destroyed */
- X DCOPYVAL(RetVal, ARG(1));
- X
- X if (StriEq(s, "int")) return DoCoerce(INT_TYPE, &RetVal);
- X else if (StriEq(s, "date")) return DoCoerce(DATE_TYPE, &RetVal);
- X else if (StriEq(s, "time")) return DoCoerce(TIM_TYPE, &RetVal);
- X else if (StriEq(s, "string")) return DoCoerce(STR_TYPE, &RetVal);
- X else return E_CANT_COERCE;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FMax - select maximum from a list of args. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FMax(void)
- X#else
- Xstatic int FMax()
- X#endif
- X{
- X Value *maxptr;
- X int i;
- X char type;
- X
- X maxptr = &ARG(0);
- X type = maxptr->type;
- X
- X for (i=1; i<Nargs; i++) {
- X if (ARG(i).type != type) return E_BAD_TYPE;
- X if (type != STR_TYPE) {
- X if (ARG(i).v.val > maxptr->v.val) maxptr=&ARG(i);
- X } else {
- X if (strcmp(ARG(i).v.str, maxptr->v.str) > 0) maxptr=&ARG(i);
- X }
- X }
- X DCOPYVAL(RetVal, *maxptr);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FMin - select minimum from a list of args. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FMin(void)
- X#else
- Xstatic int FMin()
- X#endif
- X{
- X Value *minptr;
- X int i;
- X char type;
- X
- X minptr = &ARG(0);
- X type = minptr->type;
- X
- X for (i=1; i<Nargs; i++) {
- X if (ARG(i).type != type) return E_BAD_TYPE;
- X if (type != STR_TYPE) {
- X if (ARG(i).v.val < minptr->v.val) minptr=&ARG(i);
- X } else {
- X if (strcmp(ARG(i).v.str, minptr->v.str) < 0) minptr=&ARG(i);
- X }
- X }
- X DCOPYVAL(RetVal, *minptr);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FAsc - ASCII value of first char of string */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FAsc(void)
- X#else
- Xstatic int FAsc()
- X#endif
- X{
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = *(ARG(0).v.str);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FChar - build a string from ASCII values */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FChar(void)
- X#else
- Xstatic int FChar()
- X#endif
- X{
- X
- X int i, len;
- X
- X/* Special case of one arg - if given ascii value 0, create empty string */
- X if (Nargs == 1) {
- X if (ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X if (ARG(0).v.val < 0) return E_2LOW;
- X if (ARG(0).v.val > 255) return E_2HIGH;
- X len = ARG(0).v.val ? 2 : 1;
- X RetVal.v.str = (char *) malloc(len);
- X if (!RetVal.v.str) return E_NO_MEM;
- X RetVal.type = STR_TYPE;
- X *(RetVal.v.str) = ARG(0).v.val;
- X if (len>1) *(RetVal.v.str + 1) = 0;
- X return OK;
- X }
- X
- X RetVal.v.str = (char *) malloc(Nargs + 1);
- X if (!RetVal.v.str) return E_NO_MEM;
- X RetVal.type = STR_TYPE;
- X for (i=0; i<Nargs; i++) {
- X if (ARG(i).type != INT_TYPE) return E_BAD_TYPE;
- X if (ARG(i).v.val < 1) return E_2LOW;
- X if (ARG(i).v.val > 255) return E_2HIGH;
- X *(RetVal.v.str + i) = ARG(i).v.val;
- X }
- X *(RetVal.v.str + Nargs) = 0;
- X return OK;
- X}
- X/***************************************************************/
- X/* */
- X/* Functions for extracting the components of a date. */
- X/* */
- X/* FDay - get day of month */
- X/* FMonnum - get month (1-12) */
- X/* FYear - get year */
- X/* FWkdaynum - get weekday num (0 = Sun) */
- X/* FWkday - get weekday (string) */
- X/* FMon - get month (string) */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FDay(void)
- X#else
- Xstatic int FDay()
- X#endif
- X{
- X int y, m, d;
- X if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X FromJulian(ARG(0).v.val, &y, &m, &d);
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = d;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FMonnum(void)
- X#else
- Xstatic int FMonnum()
- X#endif
- X{
- X int y, m, d;
- X if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X FromJulian(ARG(0).v.val, &y, &m, &d);
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = m+1;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FYear(void)
- X#else
- Xstatic int FYear()
- X#endif
- X{
- X int y, m, d;
- X if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X FromJulian(ARG(0).v.val, &y, &m, &d);
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = y;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FWkdaynum(void)
- X#else
- Xstatic int FWkdaynum()
- X#endif
- X{
- X if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X RetVal.type = INT_TYPE;
- X
- X /* Correct so that 0 = Sunday */
- X RetVal.v.val = (ARG(0).v.val+1) % 7;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FWkday(void)
- X#else
- Xstatic int FWkday()
- X#endif
- X{
- X char *s;
- X
- X if (ARG(0).type != DATE_TYPE && ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X if (ARG(0).type == INT_TYPE) {
- X if (ARG(0).v.val < 0) return E_2LOW;
- X if (ARG(0).v.val > 6) return E_2HIGH;
- X /* Convert 0=Sun to 0=Mon */
- X ARG(0).v.val--;
- X if (ARG(0).v.val < 0) ARG(0).v.val = 6;
- X s = DayName[ARG(0).v.val];
- X } else s = DayName[ARG(0).v.val % 7];
- X return RetStrVal(s);
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FMon(void)
- X#else
- Xstatic int FMon()
- X#endif
- X{
- X char *s;
- X int y, m, d;
- X
- X if (ARG(0).type != DATE_TYPE && ARG(0).type != INT_TYPE)
- X return E_BAD_TYPE;
- X if (ARG(0).type == INT_TYPE) {
- X m = ARG(0).v.val - 1;
- X if (m < 0) return E_2LOW;
- X if (m > 11) return E_2HIGH;
- X } else FromJulian(ARG(0).v.val, &y, &m, &d);
- X s = MonthName[m];
- X return RetStrVal(s);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FHour - extract hour from a time */
- X/* FMinute - extract minute from a time */
- X/* FTime - create a time from hour and minute */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FHour(void)
- X#else
- Xstatic int FHour()
- X#endif
- X{
- X if (ARG(0).type != TIM_TYPE) return E_BAD_TYPE;
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = ARG(0).v.val / 60;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FMinute(void)
- X#else
- Xstatic int FMinute()
- X#endif
- X{
- X if (ARG(0).type != TIM_TYPE) return E_BAD_TYPE;
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = ARG(0).v.val % 60;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FTime(void)
- X#else
- Xstatic int FTime()
- X#endif
- X{
- X int h, m;
- X
- X if (ARG(0).type != INT_TYPE || ARG(1).type != INT_TYPE) return E_BAD_TYPE;
- X
- X h = ARG(0).v.val;
- X m = ARG(1).v.val;
- X if (h<0 || m<0) return E_2LOW;
- X if (h>23 || m>59) return E_2HIGH;
- X RetVal.type = TIM_TYPE;
- X RetVal.v.val = h*60 + m;
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FAbs - absolute value */
- X/* FSgn - signum function */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FAbs(void)
- X#else
- Xstatic int FAbs()
- X#endif
- X{
- X int v;
- X
- X if (ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X v = ARG(0).v.val;
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = (v < 0) ? (-v) : v;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FSgn(void)
- X#else
- Xstatic int FSgn()
- X#endif
- X{
- X int v;
- X
- X if (ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X v = ARG(0).v.val;
- X RetVal.type = INT_TYPE;
- X if (v>0) RetVal.v.val = 1;
- X else if (v<0) RetVal.v.val = -1;
- X else RetVal.v.val = 0;
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FOrd - returns a string containing ordinal number. */
- X/* */
- X/* EG - ord(2) == "2nd", etc. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FOrd(void)
- X#else
- Xstatic int FOrd()
- X#endif
- X{
- X int t, u, v;
- X char *s;
- X
- X if (ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X
- X v = ARG(0).v.val;
- X t = v % 100;
- X if (t < 0) t = -t;
- X u = t % 10;
- X s = "th";
- X if (u == 1 && t != 11) s = "st";
- X if (u == 2 && t != 12) s = "nd";
- X if (u == 3 && t != 13) s = "rd";
- X sprintf(Buffer, "%d%s", v, s);
- X return RetStrVal(Buffer);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FPlural - pluralization function */
- X/* */
- X/* plural(n) --> "" or "s" */
- X/* plural(n, str) --> "str" or "strs" */
- X/* plural(n, str1, str2) --> "str1" or "str2" */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FPlural(void)
- X#else
- Xstatic int FPlural()
- X#endif
- X{
- X if (ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X
- X switch(Nargs) {
- X case 1:
- X if (ARG(0).v.val == 1) return RetStrVal("");
- X else return RetStrVal("s");
- X
- X case 2:
- X if (ARG(1).type != STR_TYPE) return E_BAD_TYPE;
- X if (ARG(0).v.val == 1) {
- X DCOPYVAL(RetVal, ARG(1));
- X return OK;
- X }
- X RetVal.type = STR_TYPE;
- X RetVal.v.str = (char *) malloc(strlen(ARG(1).v.str)+2);
- X if (!RetVal.v.str) {
- X RetVal.type = ERR_TYPE;
- X return E_NO_MEM;
- X }
- X strcpy(RetVal.v.str, ARG(1).v.str);
- X strcat(RetVal.v.str, "s");
- X return OK;
- X
- X default:
- X if (ARG(1).type != STR_TYPE || ARG(2).type != STR_TYPE)
- X return E_BAD_TYPE;
- X if (ARG(0).v.val == 1) DCOPYVAL(RetVal, ARG(1));
- X else DCOPYVAL(RetVal, ARG(2));
- X return OK;
- X }
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FChoose */
- X/* Choose the nth value from a list of value. If n<1, choose */
- X/* first. If n>N, choose Nth value. Indexes always start */
- X/* from 1. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FChoose(void)
- X#else
- Xstatic int FChoose()
- X#endif
- X{
- X int v;
- X
- X if (ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X v = ARG(0).v.val;
- X if (v < 1) v = 1;
- X if (v > Nargs-1) v = Nargs-1;
- X DCOPYVAL(RetVal, ARG(v));
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FVersion - version of Remind */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FVersion(void)
- X#else
- Xstatic int FVersion()
- X#endif
- X{
- X return RetStrVal(VERSION);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FOstype - the type of operating system (UNIX or MSDOS) */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FOstype(void)
- X#else
- Xstatic int FOstype()
- X#endif
- X{
- X#ifdef UNIX
- X return RetStrVal("UNIX");
- X#else
- X return RetStrVal("MSDOS");
- X#endif
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FUpper - convert string to upper-case */
- X/* FLower - convert string to lower-case */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FUpper(void)
- X#else
- Xstatic int FUpper()
- X#endif
- X{
- X char *s;
- X
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X DCOPYVAL(RetVal, ARG(0));
- X s = RetVal.v.str;
- X while (*s) { *s = UPPER(*s); s++; }
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FLower(void)
- X#else
- Xstatic int FLower()
- X#endif
- X{
- X char *s;
- X
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X DCOPYVAL(RetVal, ARG(0));
- X s = RetVal.v.str;
- X while (*s) { *s = LOWER(*s); s++; }
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FToday - return the system's notion of "today" */
- X/* Frealtoday - return today's date as read from OS. */
- X/* FNow - return the system time */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FToday(void)
- X#else
- Xstatic int FToday()
- X#endif
- X{
- X RetVal.type = DATE_TYPE;
- X RetVal.v.val = JulianToday;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FRealtoday(void)
- X#else
- Xstatic int FRealtoday()
- X#endif
- X{
- X RetVal.type = DATE_TYPE;
- X RetVal.v.val = RealToday;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FNow(void)
- X#else
- Xstatic int FNow()
- X#endif
- X{
- X RetVal.type = TIM_TYPE;
- X RetVal.v.val = (int) ( SystemTime() / 60L );
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FGetenv - get the value of an environment variable. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FGetenv(void)
- X#else
- Xstatic int FGetenv()
- X#endif
- X{
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X return RetStrVal(getenv(ARG(0).v.str));
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FValue */
- X/* */
- X/* Get the value of a variable. If a second arg is supplied, */
- X/* it is returned if variable is undefined. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FValue(void)
- X#else
- Xstatic int FValue()
- X#endif
- X{
- X Var *v;
- X
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X switch(Nargs) {
- X case 1:
- X return GetVarValue(ARG(0).v.str, &RetVal, NULL);
- X
- X case 2:
- X v = FindVar(ARG(0).v.str, 0);
- X if (!v) {
- X DCOPYVAL(RetVal, ARG(1));
- X return OK;
- X } else {
- X return CopyValue(&RetVal, &v->v);
- X }
- X }
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FDefined */
- X/* */
- X/* Return 1 if a variable is defined, 0 if it is not. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FDefined(void)
- X#else
- Xstatic int FDefined()
- X#endif
- X{
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X
- X RetVal.type = INT_TYPE;
- X
- X if (FindVar(ARG(0).v.str, 0))
- X RetVal.v.val = 1;
- X else
- X RetVal.v.val = 0;
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FTrigdate and FTrigtime */
- X/* */
- X/* Date and time of last trigger. These are stored in global */
- X/* vars. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FTrigdate(void)
- X#else
- Xstatic int FTrigdate()
- X#endif
- X{
- X RetVal.type = DATE_TYPE;
- X RetVal.v.val = LastTriggerDate;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FTrigvalid(void)
- X#else
- Xstatic int FTrigvalid()
- X#endif
- X{
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = LastTrigValid;
- X return OK;
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int FTrigtime(void)
- X#else
- Xstatic int FTrigtime()
- X#endif
- X{
- X RetVal.type = TIM_TYPE;
- X RetVal.v.val = LastTriggerTime;
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FDaysinmon */
- X/* */
- X/* Returns the number of days in mon,yr */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FDaysinmon(void)
- X#else
- Xstatic int FDaysinmon()
- X#endif
- X{
- X if (ARG(0).type != INT_TYPE || ARG(1).type != INT_TYPE) return E_BAD_TYPE;
- X
- X if (ARG(0).v.val > 12 || ARG(0).v.val < 1 ||
- X ARG(1).v.val < BASE || ARG(1).v.val > BASE+YR_RANGE)
- X return E_DOMAIN_ERR;
- X
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = DaysInMonth(ARG(0).v.val-1, ARG(1).v.val);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FIsleap */
- X/* */
- X/* Return 1 if year is a leap year, zero otherwise. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FIsleap(void)
- X#else
- Xstatic int FIsleap()
- X#endif
- X{
- X int y, m, d;
- X
- X if (ARG(0).type != INT_TYPE && ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X
- X /* If it's a date, extract the year */
- X if (ARG(0).type == DATE_TYPE)
- X FromJulian(ARG(0).v.val, &y, &m, &d);
- X else
- X y = ARG(0).v.val;
- X
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = IsLeapYear(y);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FTrigger */
- X/* */
- X/* Put out a date in a format suitable for triggering. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FTrigger(void)
- X#else
- Xstatic int FTrigger()
- X#endif
- X{
- X int y, m, d;
- X char buf[40];
- X
- X if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X
- X FromJulian(ARG(0).v.val, &y, &m, &d);
- X sprintf(buf, "%d %s %d", d, MonthName[m], y);
- X return RetStrVal(buf);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FShell */
- X/* */
- X/* The shell function. */
- X/* */
- X/* If run is disabled, will not be executed. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FShell(void)
- X#else
- Xstatic int FShell()
- X#endif
- X{
- X char buf[SHELLSIZE+1];
- X int ch, len;
- X FILE *fp;
- X char *s;
- X
- X if (RunDisabled) return E_RUN_DISABLED;
- X if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
- X s = buf;
- X len = 0;
- X fp = popen(ARG(0).v.str, "r");
- X if (!fp) return E_IO_ERR;
- X while (len < SHELLSIZE) {
- X ch = getc(fp);
- X if (ch == EOF) {
- X break;
- X }
- X if (isspace(ch)) *s++ = ' ';
- X else *s++ = ch;
- X len++;
- X }
- X *s = 0;
- X
- X /* Delete trailing newline (converted to space) */
- X if (s > buf && *(s-1) == ' ') *(s-1) = 0;
- X#ifdef __MSDOS__
- X if (s-1 > buf && *(s-2) == ' ') *(s-2) = 0;
- X#endif
- X pclose(fp);
- X return RetStrVal(buf);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FIsomitted */
- X/* */
- X/* Is a date omitted? */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FIsomitted(void)
- X#else
- Xstatic int FIsomitted()
- X#endif
- X{
- X if (ARG(0).type != DATE_TYPE) return E_BAD_TYPE;
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = IsOmitted(ARG(0).v.val, 0);
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FSubstr */
- X/* */
- X/* The substr function. We destroy the value on the stack. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FSubstr(void)
- X#else
- Xstatic int FSubstr()
- X#endif
- X{
- X char *s, *t;
- X int start, end;
- X
- X if (ARG(0).type != STR_TYPE || ARG(1).type != INT_TYPE) return E_BAD_TYPE;
- X if (Nargs == 3 && ARG(2).type != INT_TYPE) return E_BAD_TYPE;
- X
- X s = ARG(0).v.str;
- X start = 1;
- X while (start < ARG(1).v.val) {
- X if (!*s) break;
- X s++;
- X start++;
- X }
- X if (Nargs == 2 || !*s) return RetStrVal(s);
- X end = start;
- X t = s;
- X while (end <= ARG(2).v.val) {
- X if (!*s) break;
- X s++;
- X end++;
- X }
- X *s = 0;
- X return RetStrVal(t);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FIndex */
- X/* */
- X/* The index of one string embedded in another. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FIndex(void)
- X#else
- Xstatic int FIndex()
- X#endif
- X{
- X char *s;
- X int start;
- X
- X if (ARG(0).type != STR_TYPE || ARG(1).type != STR_TYPE ||
- X (Nargs == 3 && ARG(2).type != INT_TYPE)) return E_BAD_TYPE;
- X
- X s = ARG(0).v.str;
- X
- X/* If 3 args, bump up the start */
- X if (Nargs == 3) {
- X start = 1;
- X while (start < ARG(2).v.val) {
- X if (!*s) break;
- X s++;
- X start++;
- X }
- X }
- X
- X/* Find the string */
- X s = strstr(s, ARG(1).v.str);
- X RetVal.type = INT_TYPE;
- X if (!s) {
- X RetVal.v.val = 0;
- X return OK;
- X }
- X RetVal.v.val = (s - ARG(0).v.str) + 1;
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FIif */
- X/* */
- X/* The IIF function. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FIif(void)
- X#else
- Xstatic int FIif()
- X#endif
- X{
- X int istrue;
- X
- X if (ARG(0).type != STR_TYPE && ARG(0).type != INT_TYPE) return E_BAD_TYPE;
- X
- X if (ARG(0).type == INT_TYPE)
- X istrue = ARG(0).v.val;
- X else
- X istrue = *(ARG(0).v.str);
- X
- X if (istrue) DCOPYVAL(RetVal, ARG(1));
- X else DCOPYVAL(RetVal, ARG(2));
- X
- X return OK;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FFilename */
- X/* */
- X/* Return name of current file */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FFilename(void)
- X#else
- Xstatic int FFilename()
- X#endif
- X{
- X return RetStrVal(FileName);
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FAccess */
- X/* */
- X/* The UNIX access() system call. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FAccess(void)
- X#else
- Xstatic int FAccess()
- X#endif
- X{
- X int amode;
- X char *s;
- X
- X if (ARG(0).type != STR_TYPE ||
- X (ARG(1).type != INT_TYPE && ARG(1).type != STR_TYPE)) return E_BAD_TYPE;
- X
- X if (ARG(1).type == INT_TYPE) amode = ARG(1).v.val;
- X else {
- X amode = 0;
- X s = ARG(1).v.str;
- X while (*s) {
- X switch(*s++) {
- X case 'r':
- X case 'R': amode |= R_OK; break;
- X case 'w':
- X case 'W': amode |= W_OK; break;
- X case 'x':
- X case 'X': amode |= X_OK; break;
- X }
- X }
- X }
- X RetVal.type = INT_TYPE;
- X RetVal.v.val = access(ARG(0).v.str, amode);
- X return OK;
- X}
- X
- X#ifdef __MSDOS__
- X/***************************************************************/
- X/* */
- X/* popen and pclose */
- X/* */
- X/* These are some rather brain-dead kludges for MSDOS. */
- X/* They are just sufficient for the shell() function, and */
- X/* should NOT be viewed as general-purpose replacements */
- X/* for the UNIX system calls. */
- X/* */
- X/***************************************************************/
- X#ifdef __TURBOC__
- X#pragma argsused
- X#endif
- X
- Xstatic char *TmpFile;
- X#ifdef HAVE_PROTOS
- XPRIVATE FILE *popen(char *cmd, char *mode)
- X#else
- Xstatic FILE *popen(cmd, mode)
- Xchar *cmd, *mode
- X#endif
- X{
- X char *s;
- X
- X TmpFile = tmpnam(NULL);
- X if (!TmpFile) return NULL;
- X s = (char *) malloc(strlen(cmd) + 3 + strlen(TmpFile) + 1);
- X if (!s) return NULL;
- X strcpy(s, cmd);
- X strcat(s, " > ");
- X strcat(s, TmpFile);
- X system(s);
- X free(s);
- X return fopen(TmpFile, "r");
- X}
- X
- X#ifdef HAVE_PROTOS
- XPRIVATE int pclose(FILE *fp)
- X#else
- Xstatic int pclose(fp)
- XFILE *fp;
- X#endif
- X{
- X unlink(TmpFile);
- X return fclose(fp);
- X}
- X
- X#endif
- X
- X/***************************************************************/
- X/* */
- X/* FTypeof */
- X/* */
- X/* Implement the typeof() function. */
- X/* */
- X/***************************************************************/
- X#ifdef HAVE_PROTOS
- XPRIVATE int FTypeof(void)
- X#else
- Xstatic int FTypeof()
- X#endif
- X{
- X switch(ARG(0).type) {
- X case INT_TYPE: return RetStrVal("INT");
- X case DATE_TYPE: return RetStrVal("DATE");
- X case TIM_TYPE: return RetStrVal("TIME");
- X case STR_TYPE: return RetStrVal("STRING");
- X default: return RetStrVal("ERR");
- X }
- X}
- SHAR_EOF
- $TOUCH -am 1109142392 funcs.c &&
- chmod 0600 funcs.c ||
- echo "restore of funcs.c failed"
- set `wc -c funcs.c`;Wc_c=$1
- if test "$Wc_c" != "41381"; then
- echo original size 41381, current size $Wc_c
- fi
- fi
- # ============= globals.c ==============
- if test X"$1" != X"-c" -a -f 'globals.c'; then
- echo "File already exists: skipping 'globals.c'"
- else
- echo "x - extracting globals.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > globals.c &&
- X/***************************************************************/
- X/* */
- X/* GLOBALS.C */
- X/* */
- X/* This file simply instantiates all of the global variables. */
- X/* */
- X/* It does this by #defining MK_GLOBALS and #including */
- X/* globals.h and err.h */
- X/* */
- X/* This file is part of REMIND. */
- X/* Copyright (C) 1992 by David F. Skoll. */
- X/* */
- X/***************************************************************/
- X#include "config.h"
- X#include <stdio.h> /* For defintion of FILE - sigh! */
- X#include "types.h"
- X#define MK_GLOBALS
- X#include "globals.h"
- X#include "err.h"
- SHAR_EOF
- $TOUCH -am 1109141292 globals.c &&
- chmod 0600 globals.c ||
- echo "restore of globals.c failed"
- set `wc -c globals.c`;Wc_c=$1
- if test "$Wc_c" != "1011"; then
- echo original size 1011, current size $Wc_c
- fi
- fi
- echo "End of part 6, continue with part 7"
- exit 0
-
- exit 0 # Just in case...
-