home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume39 / remind / patch08b / patch.08.C
Text File  |  1993-09-07  |  61KB  |  2,052 lines

  1. *** ../prev/init.c    Mon Jun 28 12:29:50 1993
  2. --- ./init.c    Fri Aug 20 11:46:29 1993
  3. ***************
  4. *** 10,15 ****
  5. --- 10,16 ----
  6.   /*  Copyright (C) 1992, 1993 by David F. Skoll.                */
  7.   /*                                                             */
  8.   /***************************************************************/
  9. + #define L_IN_INIT 1
  10.   #include "config.h"
  11.   #include <stdio.h>
  12.   #ifdef HAVE_STDLIB_H
  13. ***************
  14. *** 29,37 ****
  15.   #include "types.h"
  16.   #include "protos.h"
  17.   #include "expr.h"
  18. - #include "globals.h"
  19.   #include "err.h"
  20.   #include "version.h"
  21.   
  22.   /***************************************************************
  23.    *
  24. --- 30,38 ----
  25.   #include "types.h"
  26.   #include "protos.h"
  27.   #include "expr.h"
  28.   #include "err.h"
  29.   #include "version.h"
  30. + #include "globals.h"
  31.   
  32.   /***************************************************************
  33.    *
  34. ***************
  35. *** 65,70 ****
  36. --- 66,72 ----
  37.    *             by non-root, changes environment but not effective uid.
  38.    *  -kcmd    = Run 'cmd' for MSG-type reminders instead of printing to stdout
  39.    *  -iVAR=EXPR = Initialize and preserve VAR.
  40. +  *  A minus sign alone indicates to take input from stdin
  41.    *
  42.    **************************************************************/
  43.   
  44. ***************
  45. *** 111,117 ****
  46.   
  47.      RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
  48.      if (RealToday < 0) {
  49. !       fprintf(ErrFp, "Illegal system date: Year is less than %d\n", BASE);
  50.         exit(1);
  51.      }
  52.      JulianToday = RealToday;
  53. --- 113,119 ----
  54.   
  55.      RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
  56.      if (RealToday < 0) {
  57. !       fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE);
  58.         exit(1);
  59.      }
  60.      JulianToday = RealToday;
  61. ***************
  62. *** 129,140 ****
  63.      i = 1;
  64.      while (i < argc) {
  65.         arg = argv[i];
  66. !       if (*arg != '-') break;  /* Exit the loop if it's not an option */
  67.         i++;
  68.         arg++;
  69.         while (*arg) {
  70.            switch(*arg++) {
  71.               case 'i':
  72.           case 'I':
  73.              InitializeVar(arg);
  74. --- 131,148 ----
  75.      i = 1;
  76.      while (i < argc) {
  77.         arg = argv[i];
  78. !       if (*arg != '-') break; /* Exit the loop if it's not an option */
  79.         i++;
  80.         arg++;
  81. !       if (!*arg) {
  82. !          UseStdin = 1;
  83. !      IgnoreOnce = 1;
  84. !      i--;
  85. !      break;
  86. !       }
  87.         while (*arg) {
  88.            switch(*arg++) {
  89.               case 'i':
  90.           case 'I':
  91.              InitializeVar(arg);
  92. ***************
  93. *** 286,292 ****
  94.                case 'v': case 'V': DebugFlag |= DB_DUMP_VARS; break;
  95.                case 'l': case 'L': DebugFlag |= DB_PRTLINE;   break;
  96.                default:
  97. !                 fprintf(ErrFp, "Unknown debug flag '%c'\n", *(arg-1));
  98.             }
  99.                  }
  100.              break;
  101. --- 294,300 ----
  102.                case 'v': case 'V': DebugFlag |= DB_DUMP_VARS; break;
  103.                case 'l': case 'L': DebugFlag |= DB_PRTLINE;   break;
  104.                default:
  105. !                 fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1));
  106.             }
  107.                  }
  108.              break;
  109. ***************
  110. *** 316,335 ****
  111.              break;
  112.   
  113.           default:
  114. !            fprintf(ErrFp, "Unknown option '%c'\n", *(arg-1));
  115.        }
  116.   
  117.         }
  118.      }
  119.   
  120.      /* Get the filename. */
  121.      if (i >= argc) {
  122.         Usage();
  123.         exit(1);
  124.      }
  125. !    InitialFile = argv[i];
  126. !    i++;
  127.   
  128.      /* Get the date, if any */
  129.      if (i < argc) {
  130. --- 324,341 ----
  131.              break;
  132.   
  133.           default:
  134. !            fprintf(ErrFp, ErrMsg[M_BAD_OPTION], *(arg-1));
  135.        }
  136.   
  137.         }
  138.      }
  139.   
  140.      /* Get the filename. */
  141.      if (i >= argc) {
  142.         Usage();
  143.         exit(1);
  144.      }
  145. !    InitialFile = argv[i++];
  146.   
  147.      /* Get the date, if any */
  148.      if (i < argc) {
  149. ***************
  150. *** 387,402 ****
  151.   /*  Print the usage info.                                      */
  152.   /*                                                             */
  153.   /***************************************************************/
  154.   #ifdef HAVE_PROTOS
  155.   PUBLIC void Usage(void)
  156.   #else
  157.   void Usage()
  158. ! #endif
  159.   {
  160.      fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992, 1993 by David F. Skoll\n", VERSION, L_LANGNAME);
  161.   #ifdef BETA
  162.      fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
  163. ! #endif   
  164.      fprintf(ErrFp, "Usage: remind [options] filename [date]\n");
  165.      fprintf(ErrFp, "Options:\n");
  166.      fprintf(ErrFp, " -n     Output next occurrence of reminders in simple format\n");
  167. --- 393,409 ----
  168.   /*  Print the usage info.                                      */
  169.   /*                                                             */
  170.   /***************************************************************/
  171. + #ifndef L_USAGE_OVERRIDE
  172.   #ifdef HAVE_PROTOS
  173.   PUBLIC void Usage(void)
  174.   #else
  175.   void Usage()
  176. ! #endif /* HAVE_PROTOS */
  177.   {
  178.      fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992, 1993 by David F. Skoll\n", VERSION, L_LANGNAME);
  179.   #ifdef BETA
  180.      fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
  181. ! #endif
  182.      fprintf(ErrFp, "Usage: remind [options] filename [date]\n");
  183.      fprintf(ErrFp, "Options:\n");
  184.      fprintf(ErrFp, " -n     Output next occurrence of reminders in simple format\n");
  185. ***************
  186. *** 425,431 ****
  187.      fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");
  188.      exit(1);
  189.   }
  190.   /***************************************************************/
  191.   /*                                                             */
  192.   /*  ChgUser                                                    */
  193. --- 432,438 ----
  194.      fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");
  195.      exit(1);
  196.   }
  197. ! #endif /* L_USAGE_OVERRIDE */
  198.   /***************************************************************/
  199.   /*                                                             */
  200.   /*  ChgUser                                                    */
  201. ***************
  202. *** 451,457 ****
  203.      int myuid;
  204.   #endif
  205.   
  206. -    static char *NoEnvMem = "Remind: Out of memory for environment\n";
  207.      struct passwd *pwent;
  208.      static char *home, *shell, *username, *logname;
  209.   
  210. --- 458,463 ----
  211. ***************
  212. *** 460,482 ****
  213.      pwent = getpwnam(user);
  214.   
  215.      if (!pwent) {
  216. !       fprintf(ErrFp, "Remind: Unknown user '%s'\n", user);
  217.         exit(1);
  218.      }
  219.   
  220.      if (!myuid && setgid(pwent->pw_gid)) {
  221. !       fprintf(ErrFp, "Remind: Could not change gid to %d\n", pwent->pw_gid);
  222.         exit(1);
  223.      }
  224.   
  225.      if (!myuid && setuid(pwent->pw_uid)) {
  226. !       fprintf(ErrFp, "Remind: Could not change uid to %d\n", pwent->pw_uid);
  227.         exit(1);
  228.      }
  229.   
  230.      home = malloc(strlen(pwent->pw_dir) + 6);
  231.      if (!home) {
  232. !       fprintf(ErrFp, NoEnvMem);
  233.         exit(1);
  234.      }
  235.      sprintf(home, "HOME=%s", pwent->pw_dir);
  236. --- 466,488 ----
  237.      pwent = getpwnam(user);
  238.   
  239.      if (!pwent) {
  240. !       fprintf(ErrFp, ErrMsg[M_BAD_USER], user);
  241.         exit(1);
  242.      }
  243.   
  244.      if (!myuid && setgid(pwent->pw_gid)) {
  245. !       fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
  246.         exit(1);
  247.      }
  248.   
  249.      if (!myuid && setuid(pwent->pw_uid)) {
  250. !       fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid);
  251.         exit(1);
  252.      }
  253.   
  254.      home = malloc(strlen(pwent->pw_dir) + 6);
  255.      if (!home) {
  256. !       fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
  257.         exit(1);
  258.      }
  259.      sprintf(home, "HOME=%s", pwent->pw_dir);
  260. ***************
  261. *** 484,490 ****
  262.   
  263.      shell = malloc(strlen(pwent->pw_shell) + 7);
  264.      if (!shell) {
  265. !       fprintf(ErrFp, NoEnvMem);
  266.         exit(1);
  267.      }
  268.      sprintf(shell, "SHELL=%s", pwent->pw_shell);
  269. --- 490,496 ----
  270.   
  271.      shell = malloc(strlen(pwent->pw_shell) + 7);
  272.      if (!shell) {
  273. !       fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
  274.         exit(1);
  275.      }
  276.      sprintf(shell, "SHELL=%s", pwent->pw_shell);
  277. ***************
  278. *** 493,499 ****
  279.      if (pwent->pw_uid) {
  280.         username = malloc(strlen(pwent->pw_name) + 6);
  281.         if (!username) {
  282. !          fprintf(ErrFp, NoEnvMem);
  283.            exit(1);
  284.         }
  285.         sprintf(username, "USER=%s", pwent->pw_name);
  286. --- 499,505 ----
  287.      if (pwent->pw_uid) {
  288.         username = malloc(strlen(pwent->pw_name) + 6);
  289.         if (!username) {
  290. !          fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
  291.            exit(1);
  292.         }
  293.         sprintf(username, "USER=%s", pwent->pw_name);
  294. ***************
  295. *** 500,506 ****
  296.         putenv(username);
  297.         logname= malloc(strlen(pwent->pw_name) + 9);
  298.         if (!logname) {
  299. !          fprintf(ErrFp, NoEnvMem);
  300.            exit(1);
  301.         }
  302.         sprintf(logname, "LOGNAME=%s", pwent->pw_name);
  303. --- 506,512 ----
  304.         putenv(username);
  305.         logname= malloc(strlen(pwent->pw_name) + 9);
  306.         if (!logname) {
  307. !          fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
  308.            exit(1);
  309.         }
  310.         sprintf(logname, "LOGNAME=%s", pwent->pw_name);
  311. ***************
  312. *** 524,530 ****
  313.   #endif
  314.   {
  315.      char *varname, *expr;
  316. -    static char Err[] = "Remind: -i option: %s\n";
  317.   
  318.      Value val;
  319.   
  320. --- 530,535 ----
  321. ***************
  322. *** 534,576 ****
  323.      varname = str;
  324.      while (*str && *str != '=') str++;
  325.      if (!*str) {
  326. !       fprintf(ErrFp, Err, "Missing '=' sign");
  327.         return;
  328.      }
  329.      *str = 0;
  330.      if (!*varname) {
  331. !       fprintf(ErrFp, Err, "Missing varname");
  332.         return;
  333.      }
  334.      expr = str+1;
  335.      if (!*expr) {
  336. !       fprintf(ErrFp, Err, "Missing expr");
  337.         return;
  338.      }
  339.   
  340.      r=EvalExpr(&expr, &val);
  341.      if (r) {
  342. !       fprintf(ErrFp, Err, ErrMsg[r]);
  343.         return;
  344.      }
  345.   
  346.      if (*varname == '$') {
  347.         if (val.type != INT_TYPE) {
  348. !          fprintf(ErrFp, Err, ErrMsg[E_BAD_TYPE]);
  349.        return;
  350.         }
  351.         r=SetSysVar(varname+1, val.v.val);
  352. !       if (r) fprintf(ErrFp, Err, ErrMsg[r]);
  353.         return;
  354.      }
  355.   
  356.      r=SetVar(varname, &val);
  357.      if (r) {
  358. !       fprintf(ErrFp, Err, ErrMsg[r]);
  359.         return;
  360.      }
  361.      r=PreserveVar(varname);
  362. !    if (r) fprintf(ErrFp, Err, ErrMsg[r]);
  363.      return;
  364.   }
  365.   
  366. --- 539,581 ----
  367.      varname = str;
  368.      while (*str && *str != '=') str++;
  369.      if (!*str) {
  370. !       fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EQ]);
  371.         return;
  372.      }
  373.      *str = 0;
  374.      if (!*varname) {
  375. !       fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
  376.         return;
  377.      }
  378.      expr = str+1;
  379.      if (!*expr) {
  380. !       fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EXPR]);
  381.         return;
  382.      }
  383.   
  384.      r=EvalExpr(&expr, &val);
  385.      if (r) {
  386. !       fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
  387.         return;
  388.      }
  389.   
  390.      if (*varname == '$') {
  391.         if (val.type != INT_TYPE) {
  392. !          fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_BAD_TYPE]);
  393.        return;
  394.         }
  395.         r=SetSysVar(varname+1, val.v.val);
  396. !       if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
  397.         return;
  398.      }
  399.   
  400.      r=SetVar(varname, &val);
  401.      if (r) {
  402. !       fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
  403.         return;
  404.      }
  405.      r=PreserveVar(varname);
  406. !    if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
  407.      return;
  408.   }
  409.   
  410. *** ../prev/lang.h    Mon Jun 28 12:29:33 1993
  411. --- ./lang.h    Wed Aug 18 11:11:53 1993
  412. ***************
  413. *** 13,20 ****
  414.   
  415.   #define ENGLISH    0 /* original by David Skoll */
  416.   #define GERMAN     1 /* translated by Wolfgang Thronicke */
  417. ! #define DUTCH      2 /* translated by Willem Kasdorp */
  418.   #define FINNISH    3 /* translated by Mikko Silvonen */
  419.   
  420.   /* Add more languages here - but please e-mail dfs@doe.carleton.ca
  421.      to have your favorite language assigned a number.  If you add a
  422. --- 13,22 ----
  423.   
  424.   #define ENGLISH    0 /* original by David Skoll */
  425.   #define GERMAN     1 /* translated by Wolfgang Thronicke */
  426. ! #define DUTCH      2 /* translated by Willem Kasdorp and Erik-Jan Vens */
  427.   #define FINNISH    3 /* translated by Mikko Silvonen */
  428. + #define FRENCH       4 /* translated by Laurent Duperval */
  429. + #define NORWEGIAN  5 /* translated by Trygve Randen */
  430.   
  431.   /* Add more languages here - but please e-mail dfs@doe.carleton.ca
  432.      to have your favorite language assigned a number.  If you add a
  433. ***************
  434. *** 48,53 ****
  435. --- 50,59 ----
  436.   #include "dutch.h"
  437.   #elif LANG == FINNISH
  438.   #include "finnish.h"
  439. + #elif LANG == FRENCH
  440. + #include "french.h"
  441. + #elif LANG == NORWEGIAN
  442. + #include "norwgian.h"
  443.   
  444.   /* If no sensible language, choose English.  I intended to use
  445.      the #error directive here, but some C compilers barf. */
  446. *** ../prev/main.c    Mon Jun 28 12:39:37 1993
  447. --- ./main.c    Wed Aug 25 13:06:26 1993
  448. ***************
  449. *** 27,44 ****
  450.   #include <varargs.h>
  451.   #endif
  452.   #include <ctype.h>
  453.   
  454.   #ifdef __MSDOS__
  455.   #include <dos.h>
  456. - #include <time.h>
  457.   #endif
  458.   
  459.   
  460.   #ifndef __MSDOS__
  461.   #include <sys/types.h>
  462. ! #ifdef SYSV
  463. ! #include <time.h>
  464. ! #else
  465.   #include <sys/time.h>
  466.   #endif
  467.   #endif /* ifndef __MSDOS__ */
  468. --- 27,42 ----
  469.   #include <varargs.h>
  470.   #endif
  471.   #include <ctype.h>
  472. + #include <time.h>
  473.   
  474.   #ifdef __MSDOS__
  475.   #include <dos.h>
  476.   #endif
  477.   
  478.   
  479.   #ifndef __MSDOS__
  480.   #include <sys/types.h>
  481. ! #ifndef SYSV
  482.   #include <sys/time.h>
  483.   #endif
  484.   #endif /* ifndef __MSDOS__ */
  485. ***************
  486. *** 51,56 ****
  487. --- 49,60 ----
  488.   
  489.   PRIVATE void DoReminders ARGS ((void));
  490.   
  491. + #if defined(NEED_TIMEGM) && !defined(HAVE_MKTIME)
  492. + PRIVATE long time_cheat ARGS ((int year, int month));
  493. + long timegm ARGS((struct tm *tm));
  494. + long timelocal ARGS((struct tm *tm));
  495. + #endif
  496.   static char TPushBuffer[TOKSIZE+1]; /* Buffer for pushing back a token. */
  497.   static char *TokenPushed = NULL;
  498.   
  499. ***************
  500. *** 97,116 ****
  501.   
  502.      if (!Hush) {
  503.         if (DestroyOmitContexts())
  504. !     Eprint("Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT.");
  505.   #ifdef HAVE_QUEUED
  506. !       if (!Daemon && !NextMode && !NumTriggered && !NumQueued) printf("No reminders.\n");
  507.      else
  508. !       if (!Daemon && !NextMode && !NumTriggered) printf("%d reminder%s queued for later today.\n",
  509. !          NumQueued, (NumQueued == 1) ? "" : "s");
  510.   #else
  511. !       if (!NextMode && !NumTriggered) printf("No reminders.\n");
  512.   #endif
  513.      }
  514.   
  515.      /* If it's MS-DOS or OS2, reset the file access date */
  516.   #if defined(__MSDOS__) || defined(OS2)
  517. !    if (RealToday == JulianToday) SetAccessDate(InitialFile, RealToday);
  518.   #endif
  519.   
  520.      /* If there are sorted reminders, handle them */
  521. --- 101,121 ----
  522.   
  523.      if (!Hush) {
  524.         if (DestroyOmitContexts())
  525. !     Eprint("%s", E_PUSH_NOPOP);
  526.   #ifdef HAVE_QUEUED
  527. !       if (!Daemon && !NextMode && !NumTriggered && !NumQueued) printf("%s\n", ErrMsg[E_NOREMINDERS]);
  528.      else
  529. !       if (!Daemon && !NextMode && !NumTriggered) printf(ErrMsg[M_QUEUED],
  530. !          NumQueued);
  531.   #else
  532. !       if (!NextMode && !NumTriggered) printf("%s\n", ErrMsg[E_NOREMINDERS]);
  533.   #endif
  534.      }
  535.   
  536.      /* If it's MS-DOS or OS2, reset the file access date */
  537.   #if defined(__MSDOS__) || defined(OS2)
  538. !    if (!UseStdin && (RealToday == JulianToday))
  539. !       SetAccessDate(InitialFile, RealToday);
  540.   #endif
  541.   
  542.      /* If there are sorted reminders, handle them */
  543. ***************
  544. *** 130,136 ****
  545.           return 0;
  546.        }
  547.        if (pid == -1) {
  548. !         fprintf(ErrFp, "Couldn't fork to do queued reminders.\n");
  549.           return 1;
  550.        }
  551.         }
  552. --- 135,141 ----
  553.           return 0;
  554.        }
  555.        if (pid == -1) {
  556. !         fprintf(ErrFp, "%s", ErrMsg[E_CANTFORK]);
  557.           return 1;
  558.        }
  559.         }
  560. ***************
  561. *** 158,173 ****
  562.      char *s;
  563.      Parser p;
  564.   
  565. !    FileAccessDate = GetAccessDate(InitialFile);
  566.   
  567.      if (FileAccessDate < 0) {
  568. !       fprintf(ErrFp, "remind: Can't access file '%s'.\n", InitialFile);
  569.         exit(1);
  570.      }
  571.   
  572.      r=OpenFile(InitialFile);
  573.      if (r) {
  574. !       fprintf(ErrFp, "Can't read %s: %s\n", InitialFile, ErrMsg[r]);
  575.         exit(1);
  576.      }
  577.   
  578. --- 163,180 ----
  579.      char *s;
  580.      Parser p;
  581.   
  582. !    if (!UseStdin) FileAccessDate = GetAccessDate(InitialFile);
  583. !    else          FileAccessDate = JulianToday;
  584.   
  585.      if (FileAccessDate < 0) {
  586. !       fprintf(ErrFp, "%s: '%s'.\n", ErrMsg[E_CANTACCESS], InitialFile);
  587.         exit(1);
  588.      }
  589.   
  590.      r=OpenFile(InitialFile);
  591.      if (r) {
  592. !       fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING],
  593. !                                     InitialFile, ErrMsg[r]);
  594.         exit(1);
  595.      }
  596.   
  597. ***************
  598. *** 175,181 ****
  599.         r = ReadLine();
  600.         if (r == E_EOF) return;
  601.         if (r) {
  602. !      Eprint("Error reading file: %s", ErrMsg[r]);
  603.        exit(1);
  604.         }
  605.         s = FindInitialToken(&tok, CurLine);
  606. --- 182,188 ----
  607.         r = ReadLine();
  608.         if (r == E_EOF) return;
  609.         if (r) {
  610. !      Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
  611.        exit(1);
  612.         }
  613.         s = FindInitialToken(&tok, CurLine);
  614. ***************
  615. *** 565,571 ****
  616.   
  617.      if (FreshLine) {
  618.         FreshLine = 0;
  619. !       (void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
  620.         if (DebugFlag & DB_PRTLINE) OutputLine(ErrFp);
  621.      } else fprintf(ErrFp, "       ");
  622.   
  623. --- 572,581 ----
  624.   
  625.      if (FreshLine) {
  626.         FreshLine = 0;
  627. !       if (strcmp(FileName, "-"))
  628. !          (void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
  629. !       else
  630. !          (void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
  631.         if (DebugFlag & DB_PRTLINE) OutputLine(ErrFp);
  632.      } else fprintf(ErrFp, "       ");
  633.   
  634. ***************
  635. *** 911,917 ****
  636.   
  637.      if ( (r = ParseToken(p, TokBuffer)) ) return r;
  638.      if (*TokBuffer && (*TokBuffer != '#') && (*TokBuffer != ';')) {
  639. !       Eprint("Expecting end-of-line, found '%s'", TokBuffer);
  640.         return E_EXTRANEOUS_TOKEN;
  641.      }
  642.      return OK;
  643. --- 921,927 ----
  644.   
  645.      if ( (r = ParseToken(p, TokBuffer)) ) return r;
  646.      if (*TokBuffer && (*TokBuffer != '#') && (*TokBuffer != ';')) {
  647. !       Eprint("%s: '%s'", ErrMsg[E_EXPECTING_EOL], TokBuffer);
  648.         return E_EXTRANEOUS_TOKEN;
  649.      }
  650.      return OK;
  651. ***************
  652. *** 1162,1164 ****
  653. --- 1172,1325 ----
  654.      if (isdst) *isdst = temp->tm_isdst;
  655.      return 0;
  656.   }
  657. + /***************************************************************/
  658. + /*                                                             */
  659. + /*  FillParagraph                                              */
  660. + /*                                                             */
  661. + /*  Write a string to standard output, formatting it as a      */
  662. + /*  paragraph according to the FirstIndent, FormWidth and      */
  663. + /*  SubsIndent variables.  Spaces are gobbled.  Double-spaces  */
  664. + /*  are inserted after periods.  As a special case, if the     */
  665. + /*  last char in s is '\n', an extra newline is emitted.       */
  666. + /*                                                             */
  667. + /***************************************************************/
  668. + #ifdef HAVE_PROTOS
  669. + PUBLIC void FillParagraph(char *s)
  670. + #else
  671. + void FillParagraph(s)
  672. + char *s;
  673. + #endif
  674. + {
  675. +    int line = 0;
  676. +    int i, j;
  677. +    int pendspace;
  678. +    int len;
  679. +    char *t;
  680. +    int roomleft;
  681. +    if (!s || !*s) return;
  682. +    /* Skip leading spaces */
  683. +    while(isspace(*s)) s++;
  684. +    /* Start formatting */
  685. +    while(1) {
  686. +       if (!*s) {
  687. +          if (*(s-1) == '\n') putchar('\n');
  688. +          return;
  689. +       }
  690. +       /* Over here, we're at the beginning of a line.  Emit the correct
  691. +          number of spaces */
  692. +       j = line ? SubsIndent : FirstIndent;
  693. +       for (i=0; i<j; i++) putchar(' ');
  694. +       /* Calculate the amount of room left on this line */
  695. +       roomleft = FormWidth - j;
  696. +       pendspace = 0;
  697. +       /* Emit words until the next one won't fit */
  698. +       while(1) {
  699. +          while(isspace(*s)) s++;
  700. +          t = s;
  701. +          while(*s && !isspace(*s)) s++;
  702. +      len = s - t;
  703. +      if (!len) {
  704. +         putchar('\n');
  705. +             if (*(s-1) == '\n') putchar('\n');
  706. +         return;
  707. +          }
  708. +      if (!pendspace || len+pendspace <= roomleft) {
  709. +             for (i=0; i<pendspace; i++) putchar(' ');
  710. +            while(t < s) {
  711. +            putchar(*t);
  712. +            t++;
  713. +             }
  714. +          } else {
  715. +         s = t;
  716. +         putchar('\n');
  717. +         line++;
  718. +         break;
  719. +          }
  720. +      pendspace = (*(t-1) == '.') ? 2 : 1;
  721. +      roomleft -= len+pendspace;
  722. +       }
  723. +    }
  724. + }
  725. + #if defined(NEED_TIMEGM) && !defined(HAVE_MKTIME)
  726. + #define        TGM_SEC        (1)
  727. + #define        TGM_MIN        (60 * TGM_SEC)
  728. + #define        TGM_HR        (60 * TGM_MIN)
  729. + #define        TGM_DAY        (24 * TGM_HR)
  730. + #ifdef HAVE_PROTOS
  731. + PRIVATE long time_cheat(int year, int month)
  732. + #else
  733. + static long time_cheat (year, month)
  734. + int year;
  735. + int month;
  736. + #endif
  737. + {
  738. +     long guess = time((long *) NULL);
  739. +     struct tm g;
  740. +     int diff;
  741. +     
  742. +     g = *gmtime (&guess);
  743. +     while ((diff = year - g.tm_year) > 0)
  744. +     {
  745. +         guess += diff * (363 - TGM_DAY);
  746. +         g = *gmtime (&guess);
  747. +     }
  748. +     g.tm_mday--;
  749. +     guess -= g.tm_sec * TGM_SEC + g.tm_min * TGM_MIN +
  750. +          g.tm_hour * TGM_HR + g.tm_mday * TGM_DAY;
  751. +     return (guess);
  752. + }
  753. + #ifdef HAVE_PROTOS
  754. + PUBLIC long timegm (struct tm *tm)
  755. + #else
  756. + long timegm(tm)
  757. + struct tm *tm;
  758. + #endif
  759. + {
  760. +     long clock = time_cheat (tm->tm_year, tm->tm_mon);
  761. +     return (clock + tm->tm_sec * TGM_SEC +
  762. +             tm->tm_min * TGM_MIN +
  763. +             tm->tm_hour * TGM_HR +
  764. +             (tm->tm_mday - 1) * TGM_DAY);
  765. + }
  766. + #ifdef HAVE_PROTOS
  767. + PUBLIC long timelocal (struct tm *tm)
  768. + #else
  769. + long timelocal (tm)
  770. + struct tm *tm;
  771. + #endif
  772. + {
  773. +     long zero = 0;
  774. +     struct tm epoch;
  775. +     int tzmin;
  776. +     long clock;
  777. +     struct tm test;
  778. +     epoch = *localtime (&zero);
  779. +     tzmin = epoch.tm_hour * 60 + epoch.tm_min;
  780. +     if (tzmin > 0)
  781. +     {
  782. +         tzmin = 24 * 60 - tzmin;
  783. +         if (epoch.tm_year == 70)
  784. +             tzmin -= 24 * 60;
  785. +     }
  786. +     clock = timegm (tm) + tzmin * TGM_MIN;
  787. +     test = *localtime (&clock);
  788. +     if (test.tm_hour != tm->tm_hour)
  789. +         clock -= TGM_HR;
  790. +     return (clock);
  791. + }
  792. + #endif /* NEED_TIMEGM */
  793. *** ../prev/makefile.os2    Mon Jun 28 12:30:19 1993
  794. --- ./makefile.os2    Wed Aug 18 11:13:19 1993
  795. ***************
  796. *** 25,37 ****
  797.   # YOU SHOULDN'T EDIT ANYTHING BELOW HERE.  You may want to change some things
  798.   # in config.h; then, you should be able to type 'make'.
  799.   #-----------------------------------------------------------------------------
  800. ! VERSION= 03.00.07
  801.   
  802.   HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
  803. ! lang.h english.h german.h dutch.h finish.h
  804.   
  805.   STDHDRS= config.h types.h protos.h globals.h err.h lang.h
  806.   
  807.   SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
  808.   main.c omit.c sort.c token.c trigger.c userfns.c utils.c var.c hbcal.c
  809.   
  810. --- 25,39 ----
  811.   # YOU SHOULDN'T EDIT ANYTHING BELOW HERE.  You may want to change some things
  812.   # in config.h; then, you should be able to type 'make'.
  813.   #-----------------------------------------------------------------------------
  814. ! VERSION= 03.00.08
  815.   
  816.   HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
  817. ! lang.h english.h german.h dutch.h finish.h french.h norwgian.h
  818.   
  819.   STDHDRS= config.h types.h protos.h globals.h err.h lang.h
  820.   
  821. + LANGHDRS= english.h german.h dutch.h finnish.h french.h norwgian.h
  822.   SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
  823.   main.c omit.c sort.c token.c trigger.c userfns.c utils.c var.c hbcal.c
  824.   
  825. ***************
  826. *** 68,74 ****
  827.   rem2ps$O: rem2ps.c rem2ps.h config.h
  828.   calendar$O: calendar.c $(STDHDRS) expr.h
  829.   dorem$O: dorem.c $(STDHDRS) expr.h
  830. ! dosubst$O: dosubst.c $(STDHDRS)
  831.   expr$O: expr.c $(STDHDRS) expr.h
  832.   files$O: files.c $(STDHDRS)
  833.   funcs$O: funcs.c $(STDHDRS) expr.h version.h
  834. --- 70,76 ----
  835.   rem2ps$O: rem2ps.c rem2ps.h config.h
  836.   calendar$O: calendar.c $(STDHDRS) expr.h
  837.   dorem$O: dorem.c $(STDHDRS) expr.h
  838. ! dosubst$O: dosubst.c $(STDHDRS) $(LANGHDRS)
  839.   expr$O: expr.c $(STDHDRS) expr.h
  840.   files$O: files.c $(STDHDRS)
  841.   funcs$O: funcs.c $(STDHDRS) expr.h version.h
  842. *** ../prev/makefile.tc    Mon Jun 28 12:30:09 1993
  843. --- ./makefile.tc    Wed Aug 18 11:13:06 1993
  844. ***************
  845. *** 1,12 ****
  846.   # Makefile for REMIND for Turbo C for MSDOS
  847.   
  848. ! VERSION= 03.00.07
  849.   
  850.   HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
  851. ! lang.h english.h german.h dutch.h finnish.h
  852.   
  853.   STDHDRS= config.h types.h protos.h globals.h err.h lang.h
  854.   
  855.   SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
  856.   main.c omit.c sort.c token.c trigger.c userfns.c utils.c var.c hbcal.c
  857.   
  858. --- 1,14 ----
  859.   # Makefile for REMIND for Turbo C for MSDOS
  860.   
  861. ! VERSION= 03.00.08
  862.   
  863.   HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
  864. ! lang.h english.h german.h dutch.h finnish.h french.h norwgian.h
  865.   
  866.   STDHDRS= config.h types.h protos.h globals.h err.h lang.h
  867.   
  868. + LANGHDRS= english.h german.h dutch.h finnish.h french.h norwgian.h
  869.   SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
  870.   main.c omit.c sort.c token.c trigger.c userfns.c utils.c var.c hbcal.c
  871.   
  872. ***************
  873. *** 37,43 ****
  874.   
  875.   dorem.obj: dorem.c $(STDHDRS) expr.h
  876.   
  877. ! dosubst.obj: dosubst.c $(STDHDRS)
  878.   
  879.   expr.obj: expr.c $(STDHDRS) expr.h
  880.   
  881. --- 39,45 ----
  882.   
  883.   dorem.obj: dorem.c $(STDHDRS) expr.h
  884.   
  885. ! dosubst.obj: dosubst.c $(STDHDRS) $(LANGHDRS)
  886.   
  887.   expr.obj: expr.c $(STDHDRS) expr.h
  888.   
  889. *** ../prev/omit.c    Mon Jun 28 12:29:53 1993
  890. --- ./omit.c    Thu Aug 19 16:16:33 1993
  891. ***************
  892. *** 304,329 ****
  893.         FindToken(TokBuffer, &tok);
  894.         switch (tok.type) {
  895.            case T_Year:
  896. !         if (y != NO_YR) {
  897. !            Eprint("Year specified twice");
  898. !            return E_PARSE_ERR;
  899. !         }
  900.           y = tok.val;
  901.           break;
  902.   
  903.            case T_Month:
  904. !         if (m != NO_MON) {
  905. !            Eprint("Month specified twice");
  906. !            return E_PARSE_ERR;
  907. !         }
  908.           m = tok.val;
  909.           break;
  910.   
  911.            case T_Day:
  912. !         if (d != NO_DAY) {
  913. !            Eprint("Day specified twice");
  914. !            return E_PARSE_ERR;
  915. !         }
  916.           d = tok.val;
  917.           break;
  918.        
  919. --- 304,320 ----
  920.         FindToken(TokBuffer, &tok);
  921.         switch (tok.type) {
  922.            case T_Year:
  923. !         if (y != NO_YR) return E_YR_TWICE;
  924.           y = tok.val;
  925.           break;
  926.   
  927.            case T_Month:
  928. !         if (m != NO_MON) return E_MON_TWICE;
  929.           m = tok.val;
  930.           break;
  931.   
  932.            case T_Day:
  933. !         if (d != NO_DAY) return E_DAY_TWICE;
  934.           d = tok.val;
  935.           break;
  936.        
  937. ***************
  938. *** 337,355 ****
  939.           break;
  940.   
  941.        default:
  942. !         Eprint("Unknown token '%s' in OMIT command", TokBuffer);
  943. !         return E_PARSE_ERR;
  944.         }
  945.      }
  946. !    if (m == NO_MON || d == NO_DAY) {
  947. !       Eprint("Must specify month and day in OMIT command");
  948. !       return E_PARSE_ERR;
  949. !    }
  950.      if (y == NO_YR) {
  951. !       if (NumPartialOmits == MAX_PARTIAL_OMITS) {
  952. !          Eprint("Too many partial OMITs");
  953. !      return E_NO_MEM;
  954. !       }
  955.         if (d > MonthDays[m]) return E_BAD_DATE;
  956.         syndrome = (m<<5) + d;
  957.         if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
  958. --- 328,342 ----
  959.           break;
  960.   
  961.        default:
  962. !         Eprint("%s: '%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN], TokBuffer);
  963. !         return E_UNKNOWN_TOKEN;
  964.         }
  965.      }
  966. !    if (m == NO_MON || d == NO_DAY) return E_SPEC_MON_DAY;
  967.      if (y == NO_YR) {
  968. !       if (NumPartialOmits == MAX_PARTIAL_OMITS) return E_2MANY_PART;
  969.         if (d > MonthDays[m]) return E_BAD_DATE;
  970.         syndrome = (m<<5) + d;
  971.         if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
  972. ***************
  973. *** 357,366 ****
  974.            NumPartialOmits++;
  975.         }
  976.      } else {
  977. !       if (NumFullOmits == MAX_FULL_OMITS) {
  978. !          Eprint("Too many full OMITs");
  979. !      return E_NO_MEM;
  980. !       }
  981.         if (d > DaysInMonth(m, y)) return E_BAD_DATE;
  982.         syndrome = Julian(y, m, d);
  983.         if (!BexistsIntArray(FullOmitArray, NumFullOmits, syndrome)) {
  984. --- 344,351 ----
  985.            NumPartialOmits++;
  986.         }
  987.      } else {
  988. !       if (NumFullOmits == MAX_FULL_OMITS) return E_2MANY_FULL;
  989.         if (d > DaysInMonth(m, y)) return E_BAD_DATE;
  990.         syndrome = Julian(y, m, d);
  991.         if (!BexistsIntArray(FullOmitArray, NumFullOmits, syndrome)) {
  992. *** ../prev/protos.h    Mon Jun 28 12:37:30 1993
  993. --- ./protos.h    Wed Aug 18 12:52:08 1993
  994. ***************
  995. *** 108,114 ****
  996.   int DoPreserve  ARGS ((Parser *p));
  997.   int DoSatRemind ARGS ((Trigger *trig, TimeTrig *tim, ParsePtr p));
  998.   int ParseNonSpaceChar ARGS ((ParsePtr p, int *err, int peek));
  999. ! int HashVal ARGS ((const char *str));
  1000.   int DateOK ARGS ((int y, int m, int d));
  1001.   Operator *FindFunc ARGS ((char *name, Operator where[], int num));
  1002.   int InsertIntoSortBuffer ARGS ((int jul, int tim, char *body, int typ));
  1003. --- 108,114 ----
  1004.   int DoPreserve  ARGS ((Parser *p));
  1005.   int DoSatRemind ARGS ((Trigger *trig, TimeTrig *tim, ParsePtr p));
  1006.   int ParseNonSpaceChar ARGS ((ParsePtr p, int *err, int peek));
  1007. ! unsigned int HashVal ARGS ((const char *str));
  1008.   int DateOK ARGS ((int y, int m, int d));
  1009.   Operator *FindFunc ARGS ((char *name, Operator where[], int num));
  1010.   int InsertIntoSortBuffer ARGS ((int jul, int tim, char *body, int typ));
  1011. ***************
  1012. *** 129,131 ****
  1013. --- 129,132 ----
  1014.   int SetSysVar ARGS ((const char *name, int value));
  1015.   void DumpSysVarByName ARGS ((const char *name));
  1016.   int CalcMinsFromUTC ARGS ((int jul, int tim, int *mins, int *isdst));
  1017. + void FillParagraph ARGS ((char *s));
  1018. *** ../prev/queue.c    Mon Jun 28 12:29:55 1993
  1019. --- ./queue.c    Thu Aug 19 16:12:20 1993
  1020. ***************
  1021. *** 74,86 ****
  1022.   
  1023.      qelem = NEW(QueuedRem);
  1024.      if (!qelem) {
  1025. -       Eprint("No memory to queue reminder.");
  1026.         return E_NO_MEM;
  1027.      }
  1028.      qelem->text = StrDup(p->pos);  /* Guaranteed that parser is not nested. */
  1029.      if (!qelem->text) {
  1030.         free(qelem);
  1031. -       Eprint("No memory to queue reminder.");
  1032.         return E_NO_MEM;
  1033.      }
  1034.      qelem->typ = typ;
  1035. --- 74,84 ----
  1036. ***************
  1037. *** 275,281 ****
  1038.                    q->tt.ttime / 60, TIMESEP, q->tt.ttime % 60,
  1039.                    q->tt.nexttime / 60, TIMESEP, q->tt.nexttime % 60,
  1040.                    q->tt.rep, q->tt.delta, NL);
  1041. !          printf("Text: %s %s%s%s", ((q->typ == MSG_TYPE) ? "MSG" : "RUN"),
  1042.                    q->text,
  1043.                    NL, NL);
  1044.         }
  1045. --- 273,280 ----
  1046.                    q->tt.ttime / 60, TIMESEP, q->tt.ttime % 60,
  1047.                    q->tt.nexttime / 60, TIMESEP, q->tt.nexttime % 60,
  1048.                    q->tt.rep, q->tt.delta, NL);
  1049. !                  printf("Text: %s %s%s%s", ((q->typ == MSG_TYPE) ? "MSG" :
  1050. !                                    ((q->typ == MSF_TYPE) ? "MSF" :"RUN")),
  1051.                    q->text,
  1052.                    NL, NL);
  1053.         }
  1054. *** ../prev/rem2ps.1    Mon Jun 28 12:30:23 1993
  1055. --- ./rem2ps.1    Wed Jul 28 10:22:25 1993
  1056. ***************
  1057. *** 29,34 ****
  1058. --- 29,43 ----
  1059.   Use ISO 8859-1 standard encoding for the PostScript fonts.  If you do
  1060.   not use this option, the default encoding is used.
  1061.   .TP
  1062. + .B \-e
  1063. + Make the calendar fill the entire page.  By default, the calendar is
  1064. + slightly smaller than the page.  This allows days with many reminders
  1065. + to "expand" as needed.  However, if you don't have days which expand,
  1066. + you can use this option to make all of the boxes slightly bigger.  
  1067. + One caveat: If you do use the \fB\-e\fR option and one day has many
  1068. + reminders, the calendar may expand off the page, losing some information.
  1069. + Experiment!
  1070. + .TP
  1071.   .B \-m media
  1072.   Set the page size.  If you use the \-m option, you must specify the
  1073.   media type, which can be one of the
  1074. *** ../prev/rem2ps.c    Mon Jun 28 12:30:22 1993
  1075. --- ./rem2ps.c    Wed Jul 28 10:15:11 1993
  1076. ***************
  1077. *** 98,103 ****
  1078. --- 98,104 ----
  1079.   int WkDayNum;
  1080.   
  1081.   int LeftMarg, RightMarg, TopMarg, BotMarg;
  1082. + int FillPage;
  1083.   
  1084.   void Init ARGS ((int argc, char *argv[]));
  1085.   void Usage ARGS ((char *s));
  1086. ***************
  1087. *** 185,191 ****
  1088.      printf("(%s %s) doheading\n", month, year);
  1089.   
  1090.   /* Calculate the minimum box size */
  1091. !    printf("/MinBoxSize ytop MinY sub 7 div def\n");
  1092.   
  1093.   /* If wkday >= 2, then do the small calendars at the top. */
  1094.      if (wkday >=2 && !NoSmallCal) {
  1095. --- 186,201 ----
  1096.      printf("(%s %s) doheading\n", month, year);
  1097.   
  1098.   /* Calculate the minimum box size */
  1099. !    if (!FillPage) {
  1100. !       printf("/MinBoxSize ytop MinY sub 7 div def\n");
  1101. !    } else {
  1102. !       if ((days == 31 && wkday >= 5) || (days == 30 && wkday == 6))
  1103. !          printf("/MinBoxSize ytop MinY sub 6 div def\n");
  1104. !       else if (days == 28 && wkday == 0 && NoSmallCal)
  1105. !          printf("/MinBoxSize ytop MinY sub 4 div def\n");
  1106. !       else
  1107. !          printf("/MinBoxSize ytop MinY sub 5 div def\n");
  1108. !    }
  1109.   
  1110.   /* If wkday >= 2, then do the small calendars at the top. */
  1111.      if (wkday >=2 && !NoSmallCal) {
  1112. ***************
  1113. *** 522,527 ****
  1114. --- 532,538 ----
  1115.      TopMarg = 36;
  1116.      BotMarg = 36;
  1117.      UseISO = 0;
  1118. +    FillPage = 0;
  1119.   
  1120.      for(j=0; j<32; j++) PsEntries[i] = NULL;
  1121.   
  1122. ***************
  1123. *** 618,623 ****
  1124. --- 629,636 ----
  1125.   
  1126.        case 'c': NoSmallCal = 1; break;
  1127.   
  1128. +      case 'e': FillPage = 1; break;
  1129.        default: Usage("Unrecognized option");
  1130.         }
  1131.      }
  1132. ***************
  1133. *** 651,656 ****
  1134. --- 664,670 ----
  1135.      fprintf(stderr, "-s[hed] size  Set size for header, calendar entries and/or day numbers\n");
  1136.      fprintf(stderr, "-b size       Set border size for calendar entries\n");
  1137.      fprintf(stderr, "-t size       Set line thickness\n");
  1138. +    fprintf(stderr, "-e            Make calendar fill entire page\n");
  1139.      fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n");
  1140.      exit(1);
  1141.   }
  1142. *** ../prev/remind-all.sh    Mon Jun 28 12:30:06 1993
  1143. --- ./remind-all.sh    Thu Aug 19 17:28:47 1993
  1144. ***************
  1145. *** 1,5 ****
  1146. --- 1,10 ----
  1147.   # Shell script to mail all users reminders.
  1148.   
  1149. + # This file is part of REMIND
  1150. + #
  1151. + # REMIND is Copyright (C) 1992, 1993 by David F. Skoll
  1152. + # This file is Copyright (C) 1990 by Bill Aten
  1153.   # Thanks to Bill Aten for this script.
  1154.   
  1155.   # Run it AFTER MIDNIGHT so that date is correct!
  1156. *** ../prev/remind.1    Mon Jul 19 11:31:13 1993
  1157. --- ./remind.1    Thu Aug 26 10:58:39 1993
  1158. ***************
  1159. *** 9,14 ****
  1160. --- 9,18 ----
  1161.   found in it.  The commands are used to issue reminders and alarms.  Each
  1162.   reminder or alarm can consist of a message sent to standard output, or
  1163.   a program to be executed.
  1164. + .PP
  1165. + If \fIfilename\fR is specified as a single dash '-', then \fBRemind\fR
  1166. + takes its input from standard input.  This also implicitly enables
  1167. + the \fB\-o\fR option, described below.
  1168.   .SH OPTIONS
  1169.   .TP
  1170.   .B \-n
  1171. ***************
  1172. *** 245,251 ****
  1173.   [\fBAT\fR \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
  1174.   [\fBUNTIL\fR \fIexpiry_date\fR]
  1175.   [\fBSCANFROM\fR \fIscan_date\fR]
  1176. ! \fBMSG\fR | \fBRUN\fR | \fBCAL\fR | \fBSATISFY\fR | \fBPS\fR | \fBPSFILE\fR
  1177.   .I body
  1178.   .RE
  1179.   .PP
  1180. --- 249,256 ----
  1181.   [\fBAT\fR \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
  1182.   [\fBUNTIL\fR \fIexpiry_date\fR]
  1183.   [\fBSCANFROM\fR \fIscan_date\fR]
  1184. ! \fBMSG\fR | \fBMSF\fR | \fBRUN\fR | \fBCAL\fR | \fBSATISFY\fR |
  1185. ! \fBPS\fR | \fBPSFILE\fR
  1186.   .I body
  1187.   .RE
  1188.   .PP
  1189. ***************
  1190. *** 256,265 ****
  1191.   The \fBREM\fR token is optional, providing that the remainder
  1192.   of the command cannot be mistaken for another \fBRemind\fR command
  1193.   such as \fBOMIT\fR or \fBRUN\fR.  The portion of the \fBREM\fR command
  1194. ! before the \fBMSG\fR, \fBRUN\fR, \fBCAL\fR or \fBSATISFY\fR clause
  1195.   is called a \fItrigger\fR.
  1196.   .PP
  1197. ! .B MSG, RUN, CAL, PS and PSFILE
  1198.   .PP
  1199.   These keywords denote the \fItype\fR
  1200.   of the reminder.  (\fBSATISFY\fR is more complicated and will be explained
  1201. --- 261,270 ----
  1202.   The \fBREM\fR token is optional, providing that the remainder
  1203.   of the command cannot be mistaken for another \fBRemind\fR command
  1204.   such as \fBOMIT\fR or \fBRUN\fR.  The portion of the \fBREM\fR command
  1205. ! before the \fBMSG\fR, \fBMSF\fR \fBRUN\fR, \fBCAL\fR or \fBSATISFY\fR clause
  1206.   is called a \fItrigger\fR.
  1207.   .PP
  1208. ! .B "MSG, MSF, RUN, CAL, PS and PSFILE"
  1209.   .PP
  1210.   These keywords denote the \fItype\fR
  1211.   of the reminder.  (\fBSATISFY\fR is more complicated and will be explained
  1212. ***************
  1213. *** 270,275 ****
  1214. --- 275,288 ----
  1215.   passed to the appropriate program.  Note that the options \fB\-c\fR,
  1216.   \fB\-s\fR, \fB\-p\fR and \fB\-n\fR disable the \fB\-k\fR option.
  1217.   .PP
  1218. + The \fBMSF\fR keyword is almost the same as the \fBMSG\fR keyword,
  1219. + except that the reminder is formatted to fit into a paragraph-like
  1220. + format.  Three system variables control the formatting of \fBMSF\fR-type
  1221. + reminders - they are \fB$FirstIndent\fR, \fB$SubsIndent\fR and
  1222. + \fB$FormWidth\fR.  They are discussed in the section "System Variables."
  1223. + The \fBMSF\fR keyword causes the spacing of your reminder to be altered -
  1224. + extra spaces are discarded, and two spaces are placed after periods.
  1225. + .PP
  1226.   A \fBRUN\fR-type
  1227.   reminder also passes the \fIbody\fR through the substitution filter, but
  1228.   then executes the result as a system command.  A \fBCAL\fR-type reminder
  1229. ***************
  1230. *** 1106,1111 ****
  1231. --- 1119,1126 ----
  1232.   .PP
  1233.   \fBINCLUDE\fR files can be nested up to a depth of 8.
  1234.   .PP
  1235. + If you specify a filename of "-" in the \fBINCLUDE\fR command, \fBRemind\fR
  1236. + will begin reading from standard input.
  1237.   .SH THE RUN COMMAND
  1238.   .PP
  1239.   If you include other files in your reminder script, you may not always
  1240. ***************
  1241. *** 1491,1496 ****
  1242. --- 1506,1515 ----
  1243.   If non-zero, then the \fB\-q\fR option was supplied on the command line.
  1244.   For the MS-DOS version, always contains 1.
  1245.   .TP
  1246. + .B $FirstIndent
  1247. + The number of spaces by which to indent the first line of a \fBMSF\fR-type
  1248. + reminder.  The default is 0.
  1249. + .TP
  1250.   .B $FoldYear
  1251.   The standard Unix library functions may have difficulty dealing with dates
  1252.   later than 2037.  If this variable is set to 1, then the UTC calculations
  1253. ***************
  1254. *** 1503,1508 ****
  1255. --- 1522,1533 ----
  1256.   this variable is 0.  Set it to 1 if the sun or UTC functions misbehave
  1257.   for years greater than 2037.
  1258.   .TP
  1259. + .B $FormWidth
  1260. + The maximum width of each line of text for formatting \fBMSF\fR-type
  1261. + reminders.  The default is 72.  If an \fBMSF\fR-type reminder contains
  1262. + a word too long to fit in this width, it will not be truncated - the
  1263. + width limit will be ignored.
  1264. + .TP
  1265.   .B $HushMode (read-only)
  1266.   If non-zero, then the \fB\-h\fR option was supplied on the command line.
  1267.   .TP
  1268. ***************
  1269. *** 1563,1568 ****
  1270. --- 1588,1599 ----
  1271.   block is greater than the saved value, then at least one holiday
  1272.   was triggered, and you can execute the command to shade in the
  1273.   calendar box.  (See the section "Calendar Mode".)
  1274. + .PP
  1275. + .RS
  1276. + Note that \fB$NumTrig\fR is affected \fIonly\fR
  1277. + by \fBREM\fR commands; triggers in \fBIFTRIG\fR commands do
  1278. + not affect it.  
  1279. + .RE
  1280.   .TP
  1281.   .B $PSCal (read-only)
  1282.   If non-zero, then the \fB\-p\fR option was supplied on the command line.
  1283. ***************
  1284. *** 1573,1578 ****
  1285. --- 1604,1613 ----
  1286.   .B $SimpleCal (read-only)
  1287.   Set to a non-zero value if \fIeither\fR of the \fB\-p\fR or \fB\-s\fR
  1288.   command-line options was supplied.
  1289. + .TP
  1290. + .B $SubsIndent
  1291. + The number of spaces by which all lines (except the first) of an
  1292. + \fBMSF\fR-type reminder should be indented.  The default is 0.
  1293.   .PP
  1294.   Note:  If any of the calendar modes are in effect, then the
  1295.   values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
  1296. ***************
  1297. *** 1741,1746 ****
  1298. --- 1776,1786 ----
  1299.   for the specified year.  If \fIarg\fR is a \fBDATE\fR, then returns the
  1300.   date of the next Easter Sunday on or after \fIarg\fR.
  1301.   .TP
  1302. + .B filedate(s_filename)
  1303. + Returns the modification date of \fIfilename\fR.  If \fIfilename\fR
  1304. + does not exist, or its modification date is before the year
  1305. + \fBbaseyr()\fR, then 1 January of \fBbaseyr()\fR is returned.
  1306. + .TP
  1307.   .B filedir()
  1308.   Returns the directory which contains the current file being
  1309.   processed.  It may be a relative or absolute pathname, but
  1310. ***************
  1311. *** 2510,2515 ****
  1312. --- 2550,2558 ----
  1313.   initialized has remained defined.  Thus, time-consuming operations which
  1314.   do not depend on the value of \fBtoday()\fR are done only once.
  1315.   .PP
  1316. + System variables (those whose names start with '$') are automatically
  1317. + preserved between calendar iterations.
  1318. + .PP
  1319.   Note that for efficiency, \fBRemind\fR caches the reminder script
  1320.   (and any \fBINCLUDE\fRd files) in memory when producing a calendar.
  1321.   .PP
  1322. ***************
  1323. *** 2723,2734 ****
  1324.   .SH FOREIGN LANGUAGE SUPPORT
  1325.   .PP
  1326.   Your version of \fBRemind\fR may have been compiled to support a
  1327. ! language other than English.  This support is not complete - for
  1328. ! example, all error and usage messages, as well as documentation, are
  1329. ! still in English.  However, foreign-language versions of \fBRemind\fR
  1330. ! will output names of months and weekdays in the foreign language.
  1331. ! Also, the substitution mechanism may substitute constructs suitable
  1332. ! for the foreign language rather than for English.
  1333.   .PP
  1334.   A foreign-language version of \fBRemind\fR will accept either the English
  1335.   or foreign-language names of weekdays and months in a reminder script.
  1336. --- 2766,2777 ----
  1337.   .SH FOREIGN LANGUAGE SUPPORT
  1338.   .PP
  1339.   Your version of \fBRemind\fR may have been compiled to support a
  1340. ! language other than English.  This support may or may not be complete -
  1341. ! for example, all error and usage messages may still be in English.
  1342. ! However, at a minimum, foreign-language versions of \fBRemind\fR will
  1343. ! output names of months and weekdays in the foreign language.  Also,
  1344. ! the substitution mechanism will substitute constructs suitable for the
  1345. ! foreign language rather than for English.
  1346.   .PP
  1347.   A foreign-language version of \fBRemind\fR will accept either the English
  1348.   or foreign-language names of weekdays and months in a reminder script.
  1349. *** ../prev/sort.c    Mon Jun 28 12:29:54 1993
  1350. --- ./sort.c    Thu Aug 19 16:12:01 1993
  1351. ***************
  1352. *** 95,101 ****
  1353.      int ShouldGoAfter;
  1354.   
  1355.      if (!new) {
  1356. !       Eprint("Out of memory for sorting.");
  1357.         IssueSortedReminders();
  1358.         SortByDate = 0;
  1359.         SortByTime = 0;
  1360. --- 95,101 ----
  1361.      int ShouldGoAfter;
  1362.   
  1363.      if (!new) {
  1364. !       Eprint("%s", ErrMsg[E_NO_MEM]);
  1365.         IssueSortedReminders();
  1366.         SortByDate = 0;
  1367.         SortByTime = 0;
  1368. ***************
  1369. *** 160,172 ****
  1370.   
  1371.      while (cur) {
  1372.         next = cur->next;
  1373. !       if (cur->typ == MSG_TYPE) {
  1374.       if (!MsgCommand) {
  1375.               if (cur->trigdate != olddate) {
  1376.                  IssueSortBanner(cur->trigdate);
  1377.              olddate = cur->trigdate;
  1378.               }
  1379. !             printf("%s\n", cur->text);
  1380.            } else {
  1381.               char buf[LINELEN+TOKSIZE];
  1382.               sprintf(buf, MsgCommand, cur->text);
  1383. --- 160,175 ----
  1384.   
  1385.      while (cur) {
  1386.         next = cur->next;
  1387. !       if (cur->typ == MSG_TYPE || cur->typ == MSF_TYPE) {
  1388.       if (!MsgCommand) {
  1389.               if (cur->trigdate != olddate) {
  1390.                  IssueSortBanner(cur->trigdate);
  1391.              olddate = cur->trigdate;
  1392.               }
  1393. !         if (cur->typ == MSG_TYPE)
  1394. !                printf("%s\n", cur->text);
  1395. !             else
  1396. !            FillParagraph(cur->text);
  1397.            } else {
  1398.               char buf[LINELEN+TOKSIZE];
  1399.               sprintf(buf, MsgCommand, cur->text);
  1400. *** ../prev/test.cmp    Mon Jun 28 12:30:09 1993
  1401. --- ./test.cmp    Thu Aug 19 17:06:48 1993
  1402. ***************
  1403. *** 187,195 ****
  1404.   y => "Heshvan"
  1405.   z => 1991/02/16
  1406.   a => 5761
  1407. ! hebdate(30, "Heshvan", 1991/02/16, 5761) => ./test.rem(33): No 30 Heshvan 5761
  1408. ! Bad date specification
  1409. ! Leaving UserFN _i() => Bad date specification
  1410.   
  1411.   [_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
  1412.   today() => 1991/02/16
  1413. --- 187,195 ----
  1414.   y => "Heshvan"
  1415.   z => 1991/02/16
  1416.   a => 5761
  1417. ! hebdate(30, "Heshvan", 1991/02/16, 5761) => ./test.rem(33): 30 Heshvan 5761: Invalid Hebrew date
  1418. ! Invalid Hebrew date
  1419. ! Leaving UserFN _i() => Invalid Hebrew date
  1420.   
  1421.   [_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
  1422.   today() => 1991/02/16
  1423. ***************
  1424. *** 220,228 ****
  1425.   y => "Kislev"
  1426.   z => 1991/02/16
  1427.   a => 5761
  1428. ! hebdate(30, "Kislev", 1991/02/16, 5761) => ./test.rem(37): No 30 Kislev 5761
  1429. ! Bad date specification
  1430. ! Leaving UserFN _i() => Bad date specification
  1431.   
  1432.   [_i(30, "Adar A", today(), 5755)] MSG Leap
  1433.   today() => 1991/02/16
  1434. --- 220,228 ----
  1435.   y => "Kislev"
  1436.   z => 1991/02/16
  1437.   a => 5761
  1438. ! hebdate(30, "Kislev", 1991/02/16, 5761) => ./test.rem(37): 30 Kislev 5761: Invalid Hebrew date
  1439. ! Invalid Hebrew date
  1440. ! Leaving UserFN _i() => Invalid Hebrew date
  1441.   
  1442.   [_i(30, "Adar A", today(), 5755)] MSG Leap
  1443.   today() => 1991/02/16
  1444. ***************
  1445. *** 243,250 ****
  1446.   z => 1991/02/16
  1447.   a => 5756
  1448.   hebdate(30, "Adar A", 1991/02/16, 5756) => ./test.rem(40): No Adar A in 5756
  1449. ! Bad date specification
  1450. ! Leaving UserFN _i() => Bad date specification
  1451.   [_i(29, "Adar A", today(), 5755)] MSG Leap
  1452.   today() => 1991/02/16
  1453.   Entering UserFN _i(29, "Adar A", 1991/02/16, 5755)
  1454. --- 243,250 ----
  1455.   z => 1991/02/16
  1456.   a => 5756
  1457.   hebdate(30, "Adar A", 1991/02/16, 5756) => ./test.rem(40): No Adar A in 5756
  1458. ! Invalid Hebrew date
  1459. ! Leaving UserFN _i() => Invalid Hebrew date
  1460.   [_i(29, "Adar A", today(), 5755)] MSG Leap
  1461.   today() => 1991/02/16
  1462.   Entering UserFN _i(29, "Adar A", 1991/02/16, 5755)
  1463. ***************
  1464. *** 264,271 ****
  1465.   z => 1991/02/16
  1466.   a => 5756
  1467.   hebdate(29, "Adar A", 1991/02/16, 5756) => ./test.rem(42): No Adar A in 5756
  1468. ! Bad date specification
  1469. ! Leaving UserFN _i() => Bad date specification
  1470.   
  1471.   # Test each possible case of the basic reminders.
  1472.   
  1473. --- 264,271 ----
  1474.   z => 1991/02/16
  1475.   a => 5756
  1476.   hebdate(29, "Adar A", 1991/02/16, 5756) => ./test.rem(42): No Adar A in 5756
  1477. ! Invalid Hebrew date
  1478. ! Leaving UserFN _i() => Invalid Hebrew date
  1479.   
  1480.   # Test each possible case of the basic reminders.
  1481.   
  1482. ***************
  1483. *** 631,637 ****
  1484.   "a05" + "6" => "a056"
  1485.   value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
  1486.   set a058 version()
  1487. ! version() => "03.00.07"
  1488.   set a059 wkday(today())
  1489.   today() => 1991/02/16
  1490.   wkday(1991/02/16) => "Saturday"
  1491. --- 631,637 ----
  1492.   "a05" + "6" => "a056"
  1493.   value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
  1494.   set a058 version()
  1495. ! version() => "03.00.08"
  1496.   set a059 wkday(today())
  1497.   today() => 1991/02/16
  1498.   wkday(1991/02/16) => "Saturday"
  1499. ***************
  1500. *** 710,716 ****
  1501.   x => "foo"
  1502.   y => 11:33
  1503.   "foo" * 11:33 => Type mismatch
  1504. ! ./test.rem(240): Operator '*' Type mismatch
  1505.   Leaving UserFN h() => Type mismatch
  1506.   set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
  1507.   dosubst("%a %b %c %d %e %f %g %h", 1992/05/05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
  1508. --- 710,716 ----
  1509.   x => "foo"
  1510.   y => 11:33
  1511.   "foo" * 11:33 => Type mismatch
  1512. ! ./test.rem(240): '*': Type mismatch
  1513.   Leaving UserFN h() => Type mismatch
  1514.   set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
  1515.   dosubst("%a %b %c %d %e %f %g %h", 1992/05/05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
  1516. ***************
  1517. *** 772,778 ****
  1518.           a048  "foo"
  1519.           a067  "INT"
  1520.           a039  "February"
  1521. !         a058  "03.00.07"
  1522.           a077  "1992 92
  1523.   "
  1524.           a049  21
  1525. --- 772,778 ----
  1526.           a048  "foo"
  1527.           a067  "INT"
  1528.           a039  "February"
  1529. !         a058  "03.00.08"
  1530.           a077  "1992 92
  1531.   "
  1532.           a049  21
  1533. *** ../prev/token.c    Mon Jun 28 12:29:56 1993
  1534. --- ./token.c    Tue Aug  3 12:29:05 1993
  1535. ***************
  1536. *** 68,73 ****
  1537. --- 68,74 ----
  1538.      { "march",        3,    T_Month,    2 },
  1539.      { "may",        3,     T_Month,     4 },
  1540.      { "monday",         3,    T_WkDay,    0 },
  1541. +    { "msf",        3,    T_RemType,    MSF_TYPE },
  1542.      { "msg",         3,     T_RemType,     MSG_TYPE },
  1543.      { "november",     3,     T_Month,    10 },
  1544.      { "october",        3,     T_Month,    9 },
  1545. *** ../prev/trigger.c    Mon Jun 28 12:29:57 1993
  1546. --- ./trigger.c    Thu Aug 19 16:44:15 1993
  1547. ***************
  1548. *** 246,252 ****
  1549.        return j;
  1550.   
  1551.         default:
  1552. !     Eprint("NextSimpleTrig: Bad type %d", typ);
  1553.       *err = E_SWERR;
  1554.       return -1;
  1555.      }
  1556. --- 246,252 ----
  1557.        return j;
  1558.   
  1559.         default:
  1560. !     Eprint("NextSimpleTrig %s %d", ErrMsg[E_SWERR], typ);
  1561.       *err = E_SWERR;
  1562.       return -1;
  1563.      }
  1564. ***************
  1565. *** 395,402 ****
  1566.          (trig->d == NO_DAY ||
  1567.       trig->m == NO_MON ||
  1568.       trig->y == NO_YR)) {
  1569. !       Eprint("Must fully specify date to use repeat.");
  1570. !       *err = E_PARSE_ERR;
  1571.         return -1;
  1572.      }
  1573.          
  1574. --- 395,402 ----
  1575.          (trig->d == NO_DAY ||
  1576.       trig->m == NO_MON ||
  1577.       trig->y == NO_YR)) {
  1578. !       Eprint("%s", ErrMsg[E_REP_FULSPEC]);
  1579. !       *err = E_REP_FULSPEC;
  1580.         return -1;
  1581.      }
  1582.          
  1583. ***************
  1584. *** 408,415 ****
  1585.         if (*err) return -1;
  1586.         if (result == -1) {
  1587.            if (DebugFlag & DB_PRTTRIG) {
  1588. !         fprintf(ErrFp, "%s(%d): Expired\n",
  1589. !            FileName, LineNo);
  1590.        }
  1591.            return -1;
  1592.         }
  1593. --- 408,415 ----
  1594.         if (*err) return -1;
  1595.         if (result == -1) {
  1596.            if (DebugFlag & DB_PRTTRIG) {
  1597. !         fprintf(ErrFp, "%s(%d): %s\n",
  1598. !            FileName, LineNo, ErrMsg[E_EXPIRED]);
  1599.        }
  1600.            return -1;
  1601.         }
  1602. ***************
  1603. *** 436,443 ****
  1604.             trig->skip == NO_SKIP &&
  1605.         trig->rep == NO_REP) {
  1606.             if (DebugFlag & DB_PRTTRIG) {
  1607. !          fprintf(ErrFp, "%s(%d): Expired\n",
  1608. !                  FileName, LineNo);
  1609.            }
  1610.            if (result != -1) {
  1611.               LastTriggerDate = result;
  1612. --- 436,443 ----
  1613.             trig->skip == NO_SKIP &&
  1614.         trig->rep == NO_REP) {
  1615.             if (DebugFlag & DB_PRTTRIG) {
  1616. !          fprintf(ErrFp, "%s(%d): %s\n",
  1617. !                  FileName, LineNo, ErrMsg[E_EXPIRED]);
  1618.            }
  1619.            if (result != -1) {
  1620.               LastTriggerDate = result;
  1621. ***************
  1622. *** 452,459 ****
  1623.           LastTrigValid = 1;
  1624.        }
  1625.            if (DebugFlag & DB_PRTTRIG) {
  1626. !         fprintf(ErrFp, "%s(%d): Expired\n",
  1627. !                   FileName, LineNo);
  1628.            }
  1629.        return -1;
  1630.         }
  1631. --- 452,459 ----
  1632.           LastTrigValid = 1;
  1633.        }
  1634.            if (DebugFlag & DB_PRTTRIG) {
  1635. !         fprintf(ErrFp, "%s(%d): %s\n",
  1636. !                   FileName, LineNo, ErrMsg[E_EXPIRED]);
  1637.            }
  1638.        return -1;
  1639.         }
  1640. *** ../prev/tstlang.rem    Mon Jun 28 12:30:24 1993
  1641. --- ./tstlang.rem    Thu Aug 19 16:01:52 1993
  1642. ***************
  1643. *** 15,23 ****
  1644.   #
  1645.   # ---------------------------------------------------------------------------
  1646.   
  1647. ! if version()<"03.00.02"
  1648.      errmsg %
  1649. !    errmsg This file only works with Remind version 03.00.02 and later - aborting
  1650.      exit
  1651.   endif
  1652.   
  1653. --- 15,30 ----
  1654.   #
  1655.   # ---------------------------------------------------------------------------
  1656.   
  1657. ! if version()<"03.00.08"
  1658.      errmsg %
  1659. !    errmsg This file only works with Remind version 03.00.08 and later - aborting
  1660. !    exit
  1661. ! endif
  1662. ! if !$RunOff || !$DontQueue || $DontTrigAts
  1663. !    errmsg %
  1664. !    errmsg Please run [filename()] with the -q and -r options, but%
  1665. !    errmsg not the -a option.
  1666.      exit
  1667.   endif
  1668.   
  1669. *** ../prev/types.h    Mon Jun 28 12:29:32 1993
  1670. --- ./types.h    Tue Aug  3 12:28:45 1993
  1671. ***************
  1672. *** 100,105 ****
  1673. --- 100,106 ----
  1674.   #define SAT_TYPE 4
  1675.   #define PS_TYPE  5
  1676.   #define PSF_TYPE 6
  1677. + #define MSF_TYPE 7
  1678.   
  1679.   /* DEFINES for debugging flags */
  1680.   #define DB_PRTLINE   1
  1681. *** ../prev/userfns.c    Mon Jun 28 12:38:47 1993
  1682. --- ./userfns.c    Thu Aug 19 16:43:05 1993
  1683. ***************
  1684. *** 87,93 ****
  1685.      StrnCpy(func->name, TokBuffer, VAR_NAME_LEN);
  1686.      if (!Hush) {
  1687.         if (FindFunc(TokBuffer, Func, NumFuncs)) {
  1688. !          Eprint("Warning:  Attempt to redefine built-in function '%s'",
  1689.                TokBuffer);
  1690.         }
  1691.      }
  1692. --- 87,93 ----
  1693.      StrnCpy(func->name, TokBuffer, VAR_NAME_LEN);
  1694.      if (!Hush) {
  1695.         if (FindFunc(TokBuffer, Func, NumFuncs)) {
  1696. !          Eprint("%s: '%s'", ErrMsg[E_REDEF_FUNC],
  1697.                TokBuffer);
  1698.         }
  1699.      }
  1700. ***************
  1701. *** 131,137 ****
  1702.   
  1703.      /* Copy the text over */
  1704.      if (p->isnested) {
  1705. !       Eprint ("Can't nest function definition in expression.");
  1706.         DestroyUserFunc(func);
  1707.         return E_PARSE_ERR;
  1708.      }
  1709. --- 131,137 ----
  1710.   
  1711.      /* Copy the text over */
  1712.      if (p->isnested) {
  1713. !       Eprint("%s", ErrMsg[E_CANTNEST_FDEF]);
  1714.         DestroyUserFunc(func);
  1715.         return E_PARSE_ERR;
  1716.      }
  1717. ***************
  1718. *** 265,276 ****
  1719.      f = FuncHash[h];
  1720.      while (f && StrinCmp(name, f->name, VAR_NAME_LEN)) f = f->next;
  1721.      if (!f) {
  1722. !       Eprint("Undefined function '%s'", name);
  1723.         return E_UNDEF_FUNC;
  1724.      }
  1725.      /* Debugging stuff */
  1726.      if (DebugFlag & DB_PRTEXPR) {
  1727. !       fprintf(ErrFp, "Entering UserFN %s(", f->name);
  1728.         for (i=0; i<nargs; i++) {
  1729.            PrintValue(&ValStack[ValStackPtr - nargs + i], ErrFp);
  1730.            if (i<nargs-1) fprintf(ErrFp, ", ");
  1731. --- 265,276 ----
  1732.      f = FuncHash[h];
  1733.      while (f && StrinCmp(name, f->name, VAR_NAME_LEN)) f = f->next;
  1734.      if (!f) {
  1735. !       Eprint("%s: '%s'", ErrMsg[E_UNDEF_FUNC], name);
  1736.         return E_UNDEF_FUNC;
  1737.      }
  1738.      /* Debugging stuff */
  1739.      if (DebugFlag & DB_PRTEXPR) {
  1740. !       fprintf(ErrFp, "%s %s(", ErrMsg[E_ENTER_FUN], f->name);
  1741.         for (i=0; i<nargs; i++) {
  1742.            PrintValue(&ValStack[ValStackPtr - nargs + i], ErrFp);
  1743.            if (i<nargs-1) fprintf(ErrFp, ", ");
  1744. ***************
  1745. *** 280,286 ****
  1746.      /* Detect illegal recursive call */
  1747.      if (f->IsActive) {
  1748.         if (DebugFlag &DB_PRTEXPR) {
  1749. !          fprintf(ErrFp, "Leaving UserFN %s() => ", name);
  1750.            fprintf(ErrFp, "%s\n", ErrMsg[E_RECURSIVE]);
  1751.         }
  1752.         return E_RECURSIVE;
  1753. --- 280,286 ----
  1754.      /* Detect illegal recursive call */
  1755.      if (f->IsActive) {
  1756.         if (DebugFlag &DB_PRTEXPR) {
  1757. !          fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
  1758.            fprintf(ErrFp, "%s\n", ErrMsg[E_RECURSIVE]);
  1759.         }
  1760.         return E_RECURSIVE;
  1761. ***************
  1762. *** 289,295 ****
  1763.      /* Check number of args */
  1764.      if (nargs != f->nargs) {
  1765.         if (DebugFlag &DB_PRTEXPR) {
  1766. !          fprintf(ErrFp, "Leaving UserFN %s() => ", name);
  1767.            fprintf(ErrFp, "%s\n",
  1768.           ErrMsg[(nargs < f->nargs) ? E_2FEW_ARGS : E_2MANY_ARGS]);
  1769.         }
  1770. --- 289,295 ----
  1771.      /* Check number of args */
  1772.      if (nargs != f->nargs) {
  1773.         if (DebugFlag &DB_PRTEXPR) {
  1774. !          fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
  1775.            fprintf(ErrFp, "%s\n",
  1776.           ErrMsg[(nargs < f->nargs) ? E_2FEW_ARGS : E_2MANY_ARGS]);
  1777.         }
  1778. ***************
  1779. *** 299,305 ****
  1780.      h = SetUpLocalVars(f);
  1781.      if (h) {
  1782.         if (DebugFlag &DB_PRTEXPR) {
  1783. !          fprintf(ErrFp, "Leaving UserFN %s() => ", name);
  1784.            fprintf(ErrFp, "%s\n", ErrMsg[h]);
  1785.         }
  1786.         return h;
  1787. --- 299,305 ----
  1788.      h = SetUpLocalVars(f);
  1789.      if (h) {
  1790.         if (DebugFlag &DB_PRTEXPR) {
  1791. !          fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
  1792.            fprintf(ErrFp, "%s\n", ErrMsg[h]);
  1793.         }
  1794.         return h;
  1795. ***************
  1796. *** 316,322 ****
  1797.      f->IsActive = 0;
  1798.      DestroyLocalVals(f);
  1799.      if (DebugFlag &DB_PRTEXPR) {
  1800. !       fprintf(ErrFp, "Leaving UserFN %s() => ", name);
  1801.         if (h) fprintf(ErrFp, "%s\n", ErrMsg[h]);
  1802.         else {
  1803.            PrintValue(&ValStack[ValStackPtr-1], ErrFp);
  1804. --- 316,322 ----
  1805.      f->IsActive = 0;
  1806.      DestroyLocalVals(f);
  1807.      if (DebugFlag &DB_PRTEXPR) {
  1808. !       fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
  1809.         if (h) fprintf(ErrFp, "%s\n", ErrMsg[h]);
  1810.         else {
  1811.            PrintValue(&ValStack[ValStackPtr-1], ErrFp);
  1812. *** ../prev/utils.c    Mon Jun 28 12:37:05 1993
  1813. --- ./utils.c    Wed Aug 25 14:49:21 1993
  1814. ***************
  1815. *** 19,25 ****
  1816. --- 19,27 ----
  1817.   #include <malloc.h>
  1818.   #endif
  1819.   #include <ctype.h>
  1820. + #include "types.h"
  1821.   #include "globals.h"
  1822. + #include "protos.h"
  1823.   
  1824.   #define UPPER(c) (islower(c) ? toupper(c) : c)
  1825.   
  1826. *** ../prev/var.c    Mon Jul 19 10:58:54 1993
  1827. --- ./var.c    Thu Aug 19 16:40:40 1993
  1828. ***************
  1829. *** 29,34 ****
  1830. --- 29,38 ----
  1831.   
  1832.   /* The variable hash table */
  1833.   #define VAR_HASH_SIZE 64
  1834. + #define VARIABLE ErrMsg[E_VAR]
  1835. + #define VALUE    ErrMsg[E_VAL]
  1836. + #define UNDEF     ErrMsg[E_UNDEF]
  1837.   static Var *VHashTbl[VAR_HASH_SIZE];
  1838.   
  1839.   /***************************************************************/
  1840. ***************
  1841. *** 38,55 ****
  1842.   /*                                                             */
  1843.   /***************************************************************/
  1844.   #ifdef HAVE_PROTOS
  1845. ! PUBLIC int HashVal(const char *str)
  1846.   #else
  1847. ! int HashVal(str)
  1848.   char *str;
  1849.   #endif
  1850.   {
  1851. !    register int i = 0;
  1852. !    register int j=1;
  1853. !    register int len=0;
  1854.   
  1855.      while(*str && len < VAR_NAME_LEN) {
  1856. !       i += j * UPPER(*str);
  1857.         str++;
  1858.         len++;
  1859.         j = 3-j;
  1860. --- 42,59 ----
  1861.   /*                                                             */
  1862.   /***************************************************************/
  1863.   #ifdef HAVE_PROTOS
  1864. ! PUBLIC unsigned int HashVal(const char *str)
  1865.   #else
  1866. ! unsigned int HashVal(str)
  1867.   char *str;
  1868.   #endif
  1869.   {
  1870. !    register unsigned int i=0;
  1871. !    register unsigned int j=1;
  1872. !    register unsigned int len=0;
  1873.   
  1874.      while(*str && len < VAR_NAME_LEN) {
  1875. !       i += j * (unsigned int) UPPER(*str);
  1876.         str++;
  1877.         len++;
  1878.         j = 3-j;
  1879. ***************
  1880. *** 187,193 ****
  1881.      v=FindVar(str, 0);
  1882.   
  1883.      if (!v) {
  1884. !      Eprint("Undefined variable: %s", str);
  1885.        return E_NOSUCH_VAR;
  1886.      }
  1887.      return CopyValue(val, &v->v);
  1888. --- 191,197 ----
  1889.      v=FindVar(str, 0);
  1890.   
  1891.      if (!v) {
  1892. !      Eprint("%s: %s", ErrMsg[E_NOSUCH_VAR], str);
  1893.        return E_NOSUCH_VAR;
  1894.      }
  1895.      return CopyValue(val, &v->v);
  1896. ***************
  1897. *** 273,279 ****
  1898.         DumpVarTable();
  1899.         return OK;
  1900.      }
  1901. !    fprintf(ErrFp, "%*s  %s\n\n", VAR_NAME_LEN, "Variable", "Value");
  1902.      while(1) {
  1903.         if (*TokBuffer == '$') {
  1904.            DumpSysVarByName(TokBuffer+1);
  1905. --- 277,283 ----
  1906.         DumpVarTable();
  1907.         return OK;
  1908.      }
  1909. !    fprintf(ErrFp, "%*s  %s\n\n", VAR_NAME_LEN, VARIABLE, VALUE);
  1910.      while(1) {
  1911.         if (*TokBuffer == '$') {
  1912.            DumpSysVarByName(TokBuffer+1);
  1913. ***************
  1914. *** 280,286 ****
  1915.         } else {
  1916.            v = FindVar(TokBuffer, 0);
  1917.            TokBuffer[VAR_NAME_LEN] = 0;
  1918. !          if (!v) fprintf(ErrFp, "%*s  *UNDEFINED*\n", VAR_NAME_LEN, TokBuffer);
  1919.            else {
  1920.               fprintf(ErrFp, "%*s  ", VAR_NAME_LEN, v->name);
  1921.               PrintValue(&(v->v), ErrFp);
  1922. --- 284,290 ----
  1923.         } else {
  1924.            v = FindVar(TokBuffer, 0);
  1925.            TokBuffer[VAR_NAME_LEN] = 0;
  1926. !          if (!v) fprintf(ErrFp, "%*s  %s\n", VAR_NAME_LEN, TokBuffer, UNDEF);
  1927.            else {
  1928.               fprintf(ErrFp, "%*s  ", VAR_NAME_LEN, v->name);
  1929.               PrintValue(&(v->v), ErrFp);
  1930. ***************
  1931. *** 309,315 ****
  1932.      register Var *v;
  1933.      register int i;
  1934.   
  1935. !    fprintf(ErrFp, "%*s  %s\n\n", VAR_NAME_LEN, "Variable", "Value");
  1936.   
  1937.      for (i=0; i<VAR_HASH_SIZE; i++) {
  1938.         v = VHashTbl[i];
  1939. --- 313,319 ----
  1940.      register Var *v;
  1941.      register int i;
  1942.   
  1943. !    fprintf(ErrFp, "%*s  %s\n\n", VAR_NAME_LEN, VARIABLE, VALUE);
  1944.   
  1945.      for (i=0; i<VAR_HASH_SIZE; i++) {
  1946.         v = VHashTbl[i];
  1947. ***************
  1948. *** 442,448 ****
  1949. --- 446,454 ----
  1950.      {   "DontFork",      0,        &DontFork,    0,    0   },
  1951.      {   "DontQueue",      0,        &DontQueue,    0,    0   },
  1952.      {   "DontTrigAts",      0,        &DontIssueAts,    0,    0   },
  1953. +    {   "FirstIndent",      1,        &FirstIndent,    0,    132 },
  1954.      {   "FoldYear",      1,        &FoldYear,    0,    1   },
  1955. +    {   "FormWidth",      1,        &FormWidth,    20,    132 },
  1956.      {   "HushMode",      0,        &Hush,        0,    0   },
  1957.      {   "IgnoreOnce",      0,        &IgnoreOnce,    0,    0   },
  1958.      {   "InfDelta",      0,        &InfiniteDelta,    0,    0   },
  1959. ***************
  1960. *** 459,465 ****
  1961.      {   "NumTrig",      0,        &NumTriggered,    0,    0   },
  1962.      {   "PSCal",          0,        &PsCal,        0,    0   },
  1963.      {   "RunOff",      0,        &RunDisabled,    0,    0   },
  1964. !    {   "SimpleCal",      0,        &DoSimpleCalendar,    0,  0 }
  1965.   };
  1966.   
  1967.   #define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
  1968. --- 465,472 ----
  1969.      {   "NumTrig",      0,        &NumTriggered,    0,    0   },
  1970.      {   "PSCal",          0,        &PsCal,        0,    0   },
  1971.      {   "RunOff",      0,        &RunDisabled,    0,    0   },
  1972. !    {   "SimpleCal",      0,        &DoSimpleCalendar,    0,  0 },
  1973. !    {   "SubsIndent",      1,        &SubsIndent,    0,    132}
  1974.   };
  1975.   
  1976.   #define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
  1977. ***************
  1978. *** 483,489 ****
  1979.      SysVar *v = FindSysVar(name);
  1980.      if (!v) return E_NOSUCH_VAR;
  1981.      if (!v->modifiable) {
  1982. !       Eprint("Cannot modify system variable '$%s'", name);
  1983.         return E_CANT_MODIFY;
  1984.      }
  1985.      if (v->max != NO_CONSTRAINT && value > v->max) return E_2HIGH;
  1986. --- 490,496 ----
  1987.      SysVar *v = FindSysVar(name);
  1988.      if (!v) return E_NOSUCH_VAR;
  1989.      if (!v->modifiable) {
  1990. !       Eprint("%s: '$%s'", ErrMsg[E_CANT_MODIFY], name);
  1991.         return E_CANT_MODIFY;
  1992.      }
  1993.      if (v->max != NO_CONSTRAINT && value > v->max) return E_2HIGH;
  1994. ***************
  1995. *** 598,610 ****
  1996.      if (v) {
  1997.         if (!v->modifiable) fprintf(ErrFp, "%d\n", *v->value);
  1998.         else {
  1999. !          fprintf(ErrFp, "%-10d  Allowed range: ", *v->value);
  2000.        if (v->min == NO_CONSTRAINT) fprintf(ErrFp, "(-Inf, ");
  2001.        else                         fprintf(ErrFp, "[%d, ", v->min);
  2002.        if (v->max == NO_CONSTRAINT) fprintf(ErrFp, "Inf)\n");
  2003.        else                         fprintf(ErrFp, "%d]\n", v->max);
  2004.         }
  2005. !    } else   fprintf(ErrFp, "*UNDEFINED*\n");
  2006.   
  2007.      return;
  2008.   }
  2009. --- 605,617 ----
  2010.      if (v) {
  2011.         if (!v->modifiable) fprintf(ErrFp, "%d\n", *v->value);
  2012.         else {
  2013. !          fprintf(ErrFp, "%-10d  ", *v->value);
  2014.        if (v->min == NO_CONSTRAINT) fprintf(ErrFp, "(-Inf, ");
  2015.        else                         fprintf(ErrFp, "[%d, ", v->min);
  2016.        if (v->max == NO_CONSTRAINT) fprintf(ErrFp, "Inf)\n");
  2017.        else                         fprintf(ErrFp, "%d]\n", v->max);
  2018.         }
  2019. !    } else   fprintf(ErrFp, "%s\n", UNDEF);
  2020.   
  2021.      return;
  2022.   }
  2023.