home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / remind23.lzh / remind.3 / files.c < prev    next >
C/C++ Source or Header  |  1991-02-24  |  8KB  |  310 lines

  1. #include <stdio.h>
  2. #ifndef UNIX
  3. #include <stdlib.h>
  4. #endif
  5. #include <string.h>
  6. #ifndef NO_MALLOC_H
  7. #include <malloc.h>
  8. #endif
  9. #ifndef UNIX
  10. #include <dos.h>
  11. #endif
  12. #include <fcntl.h>
  13. #ifdef UNIX
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <time.h>
  17. #endif
  18. #include "defines.h"
  19. #include "globals.h"
  20. #include "protos.h"
  21.  
  22. #ifdef __STDC__
  23. static int PopFile(void);
  24. #else
  25. static int PopFile();
  26. #endif
  27.  
  28. /***************************************************************/
  29. /*                                                             */
  30. /*  FILES.C                                                    */
  31. /*                                                             */
  32. /*  All the routines for opening initial file, getting         */
  33. /*  and settting initial file's date, closing files,           */
  34. /*  handling INCLUDE commands, etc.                            */
  35. /*                                                             */
  36. /***************************************************************/
  37.  
  38. /* Define the structure for saving info about a file */
  39. typedef struct {
  40.    long offset;
  41.    int  curline;
  42.    char *name;
  43. } FileSave;
  44.  
  45. #define MAXINCLUDE 10
  46. /* Set up array of MAXINCLUDE file save areas */
  47. static FileSave stack[MAXINCLUDE];
  48. static int      SP;
  49.  
  50. static FILE *fp;
  51.  
  52. /***************************************************************/
  53. /*                                                             */
  54. /*  OpenFile                                                   */
  55. /*                                                             */
  56. /*  Open the named file, initialize stack, get file date.      */
  57. /*  If there's a problem, print an error msg and die.          */
  58. /*                                                             */
  59. /***************************************************************/
  60. #ifdef __STDC__
  61. void OpenFile(char *s)
  62. #else
  63. void OpenFile(s)
  64.      char *s;
  65.      
  66. #endif
  67. {
  68.    unsigned date, time;
  69. #ifndef UNIX
  70.    unsigned handle;
  71. #endif
  72.    int d, m, y;
  73. #ifndef UNIX
  74.    
  75.    /* Get the file's modification date */
  76.    if(_dos_open(s, O_RDONLY, &handle)) {
  77.       fprintf(stderr, "remind: Can't open %s.\n", s);
  78.       exit(1);
  79. #else
  80.    struct stat t;
  81.    struct tm *t1;
  82.       
  83.    /* Get the file's access date */
  84.    if (stat(s, &t)) {
  85.      fprintf(stderr, "remind: Can't find file %s.\n", s);
  86.      exit(1);
  87. #endif
  88.    }
  89. #ifndef UNIX
  90.    _dos_getftime(handle, &date, &time);
  91.    d = date & 0x1F;
  92.    m = (date >> 5) & 0xF;
  93.    y = (date >> 9) + 1980;
  94. #else
  95.    t1 = localtime(&(t.st_atime));
  96. #endif
  97.    
  98. #ifndef UNIX
  99.    if (y < BASE) LastRun = 0; else LastRun = Julian(d, m-1, y);
  100.    _dos_close(handle);
  101. #else
  102.    y = t1->tm_year + 1900;
  103.    m = t1->tm_mon;
  104.    d = t1->tm_mday;
  105.    
  106.    if (y < BASE) LastRun = 0; else LastRun = Julian(d, m, y);
  107. #endif
  108.    fp = fopen(s, "r");
  109.    if (fp == NULL) {
  110.       fprintf(stderr, "remind: Can't open %s.\n", s);
  111.       exit(1);
  112.    }
  113.    
  114.    CurLine = 0;
  115.    strcpy(FileName, s);
  116.    SP = 0;
  117.    
  118.    return;
  119. }   
  120.  
  121. /***************************************************************/
  122. /*                                                             */
  123. /*  DoInclude                                                  */
  124. /*                                                             */
  125. /*  Push the state of the current file and open a new file.    */
  126. /*                                                             */
  127. /***************************************************************/
  128. #ifdef __STDC__
  129. void DoInclude(char **s)
  130. #else
  131. void DoInclude(s)
  132.      char **s;
  133.      
  134. #endif
  135. {
  136.    Token tok;
  137.    tok = ParseToken(s);
  138.    
  139.    /* First, check if there's room on the stack */
  140.    if (SP == MAXINCLUDE) {
  141.       Eprint("Too many levels of INCLUDE\n");
  142.       return;
  143.    }
  144.    
  145.    /* Save current data */
  146. #ifndef UNIX
  147.    stack[SP].offset = ftell(fp) - 1L;
  148. #else
  149.    stack[SP].offset = ftell(fp);
  150. #endif
  151.    stack[SP].curline = CurLine;
  152.    stack[SP].name = (char *) malloc(strlen(FileName)+1);
  153.    if (stack[SP].name == NULL) {
  154.       Eprint("Out of memory for INCLUDE\n");
  155.       return;
  156.    }
  157.    strcpy(stack[SP].name, FileName);
  158.    
  159.    SP++;
  160.    
  161.    /* Close the current file */
  162.    fclose(fp);
  163.    
  164.    /* Open the new file */
  165.    fp = fopen(tok.str, "r");
  166.    if (fp == NULL) {
  167.       Eprint("Can't open %s for INCLUDE\n", tok.str);
  168.       PopFile();
  169.       return;
  170.    }
  171.    if (Debug || Purge) {
  172.       Eprint("INCLUDING file %s\n", tok.str);
  173.    }
  174.    
  175.    /* Set the global variables */
  176.    CurLine = 0;
  177.    strcpy(FileName, tok.str);
  178.    return;
  179. }
  180.  
  181. /***************************************************************/
  182. /*                                                             */
  183. /*  PopFile                                                    */
  184. /*                                                             */
  185. /*  Pop to the previous file, if there is one.  Return 0 for   */
  186. /*  OK, non-zero for no more files.  If we can't pop back      */
  187. /*  to a file, print an error message and die.                 */
  188. /*                                                             */
  189. /***************************************************************/
  190. #ifdef __STDC__
  191. static int PopFile(void)
  192. #else
  193. static int PopFile()
  194. #endif
  195. {
  196. #ifndef UNIX
  197.    unsigned handle, date, time;
  198.    struct dostime_t t;
  199. #endif
  200.  
  201.    if (fp) fclose(fp);
  202. #ifndef UNIX
  203.    if (!SP) {
  204.       if (!Debug && !Purge && (JulianToday == RealToday)) {
  205.          if (_dos_open(FileName, O_RDONLY, &handle)) {
  206.             fprintf(stderr, "Could not reset date of %s\n", FileName);
  207.             return 1;
  208.          }
  209.      _dos_gettime(&t);
  210.      date = CurDay;
  211.      date |= (CurMon + 1) << 5;
  212.      date |= (CurYear - 1980) << 9;
  213.      time = t.second / 2;
  214.      time |= t.minute << 5;
  215.      time |= t.hour << 11;
  216.      _dos_setftime(handle, date, time);
  217.       }
  218.       return 1;
  219.    }
  220.       
  221. #else
  222.    if (!SP) return -1;
  223.          
  224. #endif
  225.    SP--;
  226.    fp = fopen(stack[SP].name, "r");
  227.    if (fp == NULL) {
  228.       Eprint("Argh! Can't return to %s from INCLUDE file %s\n", stack[SP].name, FileName);
  229.       exit(1);
  230.    }
  231. #ifndef UNIX
  232.    if (fseek(fp, stack[SP].offset, SEEK_SET)) {
  233. #else
  234.    if (fseek(fp, stack[SP].offset, 0)) {
  235. #endif
  236.       Eprint("Argh! Can't fseek %s after returning from INCLUDE file %s\n", stack[SP].name, FileName);
  237.       exit(1);
  238.    }
  239.    
  240.    if (Debug || Purge) {
  241.       Eprint("Returning to file %s\n", stack[SP].name);
  242.    }
  243.    CurLine = stack[SP].curline;
  244.    strcpy(FileName, stack[SP].name);
  245.    free(stack[SP].name);
  246.    return 0;
  247. }
  248. /***************************************************************/
  249. /*                                                             */
  250. /*  ReadLine                                                   */
  251. /*                                                             */
  252. /*  Reads a line from the file.  If EOF, pops to previous file */
  253. /*  if there was one.  Returns 0 if more input, non-zero       */
  254. /*  if no more input.  Updates CurLine.                        */
  255. /*                                                             */
  256. /***************************************************************/
  257. int ReadLine()
  258. {
  259.    int done = 0;
  260.    int len;
  261.    
  262.    Fresh = 1;
  263.    while (!done) {
  264.       CurLine++;
  265.       if (fgets(Line, 512, fp) == NULL) {
  266.          if (ferror(fp)) Eprint("Error reading %s\n", FileName);
  267.      if (PopFile()) return 1;
  268.       } else {
  269.          len = strlen(Line);
  270.          /* Remove the newline */
  271.          if (*Line && (*(Line + len-1)=='\n')) {
  272.             *(Line + strlen(Line)-1) = 0;
  273.             len--;
  274.          }
  275.          done = 1;
  276.          while(*Line && (*(Line + len-1) == '\\') && len<512) {
  277.          *(Line + len-1) = '\n';
  278.             if (fgets(Line+len, 512-len,fp) == NULL) {
  279.                *(Line + len) = 0;
  280.              break;
  281.         }
  282.  
  283.         CurLine++;
  284.         len = strlen(Line);
  285.             /* Remove the newline */
  286.             if (*Line && (*(Line + len-1)=='\n')) {
  287.                *(Line + strlen(Line)-1) = 0;
  288.                len--;
  289.             }
  290.          }
  291.       }     
  292.    }
  293.    return 0;
  294. }
  295.  
  296. /***************************************************************/
  297. /*                                                             */
  298. /*  TopLevel - Returns 1 if current file is top level, 0       */
  299. /*  if it is INCLUDEd.                                         */
  300. /*                                                             */
  301. /***************************************************************/
  302. #ifdef __STDC__
  303. int TopLevel(void) { return (SP == 0); }
  304. #else
  305. int TopLevel()
  306. {
  307.   return (SP == 0);
  308. }
  309. #endif
  310.