diff --git a/rootfs.manifest b/rootfs.manifest index 47cc8d6..4bca8b2 100644 --- a/rootfs.manifest +++ b/rootfs.manifest @@ -417,6 +417,7 @@ file /games/canfield file /games/cfscores file /games/factor file /games/fish +file /games/fortune file /games/morse file /games/number file /games/ppt @@ -440,6 +441,8 @@ file /games/lib/battle_strings mode 0444 file /games/lib/cfscores mode 0666 +file /games/lib/fortunes.dat +mode 0444 # # Files: /include diff --git a/src/games/Makefile b/src/games/Makefile index 4c7e678..0242c77 100644 --- a/src/games/Makefile +++ b/src/games/Makefile @@ -12,8 +12,8 @@ CFLAGS += -Werror -Wall -Os # Programs that live in subdirectories, and have makefiles of their own. # SUBDIR = adventure atc backgammon battlestar boggle btlgammon \ - cribbage rogue sail trek -# TODO: fortune hangman hunt mille monop phantasia quiz robots + cribbage fortune rogue sail trek +# TODO: hangman hunt mille monop phantasia quiz robots # sail snake warp # C programs that live in the current directory and do not need diff --git a/src/games/fortune/.gitignore b/src/games/fortune/.gitignore new file mode 100644 index 0000000..ce43652 --- /dev/null +++ b/src/games/fortune/.gitignore @@ -0,0 +1 @@ +fortune diff --git a/src/games/fortune/Makefile b/src/games/fortune/Makefile index cedde4e..e133edc 100644 --- a/src/games/fortune/Makefile +++ b/src/games/fortune/Makefile @@ -1,72 +1,45 @@ -FORTUNES= scene obscene -SOURCE= fortune.c strfile.h strfile.c rnd.c unstr.c $(FORTUNES) -TFILES= Troff.mac Troff.sed Do_troff -LIBDIR= /usr/games/lib -BINDIR= /usr/games -OWN= arnold -GRP= arpa -DEFS= -SEPFLAG= -i -CFLAGS= -O $(DEFS) -SFLAGS= -r -TDEV= -Pver -TROFF= ditroff $(TDEV) -DESTDIR= +TOPSRC = $(shell cd ../../..; pwd) +include $(TOPSRC)/target.mk +#include $(TOPSRC)/cross.mk -all: fortune strfile unstr fortunes.dat +CFLAGS += -O -Werror -Wall +LIBS = -lc -fortune: fortune.o rnd.o - $(CC) ${SEPFLAG} $(CFLAGS) -o fortune fortune.o rnd.o +OBJS = fortune.o +MAN = fortune.0 +MANSRC = fortune.6 -strfile: strfile.o rnd.o - $(CC) ${SEPFLAG} $(CFLAGS) -o strfile strfile.o rnd.o +all: fortune $(MAN) fortunes.dat -unstr: unstr.o - $(CC) ${SEPFLAG} $(CFLAGS) -o unstr unstr.o +fortune: $(OBJS) + $(CC) $(LDFLAGS) -o fortune.elf $(OBJS) $(LIBS) + $(OBJDUMP) -S fortune.elf > fortune.dis + $(SIZE) fortune.elf + $(ELF2AOUT) fortune.elf $@ && rm fortune.elf -fortune.o strfile.o unstr.o: strfile.h +strfile: strfile.o + $(CC) $(LDFLAGS) -o strfile strfile.o -fortunes.dat: fortunes strfile - ./strfile $(SFLAGS) fortunes +unstr: unstr.o + $(CC) $(LDFLAGS) -o unstr unstr.o -fortunes: $(FORTUNES) - cp scene fortunes - echo "%-" >> fortunes - cat obscene >> fortunes +fortunes.dat: #fortunes strfile + ./strfile -r fortunes -lint: - lint -hxb $(DEFS) fortune.c rnd.c 2>&1 > fortune.lint - lint -hxb $(DEFS) strfile.c rnd.c 2>&1 > strfile.lint - lint -hxb $(DEFS) unstr.c 2>&1 > unstr.lint +fortunes: scene obscene + cp scene fortunes + echo "%-" >> fortunes + cat obscene >> fortunes -install: all install.data - install -s -m 4711 -o daemon fortune $(DESTDIR)$(BINDIR) +$(MAN): $(MANSRC) + $(MANROFF) $< > $@ -install.data: fortunes.dat - install -m 600 -o daemon fortunes.dat $(DESTDIR)$(LIBDIR) +clean: + rm -f *.o *.0 *.elf $(MAN) fortune strfile unstr fortunes *.elf *.dis tags *~ -troff: troff.scene troff.obscene +install: all + install fortune $(DESTDIR)/games/ + cp $(MAN) $(DESTDIR)/share/man/cat6/ + cp fortunes.dat $(DESTDIR)/games/lib/ -troff.scene: - ./Do_troff scene $(TROFF) - -troff.obscene: - ./Do_troff obscene $(TROFF) - -clean: sort.clean - rm -f fortune fortunes fortunes.dat strfile unstr ? core *.o - -sort: sort.scene sort.obscene - -sort.scene: strfile unstr - strfile -oi scene - mv scene Oscene - unstr -o scene - -sort.obscene: strfile unstr - strfile -oi obscene - mv obscene Oobscene - unstr -o obscene - -sort.clean: - rm -f Oscene Oobscene +#$(OBJS): fortune.h diff --git a/src/games/fortune/Makefile.orig b/src/games/fortune/Makefile.orig new file mode 100644 index 0000000..cedde4e --- /dev/null +++ b/src/games/fortune/Makefile.orig @@ -0,0 +1,72 @@ +FORTUNES= scene obscene +SOURCE= fortune.c strfile.h strfile.c rnd.c unstr.c $(FORTUNES) +TFILES= Troff.mac Troff.sed Do_troff +LIBDIR= /usr/games/lib +BINDIR= /usr/games +OWN= arnold +GRP= arpa +DEFS= +SEPFLAG= -i +CFLAGS= -O $(DEFS) +SFLAGS= -r +TDEV= -Pver +TROFF= ditroff $(TDEV) +DESTDIR= + +all: fortune strfile unstr fortunes.dat + +fortune: fortune.o rnd.o + $(CC) ${SEPFLAG} $(CFLAGS) -o fortune fortune.o rnd.o + +strfile: strfile.o rnd.o + $(CC) ${SEPFLAG} $(CFLAGS) -o strfile strfile.o rnd.o + +unstr: unstr.o + $(CC) ${SEPFLAG} $(CFLAGS) -o unstr unstr.o + +fortune.o strfile.o unstr.o: strfile.h + +fortunes.dat: fortunes strfile + ./strfile $(SFLAGS) fortunes + +fortunes: $(FORTUNES) + cp scene fortunes + echo "%-" >> fortunes + cat obscene >> fortunes + +lint: + lint -hxb $(DEFS) fortune.c rnd.c 2>&1 > fortune.lint + lint -hxb $(DEFS) strfile.c rnd.c 2>&1 > strfile.lint + lint -hxb $(DEFS) unstr.c 2>&1 > unstr.lint + +install: all install.data + install -s -m 4711 -o daemon fortune $(DESTDIR)$(BINDIR) + +install.data: fortunes.dat + install -m 600 -o daemon fortunes.dat $(DESTDIR)$(LIBDIR) + +troff: troff.scene troff.obscene + +troff.scene: + ./Do_troff scene $(TROFF) + +troff.obscene: + ./Do_troff obscene $(TROFF) + +clean: sort.clean + rm -f fortune fortunes fortunes.dat strfile unstr ? core *.o + +sort: sort.scene sort.obscene + +sort.scene: strfile unstr + strfile -oi scene + mv scene Oscene + unstr -o scene + +sort.obscene: strfile unstr + strfile -oi obscene + mv obscene Oobscene + unstr -o obscene + +sort.clean: + rm -f Oscene Oobscene diff --git a/src/games/fortune/fortune.6 b/src/games/fortune/fortune.6 index 150456f..97a000b 100644 --- a/src/games/fortune/fortune.6 +++ b/src/games/fortune/fortune.6 @@ -40,8 +40,8 @@ often used for potentially offensive ones. .B \-a Choose from either list of adages. .PP -..The user may specify a file of adages. -..This file must be created by strfile(6), +.. The user may specify a file of adages. +.. This file must be created by strfile(6), ..and be given by the user as ...it file. ..Only one such file may be named, diff --git a/src/games/fortune/fortune.c b/src/games/fortune/fortune.c index 6253dea..97dae60 100644 --- a/src/games/fortune/fortune.c +++ b/src/games/fortune/fortune.c @@ -1,21 +1,31 @@ /* $Header: fortune.c,v 1.10 85/11/01 15:19:49 arnold Exp $ */ -# include -# include -# include -# include "strfile.h" +#include +#ifdef CROSS +# include +#else +# include +#endif +#include +#include +#include +#include +#include "strfile.h" -# define TRUE 1 -# define FALSE 0 -# define bool short +#define TRUE 1 +#define FALSE 0 -# define MINW 6 /* minimum wait if desired */ -# define CPERS 20 /* # of chars for each sec */ -# define SLEN 160 /* # of chars in short fortune */ +#define MINW 6 /* minimum wait if desired */ +#define CPERS 20 /* # of chars for each sec */ +#define SLEN 160 /* # of chars in short fortune */ -# define FORTFILE "/usr/games/lib/fortunes.dat" +#ifdef CROSS +# define FORTFILE "/usr/local/games/fortunes.dat" +#else +# define FORTFILE "/games/lib/fortunes.dat" +#endif -bool Wflag = FALSE, /* wait desired after fortune */ +int Wflag = FALSE, /* wait desired after fortune */ Sflag = FALSE, /* short fortune desired */ Lflag = FALSE, /* long fortune desired */ Oflag = FALSE, /* offensive fortunes only */ @@ -41,70 +51,11 @@ FILE *Inf; /* input file */ STRFILE Tbl; /* input table */ -time_t time(); - -main(ac, av) -int ac; -char *av[]; -{ - register char c; - register int nchar = 0; - register int i; - - getargs(ac, av); - if ((Inf = fopen(Fortfile, "r+")) == NULL) { - perror(Fortfile); - exit(-1); - } - fread((char *) &Tbl, sizeof Tbl, 1, Inf); /* NOSTRICT */ - if (Tbl.str_longlen <= SLEN && Lflag) { - puts("Sorry, no long strings in this file"); - exit(0); - } - if (Tbl.str_shortlen > SLEN && Sflag) { - puts("Sorry, no short strings in this file"); - exit(0); - } - - /* - * initialize the pointer to the first -o fortune if need be. - */ - if (Tbl.str_delims[2] == 0) - Tbl.str_delims[2] = Tbl.str_delims[0]; - - do { - getfort(); - } while ((Sflag && !is_short()) || (Lflag && !is_long())); - - fseek(Inf, Seekpts[0], 0); - while (c = getc(Inf)) { - nchar++; - putchar(c); - } - fflush(stdout); - fseek(Inf, 0L, 0); -#ifdef LOCK_EX - /* - * if we can, we exclusive lock, but since it isn't very - * important, we just punt if we don't have easy locking - * available. - */ - flock(fileno(Inf), LOCK_EX); -#endif LOCK_EX - fwrite(&Tbl, 1, sizeof Tbl, Inf); -#ifdef LOCK_EX - flock(fileno(Inf), LOCK_UN); -#endif LOCK_EX - if (Wflag) - sleep(max((int) nchar / CPERS, MINW)); - exit(0); -} - /* * is_short: * Return TRUE if fortune is "short". */ -is_short() +int is_short() { register int nchar; @@ -121,7 +72,7 @@ is_short() * is_long: * Return TRUE if fortune is "long". */ -is_long() +int is_long() { register int nchar; @@ -137,9 +88,7 @@ is_long() /* * This routine evaluates the arguments on the command line */ -getargs(ac, av) -register int ac; -register char *av[]; +void getargs(int ac, char **av) { register int i; register char *sp; @@ -182,9 +131,9 @@ register char *av[]; * few numbers to avoid any non- * randomness in startup */ - srnd(time(NULL) + getpid()); + srandom(time(NULL) + getpid()); for (j = 0; j < 20; j++) - (void) rnd(100); + (void) random(); break; default: printf("unknown flag: '%c'\n", *sp); @@ -202,7 +151,7 @@ register char *av[]; * getfort: * Get the fortune data file's seek pointer for the next fortune. */ -getfort() +void getfort() { register int fortune; @@ -216,7 +165,7 @@ getfort() Tbl.str_delims[2] = Tbl.str_delims[0]; if (Aflag) { - if (rnd(Tbl.str_numstr) < Tbl.str_delims[0]) + if (random() % Tbl.str_numstr < Tbl.str_delims[0]) fortune = Tbl.str_delims[1]++; else fortune = Tbl.str_delims[2]++; @@ -227,11 +176,70 @@ getfort() fortune = Tbl.str_delims[1]++; fseek(Inf, (long)(sizeof Seekpts[0]) * fortune + sizeof Tbl, 0); - fread((char *) Seekpts, (sizeof Seekpts[0]), 2, Inf); + if (fread((char *) Seekpts, (sizeof Seekpts[0]), 2, Inf) != 2) { + puts("Error reading data from strings file"); + exit(0); + } } -max(i, j) -register int i, j; +int max(int i, int j) { return (i >= j ? i : j); } + +int main(int ac, char **av) +{ + register char c; + register int nchar = 0; + + getargs(ac, av); + if ((Inf = fopen(Fortfile, "r+")) == NULL) { + perror(Fortfile); + exit(-1); + } + if (fread((char *) &Tbl, sizeof Tbl, 1, Inf) != 1) { + puts("Error reading strings file"); + exit(0); + } + if (Tbl.str_longlen <= SLEN && Lflag) { + puts("Sorry, no long strings in this file"); + exit(0); + } + if (Tbl.str_shortlen > SLEN && Sflag) { + puts("Sorry, no short strings in this file"); + exit(0); + } + + /* + * initialize the pointer to the first -o fortune if need be. + */ + if (Tbl.str_delims[2] == 0) + Tbl.str_delims[2] = Tbl.str_delims[0]; + + do { + getfort(); + } while ((Sflag && !is_short()) || (Lflag && !is_long())); + + fseek(Inf, Seekpts[0], 0); + while ((c = getc(Inf))) { + nchar++; + putchar(c); + } + fflush(stdout); + fseek(Inf, 0L, 0); +#ifdef LOCK_EX + /* + * if we can, we exclusive lock, but since it isn't very + * important, we just punt if we don't have easy locking + * available. + */ + flock(fileno(Inf), LOCK_EX); +#endif + fwrite(&Tbl, 1, sizeof Tbl, Inf); +#ifdef LOCK_EX + flock(fileno(Inf), LOCK_UN); +#endif + if (Wflag) + sleep(max((int) nchar / CPERS, MINW)); + exit(0); +} diff --git a/src/games/fortune/fortunes.dat b/src/games/fortune/fortunes.dat new file mode 100644 index 0000000..869c7d7 Binary files /dev/null and b/src/games/fortune/fortunes.dat differ diff --git a/src/games/fortune/rnd.c b/src/games/fortune/rnd.c index 946b460..e43c352 100644 --- a/src/games/fortune/rnd.c +++ b/src/games/fortune/rnd.c @@ -1,13 +1,14 @@ /* * code for when the good (berkeley) random number generator is around */ +#include -rnd(num) +int rnd(int num) { return (random() % num); } -srnd(num) +void srnd(int num) { srandom(num); } @@ -38,7 +39,7 @@ static char sccsid[] = "@(#)random.c 4.2 (Berkeley) 83/01/02"; * zeroeth element of the array is the type of R.N.G. being used (small * integer); the remainder of the array is the state information for the * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of - * state information, which will allow a degree seven polynomial. (Note: the + * state information, which will allow a degree seven polynomial. (Note: the * zeroeth word of state information also has some other information stored * in it -- see setstate() for details). * The random number generation technique is a linear feedback shift register @@ -120,13 +121,13 @@ static int seps[ MAX_TYPES ] = { SEP_0, SEP_1, SEP_2, */ static long randtbl[ DEG_3 + 1 ] = { TYPE_3, - 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, - 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, - 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, - 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, - 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, - 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, - 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, + 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, + 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, + 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, + 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, + 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, + 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, + 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 0x27fb47b9 }; /* @@ -344,7 +345,7 @@ long random() { long i; - + if( rand_type == TYPE_0 ) { i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff; } @@ -362,4 +363,4 @@ random() return( i ); } -#endif NO_RANDOM +#endif /* NO_RANDOM */ diff --git a/src/games/fortune/strfile.c b/src/games/fortune/strfile.c index 00ce2aa..b607b3d 100644 --- a/src/games/fortune/strfile.c +++ b/src/games/fortune/strfile.c @@ -1,6 +1,16 @@ -# include -# include -# include "strfile.h" +#include +#ifdef CROSS +# include +# include +#else +# include +# include +#endif +#include +#include +#include +#include +#include "strfile.h" /* * This program takes a file composed of strings seperated by @@ -18,7 +28,7 @@ * the run. * v - Verbose. Give summary of data processed. (Default) * o - order the strings in alphabetic order - * i - if ordering, ignore case + * i - if ordering, ignore case * r - randomize the order of the strings * * Ken Arnold Sept. 7, 1978 -- @@ -31,10 +41,10 @@ * Added ordering options. */ -# define TRUE 1 -# define FALSE 0 +#define TRUE 1 +#define FALSE 0 -# define DELIM_CH '-' +#define DELIM_CH '-' typedef struct { char first; @@ -71,13 +81,187 @@ STRFILE Tbl; /* statistics table */ STR *Firstch; /* first chars of each string */ -char *fgets(), *malloc(), *strcpy(), *strcat(); +/* + * This routine evaluates arguments from the command line + */ +void getargs(int ac, char **av) +{ + register char *sp; + register int i; + register int bad, j; -long ftell(); + bad = 0; + for (i = 1; i < ac; i++) + if (*av[i] == '-' && av[i][1]) { + for (sp = &av[i][1]; *sp; sp++) + switch (*sp) { + case 'c': /* new delimiting char */ + if ((Delimch = *++sp) == '\0') { + --sp; + Delimch = *av[++i]; + } + if (Delimch <= 0 || Delimch > '~' || + Delimch == DELIM_CH) { + printf("bad delimiting character: '\\%o\n'", + Delimch); + bad++; + } + break; + case 's': /* silent */ + Sflag++; + break; + case 'v': /* verbose */ + Sflag = 0; + break; + case 'o': /* order strings */ + Oflag++; + break; + case 'i': /* ignore case in ordering */ + Iflag++; + break; + case 'r': /* ignore case in ordering */ + Rflag++; + break; + default: /* unknown flag */ + bad++; + printf("bad flag: '%c'\n", *sp); + break; + } + } + else if (*av[i] == '-') { + for (j = 0; Usage[j]; j++) + puts(Usage[j]); + exit(0); + } + else if (Infile) + (void) strcpy(Outfile, av[i]); + else + Infile = av[i]; + if (!Infile) { + bad++; + puts("No input file name"); + } + if (*Outfile == '\0' && !bad) { + (void) strcpy(Outfile, Infile); + (void) strcat(Outfile, ".dat"); + } + if (bad) { + puts("use \"strfile -\" to get usage"); + exit(-1); + } +} -main(ac, av) -int ac; -char **av; +/* + * do_order: + * Order the strings alphabetically (possibly ignoring case). + */ +void do_order(long *seekpts, FILE *outf) +{ + register int i; + register long *lp; + register STR *fp; + extern int cmp_str(); + + (void) fflush(outf); + Sort_1 = fopen(Outfile, "r"); + Sort_2 = fopen(Outfile, "r"); + Seekpts = seekpts; + qsort((char *) Firstch, Tbl.str_numstr, sizeof *Firstch, cmp_str); + i = Tbl.str_numstr; + lp = seekpts; + fp = Firstch; + while (i--) + *lp++ = fp++->pos; + (void) fclose(Sort_1); + (void) fclose(Sort_2); + Tbl.str_flags |= STR_ORDERED; +} + +/* + * cmp_str: + * Compare two strings in the file + */ +int cmp_str(STR *p1, STR *p2) +{ + register int c1, c2; + + c1 = p1->first; + c2 = p2->first; + if (c1 != c2) + return c1 - c2; + + (void) fseek(Sort_1, p1->pos, 0); + (void) fseek(Sort_2, p2->pos, 0); + + while (!isalnum(c1 = getc(Sort_1)) && c1 != '\0') + continue; + while (!isalnum(c2 = getc(Sort_2)) && c2 != '\0') + continue; + + while (c1 != '\0' && c2 != '\0') { + if (Iflag) { + if (isupper(c1)) + c1 = tolower(c1); + if (isupper(c2)) + c2 = tolower(c2); + } + if (c1 != c2) + return c1 - c2; + c1 = getc(Sort_1); + c2 = getc(Sort_2); + } + return c1 - c2; +} + +/* + * randomize: + * Randomize the order of the string table. We must be careful + * not to randomize across delimiter boundaries. All + * randomization is done within each block. + */ +void randomize(long *seekpts) +{ + register int cnt, i, j, start; + register long tmp; + register long *origsp; + + Tbl.str_flags |= STR_RANDOM; + srandom(time((long *) NULL) + getpid()); + origsp = seekpts; + for (j = 0; j <= Delim; j++) { + + /* + * get the starting place for the block + */ + + if (j == 0) + start = 0; + else + start = Tbl.str_delims[j - 1]; + + /* + * get the ending point + */ + + if (j == Delim) + cnt = Tbl.str_numstr; + else + cnt = Tbl.str_delims[j]; + + /* + * move things around randomly + */ + + for (seekpts = &origsp[start]; cnt > start; cnt--, seekpts++) { + i = random() % (cnt - start); + tmp = seekpts[0]; + seekpts[0] = seekpts[i]; + seekpts[i] = tmp; + } + } +} + +int main(int ac, char **av) { register char *sp, dc; register long *lp; @@ -206,189 +390,3 @@ char **av; } exit(0); } - -/* - * This routine evaluates arguments from the command line - */ -getargs(ac, av) -register int ac; -register char **av; -{ - register char *sp; - register int i; - register int bad, j; - - bad = 0; - for (i = 1; i < ac; i++) - if (*av[i] == '-' && av[i][1]) { - for (sp = &av[i][1]; *sp; sp++) - switch (*sp) { - case 'c': /* new delimiting char */ - if ((Delimch = *++sp) == '\0') { - --sp; - Delimch = *av[++i]; - } - if (Delimch <= 0 || Delimch > '~' || - Delimch == DELIM_CH) { - printf("bad delimiting character: '\\%o\n'", - Delimch); - bad++; - } - break; - case 's': /* silent */ - Sflag++; - break; - case 'v': /* verbose */ - Sflag = 0; - break; - case 'o': /* order strings */ - Oflag++; - break; - case 'i': /* ignore case in ordering */ - Iflag++; - break; - case 'r': /* ignore case in ordering */ - Rflag++; - break; - default: /* unknown flag */ - bad++; - printf("bad flag: '%c'\n", *sp); - break; - } - } - else if (*av[i] == '-') { - for (j = 0; Usage[j]; j++) - puts(Usage[j]); - exit(0); - } - else if (Infile) - (void) strcpy(Outfile, av[i]); - else - Infile = av[i]; - if (!Infile) { - bad++; - puts("No input file name"); - } - if (*Outfile == '\0' && !bad) { - (void) strcpy(Outfile, Infile); - (void) strcat(Outfile, ".dat"); - } - if (bad) { - puts("use \"strfile -\" to get usage"); - exit(-1); - } -} - -/* - * do_order: - * Order the strings alphabetically (possibly ignoring case). - */ -do_order(seekpts, outf) -long *seekpts; -FILE *outf; -{ - register int i; - register long *lp; - register STR *fp; - extern int cmp_str(); - - (void) fflush(outf); - Sort_1 = fopen(Outfile, "r"); - Sort_2 = fopen(Outfile, "r"); - Seekpts = seekpts; - qsort((char *) Firstch, Tbl.str_numstr, sizeof *Firstch, cmp_str); - i = Tbl.str_numstr; - lp = seekpts; - fp = Firstch; - while (i--) - *lp++ = fp++->pos; - (void) fclose(Sort_1); - (void) fclose(Sort_2); - Tbl.str_flags |= STR_ORDERED; -} - -/* - * cmp_str: - * Compare two strings in the file - */ -cmp_str(p1, p2) -STR *p1, *p2; -{ - register int c1, c2; - - c1 = p1->first; - c2 = p2->first; - if (c1 != c2) - return c1 - c2; - - (void) fseek(Sort_1, p1->pos, 0); - (void) fseek(Sort_2, p2->pos, 0); - - while (!isalnum(c1 = getc(Sort_1)) && c1 != '\0') - continue; - while (!isalnum(c2 = getc(Sort_2)) && c2 != '\0') - continue; - - while (c1 != '\0' && c2 != '\0') { - if (Iflag) { - if (isupper(c1)) - c1 = tolower(c1); - if (isupper(c2)) - c2 = tolower(c2); - } - if (c1 != c2) - return c1 - c2; - c1 = getc(Sort_1); - c2 = getc(Sort_2); - } - return c1 - c2; -} - -/* - * randomize: - * Randomize the order of the string table. We must be careful - * not to randomize across delimiter boundaries. All - * randomization is done within each block. - */ -randomize(seekpts) -register long *seekpts; -{ - register int cnt, i, j, start; - register long tmp; - register long *origsp; - - Tbl.str_flags |= STR_RANDOM; - srnd(time((long *) NULL) + getpid()); - origsp = seekpts; - for (j = 0; j <= Delim; j++) { - - /* - * get the starting place for the block - */ - - if (j == 0) - start = 0; - else - start = Tbl.str_delims[j - 1]; - - /* - * get the ending point - */ - - if (j == Delim) - cnt = Tbl.str_numstr; - else - cnt = Tbl.str_delims[j]; - - /* - * move things around randomly - */ - - for (seekpts = &origsp[start]; cnt > start; cnt--, seekpts++) { - i = rnd(cnt - start); - tmp = seekpts[0]; - seekpts[0] = seekpts[i]; - seekpts[i] = tmp; - } - } -}