操作系统源代码

源代码在线查看: whatsnew.c

软件大小: 3264 K
上传用户: bbbbbb110
关键词: 操作系统 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				/* whatsnew - mark changes in a patched file	Author: Andy Tanenbaum */								/* MINIX programs are constantly being updated.  When a cdiff patch comes in,				 * it would be nice to be able to apply the patch, and then list the new file,				 * which the changed lines marked somehow.  This program allows that.  Suppose				 * prog.c is the newly patched file and prog.cdif is the cdiff listing that was				 * used to produce it.  Then the command				 *				 * 	whatsnew prog.c prog.cdif				 *				 * will copy prog.c to standard output, marking all added or changed lines				 * with + or ! at the end, respectively.  Output lines are forced to a standard				 * length to make the + and ! symbols easy to find.  The default length is 80,				 * but it can be changed using a flag.  For example,				 *				 *	whatsnew -75 prog.c prog.cdif				 *				 * which pads or truncates the output lines to 75 characters before appending				 * ! or +.  Tabs are converted to spaces in the process.				 */								#include 				#include 				#include 								#define MAX_WIDTH       256	/* max line length */				#define HEAP_LINES    10000	/* max length of the diff listing */				#define HEAP_BYTES    30000	/* total space for saved lines */				#define HASH_SIZE        10	/* how much of a line is the hash key */				#define TAB_WIDTH         8	/* how far apart are the tab stops */				#define DEF_WIDTH        80	/* default width */								int cdif_found = 0;		/* set to 1 if cdif entry found */				char *indices[HEAP_LINES];	/* pointers into the heap */				char heap[HEAP_BYTES];		/* the + and ! lines are saved here. */				int lines_used;			/* number of index slots used */				char *hp = heap;		/* pointer to end of the heap */				int width = DEF_WIDTH;		/* how wide to print the listing */								_PROTOTYPE(int main, (int argc, char **argv));				_PROTOTYPE(void eat_cdif, (FILE *cdif, char *name));				_PROTOTYPE(void read_and_print, (FILE *newf));				_PROTOTYPE(int present, (char *line, char *name));				_PROTOTYPE(void enter_line, (char *line));				_PROTOTYPE(int hash, (char *p));				_PROTOTYPE(void print_line, (char *line, int c));				_PROTOTYPE(void usage, (void));								int main(argc, argv)				int argc;				char *argv[];				{								  int k;				  char *p;				  FILE *newf, *cdif;								  /* Process the command line. */				  if (argc < 2) usage();								  k = 1;				  p = argv[1];				  if (*p == '-') {					width = atoi(p + 1);					if (width < 0 || width > MAX_WIDTH) {						fprintf(stderr, "%s: max line size is %d\n",argv[0],MAX_WIDTH);						exit(1);					}					k++;					if (argc != 4) usage();				  } else {					if (argc != 3) usage();				  }								  newf = fopen(argv[k], "r");				  if (newf == NULL) {					fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[k]);					exit(1);				  }				  cdif = fopen(argv[k + 1], "r");				  if (cdif == NULL) {					fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[k + 1]);					exit(1);				  }								  /* Read the cdif file and hash all the relevant lines. */				  eat_cdif(cdif, argv[k]);								  /* Read and print the new file. */				  read_and_print(newf);								  return(0);				}								void eat_cdif(cdif, name)				FILE *cdif;				char *name;				{				  char line[MAX_WIDTH];								  /* First find the start of the relevant cdif stuff. */				  while (fgets(line, MAX_WIDTH, cdif) != NULL) {					if (strncmp(line, "*** ", (size_t)4) != 0) continue;					if (present(line, name) && present(line, ":")) {						cdif_found = 1;						break;					}				  }				  if (cdif_found == 0) {					fprintf(stderr, "no cdif found for %s\n", name);					exit(2);				  }								  /* We found it. Save all the ! and + lines in the hash table. */				  while (fgets(line, MAX_WIDTH, cdif) != NULL) {					if (strncmp(line, "*** ", (size_t)4) == 0 && present(line, ":")) break;					if (line[0] != '+' && line[0] != '!') continue;					if (line[1] != ' ') continue;					enter_line(line);				  }				}												void read_and_print(newf)				FILE *newf;				{				  int h, hit;				  char line[MAX_WIDTH], c;								  /* Examine each line in the patched file. */				  while (fgets(line, MAX_WIDTH, newf) != NULL) {					/* Hash the line and see if it is in the table. */					hit = -1;					h = hash(line);					while (indices[h] != 0) {						if (strcmp(line, indices[h] + 2) == 0) {							hit = h;							break;						}						h = (h + 1) % HEAP_LINES;					}					c = (hit >= 0 ? *(indices[h]) : ' ');					print_line(line, c);				  }				}												int present(line, name)				char *line, *name;				{				/* Scan line to see if the string name is present in it anywhere.  If so,				 * return 1, else return 0.				 */								  register int n;				  register char *p;								  p = line;				  n = strlen(name);				  while (*p != 0) {					if (strncmp(p, name, (size_t)n) == 0) return(1);					p++;				  }				  return(0);				}												void enter_line(line)				char *line;				{				/* Enter a line in the hash table.  Note that the first two characters				 * do not count, as they have been added by cdiff.				 */								  int n, h;								  /* Certain lines should not be entered as they occur often. */				  n = strlen(line) - 2;				  if (n == 1) return;		/* don't enter null lines */				  if (strncmp(line, "+ /*==", (size_t)6) == 0) return;				  if (strncmp(line, "+  *==", (size_t)6) == 0) return;				  if (strncmp(line, "+   {", (size_t)5) == 0) return;				  if (strncmp(line, "+   }", (size_t)5) == 0) return;				  if (strncmp(line, "+ {", (size_t)3) == 0) return;				  if (strncmp(line, "+ }", (size_t)3) == 0) return;				  if (strncmp(line, "+ \t{", (size_t)4) == 0) return;				  if (strncmp(line, "+ \t}", (size_t)4) == 0) return;				  if (strncmp(line, "+ else", (size_t)6) == 0) return;				  if (strncmp(line, "+ #end", (size_t)6) == 0) return;								  if (lines_used == HEAP_LINES) {					fprintf(stderr, "cdif listing has too many lines\n");					exit(1);				  }				  if (hp + n >= &heap[HEAP_BYTES]) {					fprintf(stderr, "cdif listing has too many bytes\n");					exit(1);				  }								  /* Make the heap entry. */				  h = hash(line + 2);				  while (indices[h] != 0) h = (h + 1) % HEAP_LINES;				  indices[h] = hp;		/* indices table points to the lines */				  strcpy(hp, line);		/* first two chars also copied */				  lines_used++;			/* count # table slots used */				  hp += n + 3;			/* 0 byte counts also */				}												int hash(p)				char *p;				{				/* Compute and return the hash code of p. */								  int i, n;				  unsigned h;								  n = strlen(p);				  if (n > HASH_SIZE) n = HASH_SIZE;				  h = 0;				  for (i = 0; i < n; i++) {					h += 23 * i * (int) *p;					p++;				  }				  h = h % HEAP_LINES;				  return((int) h);				}												void print_line(line, c)				char *line, c;				{				/* Print the line. */								  int col, spaces;				  char out_buf[3 * MAX_WIDTH], *p, *q;								  p = line;				  q = out_buf;				  col = 0;				  while (*p != '\n') {					/* This loop executed once for each character in the line. */					if (*p != '\t') {						/* Not a tab. */						*q++ = *p++;						col++;					} else {						/* Tab. */						spaces = TAB_WIDTH - (col % TAB_WIDTH);						col += spaces;						while (spaces--) *q++ = ' ';						p++;					}				  }				  while (q < &out_buf[width]) *q++ = ' ';				  q = &out_buf[width];				  *q++ = ' ';				  *q++ = c;				  *q++ = '\n';				  *q = 0;				  fputs(out_buf, stdout);				}												void usage()				{				  fprintf(stderr, "Usage: whatsnew [-] file file.cdif\n");				  exit(1);				}							

相关资源