home *** CD-ROM | disk | FTP | other *** search
- /*
- * s m i l e y . c
- *
- * DaviD W. Sanderson is to blame for this.
- */
-
- #include "smiley.h"
- #include "patchlevel.h"
-
- /*
- * macros
- */
-
- /*
- * swrite() - write() a "string variable" (char *)
- */
-
- #define swrite(fd, s) (void) write((fd), (s), strlen(s))
-
- /*
- * lwrite() - write() a "string literal" (char [])
- */
-
- #define lwrite(fd, lit) (void) write((fd), (lit), sizeof(lit)-1)
-
- /*
- * PUTFACE() - write() a smiley and its description
- */
-
- #define PUTFACE(fd, i) swrite((fd), faces[i].face); \
- lwrite((fd), tab); \
- swrite((fd), faces[i].desc); \
- lwrite((fd), newline)
-
- /*
- * FD - file descriptor to which to write the output
- */
-
- #define FD 1
-
- /*
- * declarations
- */
-
- extern int write();
- extern int strlen();
- extern char *bsearch();
-
- /*
- * definitions
- */
-
- static char ENVAR[] = "SMILEY";
- static char tab[] = "\t";
- static char newline[] = "\n";
-
- /*
- * facecmp() - comparison routine for using bsearch()
- */
- int
- facecmp(f1, f2)
- struct smiley *f1;
- struct smiley *f2;
- {
- return strcmp(f1->face, f2->face);
- }
-
- /*
- * fsearch() - return index of face, or -1 on failure
- *
- * Note that this assumes that there will be at most one entry in
- * faces[] for a particular smiley. It also assumes that faces[] is
- * sorted in ascending order.
- */
- int
- fsearch(s)
- char *s;
- {
- struct smiley f;
- struct smiley *ans;
-
- f.face = s;
- ans = (struct smiley *) bsearch(
- (char *) &f,
- (char *) faces, (unsigned) nfaces, sizeof faces[0],
- facecmp);
-
- if (ans)
- return ans - faces;
- else
- return -1;
- }
-
- /*
- * explain() - look through the list of smileys for the given face.
- *
- * If it is found, then print out the description.
- *
- * The return value is zero if the face is not found, nonzero otherwise.
- */
- static int
- explain(s)
- char *s;
- {
- int i;
-
- if((i = fsearch(s)) == -1)
- return 0;
-
- PUTFACE(FD, i);
- return 1;
- #if 0
- int found = 0;
-
- for (i = 0; i < nfaces; i++)
- {
- extern int strcmp();
-
- if (strcmp(s, faces[i].face) == 0)
- {
- found = 1;
- PUTFACE(FD, i);
- }
- }
- return found;
- #endif
- }
-
- /*
- * main() - main program
- */
-
- main(ac, av)
- int ac;
- char **av;
- {
- extern char *optarg;
- extern int optind;
- extern int opterr;
-
- char *args = "Velf";
- int Vflag = 0;
- int eflag = 0;
- int lflag = 0;
- int fflag = 0;
- int errflag = 0;
- int c;
-
- /*
- * process command-line options
- */
- while ((c = getopt(ac, av, args)) != -1)
- {
- switch (c)
- {
- case 'V': /* version */
- Vflag = 1;
- break;
- case 'e': /* environment */
- eflag = 1;
- break;
- case 'l': /* list */
- lflag = 1;
- break;
- case 'f': /* face only */
- fflag = 1;
- break;
- case '?':
- errflag = 1;
- break;
- }
- }
- if (errflag)
- {
- static char msg0[] = "usage: ";
- static char *msg1[] =
- {
- " [-V] [-e] [-l] [-f] [smiley ...]\n",
- "where:\t-V\tprint program version\n",
- "\t-e\texplain the face in $",
- (char *) 0
- };
- static char *msg2[] =
- {
- "\n",
- "\t-l\tlist all the smileys\n",
- "\t-f\tprint a random smiley, face only\n",
- "\tsmiley\texplain the given smileys\n",
- "(no args)\tprint a random smiley\n",
- (char *) 0
- };
-
- char **p;
-
- lwrite(FD, msg0);
- swrite(FD, av[0]);
-
- for (p = msg1; *p; p++)
- swrite(FD, *p);
-
- lwrite(FD, ENVAR);
-
- for (p = msg2; *p; p++)
- swrite(FD, *p);
-
- return 1;
- }
-
- /*
- * perform command-line options
- */
-
- /*
- * Vflag - print version information
- */
- if (Vflag)
- {
- static char stat0[] = " faces, ";
- static char stat1[] = " definitions\n";
- char *num;
- int i;
- unsigned long ndefs;
- extern char *ltoa();
-
- swrite(FD, av[0]);
- lwrite(FD, version);
-
- /*
- * Print counts of the smiley faces and definitions
- * The definitions for a smiley are separated by
- * newlines, but not terminated by newlines.
- */
- num = ltoa((unsigned long)nfaces, 10);
- swrite(FD, num);
- lwrite(FD, stat0);
-
- ndefs = nfaces;
- for (i=0; i<nfaces; i++)
- {
- char *def;
-
- for (def = faces[i].desc; *def; def++)
- {
- if (*def == '\n')
- ndefs++;
- }
- }
- num = ltoa(ndefs, 10);
- swrite(FD, num);
- lwrite(FD, stat1);
-
- #ifdef __DATE__
- #ifdef __TIME__
- {
- static char when0[] = "last compiled ";
- static char when1[] = __TIME__;
- static char when2[] = " ";
- static char when3[] = __DATE__;
- static char when4[] = "\n";
-
- lwrite(FD, when0);
- lwrite(FD, when1);
- lwrite(FD, when2);
- lwrite(FD, when3);
- lwrite(FD, when4);
- }
- #endif
- #endif
-
- return 0;
- }
-
- /*
- * eflag - explain $SMILEY
- */
- if (eflag)
- {
- extern char *getenv();
- int unknown = 1;
- char *str;
-
- if ((str = getenv(ENVAR)) != (char *)0)
- {
- if(explain(str) != 0)
- unknown = 0;
- }
- else
- {
- static char notset[] = " not set\n";
-
- lwrite(FD, ENVAR);
- lwrite(FD, notset);
- }
- return unknown;
- }
-
- /*
- * lflag - list smileys
- */
- if (lflag)
- {
- int i;
-
- for (i = 0; i < nfaces; i++)
- {
- PUTFACE(FD, i);
- }
- return 0;
- }
-
- /*
- * literal smileys - try to explain them
- *
- * In this case the exit status is the number of smileys
- * that were not found.
- */
- if (optind < ac)
- {
- int unknown = 0;
-
- for (; optind < ac; optind++)
- {
- if(!explain(av[optind]))
- unknown++;
- }
-
- return unknown;
- }
-
- /*
- * otherwise - generate a random smiley
- */
- {
- extern int rand();
- extern void srand();
- extern long time();
- extern int getpid();
-
- char *f;
-
- /*
- * seed with the current time + the pid. (The pid
- * prevents smileys started at identical times from
- * getting the same random seed)
- */
- srand((unsigned) time((long *)0) + (unsigned) getpid());
- f = faces[rand() % nfaces].face;
-
- if (fflag)
- {
- swrite(FD, f);
- lwrite(FD, newline);
- }
- else
- {
- (void) explain(f);
- }
- }
- return 0;
- }
-