⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mref.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
int n;{/* Scan b for the string s and truncate it there if found. */  char *p;  p = string;  while (*p != '\0') {	if (strncmp(p, s, n) == 0) {		*p = 0;		if (*(p - 1) == ' ') *(p - 1) = 0;		return;	} else {		p++;	}  }}char *backup(q)char *q;{/* Back the pointer q up to the start of the word it points to. */  while (*q != ' ' && *q != '*') q--;  return(q + 1);}void enter_sym(p, value, type)char *p;			/* pointer to name of symbol */int value;			/* line number on which symbol occurs */int type;			/* PUB, PRIV, EXT, DEF, SYM */{/* Enter a symbol in the hash table.  A symbol may be define in FS and again * in MM, etc.  Up to 3 definitions are stored. */  int h, len;  struct symtab *hp;  if (nsymbols >= NSYMS) panic("symbol table overflow");  /* Watch out for the #define PUBLIC line, etc. */  if (strlen(p) == 0) return;  if (strcmp(p, "PUBLIC") == 0) return;  if (strcmp(p, "PRIVATE") == 0) return;  if (strcmp(p, "EXTERN") == 0) return;  if (strcmp(p, "int") == 0) return;  if (strcmp(p, "char") == 0) return;  if (strcmp(p, "void") == 0) return;  strip(p, "(", 1);  h = find_slot(p);  hp = &symtab[h];  len = strlen(p);  if (len > SYM_SIZE) len = SYM_SIZE;  /* Enter the symbol.  Multiple definitions are allowed. */  strncpy(hp->sym_name, p, (size_t)len);/* entry is SYM_SIZE+1 for \'0' */  hp->sym_type = type;  hp->sym_val = value;  nsymbols++;}int find_slot(p)char *p;{/* Hash the string and return an index into the hash table.  If a collision * occurs, the first consecutive free slot is used. */  unsigned int h;  /* Search all entries starting at h for a free slot. */  h = hash(p);  while (1) {	if (symtab[h].sym_type == 0) return((int) h);	/* empty slot */	h = (h + 1) % NSYMS;	/* try next entry */  }}int lookup(p)char *p;{/* Is p is in the symbol table?  Return slot if it is present, -1 if absent. */  unsigned int h;  h = hash(p);  while (1) {	if (symtab[h].sym_type == 0) return(-1);	/* not present */	if (strcmp(p, symtab[h].sym_name) == 0) return ((int) h);	h = (h + 1) % NSYMS;  }}unsigned int hash(p)char *p;{/* Compute and return the hash code of p. */  int i, n;  unsigned h;  n = strlen(p);  if (n > SYM_SIZE) n = SYM_SIZE;  h = 0;  for (i = 0; i < n; i++) {	h += 23 * i * (int) *p;	p++;  }  h = h % NSYMS;  return(h);}void print_sym(){/* Print all the definitions. */  int n, k, i, limit;  struct symtab *ap, *bp, *cp;  n = compact();		/* compact the symbol table */  if (n < 0 || n > NSYMS) panic("compact returned invalid value");  sort(n);			/* sort the symbol table */  /* Print the symbol table. */  if (tflag) {	/* Produce the symbol.out file for troff. */	i = 0;	limit = stride;	while (1) {		while (i < limit) {			ap = &symtab[i];			bp = &symtab[i + stride];			cp = &symtab[i + 2 * stride];			if (ap < &symtab[n])				fprintf(sym, "%s\t%d", ap->sym_name, ap->sym_val);			if (bp < &symtab[n])				fprintf(sym, "\t%s\t%d", bp->sym_name, bp->sym_val);			if (cp < &symtab[n])				fprintf(sym, "\t%s\t%d", cp->sym_name, cp->sym_val);			fprintf(sym, "\n");			i++;		}		fprintf(sym, ".bp\n");		if (cp >= &symtab[n - 1]) return;		i += 2 * stride;		stride = stride2;	/* 1st page may be different */		limit = i + stride;	}  } else {	/* Produce the flat version of symbol.out. */	for (ap = &symtab[0]; ap < &symtab[n]; ap++) {		k = strlen(ap->sym_name);		fprintf(sym, "%s%s %5d  %s\n", ap->sym_name, &spaces[k],			ap->sym_val, ppmap[ap->sym_type]);	}  }}int compact(){/* Compact the symbol table to make sorting more efficient. */  unsigned int d;  struct symtab *ap, *bp;  bp = &symtab[NSYMS - 1];	/* bp points to last entry */  for (ap = &symtab[0]; ap < bp; ap++) {	if (ap->sym_type != 0) continue;	/* skip used slots. */	/* Ap points to an empty slot.  Find a full one and swap them. */	while (bp->sym_type == 0 && bp > symtab)		bp--;		/* skip empty slots */	if (bp <= ap) {		d = ap - symtab;		return(d);	}	swap(ap, bp);  }  return(ap - symtab);}void swap(ap, bp)struct symtab *ap, *bp;{/* Swap two symbol table entries. */  struct symtab xp;  xp = *ap;  *ap = *bp;  *bp = xp;}void sort(n)int n;				/* number of nonnull entries in symtab */{/* Sort the symbol table.  Use bubble sort. */  int s;  struct symtab *ap, *bp;  for (ap = &symtab[0]; ap < &symtab[n - 1]; ap++) {	for (bp = ap + 1; bp < &symtab[n]; bp++) {		s = strcmp(ap->sym_name, bp->sym_name);		if (s < 0) continue;		if (s == 0 && ap->sym_type < bp->sym_type) continue;		swap(ap, bp);	}  }}void gen_xref(file)char *file;{/* Build the cross reference listing.  Reread file, looking up all * symbols in the hash table.  On every hit, an entry written to the temporary * file.  Later they will be sorted and printed. */  int i, k;  register char *p;  char c;  FILE *f;  if ((f = fopen(file, "r")) == NULL) {	fprintf(stderr, "%s: cannot open %s\n", prog_name, file);	exit(1);  }  while (1) {	/* Each iteration of this outer loop reads one line of the file. */	if (fgets(line_buf, LINE_SIZE, f) == NULL) {		/* End of file hit. */		fclose(f);		if (cur_line % page_len != 0) {			k = cur_line % page_len;			if (k > 0) k = page_len - k;			cur_line += k;		}		return;	}	ntokens = 0;	p = line_buf;	if (comment) {		p = skip_comment(p);		if (*p == '\n') {			cur_line++;			continue;	/* we haven't seen end yet */		}	}	c = *p;	while (c != '\n') {		/* This loop scans the line looking for tokens. */		if (isalpha(c) || c == '_') {			/* This is the start of a token. */			token[ntokens++] = p;	/* store start of token */			while (isalnum(*p) || *p == '_') p++;			c = *p;	/* save character after token */			*p = 0;	/* terminate the token */			continue;		}		/* Check to see if it is a comment. */		if (c == '/' && *(p + 1) == '*') {			p = skip_comment(p + 2);	/* it's a comment */			c = *p;			continue;		}		/* Check to see if it is a string. */		if (c == '"') {			p++;			while (*p != '"') p++;			p++;			c = *p;			continue;		}		/* Check to see if it is a character constant. */		if (c == '\'') {			p++;			while (*p != '\'') {				if (*p == '\\') p++;				p++;			}			p++;			c = *p;			continue;		}		/* It is not a token or a comment, just ignore it. */		p++;		c = *p;	}	/* Process the token array just constructed. This is where	 * the cross references are written to TMP_FILE.  Put out	 * leading zeros so that sort will get them right. */	for (i = 0; i < ntokens; i++) {		p = token[i];		if (strlen(p) > SYM_SIZE) *(p + SYM_SIZE) = 0;		k = lookup(p);		if (k >= 0) {			fprintf(tmp, "%s ", p);			if (cur_line < 10)				fprintf(tmp, "0000%d\n", cur_line);			else if (cur_line < 100)				fprintf(tmp, "000%d\n", cur_line);			else if (cur_line < 1000)				fprintf(tmp, "00%d\n", cur_line);			else if (cur_line < 10000)				fprintf(tmp, "0%d\n", cur_line);			else				fprintf(tmp, "%d\n", cur_line);		}	}	cur_line++;  }}char *skip_comment(p)char *p;{/* Skip a comment. */  while (1) {	if (*p == '*' && *(p + 1) == '/') {		comment = 0;		return(p + 2);	}	if (*p == '\n') {		comment = 1;	/* next line is still comment. */		return(p);	}	p++;  }}void collect_xref(){/* Sort the cross references and format them. */  int i, values[MAX_VALUES], used, nval, s, flag;  register char *p;  char *pname, *pnum;  char cur[SYM_SIZE + 1];	/* name currently being processed. */  /* Use the sort program to sort the file where the cross references   * have been accumulating. */  fclose(tmp);			/* close temporary file to flush the buffer */  sort_xref();			/* sort the cross references */  unlink(TMP_FILE);		/* temporary file is not needed any more */  /* Open the sorted file to read it back. */  sortf = fopen(SORTED_FILE, "r");  if (sortf == NULL) {	fprintf(stderr, "%s: cannot read back %s \n", prog_name, SORTED_FILE);	exit(2);  }  /* Read back each line in turn. */  used = 0;  while (1) {	if (fgets(line_buf, LINE_SIZE, sortf) == NULL) {		/* EOF seen.  Flush current line and return. */		fprintf(xr, "\n");		fclose(xr);		unlink(SORTED_FILE);		return;	}	/* Terminate both of the tokens contained on each line with 0s. */	p = line_buf;	pname = p;	while (*p != ' ') p++;	*p = 0;	p++;	pnum = p;	while (*p != '\n') p++;	*p = 0;	/* Is this name the one we are currently working on? */	if (used == 0 || strcmp(pname, cur) != 0) {		nval = new_name(cur, used, pname, values);		xcount = nval;	/* # refs on this line so far */		prev_ref = -1;	}	used = 1;	/* For every reference, see if it is a definition.  If so, do	 * not print it, since the definitions are printed when the	 * symbol is encountered for the first time. */	s = atoi(pnum);	flag = 0;	for (i = 0; i < nval; i++)		if (s == values[i]) flag = 1;	if (flag) continue;	if (mflag && s == prev_ref) continue;	/* max 1 citation/line */	if (xcount > 0 && xcount % MAX_PER_LINE == 0) {		if (tflag)			fprintf(xr, "\t");		else			fprintf(xr, "                       ");	}	/* The next line prints a reference on the cross reference listing. */	if (tflag)		fprintf(xr, "\t%d", s);	else		fprintf(xr, " %5d", s);	prev_ref = s;		/* remember it for subsequent use */	xcount++;		/* number of symbols printed on this line */	if (xcount % MAX_PER_LINE == 0) fprintf(xr, "\n");  }}int new_name(cur, used, pname, values)char *cur;			/* storage for current name */int used;			/* 0 only on first call. */char *pname;			/* pointer to the new name */int values[];			/* all the definitions of the new name */{/* A new name has been read.  Finish off the old one and prepare new one. */  int slot, nval, i, j, type, temp;  /* If a name is currently in use (all except first time), finish it. */  if (used && xcount % MAX_PER_LINE > 0) fprintf(xr, "\n");  xcount = 0;  /* Copy the new name in place and fetch its definitions. Multiple   * definitions are allowed, e.g., do_fork may appear in FS and also   * in MM, but if they are different types (e.g., one PUBLIC and one   * PRIVATE) only one of them will be included in the listing, to   * avoid messing up the layout. */  strcpy(cur, pname);  cur[SYM_SIZE] = 0;  slot = lookup(pname);  nval = 0;  while (symtab[slot].sym_type > 0) {	if (strcmp(pname, symtab[slot].sym_name) == 0) {		values[nval++] = symtab[slot].sym_val;		type = symtab[slot].sym_type;		if (nval == MAX_VALUES) break;	}	slot = (slot + 1) % NSYMS;  }  /* Sort the values. */  for (i = 0; i < nval - 1; i++) {	for (j = i + 1; j < nval; j++) {		if (values[i] > values[j]) {			temp = values[i];			values[i] = values[j];			values[j] = temp;		}	}  }  /* Print the line in the cross reference map that contains the symbol. */  fprintf(xr, "%s", pname);  if (tflag) {	fprintf(xr, "\t%s\\fB", ppmap2[type]);	for (i = 0; i < nval; i++) fprintf(xr, "\t%d", values[i]);	fprintf(xr, "\\fR");  } else {	i = strlen(pname);	fprintf(xr, "%s %s ", &spaces[i], ppmap2[type]);	for (i = 0; i < nval; i++) fprintf(xr, "%5d ", values[i]);  }  return(nval);}void sort_xref(){/* Sort the cross reference file by forking off a copy of 'sort'. */  int status, pid;  pid = fork();  if (pid > 0) {	/* Parent just waits. */	wait(&status);	if (status != 0) panic("couldn't sort cross references");  } else {	/* Child execs sort. */	close(0);	close(1);	if (open(TMP_FILE, O_RDONLY) < 0) exit(1);	if (creat(SORTED_FILE, 0644) < 0) exit(2);	execl("/bin/sort", "sort", (char *) 0);	execl("/usr/bin/sort", "sort", (char *) 0);	exit(3);  }}void output_macros(f, text)FILE *f;char *text[];{/* Output troff commands. */  int i;  i = 0;  while (text[i] != (char *) 0) {	fprintf(f, text[i]);	i++;  }}void sym_macros(){}void xref_macros(){}void panic(s)char *s;{  fprintf(stderr, "%s: %s\n", prog_name, s);  exit(2);}void usage(){  fprintf(stderr, "Usage: %s [-<n>] [-dlmtsx] [-p pagenr] file ... \n",	prog_name);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -