home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / sources / misc / 4067 < prev    next >
Encoding:
Text File  |  1992-11-09  |  16.1 KB  |  576 lines

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