add directory study
This commit is contained in:
375
study/linux-travel/MINIX-1.5/1.5/Source/commands/ibm/lorder.c
Normal file
375
study/linux-travel/MINIX-1.5/1.5/Source/commands/ibm/lorder.c
Normal file
@@ -0,0 +1,375 @@
|
||||
/* lorder - order a library Author: Monty Walls */
|
||||
|
||||
/* lorder: find ordering relations for object library
|
||||
*
|
||||
* author: Monty Walls
|
||||
* written: 1/29/88
|
||||
* Copyright: Copyright (c) 1988 by Monty Walls.
|
||||
* Not derived from licensed software.
|
||||
*
|
||||
* Permission to copy and/or distribute granted under the
|
||||
* following conditions:
|
||||
*
|
||||
* 1). This notice must remain intact.
|
||||
* 2). The author is not responsible for the consequences of use
|
||||
* this software, no matter how awful, even if they
|
||||
* arise from defects in it.
|
||||
* 3). Altered version must not be represented as being the
|
||||
* original software.
|
||||
*
|
||||
* change log:
|
||||
* corrected & rewrote scanner to avoid lex. - 2/22/88 - mrw
|
||||
* oops reversed output filename order. 3/14/88 - mrw
|
||||
* progname = argv[0] - should be first. 5/25/88 - mbeck
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <ar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAXLINE 256
|
||||
|
||||
FILE *lexin;
|
||||
char *yyfile;
|
||||
char *tempfile;
|
||||
char *progname;
|
||||
char template[] = "lorder.XXXXXX";
|
||||
|
||||
struct filelist {
|
||||
char *name;
|
||||
struct filelist *next;
|
||||
};
|
||||
|
||||
struct node {
|
||||
char *name;
|
||||
char *file;
|
||||
struct filelist *list;
|
||||
struct node *left, *right;
|
||||
};
|
||||
|
||||
struct filelist *list;
|
||||
struct node *tree, *lastnode;
|
||||
extern char *malloc(), *mktemp();
|
||||
extern FILE *popen(), *fopen();
|
||||
extern char *addfile();
|
||||
extern void user_abort();
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int i;
|
||||
char cmdstr[MAXLINE];
|
||||
|
||||
progname = argv[0];
|
||||
if (argc > 1) {
|
||||
signal(SIGINT, user_abort);
|
||||
for (i = 1; argv[i] && *argv[i]; ++i) {
|
||||
/* The following code is caused by not enough memory
|
||||
* on floppy systems.
|
||||
*
|
||||
* so instead of ar | libupack ->to us. we use ar
|
||||
* >tmpfle; libupack <tempfile ->to us */
|
||||
if (is_liba(argv[i])) {
|
||||
tempfile = mktemp(template);
|
||||
sprintf(cmdstr, "ar pv %s >%s", argv[i], tempfile);
|
||||
system(cmdstr);
|
||||
sprintf(cmdstr, "libupack <%s", tempfile);
|
||||
} else {
|
||||
yyfile = addfile(argv[i]);
|
||||
sprintf(cmdstr, "libupack <%s", argv[i]);
|
||||
}
|
||||
if ((lexin = popen(cmdstr, "r")) != (FILE *) NULL) {
|
||||
while (yylex() != EOF);
|
||||
pclose(lexin);
|
||||
if (tempfile) unlink(tempfile);
|
||||
} else {
|
||||
fprintf(stderr, "Error: %s could not open %s\n", progname, argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printtree(tree);
|
||||
/* Then print list of files for ar also */
|
||||
for (; list; list = list->next)
|
||||
fprintf(stdout, "%s %s\n", list->name, list->name);
|
||||
} else {
|
||||
fprintf(stderr, "Usage: %s file ....\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void user_abort()
|
||||
{
|
||||
unlink(tempfile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *xalloc(n)
|
||||
int n;
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = malloc(n)) == (char *) NULL) {
|
||||
fprintf(stderr, "Error %s - out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
int is_liba(s) /* error handling done later */
|
||||
char *s;
|
||||
{
|
||||
unsigned short key;
|
||||
FILE *fp;
|
||||
int ret = 0;
|
||||
|
||||
if ((fp = fopen(s, "r")) != (FILE *) NULL) {
|
||||
fread(&key, sizeof(key), 1, fp);
|
||||
if (key == ARMAG) ret = 1;
|
||||
fclose(fp);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
char *strsave(s)
|
||||
char *s;
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = xalloc(strlen(s) + 1);
|
||||
strcpy(p, s);
|
||||
return(p);
|
||||
}
|
||||
|
||||
char *addfile(s)
|
||||
char *s;
|
||||
{
|
||||
struct filelist *p;
|
||||
|
||||
p = (struct filelist *) xalloc(sizeof(struct filelist));
|
||||
p->name = strsave(s);
|
||||
if (list)
|
||||
p->next = list;
|
||||
else
|
||||
p->next = NULL;
|
||||
list = p;
|
||||
return(p->name);
|
||||
}
|
||||
|
||||
printtree(t)
|
||||
struct node *t;
|
||||
{
|
||||
struct filelist *fp;
|
||||
|
||||
if (t) {
|
||||
if (t->file) {
|
||||
for (fp = t->list; fp && fp->name; fp = fp->next)
|
||||
if (t->file != fp->name)
|
||||
fprintf(stdout, "%s %s\n", fp->name, t->file);
|
||||
}
|
||||
printtree(t->right);
|
||||
printtree(t->left);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct node *finddef(s)
|
||||
char *s;
|
||||
{
|
||||
struct node *n;
|
||||
int cmp;
|
||||
|
||||
if (tree) {
|
||||
lastnode = n = tree;
|
||||
while (n && n->name) {
|
||||
lastnode = n;
|
||||
if (!(cmp = strcmp(s, n->name)))
|
||||
return(n);
|
||||
else if (cmp > 0)
|
||||
n = n->left;
|
||||
else
|
||||
n = n->right;
|
||||
}
|
||||
}
|
||||
return((struct node *) NULL);
|
||||
}
|
||||
|
||||
struct node *makedef(s)
|
||||
char *s;
|
||||
{
|
||||
struct node *n;
|
||||
int cmp;
|
||||
|
||||
n = (struct node *) xalloc(sizeof(struct node));
|
||||
n->name = strsave(s);
|
||||
n->left = (struct node *) NULL;
|
||||
n->right = (struct node *) NULL;
|
||||
if (tree) {
|
||||
cmp = strcmp(s, lastnode->name);
|
||||
if (cmp > 0)
|
||||
lastnode->left = n;
|
||||
else
|
||||
lastnode->right = n;
|
||||
} else
|
||||
tree = n;
|
||||
|
||||
return(n);
|
||||
}
|
||||
|
||||
void dodef(s)
|
||||
char *s;
|
||||
{
|
||||
struct node *n;
|
||||
|
||||
if (n = finddef(s)) {
|
||||
if (n->file != NULL) fprintf(stderr,
|
||||
"Error %s - %s defined twice in %s and %s\n",
|
||||
progname, s, n->file, yyfile);
|
||||
else
|
||||
n->file = yyfile;
|
||||
} else {
|
||||
n = makedef(s);
|
||||
n->file = yyfile;
|
||||
n->list = (struct filelist *) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void usedef(s)
|
||||
char *s;
|
||||
{
|
||||
struct node *n;
|
||||
struct filelist *fp, *lastfp;
|
||||
|
||||
if (n = finddef(s)) {
|
||||
/* Scan file list for match */
|
||||
if (n->list) {
|
||||
for (fp = n->list; fp; fp = fp->next) {
|
||||
if (fp->name == yyfile) {
|
||||
return;
|
||||
}
|
||||
lastfp = fp;
|
||||
}
|
||||
|
||||
/* Reached here with no match */
|
||||
lastfp->next = (struct filelist *) xalloc(sizeof(struct filelist));
|
||||
lastfp->next->name = yyfile;
|
||||
lastfp->next->next = (struct filelist *) NULL;
|
||||
} else {
|
||||
/* Empty list so far */
|
||||
n->list = (struct filelist *) xalloc(sizeof(struct filelist));
|
||||
n->list->name = yyfile;
|
||||
n->list->next = (struct filelist *) NULL;
|
||||
}
|
||||
} else {
|
||||
n = makedef(s);
|
||||
n->file = (char *) NULL;
|
||||
n->list = (struct filelist *) xalloc(sizeof(struct filelist));
|
||||
n->list->name = yyfile;
|
||||
n->list->next = (struct filelist *) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Yylex - scanner for lorder
|
||||
*
|
||||
*/
|
||||
#define MAXNAME 33
|
||||
#define is_first_char(c) ((c) == '.' || (c) == '_')
|
||||
#define is_second_char(c) ((c) == '_' || isalpha((c)))
|
||||
#define is_other_char(c) ((c) == '_' || isalnum((c)))
|
||||
#define alt_space(c) ((c) == ',' || (c) == '#')
|
||||
int yylex()
|
||||
{
|
||||
int col = 0;
|
||||
int i = 0;
|
||||
int is_member = 0;
|
||||
int in_define = 0;
|
||||
int lastch = 0;
|
||||
int was_space = 1;
|
||||
char s[MAXNAME];
|
||||
|
||||
|
||||
while ((lastch = fgetc(lexin)) != EOF) {
|
||||
col++; /* increment col */
|
||||
if (isspace(lastch)) {
|
||||
EOS: /* eos comes here */
|
||||
if (i) { /* we have a string */
|
||||
s[i] = '\0'; /* set eos */
|
||||
i = 0;
|
||||
/* If we are in a define use dodef to add
|
||||
* location of defining member and global to
|
||||
* symbol table. */
|
||||
if (in_define) dodef(s);
|
||||
/* If we are on a 'p -' line for an ar lib
|
||||
* define this member as the file we are
|
||||
* using. */
|
||||
else if (is_member > 0) {
|
||||
is_member = 0;
|
||||
yyfile = addfile(s);
|
||||
}
|
||||
|
||||
/* If we have a '.define' mark this line as
|
||||
* in_define. */
|
||||
else if (strcmp(s, ".define") == 0)
|
||||
in_define = 1;
|
||||
/* Just a reference in the code to a var, so
|
||||
* add this reference to our symbol table. */
|
||||
else
|
||||
usedef(s);
|
||||
}
|
||||
|
||||
/* We are at the eol: reset our counters and switches */
|
||||
if (lastch == '\n') {
|
||||
col = 0;
|
||||
is_member = 0;
|
||||
in_define = 0;
|
||||
}
|
||||
|
||||
/* Lets do another character */
|
||||
was_space = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Not a space and i == 0 */
|
||||
if (i == 0) {
|
||||
/* Are we seeing 'p' in col 1 */
|
||||
if (lastch == 'p' && col == 1) {
|
||||
is_member = -1;
|
||||
}
|
||||
|
||||
/* Are we seeing '-' that follows 'p' in col 1 */
|
||||
else if (lastch == '-' && is_member < 0 && col == 3) {
|
||||
is_member = 1;
|
||||
}
|
||||
|
||||
/* If we have seen 'p -' now we are reading the name
|
||||
* or the first character of a global symbol */
|
||||
else if (is_member > 0 || (is_first_char(lastch) && was_space)) {
|
||||
s[i++] = lastch;
|
||||
if (is_member < 0) is_member = 0;
|
||||
}
|
||||
was_space = alt_space(lastch);
|
||||
}
|
||||
|
||||
/* Do the second char of a name */
|
||||
else if (i == 1) {
|
||||
if (is_member > 0 || is_second_char(lastch)) {
|
||||
s[i++] = lastch;
|
||||
} else
|
||||
is_member = 0;
|
||||
was_space = alt_space(lastch);
|
||||
}
|
||||
|
||||
/* Do the rest of a symbol or member name */
|
||||
else if (is_member > 0 || is_other_char(lastch)) {
|
||||
s[i++] = lastch;
|
||||
was_space = alt_space(lastch);
|
||||
} else {
|
||||
was_space = alt_space(lastch);
|
||||
goto EOS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns EOF on end of file */
|
||||
return(lastch);
|
||||
}
|
||||
Reference in New Issue
Block a user