walls@killer.UUCP (Monty Walls) (02/24/88)
In response to bug reports I've received I am posting these patches to ar, lorder, and tsort. All these diff's are relative to my original versions, and lorder.c is a complete reposting. Also the original LEX scanner for lorder has been replaced with a hand written scanner(this one will happily think the asm directives are global symbols the code is referencing but since no module ever actually defines them it doesn't hurt any thing). So sorry about missing this stuff the first time. -------------------------CUT HERE------------------------------- echo x - ar.c.diff gres '^X' '' > ar.c.diff << '/' X32a33 X> * fixed up error messages to give more info (mrw). X35a37,41 X> * X> * change log: X> * forgot that ar_size is a long for printing - 2/14/88 - mrw X> * got the mode bit maps mirrored - 2/19/88 - mrw X> * print & extract member logic fixed - 2/19/88 - mrw X72c78 X< #define EXEC_OWNER 00001 X--- X> #define EXEC_OWNER 00100 X74,75c80,81 X< #define EXEC_ALL 00100 X< #define READ_OWNER 00004 X--- X> #define EXEC_ALL 00001 X> #define READ_OWNER 00400 X77,78c83,84 X< #define READ_ALL 00400 X< #define WRITE_OWNER 00002 X--- X> #define READ_ALL 00004 X> #define WRITE_OWNER 00200 X80c86 X< #define WRITE_ALL 00200 X--- X> #define WRITE_ALL 00002 X247c253 X< fprintf(stderr,"Error %s: %s not found in ar\n", progname, argv[ac]); X--- X> fprintf(stderr,"Error %s: %s not found in %s\n", progname, argv[ac], afile); X324c330 X< fprintf(stderr,"Error: ar corrupted archive ar\n"); X--- X> fprintf(stderr,"Error: ar corrupted archive %s\n",afile); X440c446 X< fprintf(stdout,"%5.5d",member->ar_size); X--- X> fprintf(stdout,"%5.5D",member->ar_size); /* oops is long - mrw */ X450a457 X> long size; X469,471c476,479 X< X< for (cnt = member->ar_size; cnt > 0; cnt -= ret) { X< ret = read(fd, buffer, (cnt < BUFFERSIZE ? cnt : BUFFERSIZE)); X--- X> /* changed loop to use long size for correct extracts */ X> for (size = member->ar_size; size > 0; size -= ret) { X> cnt = (size < BUFFERSIZE ? size : BUFFERSIZE); X> ret = read(fd, buffer, cnt); X661c669 X< int a, fd; X--- X> int a, fd, did_print; X665a674 X> did_print = 0; X671c680 X< else if (major & (PRINT | EXTRACT)) X--- X> else if (major & (PRINT | EXTRACT)) { X672a682,683 X> did_print = 1; X> } X676,677d686 X< else if (major & (PRINT | EXTRACT)) X< lseek(fd, (long)even(member->ar_size), 1); X683c692 X< else if (major & (PRINT | EXTRACT)) X--- X> else if (major & (PRINT | EXTRACT)) { X684a694,695 X> did_print = 1; X> } X686c697,700 X< if (major & TABLE) X--- X> /* if we didn't print the member or didn't use it we will X> * have to seek over its contents X> */ X> if (!did_print) / echo x - tsort.c.diff gres '^X' '' > tsort.c.diff << '/' X24a25 X> * possible bug in ungetc(), fixed readone() to avoid - 2/19/88 - mrw X26d26 X< * X156,161c156,163 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> if (c != EOF) { X> name[n++] = c; /* save into name first non blank */ X> while ((c = getchar()) != EOF && !isspace(c)) { X> if (n < MAXNAMELEN) X> name[n++] = c; X> } X> name[n] = '\0'; X> return (name); X163,164c165 X< X< if (c == EOF) X--- X> else X167,168d167 X< name[n] = '\0'; X< return (name); / echo x - lorder.c gres '^X' '' > lorder.c << '/' 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 * corrected & rewrote scanner to avoid lex. - 2/22/88 - mrw X */ X X#include <stdio.h> X#include <ctype.h> X#include <signal.h> X#include <ar.h> X X#define MAXLINE 256 X XFILE *lexin; Xchar *yyfile; Xchar *tmpfile; Xchar *progname; 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 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() != EOF) ; 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 } 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/* X * yylex - scanner for lorder X * X */ X#define MAXNAME 33 X#define is_first_char(c) ((c) == '.' || (c) == '_') X#define is_second_char(c) ((c) == '_' || isalpha((c))) X#define is_other_char(c) ((c) == '_' || isalnum((c))) X Xint yylex() X{ X int col = 0; X int i = 0; X int is_member = 0; X int in_define = 0; X int lastch = 0; X char s[MAXNAME]; X X X while ((lastch = fgetc(lexin)) != EOF) { X col++; /* increment col */ X if (isspace(lastch)) { X EOS: /* eos comes here */ X if (i) { /* we have a string */ X s[i] = '\0'; /* set eos */ X i = 0; X /* X * if we are in a define use dodef to add location X * of defining member and global to symbol table. X */ X if (in_define) X dodef(s); X /* X * if we are on a 'p -' line for an ar lib define X * this member as the file we are using. X */ X else if (is_member > 0) { X is_member = 0; X yyfile = addfile(s); X } X /* X * if we have a '.define' mark this line as in_define. X */ X else if (strcmp(s,".define") == 0) X in_define = 1; X /* X * just a reference in the code to a var, so add this X * reference to our symbol table. X */ X else X usedef(s); X } X /* X * we are at the eol: reset our counters and switches X */ X if (lastch == '\n') { X col = 0; X is_member = 0; X in_define = 0; X } X /* X * lets do another character X */ X continue; X } X /* X * not a space and i == 0 X */ X if (i == 0) { X /* X * are we seeing 'p' in col 1 X */ X if (lastch == 'p' && col == 1) { X is_member = -1; X continue; X } X /* X * are we seeing '-' that follows 'p' in col 1 X */ X else if (lastch == '-' && is_member < 0 && col == 3) { X is_member = 1; X continue; X } X /* X * if we have seen 'p -' now we are reading the name or X * the first character of a global symbol X */ X if (is_member > 0 || is_first_char(lastch)) { X s[i++] = lastch; X if (is_member < 0) X is_member = 0; X } X continue; X } X /* X * do the second char of a name X */ X else if (i == 1) { X if (is_member > 0 || is_second_char(lastch)) { X s[i++] = lastch; X } X else X is_member = 0; X } X /* X * do the rest of a symbol or member name X */ X else if (is_member > 0 || is_other_char(lastch)) { X s[i++] = lastch; X continue; X } X else X goto EOS; X } X /* X * returns EOF on end of file X */ X return (lastch); X} / -------------------------END HERE------------------------------- Monty Walls MIS Division, Tech. Support Oklahoma Tax Commission 2501 N. Lincoln OKC, OK, 73194