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

📄 cccp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      ip2->buf = xbuf;      ip2->length = totlen;      /* skip the input over the whole macro call. */      ip->bufp = bp;    }  else    {      ip2->buf = ip2->bufp = defn->expansion;      ip2->length = defn->length;    }    rescan (ip2, op);  --indepth;  *excess_newlines_ptr += newlines_found;  ip->lineno += newlines_found;  return 0; nope:  error ("argument mismatch");  --indepth;  return 1;}/* * skip a balanced paren string up to the next comma. */U_CHAR *skip_macro_argument(bp, ip, newlines)     U_CHAR *bp;     FILE_BUF *ip;     int *newlines;{  int paren = 0;  int quotec = 0;    while (bp < ip->buf + ip->length) {    switch (*bp) {    case '(':      paren++;      break;    case ')':      if (--paren < 0)	return bp;      break;    case '\n':      ++*newlines;      break;    case '/':      if (bp[1] != '*' || bp + 1 >= ip->buf + ip->length)	break;      bp += 2;      while ((bp[0] != '*' || bp[1] != '/')	     && bp + 1 < ip->buf + ip->length)	{	  if (*bp == '\n') ++*newlines;	  bp++;	}      break;    case '\'':		/* JF handle quotes right  */    case '\"':      for (quotec = *bp++; bp < ip->buf + ip->length && *bp != quotec; bp++)	{	  if (*bp == '\\') bp++;	  if (*bp == '\n')	    ++*newlines;	}      break;    case ',':      if (paren == 0)	return bp;      break;    }    bp++;  }  return bp;}/* * error - print out message.  also make print on stderr.  Uses stdout * now for debugging convenience. */error (msg)     U_CHAR *msg;{  int i;  FILE_BUF *ip = NULL;  for (i = indepth - 1; i >= 0; i--)    if (instack[i].fname != NULL) {      ip = &instack[i];      break;    }  if (ip != NULL)    fprintf(stdout, "file %s, offset %d (line %d): ",	    ip->fname, ip->bufp - ip->buf, ip->lineno);  fprintf(stdout, "%s\n", msg);  return 0;}/* * if OBUF doesn't have NEEDED bytes after OPTR, make it bigger *    this should be a macro, for speed. * The "expand" in the name of this routine means buffer expansion, * not macro expansion.  It may become necessary to have some hacky * mechanism for flushing out the output buffer if it gets too big. * * As things stand, nothing is ever placed in the output buffer to be * removed again except when it's KNOWN to be part of an identifier, * so flushing and moving down everything left, instead of expanding, * should work ok. */U_CHAR *check_expand(obuf, needed)     register FILE_BUF *obuf;     register int needed;{  register int i;  register U_CHAR *p;    if (obuf->length - (obuf->bufp - obuf->buf) > needed)    return obuf->buf;  i = 2 * obuf->length;  if (needed >= i)    i += (3 * needed) / 2;  if ((p = (U_CHAR *) xrealloc (obuf->buf, i)) == NULL)    return NULL;  obuf->bufp = p + (obuf->bufp - obuf->buf);  obuf->buf = p;  obuf->length = i;  return p;}  /* * install a name in the main hash table, even if it is already there. *   name stops with first non alphanumeric, except leading '#'. * caller must check against redefinition if that is desired. * delete() removes things installed by install() in fifo order. * this is important because of the `defined' special symbol used * in #if, and also if pushdef/popdef directives are ever implemented. */HASHNODE *install (name, type, value)     U_CHAR *name;     int type;     int value;        /* watch out here if sizeof(U_CHAR *) != sizeof (int) */{  HASHNODE *hp;  int i, len = 0, bucket;  register U_CHAR *p;  p = name;  while (is_idchar[*p])    p++;  len = p - name;  i = sizeof (HASHNODE) + len + 1;  hp = (HASHNODE *) xmalloc (i);  bucket = hashf(name, len, HASHSIZE);  hp->bucket_hdr = &hashtab[bucket];  hp->next = hashtab[bucket];  hashtab[bucket] = hp;  hp->prev = NULL;  if (hp->next != NULL)    hp->next->prev = hp;  hp->type = type;  hp->length = len;  hp->value.ival = value;  hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);  bcopy (name, hp->name, len);  return hp;}/* * find the most recent hash node for name name (ending with first * non-identifier char) installed by install */HASHNODE *lookup (name)     U_CHAR *name;{  register U_CHAR *bp;  register HASHNODE *bucket;  int len;  for (bp = name; is_idchar[*bp]; bp++)    ;  len = bp - name;  bucket = hashtab[hashf(name, len, HASHSIZE)];  while (bucket) {    if (bucket->length == len && strncmp(bucket->name, name, len) == 0)      return bucket;    bucket = bucket->next;  }  return NULL;}/* * Delete a hash node.  Some weirdness to free junk from macros. * More such weirdness will have to be added if you define more hash * types that need it. */delete(hp)     HASHNODE *hp;{    if (hp->prev != NULL)    hp->prev->next = hp->next;  if (hp->next != NULL)    hp->next->prev = hp->prev;  /* make sure that the bucket chain header that     the deleted guy was on points to the right thing afterwards. */  if (hp == *hp->bucket_hdr)    *hp->bucket_hdr = hp->next;  if (hp->type == T_MACRO) {    DEFINITION *d = hp->value.defn;    struct reflist *ap, *nextap;    for (ap = d->pattern; ap != NULL; ap = nextap) {      nextap = ap->next;      free (ap);    }    free (d);  }}/* * return hash function on name.  must be compatible with the one * computed a step at a time, elsewhere */inthashf(name, len, hashsize)     register U_CHAR *name;     register int len;     int hashsize;{  register int r = 0;    while (len--)    r = HASHSTEP(r, *name++);    return MAKE_POS(r) % hashsize;}/* * initialize random junk in the hash table and maybe other places */initialize_random_junk(){  register int i;  /*   * Set up is_idchar and is_idstart tables.  These should be   * faster than saying (is_alpha(c) || c == '_'), etc.   * Must do set up these things before calling any routines tthat   * refer to them.   */  for (i = 'a'; i <= 'z'; i++) {    ++is_idchar[i - 'a' + 'A'];    ++is_idchar[i];    ++is_idstart[i - 'a' + 'A'];    ++is_idstart[i];  }  for (i = '0'; i <= '9'; i++)    ++is_idchar[i];  ++is_idchar['_'];  ++is_idstart['_'];  /* horizontal space table */  ++is_hor_space[' '];  ++is_hor_space['\t'];  install("__LINE__", T_SPECLINE, 0);  install("__DATE__", T_DATE, 0);  install("__FILE__", T_FILE, 0);  install("__TIME__", T_TIME, 0);#ifdef vax  make_definition("vax 1");#endif#ifdef unix  make_definition("unix 1");#endif  /* is there more? */  }/* * process a given definition string, for initialization */make_definition(str)     U_CHAR *str;{  FILE_BUF *ip;  struct keyword_table *kt;  ip = &instack[indepth++];  ip->fname = "*Initialization*";  ip->buf = ip->bufp = str;  ip->length = strlen(str);  ip->lineno = 1;  for (kt = keyword_table; kt->type != T_DEFINE; kt++)    ;  /* pass NULL as output ptr to do_define since we KNOW it never     does any output.... */  do_define (str, str + strlen(str) /* - 1 JF */ , NULL, kt);  --indepth;}/* JF, this does the work for the -U option */make_undef(str)     U_CHAR *str;{  FILE_BUF *ip;  struct keyword_table *kt;  ip = &instack[indepth++];  ip->fname = "*undef*";  ip->buf = ip->bufp = str;  ip->length = strlen(str);  ip->lineno = 1;  for(kt = keyword_table; kt->type != T_UNDEF; kt++)    ;  do_undef(str,str + strlen(str) - 1, NULL, kt);  --indepth;}#ifndef BSD#ifndef BSTRINGvoidbzero (b, length)     register char *b;     register int length;{#ifdef VMS  short zero = 0;  long max_str = 65535;  while (length > max_str)    {      (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);      length -= max_str;      b += max_str;    }  (void) LIB$MOVC5 (&zero, &zero, &zero, &length, b);#else  while (length-- > 0)    *b++ = 0;#endif /* not VMS */}void bcopy (b1, b2, length)     register char *b1;     register char *b2;     register int length;{#ifdef VMS  long max_str = 65535;  while (length > max_str)    {      (void) LIB$MOVC3 (&max_str, b1, b2);      length -= max_str;      b1 += max_str;      b2 += max_str;    }  (void) LIB$MOVC3 (&length, b1, b2);#else  while (length-- > 0)    *b2++ = *b1++;#endif /* not VMS */} intbcmp (b1, b2, length)	/* This could be a macro! */     register char *b1;     register char *b2;      register int length; {#ifdef VMS   struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};   struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};   return STR$COMPARE (&src1, &src2);#else   while (length-- > 0)     if (*b1++ != *b2++)       return 1;   return 0;#endif /* not VMS */}#endif /* not BSTRING */#endif /* not BSD */voidfatal (str, arg)     char *str, *arg;{  fprintf (stderr, "%s: ", progname);  fprintf (stderr, str, arg);  fprintf (stderr, "\n");  exit (FATAL_EXIT_CODE);}voidperror_with_name (name)     char *name;{  extern int errno, sys_nerr;  extern char *sys_errlist[];  fprintf (stderr, "%s: ", progname);  if (errno < sys_nerr)    fprintf (stderr, "%s for %s\n", sys_errlist[errno], name);  else    fprintf (stderr, "cannot open %s\n", sys_errlist[errno], name);}voidpfatal_with_name (name)     char *name;{  perror_with_name (name);  exit (FATAL_EXIT_CODE);}static voidmemory_full (){  fatal ("Memory exhausted.");}char *xmalloc (size)     int size;{  extern char *malloc ();  register char *ptr = malloc (size);  if (ptr != 0) return (ptr);  memory_full ();  /*NOTREACHED*/}char *xrealloc (old, size)     char *old;     int size;{  extern char *realloc ();  register char *ptr = realloc (old, size);  if (ptr != 0) return (ptr);  memory_full ();  /*NOTREACHED*/}char *xcalloc (number, size)     int number, size;{  extern char *malloc ();  register int total = number * size;  register char *ptr = malloc (total);  if (ptr != 0)    {      bzero (ptr, total);      return (ptr);    }  memory_full ();  /*NOTREACHED*/}

⌨️ 快捷键说明

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