walls@killer.UUCP (Monty Walls) (02/11/88)
-------------------------------------------------------------------------- Enclosed is tsort (source & man), lorder (source, man & exe), ar (reposting of v7 compatible source & man), libupack (diff fixes bug). Some slight changes had to be made to my original posting of ar to support a 'pv' option. The addition of support for 'pv' in ar allows lorder to read in a simple way ar archives. If you want to recompile lorder you will need the decus lex program (check your local bbs it should already be posted on one of them. minix can run & compile it). -Monty Walls ------------------------CUT HERE------------------------------------------ echo x - ar.c gres '^X' '' > ar.c << '/' X/* ar - archiver Author: Michiel Huisjes */ X/* V7 upgrade Author: Monty Walls */ X X/* X * Usage: ar 'key' [posname] archive [file] ... X * X * where 'key' is one of: qrqtpmx X * X * q: quickly append to the end of the archive file X * m: move named files X * r: replace (append when not in archive) X * d: delete X * t: print contents of archive X * p: print named files X * x: extract X * X * concatencated with one or more of: vuaibcl X * X * l: local temporary file for work instead of /tmp/ar.$$$$$ X * v: verbose X * a: after 'posname' X * b: before 'posname' X * i: before 'posname' X * c: create (suppresses creation message) X * u: replace only if dated later than member in archive X */ X X/* mods: X * 1.2 upgrade. X * local directory support (mrw). X * full V7 functionality + complete rewrite (mrw). X * changed verbose mode to give member name on print (mrw). X * X * notes: X * pdp11 long format & Intel long format are different. X */ X X/* include files */ X#include <stdio.h> X#include <sys/stat.h> X#include <signal.h> X#include <ar.h> X X/* macro functions */ X#define FOREVER (32766) X#define odd(nr) (nr & 1) X#define even(nr) (odd(nr) ? nr + 1 : nr) X#define quit(pid,sig) (kill(pid,sig),sleep(FOREVER)) X#ifndef tell X# define tell(f) (lseek(f, 0l, 1)) X#endif X X/* option switches */ X/* major options */ X#define EXTRACT 0x01 X#define REPLACE 0x02 X#define PRINT 0x04 X#define TABLE 0x08 X#define DELETE 0x10 X#define APPEND 0x20 X#define MOVE 0x40 X X/* minor options */ X#define BEFORE 0x01 X#define AFTER 0x02 X#define LOCAL 0x01 X#define VERBOSE 0x01 X#define CREATE 0x01 X#define ONLY 0x01 X X/* mode bits maps */ X#define EXEC_OWNER 00001 X#define EXEC_GROUP 00010 X#define EXEC_ALL 00100 X#define READ_OWNER 00004 X#define READ_GROUP 00040 X#define READ_ALL 00400 X#define WRITE_OWNER 00002 X#define WRITE_GROUP 00020 X#define WRITE_ALL 00200 X#define SET_UID 04000 X#define SET_GID 02000 X X/* global defines */ X#define BUFFERSIZE 4096 X#define WRITE 2 /* both read & write */ X#define READ 0 X#define MAGICSIZE sizeof(short) /* size of magic number in file */ X X/* option switches */ Xchar verbose = 0; Xchar local = 0; Xchar create = 0; Xchar only = 0; Xchar major = 0; Xchar minor = 0; X X/* global variables */ Xchar *tmp1; Xchar *tmp2; Xchar *progname; Xchar *posname = NULL; Xchar *afile; Xchar buffer[BUFFERSIZE]; Xlong pos_offset = -1; Xint mypid; X X/* keep track of member moves using this struct */ Xstruct mov_list { X long pos; X struct mov_list *next; X} *moves = NULL; X X/* forward declarations and external references */ Xextern char *malloc(); Xextern char *mktemp(), *rindex(); Xextern int strcmp(); Xextern print_date(); Xextern user_abort(), usage(); Xextern long lseek(); X Xint Xmain(argc, argv) Xint argc; Xchar **argv; X{ X int ac, opts_seen = 0, rc; X char *av; X X progname = argv[0]; X if (argc < 3) X usage(); X X for (av = argv[1]; *av; ++av) { X switch (*av) { /* major option */ X case 'q': X major |= APPEND; X ++opts_seen; X break; X case 'r': X major |= REPLACE; X ++opts_seen; X break; X case 'x': X major |= EXTRACT; X ++opts_seen; X break; X case 'p': X major |= PRINT; X ++opts_seen; X break; X case 'm': X major |= MOVE; X ++opts_seen; X break; X case 'd': X major |= DELETE; X ++opts_seen; X break; X case 't': X major |= TABLE; X ++opts_seen; X break; X case 'l': X local |= LOCAL; X break; X case 'a': X minor |= AFTER; X break; X case 'i': X case 'b': X minor |= BEFORE; X break; X case 'v': X verbose |= VERBOSE; X break; X case 'c': X create |= CREATE; X break; X case 'u': X only |= ONLY; X break; X default: X usage(); X } X } X X if (opts_seen != 1) X usage(); X X /* now do edits on options */ X if (!(major & (REPLACE | MOVE))) { X if (minor & (AFTER | BEFORE)) X usage(); X } X else if (major & MOVE) { X if (!(minor & (AFTER | BEFORE))) X usage(); X } X else if (only & ONLY) X if (!(major & REPLACE)) X usage(); X X if (local) X tmp1 = mktemp("./ar.1.XXXXXX"); X else X tmp1 = mktemp("/tmp/ar.1.XXXXXX"); X X /* now if minor says AFTER or BEFORE - then get posname */ X if (minor & (AFTER | BEFORE) && argc >= 4) { X posname = argv[2]; X afile = argv[3]; X ac = 4; X } X else { X posname = (char *)NULL; X afile = argv[2]; X ac = 3; X } X X /* exit logic consists of doing a kill on my pid to insure that we */ X /* get the current clean up and exit logic */ X mypid = getpid(); X signal(SIGINT, user_abort); X X switch (major) { X case REPLACE: X case DELETE: X case MOVE: X ar_members(ac, argc, argv); X break; X case EXTRACT: X case TABLE: X case PRINT: X ar_common(ac, argc, argv); X break; X case APPEND: X append_members(ac, argc, argv); X break; X default: X usage(); X } X X for (rc = 0; ac < argc; ++ac) { X if (*argv[ac] != '\0') { X /* no processing done on this name */ X fprintf(stderr,"Error %s: %s not found in ar\n", progname, argv[ac]); X rc = 1; X } X } X fflush(stdout); X exit(rc); X} X Xusage() X{ X fprintf(stderr,"Usage: %s [qrxdpmt][abivulc] [posname] afile name ... \n",progname); X exit(1); X} X Xuser_abort() X{ X unlink(tmp1); X exit(1); X} X Xinsert_abort() X{ X unlink(tmp1); X unlink(tmp2); X exit(1); X} X Xmwrite(fd, address, bytes) Xint fd; Xregister char *address; Xregister int bytes; X{ X if (write(fd, address, bytes) != bytes) { X fprintf(stderr," Error: %s - Write error\n",progname); X quit(mypid, SIGINT); X } X} X Xlong Xswap(l) Xlong l; X{ X union { X struct { X int word1, word2; X } words; X long n; X } u_in, u_out; X X u_in.n = l; X u_out.words.word1 = u_in.words.word2; X u_out.words.word2 = u_in.words.word1; X return (u_out.n); X X} X Xaddmove(pos) Xlong pos; X{ X struct mov_list *newmove; X X newmove = (struct mov_list *)malloc(sizeof(struct mov_list)); X newmove->pos = pos; X newmove->next = moves; X moves = newmove; X} X Xstruct ar_hdr * Xget_member(fd) Xint fd; X{ X int ret; X static struct ar_hdr member; X X if ((ret = read(fd, &member, sizeof(struct ar_hdr))) <= 0) X return ((struct ar_hdr *)NULL); X if (ret != sizeof(struct ar_hdr)) { X fprintf(stderr,"Error: ar corrupted archive ar\n"); X quit(mypid,SIGINT); X } X X /* the archive long format is pdp11 not intel X * therefore we must reformat them for our internal use X */ X X member.ar_date = swap(member.ar_date); X member.ar_size = swap(member.ar_size); X return (&member); X} X Xint Xopen_archive(filename, opt, to_create) Xchar *filename; Xint opt; X{ X static unsigned short magic; X int fd; X X /* to_create can have values of 0,1,2 */ X /* 0 - don't create a file. */ X /* 1 - create file but use create switch message mode */ X /* 2 - create file but don't talk about it */ X X if (to_create) { X if ((fd = creat(filename, 0644)) < 0) { X fprintf(stderr, "Error: %s can not create %s\n",progname, filename); X quit(mypid,SIGINT); X } X if (!create && to_create == 1) fprintf(stderr, "%s:%s created\n", progname, filename); X magic = ARMAG; X mwrite(fd, &magic, MAGICSIZE); X return (fd); X } X else { X if ((fd = open(filename, opt)) < 0) { X if (opt == WRITE) X return (open_archive(filename, opt, 1)); X else { X fprintf(stderr, "Error: %s can not open %s\n",progname, filename); X quit(mypid,SIGINT); X } X } X /* now check the magic number for ar V7 file */ X lseek(fd, 0l, 0); X read(fd, &magic, MAGICSIZE); X if (magic != ARMAG) { X fprintf(stderr, "Error: not %s V7 format - %s\n",progname, filename); X quit(mypid,SIGINT); X } X if (major & APPEND) X lseek(fd, 0l, 2); /* seek eof position */ X X return (fd); X } X} X X Xint Xrebuild(fd, tempfd) Xregister int fd, tempfd; X{ X register int n; X X /* after we have built the archive to a temporary file and */ X /* everything has worked out- we copy the archive back to */ X /* original file */ X X signal(SIGINT, SIG_IGN); X close(fd); X close(tempfd); X fd = open_archive(afile, WRITE, 2); X tempfd = open_archive(tmp1, WRITE, 0); X while ((n = read(tempfd, buffer, BUFFERSIZE)) > 0) X mwrite(fd, buffer, n); X close(tempfd); X unlink(tmp1); X return (fd); X} X Xprint_mode(mode) Xshort mode; X{ X char g_ex, o_ex, all_ex; X char g_rd, o_rd, all_rd; X char g_wr, o_wr, all_wr; X X g_ex = EXEC_GROUP & mode ? 'x' : '-'; X o_ex = EXEC_OWNER & mode ? 'x' : '-'; X all_ex = EXEC_ALL & mode ? 'x' : '-'; X X g_ex = SET_GID & mode ? 's' : g_ex; X o_ex = SET_UID & mode ? 's' : o_ex; X X g_rd = READ_GROUP & mode ? 'r' : '-'; X o_rd = READ_OWNER & mode ? 'r' : '-'; X all_rd = READ_ALL & mode ? 'r' : '-'; X X g_wr = WRITE_GROUP & mode ? 'w' : '-'; X o_wr = WRITE_OWNER & mode ? 'w' : '-'; X all_wr = WRITE_ALL & mode ? 'w' : '-'; X X fprintf(stdout,"%c%c%c",o_rd, o_wr, o_ex); X fprintf(stdout,"%c%c%c",g_rd, g_wr, g_ex); X fprintf(stdout,"%c%c%c",all_rd, all_wr, all_ex); X} X Xprint_header(member) Xstruct ar_hdr *member; X{ X if (verbose) { X print_mode(member->ar_mode); X fprintf(stdout,"%3.3d",member->ar_uid); X fprintf(stdout,"/%-3.3d ",member->ar_gid); X fprintf(stdout,"%5.5d",member->ar_size); X print_date(member->ar_date); X } X fprintf(stdout,"%-14.14s\n",member->ar_name); X} X Xprint(fd,member) Xint fd; Xstruct ar_hdr *member; X{ X int outfd; X register int cnt, ret; X int do_align; X X if (major & EXTRACT) { X if ((outfd = creat(member->ar_name,0666)) < 0) { X fprintf(stderr,"Error: %s could not creat %s\n",progname, member->ar_name); X quit(mypid,SIGINT); X } X if (verbose) X fprintf(stdout,"x - %s\n",member->ar_name); X } X else { X if (verbose) { X fprintf(stdout,"p - %s\n",member->ar_name); X fflush(stdout); X } X outfd = fileno(stdout); X } X X for (cnt = member->ar_size; cnt > 0; cnt -= ret) { X ret = read(fd, buffer, (cnt < BUFFERSIZE ? cnt : BUFFERSIZE)); X if (ret > 0) X write(outfd,buffer, ret); X } X if (odd(member->ar_size)) X lseek(fd,1l,1); /* realign ourselves */ X X if (major & EXTRACT) { X close(outfd); X chmod(member->ar_name, member->ar_mode); X } X} X X/* copy a given member from fd1 to fd2 */ Xcopy_member(infd, outfd, member) Xint infd, outfd; Xstruct ar_hdr *member; X{ X int n, cnt; X long m, size; X X /* save copies for our use */ X m = size = member->ar_size; X X /* format for disk usage */ X member->ar_size = swap(member->ar_size); X member->ar_date = swap(member->ar_date); X X mwrite(outfd, member, sizeof(struct ar_hdr)); X for (; m > 0; m -= n) { X cnt = (m < BUFFERSIZE ? m : BUFFERSIZE); X if ((n = read(infd, buffer, cnt)) != cnt) { X fprintf(stderr,"Error: %s - read error on %s\n",progname, member->ar_name); X quit(mypid, SIGINT); X } X mwrite(outfd, buffer, n); X } X if (odd(size)) { /* pad to word boundary */ X mwrite(outfd, buffer, 1); X lseek(infd,1l,1); /* realign reading fd */ X } X} X X/* insert at current offset - name file */ Xinsert(fd, name, mess, oldmember) Xint fd; Xchar *name, *mess; Xstruct ar_hdr *oldmember; X{ X static struct ar_hdr member; X static struct stat status; X int in_fd; X X if (stat(name, &status) < 0) { X fprintf(stderr,"Error: %s cannot find file %s\n",progname,name); X quit(mypid,SIGINT); X } X else if ((in_fd = open(name, READ)) < 0) { X fprintf(stderr,"Error: %s cannot open file %s\n",progname,name); X quit(mypid,SIGINT); X } X strcpy(member.ar_name, basename(name)); X member.ar_uid = status.st_uid; X member.ar_gid = status.st_gid; X member.ar_mode = status.st_mode & 07777; X member.ar_date = status.st_mtime; X member.ar_size = status.st_size; X if (only & ONLY) X if (oldmember != (struct ar_hdr *)NULL) X if (member.ar_date <= oldmember->ar_date) { X close(in_fd); X if (verbose) fprintf(stdout, "not %s - %s\n",mess, name); X return (-1); X } X X copy_member(in_fd, fd, &member); X if (verbose) X fprintf(stdout, "%s - %s\n",mess, name); X close(in_fd); X return (1); X} X Xint Xar_move(oldfd, arfd,mov) Xint oldfd, arfd; Xstruct mov_list *mov; X{ X long pos; X int cnt, want, a, newfd; X struct ar_hdr *member; X X if (local) X tmp2 = mktemp("./ar.2.XXXXXX"); X else X tmp2 = mktemp("/tmp/ar.2.XXXXXX"); X X close(oldfd); /* close old temp file */ X signal(SIGINT, insert_abort); /* set new signal handler */ X newfd = open_archive(tmp2, WRITE, 2); /* open new tmp file */ X oldfd = open_archive(tmp1, WRITE, 0); /* reopen old tmp file */ X X /* copy archive till we get to pos_offset */ X for (pos = pos_offset; pos > 0; pos -= cnt) { X want = (pos < BUFFERSIZE ? pos : BUFFERSIZE); X if ((cnt = read(oldfd, buffer, want)) > 0) X mwrite(newfd, buffer, cnt); X } X /* if minor = 'a' then skip over posname */ X if (minor & AFTER) { X if ((member = get_member(oldfd)) != NULL) X copy_member(oldfd, newfd, member); X } X /* move members in the library */ X while (mov != NULL) { X lseek(arfd, mov->pos, 0); X if ((member = get_member(arfd)) != NULL) X copy_member(arfd, newfd, member); X mov = mov->next; X if (verbose) fprintf(stdout, "m - %s\n", member->ar_name); X } X X /* copy rest of library into new tmp file */ X while ((member = get_member(oldfd)) != NULL) X copy_member(oldfd, newfd, member); X X /* detach old temp file */ X close(oldfd); X unlink(tmp1); X X /* change context temp file */ X tmp1 = tmp2; X return (newfd); X} X Xint Xar_insert(oldfd, ac, argc, argv) Xint oldfd; Xint ac, argc; Xchar **argv; X{ X long pos; X int cnt, want, a, newfd; X struct ar_hdr *member; X X if (local) X tmp2 = mktemp("./ar.2.XXXXXX"); X else X tmp2 = mktemp("/tmp/ar.2.XXXXXX"); X X close(oldfd); /* close old temp file */ X signal(SIGINT, insert_abort); /* set new signal handler */ X newfd = open_archive(tmp2, WRITE, 2); /* open new tmp file */ X oldfd = open_archive(tmp1, WRITE, 0); /* reopen old tmp file */ X X /* copy archive till we get to pos_offset */ X for (pos = pos_offset; pos > 0; pos -= cnt) { X want = (pos < BUFFERSIZE ? pos : BUFFERSIZE); X if ((cnt = read(oldfd, buffer, want)) > 0) X mwrite(newfd, buffer, cnt); X } X /* if minor = 'a' then skip over posname */ X if (minor & AFTER) { X if ((member = get_member(oldfd)) != NULL) X copy_member(oldfd, newfd, member); X } X X /* copy new members into the library */ X for (a = ac+1; a <= argc; ++a) X if (argv[a-1] && *argv[a-1] != '\0') { X insert(newfd, argv[a-1], "a", (struct ar_hdr *)NULL); X *argv[a-1] = '\0'; X } X X /* copy rest of library into new tmp file */ X while ((member = get_member(oldfd)) != NULL) X copy_member(oldfd, newfd, member); X X /* detach old temp file */ X close(oldfd); X unlink(tmp1); X X /* change context temp file */ X tmp1 = tmp2; X return (newfd); X} X Xar_common(ac, argc, argv) Xint ac, argc; Xchar **argv; X{ X int a, fd; X struct ar_hdr *member; X X fd = open_archive(afile, READ, 0); X while ((member = get_member(fd)) != NULL) { X if (ac < argc) { X for (a = ac+1; a <= argc; ++a) { X if (strcmp(basename(argv[a-1]),member->ar_name) == 0) { X if (major & TABLE) X print_header(member); X else if (major & (PRINT | EXTRACT)) X print(fd, member); X *argv[a-1] = '\0'; X break; X } X else if (major & (PRINT | EXTRACT)) X lseek(fd, (long)even(member->ar_size), 1); X } X } X else { X if (major & TABLE) X print_header(member); X else if (major & (PRINT | EXTRACT)) X print(fd, member); X } X if (major & TABLE) X lseek(fd, (long)even(member->ar_size), 1); X } X} X Xar_members(ac, argc, argv) Xint ac, argc; Xchar **argv; X{ X int a, fd, tempfd, rc; X struct ar_hdr *member; X long *lpos; X X fd = open_archive(afile, WRITE, 0); X tempfd = open_archive(tmp1, WRITE, 2); X while ((member = get_member(fd)) != NULL) { X X /* if posname specified check for our member */ X /* if our member save his starting pos in our working file*/ X if (posname && strcmp(posname, member->ar_name) == 0) X pos_offset = tell(tempfd) - MAGICSIZE; X X if (ac < argc) { /* we have a list of members to check */ X for (a = ac+1; a <= argc; ++a) X if (strcmp(basename(argv[a-1]),member->ar_name) == 0) { X if (major & REPLACE) { X if (insert(tempfd,argv[a-1],"r", member) < 0) X copy_member(fd, tempfd, member); X else X lseek(fd, (long)even(member->ar_size), 1); X } X else if (major & MOVE) { X /* cheat by saving pos in archive */ X addmove((tell(fd) - sizeof(struct ar_hdr))); X lseek(fd, (long)even(member->ar_size), 1); X } X *argv[a-1] = '\0'; X break; X } X } X if (ac >= argc || a > argc) /*nomatch on a member name */ X copy_member(fd, tempfd, member); X else if (major & DELETE) { X if (verbose) fprintf(stdout,"d - %s\n",member->ar_name); X lseek(fd, (long)even(member->ar_size), 1); X } X } X if (major & MOVE) { X if (posname == NULL) X pos_offset = lseek(fd, 0l, 2); X else if (pos_offset == (-1)) { X fprintf(stderr,"Error: %s cannot find file %s\n",progname,posname); X quit(mypid,SIGINT); X } X tempfd = ar_move(tempfd, fd, moves); X } X else if (major & REPLACE) { X /* take care to add left overs */ X /* if the posname is not found we just add to end of ar */ X if (posname && pos_offset != (-1)) { X tempfd = ar_insert(tempfd, ac, argc, argv); X } X else { X for (a = ac+1; a <= argc; ++a) X if (*argv[a-1]) { X insert(tempfd, argv[a-1], "a", (struct ar_hdr *)NULL); X *argv[a-1] = '\0'; X } X } X } X fd = rebuild(fd, tempfd); X close(fd); X} X Xappend_members(ac, argc, argv) Xint ac, argc; Xchar **argv; X{ X int a, fd; X struct ar_hdr *member; X X /* quickly append members don't worry about dups in ar */ X fd = open_archive(afile, WRITE, 0); X if (ac < argc) { X if (odd(lseek(fd, 0l, 2))) X mwrite(fd, buffer, 1); X /* while not end of member list insert member at end */ X for (a = ac+1; a <= argc; ++a) { X insert(fd, argv[a-1], "a", (struct ar_hdr *)NULL); X *argv[a-1] = '\0'; X } X } X close(fd); X} X / echo x - ar.h gres '^X' '' > ar.h << '/' X/* ar.c header file V7 */ X X#define ARMAG 0177545l Xstruct ar_hdr { X char ar_name[14]; X long ar_date; /* not Intel format */ X char ar_uid; X char ar_gid; X int ar_mode; X long ar_size; /* not Intel format */ X}; / echo x - basename.c gres '^X' '' > basename.c << '/' X#include <stdio.h> X Xchar *basename(path) Xchar *path; X{ X register char *ptr = path; X register char *last = (char *)NULL; X X while (*ptr != '\0') { X if (*ptr == '/') X last = ptr; X ptr++; X } X if (last == (char *)NULL) X return path; X if (*(last + 1) == '\0') { X *last = '\0'; X return basename(path); X } X return last + 1; X} / echo x - date.c gres '^X' '' > date.c << '/' X#include <stdio.h> X X#define MINUTE 60L X#define HOUR (60L * MINUTE) X#define DAY (24L * HOUR) X#define YEAR (365L * DAY) X#define LYEAR (366L * DAY) X Xint mo[] = { X 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 X}; X Xchar *moname[] = { X " Jan ", " Feb ", " Mar ", " Apr ", " May ", " Jun ", X " Jul ", " Aug ", " Sep ", " Oct ", " Nov ", " Dec " X}; X X/* Print the date. This only works from 1970 to 2099. */ Xprint_date(t) Xlong t; X{ X int i, year, day, month, hour, minute; X long length, time(), original; X X year = 1970; X original = t; X while (t > 0) { X length = (year % 4 == 0 ? LYEAR : YEAR); X if (t < length) X break; X t -= length; X year++; X } X X /* Year has now been determined. Now the rest. */ X day = (int) (t / DAY); X t -= (long) day * DAY; X hour = (int) (t / HOUR); X t -= (long) hour * HOUR; X minute = (int) (t / MINUTE); X X /* Determine the month and day of the month. */ X mo[1] = (year % 4 == 0 ? 29 : 28); X month = 0; X i = 0; X while (day >= mo[i]) { X month++; X day -= mo[i]; X i++; X } X X /* At this point, 'year', 'month', 'day', 'hour', 'minute' ok */ X fprintf(stdout, "%s%2.2d ",moname[month],++day); X if (time((long *)NULL) - original >= YEAR / 2L) X fprintf(stdout,"%4.4D ",(long)year); X else X fprintf(stdout,"%02.2d:%02.2d ",hour, minute); X} X / echo x - lorder.lxi gres '^X' '' > lorder.lxi << '/' X%{ X/* X * lorder: find ordering relations for object library X * X * author: Monty Walls X * written: 1/29/88 X * Copyright: Copyright (c) 1988 by Monty Walls. X * Not derived from licensed software. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). This notice must remain intact. X * 2). The author is not responsible for the consequences of use X * this software, no matter how awful, even if they X * arise from defects in it. X * 3). Altered version must not be represented as being the X * original software. X * X * change log: X * X */ X X#include <ctype.h> X#include <signal.h> X#include <ar.h> X X#define MAXLINE 256 X Xchar *yyfile; Xchar *tmpfile; Xchar *progname; Xint toklen; Xchar token[MAXLINE], *cp; Xchar template[] = "lorder.XXXXXX"; X Xstruct filelist { X char *name; X struct filelist *next; X}; X Xstruct node { X char *name; X char *file; X struct filelist *list; X struct node *left, *right; X}; X Xstruct filelist *list; Xstruct node *tree, *lastnode; Xextern char *malloc(), *mktemp(); Xextern FILE *popen(), *fopen(); Xextern char *addfile(); Xextern FILE *lexin; Xextern void user_abort(); X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X int i; X char cmdstr[MAXLINE]; X X if (argc > 1) { X progname = argv[0]; X signal(SIGINT, user_abort); X for (i = 1; argv[i] && *argv[i]; ++i ) { X /* the following code is caused by X * not enough memory on floppy systems. X * X * so instead of ar | libupack ->to us. we use X * ar >tmpfle; libupack <tmpfile ->to us X */ X if (is_liba(argv[i])) { X tmpfile = mktemp(template); X sprintf(cmdstr,"ar pv %s >%s",argv[i],tmpfile); X system(cmdstr); X sprintf(cmdstr,"libupack <%s",tmpfile); X } X else { X yyfile = addfile(argv[i]); X sprintf(cmdstr, "libupack <%s", argv[i]); X } X if ((lexin = popen(cmdstr, "r")) != (FILE *)NULL) { X while (yylex()) ; X pclose(lexin); X if (tmpfile) X unlink(tmpfile); X } X else { X fprintf(stderr,"Error: %s could not open %s\n",progname, argv[i]); X exit(1); X } X llinit(); X } X printtree(tree); X /* then print list of files for ar also */ X for (; list; list = list->next) X fprintf(stdout,"%s %s\n",list->name, list->name); X } X else { X fprintf(stderr,"Usage: %s file ....\n",progname); X exit(1); X } X} X Xvoid Xuser_abort() X{ X unlink(tmpfile); X exit(1); X} X Xchar * Xxalloc(n) Xint n; X{ X char *p; X X if ((p = malloc(n)) == (char *)NULL) { X fprintf(stderr, "Error %s - out of memory\n", progname); X exit(1); X } X return (p); X} X Xint Xis_liba(s) /* error handling done later */ Xchar *s; X{ X unsigned short key; X FILE *fp; X int ret = 0; X X if ((fp = fopen(s,"r")) != (FILE *)NULL) { X fread(&key, sizeof(key), 1, fp); X if (key == ARMAG) ret = 1; X fclose(fp); X } X return (ret); X} X Xchar * Xstrsave(s) Xchar *s; X{ X char *p; X X p = xalloc(strlen(s) + 1); X strcpy(p,s); X return (p); X} X Xchar * Xaddfile(s) Xchar *s; X{ X struct filelist *p; X X p = (struct filelist *)xalloc(sizeof(struct filelist)); X p->name = strsave(s); X if (list) X p->next = list; X else X p->next = NULL; X list = p; X return (p->name); X} X Xprinttree(t) Xstruct node *t; X{ X struct filelist *fp; X X if (t) { X if (t->file) { X for (fp = t->list; fp && fp->name; fp = fp->next) X if (t->file != fp->name) X fprintf(stdout,"%s %s\n",t->file, fp->name); X } X printtree(t->right); X printtree(t->left); X } X} X X Xstruct node * Xfinddef(s) Xchar *s; X{ X struct node *n; X int cmp; X X if (tree) { X lastnode = n = tree; X while (n && n->name) { X lastnode = n; X if (!(cmp=strcmp(s,n->name))) X return (n); X else if (cmp > 0) X n = n->left; X else X n = n->right; X } X } X return ((struct node *)NULL); X} X Xstruct node * Xmakedef(s) Xchar *s; X{ X struct node *n; X int cmp; X X n = (struct node *)xalloc(sizeof(struct node)); X n->name = strsave(s); X n->left = (struct node *)NULL; X n->right = (struct node *)NULL; X if (tree) { X cmp = strcmp(s, lastnode->name); X if (cmp > 0) X lastnode->left = n; X else X lastnode->right = n; X } X else X tree = n; X X return (n); X} X Xvoid Xdodef(s) Xchar *s; X{ X struct node *n; X X if (n = finddef(s)) { X if (n->file != NULL) X fprintf(stderr,"Error %s - %s defined twice in %s and %s", progname, s, n->file, yyfile); X else X n->file = yyfile; X } X else { X n = makedef(s); X n->file = yyfile; X n->list = (struct filelist *)NULL; X } X} X Xvoid Xusedef(s) Xchar *s; X{ X struct node *n; X struct filelist *fp, *lastfp; X X if (n = finddef(s)) { X /* scan file list for match */ X if (n->list) { X for (fp = n->list; fp ; fp = fp->next) { X if (fp->name == yyfile) { X return; X } X lastfp = fp; X } X /* reached here with no match */ X lastfp->next = (struct filelist *)xalloc(sizeof(struct filelist)); X lastfp->next->name = yyfile; X lastfp->next->next = (struct filelist *)NULL; X } X else { X /* empty list so far */ X n->list = (struct filelist *)xalloc(sizeof(struct filelist)); X n->list->name = yyfile; X n->list->next = (struct filelist *)NULL; X } X } X else { X n = makedef(s); X n->file = (char *)NULL; X n->list = (struct filelist *) xalloc(sizeof(struct filelist)); X n->list->name = yyfile; X n->list->next = (struct filelist *)NULL; X } X} X X%} Xany = [^\t\n ]; Xmember = "p - " any*; Xname = '_'[a-zA-Z_][a-zA-Z0-9_]*; Xdotdefine = ".define" ' '* name; X%% Xmember { X toklen = lexlength() + 1; X gettoken(token, toklen); X yyfile = addfile(&token[4]); X } Xdotdefine { X toklen = lexlength() + 1; X gettoken(token,toklen); X for (cp = &token[7]; *cp && isspace(*cp); ++cp) X ; X if (*cp) X dodef(cp); X } Xname { X toklen = lexlength() + 1; X gettoken(token,toklen); X usedef(token); X } / echo x - makefile gres '^X' '' > makefile << '/' Xlib=-llex -laux X# decus lex rules X.lxi.c: X lex -e $* X Xlorder: lorder.s X cc -o lorder -i lorder.s $(lib) / echo x - tsort.c gres '^X' '' > tsort.c << '/' X/* X * tsort - do a topological sort on the ordered pairs of names X * X * syntax - tsort [ file ] X * X * based on the discussion in 'The AWK programming Language', by X * Aho, Kernighan, & Weinberger. X * X * author: Monty Walls X * written: 1/28/88 X * Copyright: Copyright (c) 1988 by Monty Walls. X * Not derived from licensed software. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). This notice must remain intact. X * 2). The author is not responsible for the consequences of use X * this software, no matter how awful, even if they X * arise from defects in it. X * 3). Altered version must not be represented as being the X * original software. X * X * change log: X * X * X */ X X#include <stdio.h> X#include <errno.h> X#include <ctype.h> X X#define printmem(_s) (fprintf(stdout,"%s ",(_s))) X#define MAXNAMELEN 32 X Xstruct dependents { X struct node *nd; X struct dependents *next; X}; X Xstruct node { X char *name; X struct dependents *pred; X struct node *left, *right; X}; X Xchar *progname; X Xextern struct node *readnode(), *findnode(); Xextern char *malloc(), *xalloc(), *readone(), *strsave(); Xextern struct dependents *finddep(); Xextern void dumptree(); X Xextern int errno; Xextern char *sys_errlist[]; X Xstruct node *tree, *lastnode; Xstruct dependents *lastpred; X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X progname = argv[0]; X if (argc > 1) X if (freopen(argv[1], "r", stdin) == (FILE *)NULL) { X fprintf(stderr,"Error: %s - %s\n",progname, sys_errlist[errno]); X exit(1); X } X X /* read in the tree of entries */ X while (readnode() != (struct node *)NULL) X ; X dumptree(tree); X fflush(stdout); X exit(0); X} X X Xstruct node * Xreadnode() X{ X char *s1, *s2; X register struct node *n1, *n2; X struct dependents *pd; X X if ((s1 = readone()) != (char *)NULL) { X if ((n1 = findnode(s1)) == (struct node *)NULL) { X /* is a new node so build it */ X n1 = (struct node *)xalloc(sizeof(struct node)); X n1->name = strsave(s1); X n1->pred = (struct dependents *)NULL; X n1->left = (struct node *)NULL; X n1->right = (struct node *)NULL; X linknode(n1); X } X if ((s2 = readone()) != (char *)NULL) { X if ((n2 = findnode(s2)) == (struct node *)NULL) { X /* is a new node so build it */ X n2 = (struct node *)xalloc(sizeof(struct node)); X n2->name = strsave(s2); X n2->pred = (struct dependents *)NULL; X n2->left = (struct node *)NULL; X n2->right = (struct node *)NULL; X linknode(n2); X } X if (finddep(n1->pred,s2) == (struct dependents *)NULL) { X /* new dependence here */ X pd = (struct dependents *)xalloc(sizeof(struct dependents)); X pd->nd = n2; X pd->next = (struct dependents *)NULL; X if (n1->pred == (struct dependents *)NULL) X n1->pred = pd; X else X lastpred->next = pd; X } X return (n1); X } X else X return ((struct node *)NULL); X } X else X return ((struct node *)NULL); X} X Xvoid Xdumptree(t) Xstruct node *t; X{ X register struct dependents *p; X register char *s; X X if (t) { X if (t->name) { X s = t->name; /* save name in s */ X t->name = (char *)NULL; /* mark this node as visited */ X for (p = t->pred; p != (struct dependents *)NULL; p = p->next) X dumptree(p->nd); X printmem(s); X } X dumptree(t->left); X dumptree(t->right); X } X} X Xchar * Xreadone() X{ X register int c, n = 0; X static char name[MAXNAMELEN]; X X /* eat up leading spaces */ X while ((c = getchar()) != EOF && isspace(c)) X ; X X if (c != EOF && !isspace(c)) X ungetc(c,stdin); X X while ((c = getchar()) != EOF && !isspace(c)) { X if (n < MAXNAMELEN) X name[n++] = c; X } X X if (c == EOF) X return ((char *)NULL); X X name[n] = '\0'; X return (name); X} X Xstruct node * Xfindnode(s) Xchar *s; X{ X register struct node *n; X register int cmp; X X if (tree) { X lastnode = n = tree; X while (n && n->name) { X lastnode = n; X if (!(cmp = strcmp(s,n->name))) X return (n); X else if (cmp > 0) X n = n->left; X else X n = n->right; X } X } X return ((struct node *)NULL); X} X Xstruct dependents * Xfinddep(dp, s) Xregister struct dependents *dp; Xregister char *s; X{ X lastpred = (struct dependents *)NULL; X while (dp && dp->nd) { X lastpred = dp; X if (strcmp(dp->nd->name,s) == 0) X return (dp); X else { X dp = dp->next; X } X } X return ((struct dependents *)NULL); X} X Xlinknode(n) Xregister struct node *n; X{ X register int cmp; X X if (tree) { X cmp = strcmp(n->name,lastnode->name); X if (cmp > 0) X lastnode->left = n; X else X lastnode->right = n; X } X else X tree = n; X} X Xchar * Xxalloc(n) Xint n; X{ X char *p; X X if ((p = malloc(n)) != (char *)NULL) X return (p); X else { X fprintf(stderr,"Error: %s out of memory\n",progname); X exit(1); X } X} X Xchar * Xstrsave(s) Xchar *s; X{ X char *p; X X p = xalloc(strlen(s)+1); X strcpy(p,s); X return (p); X} / echo x - tsort.man gres '^X' '' > tsort.man << '/' XNAME X tsort -- topological sort X XSYNOPSIS X tsort [file] X XDESCRIPTION X tsort performs a topological sort on the partially order pairs of X strings given as input. if no file is given standard input is X used. X The input consists of a list of pairs of strings separated by X blanks between strings and newlines between pairs. If the strings X of a pair is identical it indicates presence not ordering. X X XSEE ALSO X lorder (1) X XBUGS X build a simple btree of dependent chains the just walks the X tree(uses lots of memory). X X / echo x - libupack.diff gres '^X' '' > libupack.diff << '/' X122,123c122,123 X< #define IBUFSIZE 2000 X< #define OBUFSIZE 24000 X--- X> #define IBUFSIZE 10000 X> #define OBUFSIZE 30000 / echo x - lorder.uue gres '^X' '' > lorder.uue << '/' Xbegin 755 lorder.out XM 0,@!" @)@ 10H .$) ! ")XXL/@\,"B<A T> ! XMV*, %!34>@' (/$!E#HNQM5B>6![ (!@WX$ 7\#Z70!BUX&BQ^)'EH+N,$! XM4+@" %#HYR"#Q 3'1OX! (M&_M'@B<,#7@:#/P!U ^D/ 8M&_M'@B<,#7@:+ XM'X _ '4#Z?L BT;^T>")PP->!O\WZ)(!1$0)P'1*N ( 4.@:'T1$HUP+BT;^ XMT>")PP->!O\V7 O_-[B6!%"-AO[^4.AO$8/$"(V&_OY0Z) +1$3_-EP+N*0$ XM4(V&_OY0Z%(1@\0&ZR^+1O[1X(G# UX&_S?HN %$1*->"XM&_M'@B<,#7@;_ XM-[BR!%"-AO[^4.@A$8/$!KC !%"-AO[^4.B;"8/$!*-B"X,^8@L ="3H? 4) XMP'0"Z_?_-F(+Z(T*1$2#/EP+ '0R_S9<"^@((41$ZR>+1O[1X(G# UX&_S?_ XM-EH+N,($4/\V*@;HW R#Q BX 0!0Z'D:1$3HT ?_1O[IW_[_-E(*Z&T!1$2# XM/E0* '1"BQY4"HLV5 K_-_\TN. $4/\V* ;HH R#Q B+'E0*BU\"B1Y4"NO2 XM_S9:"[CH!%#_-BH&Z($,@\0&N $ 4.@>&D1$B>Q=PU6)Y?\V7 OH="!$1+@! XM %#H!1I$1(GL7<-5B>5,3/]V!.B!&T1$B4;^/0 =1O_-EH+N/X$4/\V*@;H XM- R#Q :X 0!0Z-$91$2+1OZ)[%W#58GE@^P&QT;Z "X& 50_W8$Z$@-@\0$ XMB4;\/0 =#3_=ORX 0!0N ( 4(U&_E#H0@R#Q @QP%#_=OY0N&7_4.B4(0G XM=07'1OH! /]V_.B,#$1$BT;ZB>Q=PU6)Y4Q,_W8$Z%T?1$1 4.A<_T1$B4;^ XM_W8$_W;^Z#0?@\0$BT;^B>Q=PU6)Y4Q,N 0 4.@X_T1$B4;^_W8$Z+__1$2+ XM7OZ)!X,^5 H = R+7OZ+#E0*B4\"ZPB+7O['1P( (M>_HD>5 J+7OZ+!XGL XM7<-5B>5,3(-^! !T9XM>!(-_ @!T2(M>!(M'!(E&_H-^_@!T.8M>_H,_ '0Q XMBUX$BW;^BP0Y1P)T&8M>_HMV!/\W_W0"N!H%4/\V* ;H!0N#Q B+7OZ+1P*) XM1O[KP8M>!/]W".B;_T1$BUX$_W<&Z)#_1$2)[%W#58GE@^P$@SY2"@!T6XL> XM4@J)7OZ+'E(*B1Y0"H-^_@!T1HM>_H,_ '0^BU[^B1Y0"HM>_O\W_W8$Z%H5 XM@\0$B4;\/0 =07_=O[K'X-^_ !^"XM>_HM'!HE&_NN_BU[^BT<(B4;^Z[0Q XMP%!8B>Q=PU6)Y8/L!+@* %#H"/Y$1(E&_O]V!.B/_D1$BU[^B0?'1P8 (M> XM_L='" @SY2"@!T+XL>4 K_-_]V!.CG%(/$!(E&_#T 'X,BQY0"HM&_HE' XM!NL3BQY0"HM&_HE'".L'BU[^B1Y2"HM&_HGL7<-5B>5,3/]V!.@5_T1$B4;^ XM/0 =#:+7OZ#?P( ="&+7O[_-EX+_W<"_W8$_S9:"[@B!5#_-BH&Z,,)@\0, XMZRF+7OZ+#EX+B4\"ZQW_=@3H/_]$1(E&_HM>_HL.7@N)3P*+7O['1P0 (GL XM7<-5B>6#[ ;_=@3HJ/Y$1(E&_CT '4#Z8( BU[^@W\$ '14BU[^BT<$B4;\ XM@W[\ '0@BU[\BPY>"SD/=02)[%W#BT;\B4;ZBU[\BT<"B4;\Z]JX! !0Z.'\ XM1$2+7OJ)1P*+7P*+#EX+B0^+7OJ+7P+'1P( .M;N 0 4.B\_$1$BU[^B4<$ XMBU\$BPY>"XD/BU[^BU\$QT<" #K-O]V!.B#_D1$B4;^BU[^QT<" "X! !0 XMZ(3\1$2+7OZ)1P2+7P2+#EX+B0^+7OZ+7P3'1P( (GL7<-5B>7_=@3IJ@"X XM 0!0Z'\$6P'#B1Y8"_\V6 NX6 I0Z!P$@\0$N%P*4.CT_$1$HUX+Z88 N $ XM4.A4!%L!PXD>6 O_-E@+N%@*4.CQ X/$!,<&5@I?"HL>5@J /P!T&8L>5@J* XM!YB)PXJ'*PF8J AT!X,&5@H!Z]Z+'E8*@#\ =#G_-E8*Z#?^1$3K+K@! %#H XM_ -; <.)'E@+_S98"[A8"E#HF0.#Q 2X6 I0Z'S^1$3K![X0 %OITAVX__^) XM[%W#58GE@SYB"P!U"(L>)@:)'F(+@SY,!0!U";A\!%#HNP-$1(GL7<-5B>6Y XM P"+1@33^/]V!B4? %L!PXH'F%"Y @"[ @"+1@2Z 0!2Z+(=)0< B<%8T^!; XM(<-36(GL7<-5B>6#[!#HF/_'1O8 .@M @G = 8QP%#IB0''1OP ,=&^O__ XMBQY,!8E>\HM>\H-_$@!T1HM>\HM&_-'@B<8#=Q*+!(E&^#T '0OQT;^ "# XM?OX0?2&+3OZX 0#3X(5&^'0/BT;^T>")PXL.3@6)C\H+_T;^Z]G_1O:+7O*+ XM1OS1X(G& W<.BP2)1O0]__]T#HM&](E&^HL>3@6)'E(%Z 8!B4;^/0 ?0+K XM2HM>\HM'%HE&\#T '0=@W[V '47_W;P_W;^Z/W^@\0$"<!T!X,&3@7_ZQ^+ XM7O*+1PS_=OS_=O[_=O+_T(/$!HE&_#W__W0#Z37_BQY.!3D>4 5S"(L>3@6) XM'E %@W[Z_W51BQY.!8D>4@6#?OP =0R#?OX ?08QP%#I>P"+7O*+1QB)1O ] XM !T(_]V\/]V_NB'_H/$! G =!/_=O[_=OZX6@50Z)0!@\0&Z:_^N !4.M$ XMN0L BT;ZT_@E'P")1OX] !T$HM&_M'@+0( B<.+G\H+B1Y2!8M&^B7_!XM> XM\HM?$%#_TT1$B4;^/0 ?0/I:/[_=OY8B>Q=PU6)Y8/L!HL>3 6)7OR+1Q2) XM1OJ+'E %.1Y.!7,+BQY.!3' B@=0ZQ.#/F0+ '0&N/__4.L$Z/< 4%A06(E& XM_CT 'Q$@W[Z '02_W;Z_W;^Z,O]@\0$"<!T NNWBQY4!3D>3@5R$KAX!5#H XMT@!$1+@! %#H)!-$1(L>3@6+1OZ(!X,&3@4!ZP;'!F0+ 0"+1OZ)[%W#58GE XM@^P$QT;^9@N+'E(%B5[\BQY0!3E>_',5_W;\@T;\ 5N+=OZ*!X@$@T;^ >OB XMQP9.!68+BQY.!8D>4@6+7OZ)'E %@SYD"P!T#8%^_F8+=0:X 0!0ZP,QP%!8 XMB>Q=PU6)Y<<&4@5F"XL>4@7_-E(%B1Y0!8\&3@7'!E0%R@O'!E@% "+'E@% XM_S98!8D>5@6/!F0+B>Q=PU6)Y?\V8@OHL@=$1(GL7<-5B>6#/E@% '02_S98 XM!;B.!5#_-BH&Z)L$@\0&_W8*_W8(_W8&_W8$_S8J!NB%!(/$"HGL7<-5B>6# XM[ :+1@2)1OR+7@8#7OQ+B5[ZQT;^9@N+'E(%.5[^<QV+1OHY1OQS%?]V_H-& XM_@%;BW;\B@>(!(-&_ 'KVHM>_,8' (M&_"M&!(GL7<-5B>6A4@4M9@N)[%W# XM58GE3$R+'DP%B5[^BUX$B1Y,!8M&_HGL7<-5B>5,3(M>!(M&"-'@B<8#=PB+ XM! -&!HE&_HM'"CE&_G\?BUX$BW;^ W<&N0( NP( BT8(,=**%%+HSQE;.<-T XM)8M>!(L'.48(=!6+7@2+=@@#=P**!##DB4;^B48(ZZ6X__]0ZPZ+7@2+=OX# XM=P2*!##D4%B)[%W#58GE@^P&BUX&B@>84.L4QT;Z #K%,=&^@$ ZPTQP%#I XMYP"^E 5:Z5$9C4;\4.CH%41$"<!]!C' 4.G- .@2$:/,"X,^S L = /IA@"# XM?OH =07_=OSK _]V_NB$$41$@W[Z '4&N $ 4.L#,<!0Z' 11$2#?OH =07_ XM=O[K _]V_.@ #D1$@W[Z '4%_W;^ZP/_=OSH2A%$1#' 4/]V!+BL!5"XJ 50 XMN* %4.CU#8/$"C' 4/]V!+C !5"XO 50N+ %4.C=#8/$"K@! %#H8Q!$1(,^ XMS O_=04QP%#K*X-^^@!U!?]V_NL#_W;\Z/(01$3_=@:#?OH =07_=OSK _]V XM_NB; 8/$!%!8B>Q=PU6)Y8/L"O]V!.@O T1$N $ 4+@" %#H7!6#Q 2)1OJX XM 0!0N , 4.A+%8/$!(E&^+@! %!0Z#T5@\0$B4;\C4;V4.AA%D1$B4;^BQ[, XM"SE>_G0(@W[^_W0"Z^.#?O[_=07'1O;___]V^K@" %#H!16#Q 3_=OBX P!0 XMZ/@4@\0$_W;\N $ 4.CK%(/$!(M&]HGL7<-5B>6#[ RXQ 50Z+X/1$2)1O0] XM !T"(M>]( _ '4%QT;TR@7HB ^)1OP] !U3_]V].A7%41$4/]V!/]V].A> XM%8/$!@G =14QP%"XT@50_W;T_W;TZ*D,@\0(ZQ8QP%#_=@2XU@50_W;T_W;T XMZ)$,@\0*N'\ 4.@7#T1$ZQ6#?OS_=0^XV@50Z&831$2X__]0ZV:X 0!0N ( XM4.A#%(/$!(E&^+@! %"X P!0Z#(4@\0$B4;VC4;Z4.A6%41$B4;^BT;\.4;^ XM= B#?O[_= +KY(-^_O]U!<=&^O___W;XN ( 4.C[$X/$!/]V]K@# %#H[A.# XMQ 3_=OI8B>Q=PU6)Y8/L#,=&^@ QT;^ "+7O[1XX._)@8 =!&#?OX4? 8Q XMP%#IOP#_1O[KXXM>!HH'F%#K+(%.^@( ZRR!3OH" +@" % QP%!0_W8$Z! / XM@\0(ZQ2!3OH! .L-,<!0Z84 ON@%6NEQ%K@* %#HL ]$1(E&_#T '4%,<!0 XMZVB+7OS'1P( (M&!(M>_(D'BT;ZB4<$N $4.B$#T1$BU[\B4<&@W\& '42 XMBU[\@\,$B5[XBP<-! ")!^L0BU[\@\,$B5[XBP<-( ")!XM>_(MV_(M'!HE$ XM"(M>_M'CBT;\B8<F!O]V_%B)[%W#58GEC48(4/]V!O]V!.@;!(/$!HM>!/9' XM!$!T"/]V!.A7 D1$B>Q=PU6)Y8U&!E#_=@3_-B@&Z/(#@\0&BQXH!O9'!$!T XM"?\V* ;H+ )$1(GL7<-5B>6#[ ;'1OP ,=&_ @WX& '1+BT8(.4;\<T.+ XM1@:)1OK_=@KH>P)$1(E&_CW__W0.BUX$BT;^B >#1@0!ZP:+1OQ0ZQV+1OHM XM 0")1OH] !USHM&_ 4! (E&_.NUBT;\4%B)[%W#58GE3$S'1OX (-^_A1] XM)(M&_M'@B<.+AR8&.48$=0^+1O[1X(G#QX<F!@ ZP7_1O[KUH-^_A1\!KC_ XM_U#K.O]V!.AV 41$BUX$_S?H2 U$1(M>!/9'!"!T%(M>!(-_!@!T"XM>!/]W XM!NC'#T1$_W8$Z+\/1$0QP%!8B>Q=PU6)Y8/L"L=&^ QT;^ "+1O[1X(G# XM@[\F!@!T$8-^_A1\!C' 4.D. ?]&_NOABUX&B@>84.EX (%.^ ( N*0!4/]V XM!.A9"8/$!(E&^CT 'UE,<!0Z=\ @4[X @"X 0!0_W8$Z$@0@\0$B4;Z/0 XM?08QP%#IOP"X @!0,<!04/]V^NBQ#(/$".LL@4[X 0 QP%#_=@3H%A"#Q 2) XM1OH] !]$S' 4.F- #' 4.F' +[X!5KI^A.X"@!0Z#D-1$2)1OP] !U!3' XM4.MJBU[\QT<" "+1OJ+7OR)!XM&^(E'!+@ !%#H#0U$1(M>_(E'!H-_!@!U XM$HM>_(/#!(E>]HL'#00 B0?K$(M>_(/#!(E>]HL'#2 B0>+7OR+=OR+1P:) XM1 B+1O[1X(G#BT;\B8<F!O]V_%B)[%W#58GE@^P$BUX$]D<$!'4)BUX$]D<$ XM G4%,<!0ZUV+7@2#?P( ?P4QP%#K3XM>!(MV!(M^!/]W O]T!O\UZ)T1@\0& XMB4;^BUX$BT<".4;^=1:+7@3'1P( (MV!(M'!HE$"/]V_NL4BUX$@\,$B5[\ XMBP<-$ ")![C__U!8B>Q=PU6)Y8/L!(M>!/9'!!AT![C__U#IUP"+7@3V1P0! XM=0>X__]0Z<< BUX$@\,"B5[\BP=(B0>+7OR#/P!^ ^F% (M>!/9'! 1T&XM> XM!+@! %"-1OY0_S?H?P^#Q :+7@2)1P+K&XM>!(MV!+@ !%#_=P;_-.AB#X/$ XM!HM>!(E' HM>!(-_ @!_,8M>!(-_ @!U$HM>!(/#!(E>_(L'#0@ B0?K$(M> XM!(/#!(E>_(L'#1 B0>X__]0ZS6+7@2+=@2+1P:)1 B+7@3V1P0$= B+1OXP XMY%#K&(M>!(/#"(E>_(MV_/\W@P0!6XH'F##D4%B)[%W#58GE@^P*QT;V___' XM1OJ" (M&!(E&_(M&!(E&_HU&"%#_=@:-1O90Z!< @\0&C4;V4#' 4.B%!8/$ XM!(M&!(GL7<-5B>6#[#*+1@B)1OZ+7@:*!Y@)P'4#Z;H"BUX&B@>8/24 =!?_ XM=@3_=@:#1@8!6XH'F%#H106#Q 3KT<=&^@ QT;X #'1O8! ,9&[2"#1@8! XMBUX&B@>8/2T =0G'1O;__X-&!@&+7@:*!Y@], !U",9&[3"#1@8!BUX&B@>8 XM/3 ?"J+7@:*!Y@].0!_'XM>!HH'F"TP /=F]E"X"@#W9OI; <.)7OJ#1@8! XMZ\N+7@:*!Y@]+@!U-H-&!@&+7@:*!Y@], !\)XM>!HH'F#TY '\<BUX&B@>8 XM+3 4+@* /=F^%L!PXE>^(-&!@'KSHM>!HH'F%#IEPOX"BU[^BT?^F8E& XM\HE6],=&_ H Z84!@T;^ HM>_HM'_IF)1O*)5O2+1O+_=O1;)?__,=M3B4;R XMCT;TQT;\"@#I60OX"BU[^BT?^F8E&\HE6](M&\HM>]"T (/; '4%(<!T XM 4,)VWT3BT;R_W;T6R7__S';4XE&\H]&],=&_ @ Z18!@T;^ HM>_HM'_IF) XM1O*)5O2+1O*+7O0M "#VP!U!2' = %#"=M]$XM&\O]V]%LE__\QVU.)1O*/ XM1O3'1OP0 .G3 (-&_@2+7OZ+1_S_=_Z)1O*/1O3'1OP* .FX (-&_@2+7OZ+ XM1_S_=_Z)1O*/1O3'1OP( .F= (-&_@2+7OZ+1_S_=_Z)1O*/1O3'1OP0 .F" XM (-&_@*+7OZ+1_Z(1O&*1O&8_W8$4.A. X/$!(-&!@'IU?V#1OX"BU[^BT?^ XMB4;N_W8$_W;NZ"H-1$10BD;MF%#_=OC_=OK_=N[H9P*#Q R#1@8!Z:']_W8$ XMN"4 4.@& X/$!/]V!/]V!H-&!@%;B@>84.CQ H/$!.E\_;Y.!EKI+ ^-1N%0 XM_W;\_W;T_W;RZ# @\0(_W8$C4;A4.C##$1$4(I&[9A0_W;X_W;ZC4;A4.C_ XM 8/$#(-&!@'I.?V)[%W#58GE@^P6QT;P "+1@2+7@8M "#VP!U @G#"=MU XM$XM>"L8',(M&"D")P\8' (GL7<.#?@@*=2V+1@2+7@8M "#VP!U!2' = %# XM"=M]%HM>!(M&!O?8]]L= ")7@2)1@;_1O#'1NX (-^[@Q]#(MV[L9"] #_ XM1N[K[L=&[@ @WX("G4Z_W8&_W8$,<!0N H 4.AD#XMV[HA2](MV[HI"])B9 XMBUX$BTX&*<,9T5%3,<!0N H 4.AM#HE&!(E.!H-^" AU,(M&!/]V!ELE!P Q XMVXMV[HA"]+D# (M&!(M>!N,&T?O1V.+Z)?__@>/_'XE&!(E>!H-^"!!U,(M& XM!/]V!ELE#P QVXMV[HA"]+D$ (M&!(M>!N,&T?O1V.+Z)?__@>/_#XE&!(E> XM!O]&[HM&!(M>!BT (/; '4""<,)VW0#Z3K_QT;R "+1NY(B4;L@W[L 'Q2 XMBW;LBD+TF G =0^#?O( =0F+=NS&0O0@ZS.+=NR*0O28/0H ?1.+=NR-6O2) XM7NJ*!Y@%, "(!^L1BW;LC5KTB5[JB@>8!3< B ?_1O+_3NSKJ(-^\ !T%;@M XM %"-1O10_W;N_T;N6U@!PUB(!XM&[DB)1NR#?NP ?!2+=NR+7@J*0O2(!X-& XM"@'_3NSKYHM>"L8' (GL7<-5B>6#[ 2+1@R)1OZ#?@@ ?@Z+1@@Y1@Q^!HM& XM"(E&_HM&_HE&_(-^!@!^&XM&_CE&!GX3_TX&BD8*F/]V#E#H<0"#Q 3KY8M> XM!(H'F G ="+_=O[_3OY8"<!T%_]V#O]V!(-&! %;B@>84.A% (/$!.O4@WX& XM 'T9BD8*F#TP '40_W8.N"X 4.@G (/$!/]&!HM&_/?8.48&?1/_1@:*1@J8 XM_W8.4.@) (/$!.OCB>Q=PU6)Y8/L!L=&_ BUX&]D<$&'0'N/__4.GS (M> XM!O9'! )U![C__U#IXP"+7@;V1P0$=".+7@:X 0!0C48$4/\WZ&L*@\0&B4;^ XMBUX&QT<" 0#_1OSK9(M>!H/#"(E>^HMV^C' BD8$4/\W@P0!6UB(!XM>!H/# XM HE>^HL'0(D'BU[Z@3\ !'PRBUX&]D<$@'4IBUX&BW8&BWX&_W<"_W0&_S7H XM"0J#Q :)1OZ+7@:+=@:+1P:)1 C_1OR#?OP =$>#?OX ?@N+7@:+1OXY1P)T XM+H-^_@!]$HM>!H/#!(E>^HL'#1 B0?K$(M>!H/#!(E>^HL'#0@ B0>X__]0 XMZPZ+7@;'1P( (I&!##D4%B)[%W#58GEBW8$BWX&,<"*!#H%? Y_" C = M' XM1NOPL 'K [C__UW#58GE_W8$_W8&N @ 4+@! %#HQ F#Q B)[%W#58GE,<!0 XM4%!04/]V!+@I %"X 0!0Z&@)@\00B>Q=PU6)Y;C.$U"-1@90_W8$Z$X @\0& XMB>Q=PU6)Y4Q,C5X&B5[^_W;^@T;^ EN#/P!T NOQBU[^_S>-1@90_W8$Z!X XM@\0&B>Q=PU6)Y;C.$U#_=@;_=@3H!P"#Q :)[%W#58GE@>P6!,>&\OL ,>& XM\/L (M&!HF&_ON+1@B)AOS[_[;^^X.&_OL"6X,_ '0&_X;R^^OK_[;\^X.& XM_/L"6X,_ '0&_X;P^^OKQX;L^P( BX;P^P.&\OL% P#WINS[B<:-F@#\B9[Z XM^XN>\OL#GOK[ Y[P^XUV #GS<@>X^?]0Z6<!C9X _(F>^/N+AO+[B0>#AOC[ XM L>&]/L (N&\OLYAO3[?6N-G@#\BX;Z^RG8B8;J^XN>^/N)!X.&^/L"_W8& XM@T8& EN+!XF&]ON+GO;[B@>8"<!T)_^V]ON#AO;[ 5N+MOK[B@>(!(.&^OL! XMC5X .9[Z^W+5N/G_4.GK (N>^OO&!P"#AOK[ ?^&]/OKBXN>^/O'!P @X;X XM^P+'AO3[ "+AO#[.8;T^WUJC9X _(N&^OLIV(F&ZON+GOC[B0>#AOC[ O]V XM"(-&" );BP>)AO;[BY[V^XH'F G =";_MO;[@X;V^P%;B[;Z^XH'B 2#AOK[ XM 8U> #F>^OMRU;CY_U#K9(N>^OO&!P"#AOK[ ?^&]/OKC(N>^/O'!P @X;X XM^P*-G@#\BX;Z^RG8 X;L^TB9][[L^_>F[/N)AN[[,<!0C88 _%#_=@0QP%#_ XMMN[[_W8$Z P(1$10N#L 4#' 4.@;!X/$$%!8B>Q=PU6)Y8/L!,9&_ #&1OT XMQD;^ ,9&_P QP%"-1OQ0_W8$,<!0N 0 4/]V!.C)!T1$4+@[ % QP%#HV :# XMQ!")[%W#58GE,<!04%!04/]V!+@! % QP%#HN@:#Q!")[%W#58GE,<!04%!0 XM4%"X @!0,<!0Z)X&@\00B>Q=PU6)Y8/L!HL> ")7O[_=OZ#1OX"6XL'B4;\ XM/0 =$V+1@2)1OJ+7OR /P!T)(M>^H _ '0<BU[\B@>8BU[Z4(H'F%LYPW4* XM@T;\ 8-&^@'KU(M>_( _/76TBU[Z@#\ = +KJH-&_ '_=OSK S' 4%B)[%W# XM58GE,<!04%!04/]V!+@& %"X 0!0Z L&@\00B>Q=PU6)Y4Q,BUX$B1[Z$XM> XM!HD> !2+7@B)'@(4BUX*B1[\$[@3 %"X 0!0Z'8&@\0$B4;^/0 = B+1OZ9 XM4E#K"/\V A3_-@ 46%J)[%W#58GE3$R+'M 3@\," UX$@\,/@>/P_X/#_HE> XM_HL>T!,Y7OYR#/]V_N@> D1$"<!]!3' 4.LXBU[^B1[0$XL>TA.)7OZ+7OZ# XM/P!T#8M>_HL')?[_B4;^Z^N+'M 3BW;^B1R+'M 3QP< +@! %!8B>Q=PU6) XMY8/L"(M&! 4! "7^_P4" (E&^(L>TA.)7OZ#/M(3 '4>N ( 4.CF 41$B4;^ XMBU[^B1[2$XM>_HD>T!/'!P BU[^BW;^BP3_-XE&_%@] !U ^EU /9&_ %T XM"XM&_"7^_XE&_NO9BU[\BW;\BP3_-XE&^E@] !T#O9&^@%U"(M&^HE&_.O? XMBT;\*T;^.4;X=R^X 0#W9OB)PP->_HE>^HM&_#E&^G,(BT;\BU[ZB0>+1OH- XM 0"+7OZ)!X/# E/K(XM&_(E&_NEU__]V^.B[_D1$"<!T"_]V!.@B_T1$4.L# XM,<!06(GL7<-5B>6#[ R+7@2#P_Z)7OZ+1@8% 0 E_O\% @")1OB+7OZ+!R7^ XM_XE&_"M&!(E&]HM>_(MV_(L$_S>)1OI8/0 = [V1OH!=0B+1OJ)1OSKWXM& XM_"M&_CE&^'<[N $ ]V;XB<,#7OZ)7OJ+1OPY1OIS%8M&_(M>^HD'BT;Z#0$ XMBU[^B0?K"XM&_ T! (M>_HD'_W8$ZS?_=@;H>?Y$1(E&^CT '4%,<!0ZR+_ XM=O;_=OK_=@3HQ@2#Q :+1OZ)1O2+7O2+!R7^_XD'_W;Z6(GL7<-5B>5,3(M> XM!(/#_HE>_HL')?[_B0>)[%W#58GE3$PQP%!0_W8$4%!0N!$ 4#' 4.A5 X/$ XM$(E&_CT '4-BQX(%(D>=@8QP%#K!+C__U!8B>Q=PU6)Y8/L!(L>=@:)7OR+ XM7@0#'G8&B5[^4^BK_T1$/0 =07_=OSK!+C__U!8B>Q=PU6)Y8/L!NA3 (E& XM_HM&!(E&^O]V^H-&^@%;B@>8"<!T NOO@T;Z_X-&^O^+7OJ*!Y@]6 !U'[L* XM (M&_IGW^X/",(M>^H@7NPH BT;^F??[B4;^Z]*+1@2)[%W#58GE,<!04%!0 XM4%"X% !0,<!0Z),"@\00B>Q=PU6)Y?]V!/]V!K@% %"X 0!0Z+4"@\0(B>Q= XMPU6)Y8,^]!, ? >#/O03(GX4N X 4+@2"5"X @!0Z"X"@\0&ZUS_=@3H< %> XM4/]V!+@" %#H%P*#Q :X @!0N"()4+@" %#H!0*#Q :+'O03T>/_MW@&Z$(! XM7HL>]!/1XU#_MW@&N ( 4.CB 8/$!K@! %"X)@E0N ( 4.C0 8/$!HGL7<-5 XMB>5,3#' 4%!04%!0N"H 4+@! %#HU &#Q!")1OX] !\&(L>^A.+=@2)'(M> XM!(L._!.)3P(QP%#K _]V_EB)[%W#58GE3$PQP%!0_W8&4/]V"/]V!+@# %"X XM 0!0Z(L!@\00B4;^B>Q=PU6)Y8/L!(M&!-'@+0( B<.+A]03B4;\BT8$T> M XM @")PXM&!HF'U!.+7@2)'OH3@WX& 70&@WX& '4%_W8&ZP2XDR%0CP8$%+@P XM % QP%#HS0&#Q 2)1OX] !]!?]V_NL#_W;\6(GL7<-04U%25E=5'@:)XXM? XM$DL!VXN?U!/_-O@3_]./!O@3!Q]=7UY:65M8CP8H"<]5B>6+?@2+=@:LJ@C XM=?J+1@1=PU6)Y8M^!#' @#T = 1 1^OW7<-5B>7_3@A\*XM>!(H'F%#_=@:# XM1@8!6XH'F%LYPW44_W8$@T8$ 5N*!Y@)P'75,<!0ZR"#?@@ ?04QP%#K%8M> XM!(H'F(-&!O^+7@90B@>86RG#4UB)[%W#58GE_W8$,<!0N H 4+@! %#HE "# XMQ B)[%W#58GE3$PQP%!04%!04+@' % QP%#H.0"#Q!")1OZ+'OH3BW8$B1R+ XM1OZ)[%W#58GE,<!04/]V!E#_=@C_=@2X! !0N $ 4.@' (/$$(GL7<-5B>6+ XM7@B)'OH3BUX*B1[\$XM>#(D>_A.+7@Z)'@ 4BUX0B1X"%(M>$HD>!!3_=@;_ XM=@3H: "#Q 2)[%W#58GE@^P$_W8*Z)L 1$2)1OZ+7OZ)'OH3BUX(B1[\$XM> XM"HD>_A/'1OP %(-^_@Y_(/]V_O]._E@)P'05_W8*@T8* 5N+=OR*!X@$@T;\ XM >O@_W8&_W8$Z < @\0$B>Q=PU6)Y4Q,BUX&B1[X$[CV$U#_=@3H8 "#Q 2) XM1OX] !T!?]V_NL;@S[X$P!]$(L>^!/WVXD>]!.X__]0ZP3_-O@36(GL7<-5 XMB>5,3,=&_@ _W8$@T8$ 5N*!Y@)P'0%_T;^Z^R+1OY B>Q=P[D! .L(N0( XMZP.Y P!5B>6+1@2+7@;-(%W#58GEBTX(BWX&BW8$B?C1^7,#I'0#_/*E7<-; XM,<!96EY?.==W"W(&.<YW!70!2/_C0/_CPXL4*UP".UP$=PG1XXM8!H7;=0F) XMTX7;=0/HF@'_XZV3K9%)? >M.="M=?>3A=MU ^B# ?_C7SG+=!"#^P)T#8/[ XM!'42@_D"=0U:_^>#^01U!3'24O_G4.A7 56)Y5<I_XM6"HM&"(M>!HM.!(72 XM>0GWVO?8@]H ]]>%VWD)]]OWV8/; /?7Z!( A?]T!_?:]]B#V@!?78G1P@@ XMA=MU$HG#B= ITO?QD_?QB=&)VBG;PU575BG_A/]U)D=7B-^(ZXC-*,F)S8C% XM*,F(X(C4B/(H]E)048GI.=IR#;C__^L*5U=24(G0*=+W\XG%]^%?*<>#T@") XMUHG8]^4!\(/2 %XIQH/2 %@IT'D*30'/$=X5 #K](GYB?-?A?]T"(CIB-V( XM^XC'B>@ITEY?7<.)YHM< HM$!)DYPG4Q(=)]!/?;="DQTHM,!HM$""' ?0;W XMV/?9&=#W\Y'W\S';@WP( 'T']]OWVH/; ,(( (G',=LA_WT']]_W7 (9WXM$ XM!HM4""'2?0;WVO?8&=JY$ #1X-'2T=,YWW<'<KLY5 )V!.+MZ[DK5 (9^T#B XMX^NON*P)ZQZXPPGK&;C:">L4N/$)ZP^X" KK"K@>"NL%N#4*ZP"[%@!34+@" XM %#H P#H^?55B>7'!A 4! "+7@2)'A(4BUX(B1X4%(M>!HD>&!2X#A10N $ XM4+@! +L.%+D# ,T@B>Q=PP !L;W)D97(N6%A86%A8 # & XM " '\%J@4"!O____\" ( _____________________P$ 0#_________ XM_P #__Q04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04$ X2%!04 XM%!04%!04%!$$%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04 XM%!04%!04%!04%!04 0L4%!0%!@<*% @4%!04"10/ @(" @(" @(" @(" @(" XM @(" @(" @(" @(4%!04 A0" @(" @(" @(" @(" @(" @(" @(" @(" @,# XM P,# P,# P,4%!04%!04 P,# P,# P,# P,# P,# P,# P,# P,# P,4%!04 XM Q0# P,# P,# P,# P,# P,# P,# P,# P,# PP,# P,# P,# P,# P,# P, XM# P,# P,# P,%!04% P4# P,# P,# P,# P,# P,# P,# P,# P,# P-#0T- XM#0T-#0T-%!04%!04% T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-%!04% T4 XM#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T3$Q,3$Q,3$Q,4%!,3$Q,3$Q,3 XM$Q,3$Q,3$Q,3$Q,3$Q03$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3 XM$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3 XM$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$P#_________________________________ XM_________P\*$?____________\0 /______________________________ XM_________________________________P *____! 4&"?\'_____PC_ $! XM 0$! 0$! 0$! 0$! 0$! 0$! 0$! 0$!_____P'_ 0$! 0$! 0$! 0$! 0$! XM 0$! 0$! 0$! 0$" @(" @(" @("_________P(" @(" @(" @(" @(" @(" XM @(" @(" @("_____P+_ @(" @(" @(" @(" @(" @(" @(" @(" @(+"PL+ XM"PL+"PL+"PL+"PL+"PL+"PL+"PL+"_____\+_PL+"PL+"PL+"PL+"PL+"PL+ XM"PL+"PL+"PL+# P,# P,# P,#/________\,# P,# P,# P,# P,# P,# P, XM# P,# P,#/____\,_PP,# P,# P,# P,# P,# P,# P,# P,# P,$A(2$A(2 XM$A(2__\2$A(2$A(2$A(2$A(2$A(2$A(2$A+_$A(2$A(2$A(2$A(2$A(2$A(2 XM$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2 XM$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A( %!04 A04%!04%!04 XM% P*%!04%!( # >P " $ M0 0 @![ XM 0 4 #X$1@!" E($^@$L"AP =@4 &%R('!V("5S(#XE<P XM;&EB=7!A8VL@/"5S !L:6)U<&%C:R \)7, '( 17)R;W(Z("5S(&-O=6QD XM(&YO="!O<&5N("5S"@ )7,@)7,* !5<V%G93H@)7,@9FEL92 N+BXN"@ XM17)R;W(@)7,@+2!O=70@;V8@;65M;W)Y"@!R "5S("5S"@ 17)R;W(@)7,@ XM+2 E<R!D969I;F5D('1W:6-E(&EN("5S(&%N9" E<P !F"V8+9@O*"P XM !);&QE9V%L(&-H87)A8W1E<CH@)6,@*"4P,V\I !4;VME;B!B=69F97(@ XM;W9E<F9L;W< )60Z( P@H" '( M IW +L*+V)I;B]S: !S: +6, "]U XM<W(O8FEN+W-H '-H M8P 4TA%3$P +V)I;B]S: M:0 +6, $-A;FYO XM="!F;W)K+@ H@T# &$ @PUR )L-=P!\#1D0 P!A ,</<@#Z#W< IP\ XM 0#.#\X/ 0 $( S@O."P( & (!A(&' 8 XM R!0) $0 (11/ #P46 !7%&, <A1D %83 XM;P";$W, E!1U &\3> #>$R84P ;(!M(&[ ;\!A0''@<X!TH'7 =L!W@'B@>: XM!ZP'N ?.!^ '[ ?^!PX('@@N"$ (5 AH"'H(B@B:"+((P C6".8(\@@ "2, XM17)R;W(@, !.;W0@;W=N97( 3F\@<W5C:"!F:6QE(&]R(&1I<F5C=&]R>0!. XM;R!S=6-H('!R;V-E<W, 26YT97)R=7!T960@<WES=&5M(&-A;&P 22]/(&5R XM<F]R $YO('-U8V@@9&5V:6-E(&]R(&%D9')E<W, 07)G(&QI<W0@=&]O(&QO XM;F< 17AE8R!F;W)M870@97)R;W( 0F%D(&9I;&4@;G5M8F5R $YO(&-H:6QD XM<F5N $YO(&UO<F4@<')O8V5S<V5S $YO="!E;F]U9V@@8V]R90!097)M:7-S XM:6]N(&1E;FEE9 !"860@861D<F5S<P!";&]C:R!D979I8V4@<F5Q=6ER960 XM36]U;G0@9&5V:6-E(&)U<WD 1FEL92!E>&ES=', 0W)O<W,M9&5V:6-E(&QI XM;FL 3F\@<W5C:"!D979I8V4 $YO="!A(&1I<F5C=&]R>0!)<R!A(&1I<F5C XM=&]R>0 26YV86QI9"!A<F=U;65N= 1FEL92!T86)L92!O=F5R9FQO=P!4 XM;V\@;6%N>2!O<&5N(&9I;&5S $YO="!A('1Y<&5W<FET97( %1E>'0@9FEL XM92!B=7-Y !&:6QE('1O;R!L87)G90 3F\@<W!A8V4@;&5F="!O;B!D979I XM8V4 26QL96=A;"!S965K !296%D+6]N;'D@9FEL92!S>7-T96T 5&]O(&UA XM;GD@;&EN:W, $)R;VME;B!P:7!E $UA=&@@87)G=6UE;G0 4F5S=6QT('1O XM;R!L87)G90 26YV86QI9"!E<G)N;PH #H@ * " @(" @(" @( @( XM" @((" @(" @(" @(" @(" @(" @"! 0$! 0$! 0$! 0$! 0$ 0$! 0$! 0$ XM! 00$! 0$! 004%!04%! 0$! 0$! 0$! 0$! 0$! 0$! 0$0$! 0$!!"0D)" XM0D(" @(" @(" @(" @(" @(" @(" A 0$! @ $5R<F]R.B!$:79I<VEO;B!B XM>2 P( H 26QL96=A;"!%32!I;G-T<G5C="=N"@!%<G(@:6X@14T@8V%S92!I XM;G-T<B * %9A<FEA8FQE(&]U="!O9B!R86YG90H 17)R(&EN($5-('-E="!I XM;G-T<B * $9L;V%T:6YG('!T(&YO="!I;7!L+@H 2&5A<"!O=F5R9FQO=R * X! '-T X Xend / echo x - lorder.man gres '^X' '' > lorder.man << '/' XNAME X lorder -- find an ordering relation for an assembler library X XSYNOPSIS X lorder file .... X XDESCRIPTION X Lorder accepts as input one or more packed or unpacked .s files or X libraries (ar(1) format). It produces on the standard output a list X of pairs of .s file names. The first file of the pair refers to X external identifiers defined in the second. The output of lorder X may processed by tsort to produce a suitable ordering for a X one pass access by asld(1). X X XSEE ALSO X ar(1), libupack(1), tsort(1), asld(1) X XBUGS X only handles ar(1) and .s files. X only uses memory. no work files(no huge libraries please). X slow. X X / ------------------------CUT HERE------------------------------------------ Monty Walls MIS Division, Tech. Support Oklahoma Tax Commission 2501 N. Lincoln OKC, OK, 73194