view lib-src/yow.c @ 22293:0544aa57ff27

(cperl-style-alist): New variable, since `c-mode' is no longer loaded. - (Somebody who uses the styles should check that they work OK!) - (a lot of work is needed, especially with new `cperl-fix-line-spacing'). Old value of style is memorized when choosing a new style, may be restored from the same menu. (cperl-perldoc, cperl-pod-to-manpage): New commands; thanks to Anthony Foiani <afoiani@uswest.com> and Nick Roberts <Nick.Roberts@src.bae.co.uk>. (`Perl doc', `Regexp'): New submenus (latter to allow short displays). (cperl-clobber-lisp-bindings): New cfg variable. (cperl-find-pods-heres): $a->y() is not y///. (cperl-after-block-p): Add save-excursion. (cperl-init-faces): Was failing. Init faces when loading `ps-print'. (cperl-toggle-autohelp): New command. (cperl-electric-paren): `while SPACE LESS' was buggy. (cperl-init-faces): `-text' in `[-text => 1]' was not highlighted. (cperl-after-block-p): was FALSE after `sub f {}'. (cperl-electric-keyword): `foreachmy', `formy' expanded too, Expands `=pod-directive'. (cperl-linefeed): behaves reasonable in POD-directive lines. (cperl-message-electric-keyword): new cfg variable. (cperl-electric-keyword): print a message, governed by `cperl-message-electric-keyword'. (cperl-electric-paren): Typing `}' was not checking for being block or not. (cperl-beautify-regexp-piece): Did not know about lookbehind; finding *which* level to work with was not intuitive. (cperl-beautify-levels): New command. (cperl-electric-keyword): Allow here-docs contain `=head1' and friends for keyword expansion. Fix for broken `font-lock-unfontify-region-function'. Should preserve `syntax-table' properties even with `lazy-lock'. (cperl-indent-region-fix-else): New command. (cperl-fix-line-spacing): New command. (cperl-invert-if-unless): New command (C-c C-t and in Menu). (cperl-hints): mention 20.2's goods/bads. (cperl-extra-newline-before-brace-multiline): Started to use it. (cperl-break-one-line-blocks-when-indent): New cfg variable. (cperl-fix-hanging-brace-when-indent): New cfg variable. (cperl-merge-trailing-else): New cfg variable. Workaround for another `font-lock's `syntax-table' text-property bug. `zerop' could be applied to nil. At last, may work with `font-lock' without setting `cperl-font-lock'. (cperl-indent-region-fix-constructs): Renamed from `cperl-indent-region-fix-constructs'. (cperl-fix-line-spacing): could be triggered inside strings, would not know what to do with BLOCKs of map/printf/etc. (cperl-merge-trailing-else): Handle `continue' too. (cperl-fix-line-spacing): Likewise. (cperl-calculate-indent): Knows about map/printf/etc before {BLOCK}; treat after-comma lines as continuation lines. (cperl-mode): `continue' made electric. (cperl-electric-keyword): Electric `do' inserts `do/while'. (cperl-fontify-syntaxically): New function. (cperl-syntaxify-by-font-lock): New cfg variable. Make syntaxification to be autoredone via `font-lock', switched on by `cperl-syntaxify-by-font-lock', off by default so far. Remove some commented out chunks. (cperl-set-style-back): Old value of style is memorized when choosing a new style, may be restored from the same menu. Mode-documentation added to micro-docs. (cperl-praise): updated. (cperl-toggle-construct-fix): New command. Added on C-c C-w and menu. (auto-fill-mode): added on C-c C-f and menu. (cperl-style-alist): `PerlStyle' style added. (cperl-find-pods-heres): Message for termination of scan corrected. (cperl-speed): New variable with hints. (cperl-electric-else): Make backspace electric after expansion of `else/continue' too. Fixed customization to honor cperl-hairy. Created customization groups. All the compile-time warnings fixed. (cperl-syntaxify-by-font-lock): Interaction with `font-lock-hot-pass' fixed. (cperl-after-block-and-statement-beg): It is BLOCK if we reach lim when backup sexp. (cperl-after-block-p, cperl-after-expr-p): Likewise. (cperl-indent-region): Make a marker for END - text added/removed. (cperl-style-alist): Include `cperl-merge-trailing-else' where the value is clear. (cperl-styles-entries): Likewise. (cperl-tips, cperl-problems): Improvements to docs.
author Richard M. Stallman <rms@gnu.org>
date Sat, 30 May 1998 15:43:16 +0000
parents fdac027af4e1
children 595856efc8f1
line wrap: on
line source

