home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / remind / part05 < prev    next >
Encoding:
Text File  |  1992-11-10  |  15.8 KB  |  570 lines

  1. Newsgroups: comp.sources.misc
  2. From: dfs@doe.carleton.ca (David F. Skoll)
  3. Subject:  v33i062:  remind - A replacement for calendar, Part05/12
  4. Message-ID: <1992Nov10.041901.990@sparky.imd.sterling.com>
  5. X-Md4-Signature: bc3d8f3d8f0787059f232cefb966a783
  6. Date: Tue, 10 Nov 1992 04:19:01 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: dfs@doe.carleton.ca (David F. Skoll)
  10. Posting-number: Volume 33, Issue 62
  11. Archive-name: remind/part05
  12. Environment: UNIX, MS-DOS
  13. Supersedes: remind: Volume 17, Issue 3-6
  14.  
  15. #!/bin/sh
  16. # This is part 05 of Remind 03.00.00
  17. if touch 2>&1 | fgrep 'amc' > /dev/null
  18.  then TOUCH=touch
  19.  else TOUCH=true
  20. fi
  21. # ============= files.c ==============
  22. if test X"$1" != X"-c" -a -f 'files.c'; then
  23.     echo "File already exists: skipping 'files.c'"
  24. else
  25. echo "x - extracting files.c (Text)"
  26. sed 's/^X//' << 'SHAR_EOF' > files.c &&
  27. X/***************************************************************/
  28. X/*                                                             */
  29. X/*  FILES.C                                                    */
  30. X/*                                                             */
  31. X/*  Controls the opening and closing of files, etc.  Also      */
  32. X/*  handles caching of lines and reading of lines from         */
  33. X/*  files.                                                     */
  34. X/*                                                             */
  35. X/*  This file is part of REMIND.                               */
  36. X/*  Copyright (C) 1992 by David F. Skoll.                      */
  37. X/*                                                             */
  38. X/***************************************************************/
  39. X
  40. X#include "config.h"
  41. X#include <stdio.h>
  42. X#ifdef HAVE_STDLIB_H
  43. X#include <stdlib.h>
  44. X#endif
  45. X#ifdef HAVE_MALLOC_H
  46. X#include <malloc.h>
  47. X#endif
  48. X#include <string.h>
  49. X#include <ctype.h>
  50. X#include <sys/types.h>
  51. X#include <sys/stat.h>
  52. X#include <time.h>
  53. X
  54. X#ifdef __MSDOS__
  55. X#include <io.h>
  56. X#endif
  57. X
  58. X#ifdef __MSC__
  59. X#include <dos.h>
  60. X#endif
  61. X
  62. X#include "config.h"
  63. X#include "types.h"
  64. X#include "protos.h"
  65. X#include "globals.h"
  66. X#include "err.h"
  67. X
  68. X/* Define the structures needed by the file caching system */
  69. Xtypedef struct _cache_ {
  70. X   struct _cache_ *next;
  71. X   char *text;
  72. X   int LineNo;
  73. X} CachedLine;
  74. X
  75. Xtypedef struct _cheader_ {
  76. X   struct _cheader_ *next;
  77. X   char *filename;
  78. X   CachedLine *cache;
  79. X} CachedFile;
  80. X
  81. X/* Define the structures needed by the INCLUDE file system */
  82. Xtypedef struct {
  83. X   char *filename;
  84. X   int LineNo;
  85. X   unsigned int IfFlags;
  86. X   int NumIfs;
  87. X   long offset;
  88. X   CachedLine *CLine;
  89. X} IncludeStruct;
  90. X
  91. Xstatic CachedFile *CachedFiles = (CachedFile *) NULL;
  92. Xstatic CachedLine *CLine = (CachedLine *) NULL;
  93. X
  94. Xstatic FILE *fp;
  95. X
  96. Xstatic IncludeStruct IStack[INCLUDE_NEST];
  97. Xstatic int IStackPtr = 0;
  98. X
  99. XPRIVATE int ReadLineFromFile ARGS ((void));
  100. XPRIVATE int CacheFile ARGS ((const char *fname));
  101. XPRIVATE void DestroyCache ARGS ((CachedFile *cf));
  102. X
  103. X/***************************************************************/
  104. X/*                                                             */
  105. X/*  ReadLine                                                   */
  106. X/*                                                             */
  107. X/*  Read a line from the file or cache.                        */
  108. X/*                                                             */
  109. X/***************************************************************/
  110. X#ifdef HAVE_PROTOS
  111. XPUBLIC int ReadLine(void)
  112. X#else
  113. Xint ReadLine()
  114. X#endif
  115. X{
  116. X   int r;
  117. X
  118. X/* If we're at the end of a file, pop */
  119. X   while (!CLine && !fp) {
  120. X      r = PopFile();
  121. X      if (r) return r;
  122. X   }
  123. X
  124. X/* If it's cached, read line from the cache */
  125. X   if (CLine) {
  126. X      CurLine = CLine->text;
  127. X      LineNo = CLine->LineNo;
  128. X      CLine = CLine->next;
  129. X      FreshLine = 1;
  130. X      if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
  131. X      return OK;
  132. X   }
  133. X
  134. X/* Not cached.  Read from the file. */
  135. X   CurLine = LineBuffer;
  136. X   return ReadLineFromFile();
  137. X}
  138. X
  139. X/***************************************************************/
  140. X/*                                                             */
  141. X/*  ReadLineFromFile                                           */
  142. X/*                                                             */
  143. X/*  Read a line from the file pointed to by fp.                */
  144. X/*                                                             */
  145. X/***************************************************************/
  146. X#ifdef HAVE_PROTOS
  147. XPRIVATE int ReadLineFromFile(void)
  148. X#else
  149. Xstatic ReadLineFromFile()
  150. X#endif
  151. X{
  152. X   int l;
  153. X   char *ptr;
  154. X
  155. X   *LineBuffer = (char) 0;
  156. X   l = 0;
  157. X   ptr = LineBuffer;
  158. X   while(fp) {
  159. X      (void) fgets(ptr, LINELEN-l, fp);
  160. X      LineNo++;
  161. X      if (ferror(fp)) return E_IO_ERR;
  162. X      if (feof(fp)) {
  163. X         fclose(fp);
  164. X     fp = NULL;
  165. X      }
  166. X      l = strlen(LineBuffer);
  167. X      if (l && (LineBuffer[l-1] == '\n')) LineBuffer[--l] = '\0';
  168. X      if (l && (LineBuffer[l-1] == '\\')) {
  169. X     l--;
  170. X     ptr = LineBuffer+l;
  171. X     if (l >= LINELEN-1) return E_LINE_2_LONG;
  172. X     continue;
  173. X      }
  174. X      FreshLine = 1;
  175. X      if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
  176. X      return OK;
  177. X   }
  178. X   return OK;
  179. X}
  180. X
  181. X/***************************************************************/
  182. X/*                                                             */
  183. X/*  OpenFile                                                   */
  184. X/*                                                             */
  185. X/*  Open a file for reading.  If it's in the cache, set        */
  186. X/*  CLine.  Otherwise, open it on disk and set fp.  If         */
  187. X/*  ShouldCache is 1, cache the file                           */
  188. X/*                                                             */
  189. X/***************************************************************/
  190. X#ifdef HAVE_PROTOS
  191. XPUBLIC int OpenFile(const char *fname)
  192. X#else
  193. Xint OpenFile(fname)
  194. Xchar *fname;
  195. X#endif
  196. X{
  197. X   CachedFile *h = CachedFiles;
  198. X   int r;
  199. X
  200. X/* If it's in the cache, get it from there. */
  201. X
  202. X   while (h) {
  203. X      if (!strcmp(fname, h->filename)) {
  204. X     CLine = h->cache;
  205. X     STRSET(FileName, fname);
  206. X     LineNo = 0;
  207. X     if (FileName) return OK; else return E_NO_MEM;
  208. X      }
  209. X      h = h->next;
  210. X   }
  211. X   fp = fopen(fname, "r");
  212. X   if (!fp) return E_CANT_OPEN;
  213. X   CLine = NULL;
  214. X   if (ShouldCache) {
  215. X      LineNo = 0;
  216. X      r = CacheFile(fname);
  217. X      if (r == OK) {
  218. X         fp = NULL;
  219. X     CLine = CachedFiles->cache;
  220. X      } else {
  221. X         fp = fopen(fname, "r");
  222. X     if (!fp) return E_CANT_OPEN;
  223. X      }
  224. X   }
  225. X   STRSET(FileName, fname);
  226. X   LineNo = 0;
  227. X   if (FileName) return OK; else return E_NO_MEM;
  228. X}
  229. X
  230. X/***************************************************************/
  231. X/*                                                             */
  232. X/*  CacheFile                                                  */
  233. X/*                                                             */
  234. X/*  Cache a file in memory.  If we fail, set ShouldCache to 0  */
  235. X/*  Returns an indication of success or failure.               */
  236. X/*                                                             */
  237. X/***************************************************************/
  238. X#ifdef HAVE_PROTOS
  239. XPRIVATE int CacheFile(const char *fname)
  240. X#else
  241. Xstatic int CacheFile(fname)
  242. Xchar *fname;
  243. X#endif
  244. X{
  245. X   int r;
  246. X   CachedFile *cf;
  247. X   CachedLine *cl;
  248. X   char *s;
  249. X
  250. X   cl = NULL;
  251. X/* Create a file header */
  252. X   cf = NEW(CachedFile);
  253. X   cf->cache = NULL;
  254. X   if (!cf) { ShouldCache = 0; fclose(fp); return E_NO_MEM; }
  255. X   cf->filename = StrDup(fname);
  256. X   if (!cf->filename) {
  257. X      ShouldCache = 0;
  258. X      fclose(fp);
  259. X      free(cf);
  260. X      return E_NO_MEM;
  261. X   }
  262. X
  263. X/* Read the file */
  264. X   while(fp) {
  265. X      r = ReadLineFromFile();
  266. X      if (r) {
  267. X         DestroyCache(cf);
  268. X     ShouldCache = 0;
  269. X     if(fp) fclose(fp);
  270. X     return r;
  271. X      }
  272. X/* Skip blank chars */
  273. X      s = LineBuffer;
  274. X      while (isspace(*s)) s++;
  275. X      if (*s && *s!=';' && *s!='#') {
  276. X/* Add the line to the cache */
  277. X         if (!cl) {
  278. X        cf->cache = NEW(CachedLine);
  279. X        if (!cf->cache) {
  280. X           DestroyCache(cf);
  281. X           ShouldCache = 0;
  282. X           if(fp) fclose(fp);
  283. X           return E_NO_MEM;
  284. X            }
  285. X        cl = cf->cache;
  286. X         } else {
  287. X        cl->next = NEW(CachedLine);
  288. X        if (!cl->next) {
  289. X           DestroyCache(cf);
  290. X           ShouldCache = 0;
  291. X           if(fp) fclose(fp);
  292. X           return E_NO_MEM;
  293. X            }
  294. X        cl = cl->next;
  295. X         }
  296. X     cl->next = NULL;
  297. X     cl->LineNo = LineNo;
  298. X     cl->text = StrDup(s);
  299. X     if (!cl->text) {
  300. X        DestroyCache(cf);
  301. X        ShouldCache = 0;
  302. X        if(fp) fclose(fp);
  303. X        return E_NO_MEM;
  304. X         }
  305. X      }
  306. X   }
  307. X
  308. X/* Put the cached file at the head of the queue */
  309. X   cf->next = CachedFiles;
  310. X   CachedFiles = cf;
  311. X
  312. X   return OK;
  313. X}
  314. X
  315. X/***************************************************************/
  316. X/*                                                             */
  317. X/*  PopFile - we've reached the end.  Pop up to the previous   */
  318. X/*  file, or return E_EOF                                      */
  319. X/*                                                             */
  320. X/***************************************************************/
  321. X#ifdef HAVE_PROTOS
  322. XPUBLIC int PopFile(void)
  323. X#else
  324. Xint PopFile()
  325. X#endif
  326. X{
  327. X   IncludeStruct *i;
  328. X
  329. X   if (!Hush && NumIfs) Eprint("Warning: Missing ENDIF");
  330. X   if (!IStackPtr) return E_EOF;
  331. X   IStackPtr--;
  332. X   i = &IStack[IStackPtr];
  333. X
  334. X   LineNo = i->LineNo;
  335. X   IfFlags = i->IfFlags;
  336. X   NumIfs = i->NumIfs;
  337. X   CLine = i->CLine;
  338. X   fp = NULL;
  339. X   STRSET(FileName, i->filename);
  340. X   if (!CLine && (i->offset != -1L)) {
  341. X   /* We must open the file, then seek to specified position */
  342. X      fp = fopen(i->filename, "r");
  343. X      if (!fp) return E_CANT_OPEN;
  344. X      (void) fseek(fp, i->offset, 0);  /* Trust that it works... */
  345. X   }
  346. X   free(i->filename);
  347. X   return OK;
  348. X}
  349. X
  350. X/***************************************************************/
  351. X/*                                                             */
  352. X/*  DoInclude                                                  */
  353. X/*                                                             */
  354. X/*  The INCLUDE command.                                       */
  355. X/*                                                             */
  356. X/***************************************************************/
  357. X#ifdef HAVE_PROTOS
  358. XPUBLIC int DoInclude(ParsePtr p)
  359. X#else
  360. Xint DoInclude(p)
  361. XParsePtr p;
  362. X#endif
  363. X{     
  364. X    char tok[TOKSIZE];
  365. X    int r, e;
  366. X
  367. X    if(r=ParseToken(p, tok)) return r;
  368. X    e = VerifyEoln(p); 
  369. X    if (e) Eprint("%s", ErrMsg[e]);
  370. X    if(r=IncludeFile(tok)) return r;
  371. X    NumIfs = 0;
  372. X    IfFlags = 0;
  373. X    return OK;
  374. X}
  375. X
  376. X/***************************************************************/
  377. X/*                                                             */
  378. X/*  IncludeFile                                                */
  379. X/*                                                             */
  380. X/*  Process the INCLUDE command - actually do the file         */
  381. X/*  inclusion.                                                 */
  382. X/*                                                             */
  383. X/***************************************************************/
  384. X#ifdef HAVE_PROTOS
  385. XPUBLIC int IncludeFile(const char *fname)
  386. X#else
  387. Xint IncludeFile(fname)
  388. Xchar *fname;
  389. X#endif
  390. X{
  391. X   IncludeStruct *i;
  392. X   int r;
  393. X
  394. X   if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
  395. X   i = &IStack[IStackPtr];
  396. X
  397. X   i->filename = StrDup(FileName);
  398. X   if (!i->filename) return E_NO_MEM;
  399. X   i->LineNo = LineNo;
  400. X   i->NumIfs = NumIfs;
  401. X   i->IfFlags = IfFlags;
  402. X   i->CLine = CLine;
  403. X   i->offset = -1L;
  404. X   if (fp) {
  405. X      i->offset = ftell(fp);
  406. X      fclose(fp);
  407. X      fp = (FILE *) NULL;
  408. X   }
  409. X
  410. X   IStackPtr++;
  411. X
  412. X   /* Try to open the new file */
  413. X   if (!OpenFile(fname)) {
  414. X      return OK;
  415. X   }
  416. X   /* Ugh!  We failed!  */
  417. X   if (r=PopFile()) return r;
  418. X   return E_CANT_OPEN;
  419. X}
  420. X
  421. X/***************************************************************/
  422. X/*                                                             */
  423. X/* GetAccessDate - get the access date of a file.              */
  424. X/*                                                             */
  425. X/***************************************************************/
  426. X#ifdef HAVE_PROTOS
  427. XPUBLIC int GetAccessDate(char *file)
  428. X#else
  429. Xint GetAccessDate(file)
  430. Xchar *file;
  431. X#endif
  432. X{
  433. X   struct stat statbuf;
  434. X   struct tm *t1;
  435. X
  436. X   if (stat(file, &statbuf)) return -1;
  437. X#ifdef __TURBOC__
  438. X   t1 = localtime( (time_t *) &(statbuf.st_atime) );
  439. X#else
  440. X   t1 = localtime(&(statbuf.st_atime));
  441. X#endif
  442. X
  443. X   if (t1->tm_year + 1900 < BASE)
  444. X      return 0;
  445. X   else
  446. X      return Julian(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
  447. X}
  448. X
  449. X/***************************************************************/
  450. X/*                                                             */
  451. X/*  SetAccessDate                                              */
  452. X/*                                                             */
  453. X/*  Used only by DOS to set access date after we close the     */
  454. X/*  file.  Not needed for UNIX.                                */
  455. X/*                                                             */
  456. X/***************************************************************/
  457. X#ifdef __MSDOS__
  458. X/*
  459. X * WARNING WARNING WARNING WARNING
  460. X * In the version of Turbo C which I have, there is a bug in the
  461. X * stdio.h file.  The following lines correct the bug.  YOU MAY
  462. X * HAVE TO REMOVE THESE LINES FOR LATER VERSIONS OF TURBOC
  463. X */
  464. X#ifdef __TURBOC__
  465. X#ifndef fileno
  466. X#define fileno(f) ((f)->fd)
  467. X#endif
  468. X#endif
  469. X
  470. X#ifdef HAVE_PROTOS
  471. XPUBLIC int SetAccessDate(char *fname, int jul)
  472. X#else
  473. Xint SetAccessDate(fname, jul)
  474. Xchar *fname;
  475. Xint jul;
  476. X#endif
  477. X{
  478. X   int y, m, d;
  479. X#ifdef __TURBOC__   
  480. X   struct ftime ft;
  481. X#endif   
  482. X   FILE *f;
  483. X
  484. X   FromJulian(jul, &y, &m, &d);
  485. X   
  486. X#ifdef __TURBOC__   
  487. X   ft.ft_tsec = 0;
  488. X   ft.ft_min = 0;
  489. X   ft.ft_hour = 12;  /* Arbitrarily set time to noon. */
  490. X   ft.ft_day = (unsigned int) d;
  491. X   ft.ft_month = (unsigned int) m+1;
  492. X   ft.ft_year = (unsigned int) (y - 1980);
  493. X#endif
  494. X
  495. X   f = fopen(fname, "r");
  496. X
  497. X#ifdef __TURBOC__   
  498. X   if (!f || setftime(fileno(f) , &ft)) {
  499. X#endif
  500. X
  501. X#ifdef __MSC__
  502. X   if (!f || _dos_setftime(fileno(f),
  503. X    ((y-1980)<<9) + (m+1)<<5 + d,
  504. X    (12<<11))) {
  505. X#endif       
  506. X      fprintf(ErrFp, "Can't reset access date of %s\n", fname);
  507. X      if (f) fclose(f);
  508. X      return -1;
  509. X   }
  510. X
  511. X   fclose(f);
  512. X   return 0;
  513. X}
  514. X#endif /* __MSDOS__ */
  515. X
  516. X/***************************************************************/
  517. X/*                                                             */
  518. X/*  DestroyCache                                               */
  519. X/*                                                             */
  520. X/*  Free all the memory used by a cached file.                 */
  521. X/*                                                             */
  522. X/***************************************************************/
  523. X#ifdef HAVE_PROTOS
  524. XPRIVATE void DestroyCache(CachedFile *cf)
  525. X#else
  526. Xstatic void DestroyCache(cf)
  527. XCachedFile *cf;
  528. X#endif
  529. X{
  530. X   CachedLine *cl, *cnext;
  531. X   if (cf->filename) free(cf->filename);
  532. X   cl = cf->cache;
  533. X   while (cl) {
  534. X      if (cl->text) free (cl->text);
  535. X      cnext = cl->next;
  536. X      free(cl);
  537. X      cl = cnext;
  538. X   }
  539. X   free(cf);
  540. X}
  541. X
  542. X/***************************************************************/
  543. X/*                                                             */
  544. X/*  TopLevel                                                   */
  545. X/*                                                             */
  546. X/*  Returns 1 if current file is top level, 0 otherwise.       */
  547. X/*                                                             */
  548. X/***************************************************************/
  549. X#ifdef HAVE_PROTOS
  550. XPUBLIC int TopLevel(void)
  551. X#else
  552. Xint TopLevel()
  553. X#endif
  554. X{
  555. X   return !IStackPtr;
  556. X}
  557. SHAR_EOF
  558. $TOUCH -am 1109141292 files.c &&
  559. chmod 0600 files.c ||
  560. echo "restore of files.c failed"
  561. set `wc -c files.c`;Wc_c=$1
  562. if test "$Wc_c" != "14553"; then
  563.     echo original size 14553, current size $Wc_c
  564. fi
  565. fi
  566. echo "End of part 5, continue with part 6"
  567. exit 0
  568.  
  569. exit 0 # Just in case...
  570.