/*
 * yow.c
 * 
 * Print a quotation from Zippy the Pinhead.
 * Qux <Kaufman-David@Yale> March 6, 1986
 *
 * This file is in the public domain because the author published it
 * with no copyright notice before the US signed the Bern Convention.
 * 
 * With dynamic memory allocation.
 */

#include <stdio.h>
#include <ctype.h>
#include <../src/paths.h>      /* For PATH_DATA.  */

#define BUFSIZE  80
#define SEP      '\0'

#ifndef YOW_FILE
#define YOW_FILE "yow.lines"
#endif

#ifdef MSDOS
#define rootrelativepath(rel) \
({\
    static char res[BUFSIZE], *p;\
    strcpy (res, argv[0]);\
    p = res + strlen (res);\
    while (p != res && *p != '/' && *p != '\\' && *p != ':') p--;\
    strcpy (p + 1, "../");\
    strcpy (p + 4, rel);\
    &res;})
#endif

char *malloc(), *realloc();

void yow();
void setup_yow();

int
main (argc, argv)
     int argc;
     char *argv[];
{
  FILE *fp;
  char file[BUFSIZ];

  if (argc > 2 && !strcmp (argv[1], "-f"))
    strcpy (file, argv[2]);
  else
#ifdef vms
    sprintf (file, "%s%s", PATH_DATA, YOW_FILE);
#else
    sprintf (file, "%s/%s", PATH_DATA, YOW_FILE);
#endif

  if ((fp = fopen(file, "r")) == NULL) {
    fprintf(stderr, "yow: ");
    perror(file);
    exit(1);
  }

  /* initialize random seed */
  srand((int) (getpid() + time((long *) 0)));

  setup_yow(fp);
  yow(fp);
  fclose(fp);
  return 0;
}

static long len = -1;
static long header_len;

#define AVG_LEN 40		/* average length of a quotation */

/* Sets len and header_len */
void
setup_yow(fp)
     FILE *fp;
{
  int c;

  /* Get length of file */
  /* Because the header (stuff before the first SEP) can be very long,
   * thus biasing our search in favor of the first quotation in the file,
   * we explicitly skip that. */
  while ((c = getc(fp)) != SEP) {
    if (c == EOF) {
      fprintf(stderr, "yow: file contains no separators\n");
      exit(2);
    }
  }
  header_len = ftell(fp);
  if (header_len > AVG_LEN)
    header_len -= AVG_LEN;	/* allow the first quotation to appear */
	
  if (fseek(fp, 0L, 2) == -1) {
    perror("yow");
    exit(1);
  }
  len = ftell(fp) - header_len;
}


/* go to a random place in the file and print the quotation there */
void
yow (fp)
     FILE *fp;
{
  long offset;
  int c, i = 0;
  char *buf;
  unsigned int bufsize;

  offset = rand() % len + header_len;
  if (fseek(fp, offset, 0) == -1) {
    perror("yow");
    exit(1);
  }

  /* Read until SEP, read next line, print it.
     (Note that we will never print anything before the first separator.)
     If we hit EOF looking for the first SEP, just recurse. */
  while ((c = getc(fp)) != SEP)
    if (c == EOF) {
      yow(fp);
      return;
    }

  /* Skip leading whitespace, then read in a quotation.
     If we hit EOF before we find a non-whitespace char, recurse. */
  while (isspace(c = getc(fp)))
    ;
  if (c == EOF) {
    yow(fp);
    return;
  }

  bufsize = BUFSIZE;
  buf = malloc(bufsize);
  if (buf == (char *)0) {
    fprintf(stderr, "yow: virtual memory exhausted\n");
    exit (3);
  }

  buf[i++] = c;
  while ((c = getc(fp)) != SEP && c != EOF) {
    buf[i++] = c;
	
    if (i == bufsize-1) {
      /* Yow! Is this quotation too long yet? */
      bufsize *= 2;
      buf = realloc(buf, bufsize);
      if (buf == (char *)0) {
	fprintf(stderr, "yow: virtual memory exhausted\n");
	exit (3);
      }
    }
  }
  buf[i++] = 0;
  printf("%s\n", buf);
}