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

📄 read.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* end-of-line. */     register int	nbytes;	/* 8=.quad 16=.octa ... */{  register char		c;	/* input_line_pointer -> c. */  register int		radix;  register long int	length;	/* Number of chars in an object. */  register int		digit;	/* Value of 1 digit. */  register int		carry;	/* For multi-precision arithmetic. */  register int		work;	/* For multi-precision arithmetic. */  register char *	p;	/* For multi-precision arithmetic. */  extern char hex_value[];	/* In hex_value.c. */  /*   * The following awkward logic is to parse ZERO or more strings,   * comma seperated. Recall an expression includes its leading &   * trailing blanks. We fake a leading ',' if there is (supposed to   * be) a 1st expression, and keep demanding 1 expression for each ','.   */  if (is_it_end_of_statement())    {      c = 0;			/* Skip loop. */    }  else    {      c = ',';			/* Do loop. */      -- input_line_pointer;    }  while (c == ',')    {      ++ input_line_pointer;      SKIP_WHITESPACE();      c = * input_line_pointer;      /* C contains 1st non-blank character of what we hope is a number. */      if (c == '0')	{	  c = * ++ input_line_pointer;	  if (c == 'x' || c=='X')	    {	      c = * ++ input_line_pointer;	      radix = 16;	    }	  else	    {	      radix = 8;	    }	}      else	{	  radix = 10;	}      /*       * This feature (?) is here to stop people worrying about       * mysterious zero constants: which is what they get when       * they completely omit digits.       */      if (hex_value[c] >= radix)	{	  as_warn( "Missing digits. 0 assumed." );	}      bignum_high = bignum_low - 1; /* Start constant with 0 chars. */      for(   ;   (digit = hex_value [c]) < radix;   c = * ++ input_line_pointer)	{	  /* Multiply existing number by radix, then add digit. */	  carry = digit;	  for (p=bignum_low;   p <= bignum_high;   p++)	    {	      work = (*p & MASK_CHAR) * radix + carry;	      *p = work & MASK_CHAR;	      carry = work >> BITS_PER_CHAR;	    }	  if (carry)	    {	      grow_bignum();	      * bignum_high = carry & MASK_CHAR;	      know( (carry & ~ MASK_CHAR) == 0);	    }	}      length = bignum_high - bignum_low + 1;      if (length > nbytes)	{	  as_warn( "Most significant bits truncated in integer constant." );	}      else	{	  register long int	leading_zeroes;	  for(leading_zeroes = nbytes - length;	      leading_zeroes;	      leading_zeroes --)	    {	      grow_bignum();	      * bignum_high = 0;	    }	}      if (! need_pass_2)	{	  p = frag_more (nbytes);	  bcopy (bignum_low, p, (int)nbytes);	}      /* C contains character after number. */      SKIP_WHITESPACE();      c = * input_line_pointer;      /* C contains 1st non-blank character after number. */    }  demand_empty_rest_of_line();}				/* big_cons() */static voidgrow_bignum()			/* Extend bignum by 1 char. */{  register long int	length;  bignum_high ++;  if (bignum_high >= bignum_limit)    {      length = bignum_limit - bignum_low;      bignum_low = xrealloc (bignum_low, length + length);      bignum_high = bignum_low + length;      bignum_limit = bignum_low + length + length;    }}				/* grow_bignum(); *//* *			float_cons() * * CONStruct some more frag chars of .floats .ffloats etc. * Makes 0 or more new frags. * If need_pass_2 == TRUE, no frags are emitted. * This understands only floating literals, not expressions. Sorry. * * A floating constant is defined by atof_generic(), except it is preceded * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its * reading, I decided to be incompatible. This always tries to give you * rounded bits to the precision of the pseudo-op. Former AS did premature * truncatation, restored noisy bits instead of trailing 0s AND gave you * a choice of 2 flavours of noise according to which of 2 floating-point * scanners you directed AS to use. * * In:	input_line_pointer -> whitespace before, or '0' of flonum. * */void	/* JF was static, but can't be if VAX.C is goning to use it */float_cons(float_type)		/* Worker to do .float etc statements. */				/* Clobbers input_line-pointer, checks end-of-line. */     register float_type;	/* 'f':.ffloat ... 'F':.float ... */{  register char *	p;  register char		c;  int	length;	/* Number of chars in an object. */  register char *	err;	/* Error from scanning floating literal. */  char		temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];  /*   * The following awkward logic is to parse ZERO or more strings,   * comma seperated. Recall an expression includes its leading &   * trailing blanks. We fake a leading ',' if there is (supposed to   * be) a 1st expression, and keep demanding 1 expression for each ','.   */  if (is_it_end_of_statement())    {      c = 0;			/* Skip loop. */      ++ input_line_pointer;	/* -> past termintor. */    }  else    {      c = ',';			/* Do loop. */    }  while (c == ',')    {      /* input_line_pointer -> 1st char of a flonum (we hope!). */      SKIP_WHITESPACE();      /* Skip any 0{letter} that may be present. Don't even check if the       * letter is legal. Someone may invent a "z" format and this routine       * has no use for such information. Lusers beware: you get       * diagnostics if your input is ill-conditioned.       */      if(input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))	  input_line_pointer+=2;      err = md_atof (float_type, temp, &length);      know( length <=  MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);      know( length > 0 );      if (* err)	{	  as_warn( "Bad floating literal: %s", err);	  ignore_rest_of_line();	  /* Input_line_pointer -> just after end-of-line. */	  c = 0;		/* Break out of loop. */	}      else	{	  if ( ! need_pass_2)	    {	      p = frag_more (length);	      bcopy (temp, p, length);	    }	  SKIP_WHITESPACE();	  c = * input_line_pointer ++;	  /* C contains 1st non-white character after number. */	  /* input_line_pointer -> just after terminator (c). */	}    }  -- input_line_pointer;		/* -> terminator (is not ','). */  demand_empty_rest_of_line();}				/* float_cons() *//* *			stringer() * * We read 0 or more ',' seperated, double-quoted strings. * * Caller should have checked need_pass_2 is FALSE because we don't check it. */static voidstringer(append_zero)		/* Worker to do .ascii etc statements. */				/* Checks end-of-line. */     register int append_zero;	/* 0: don't append '\0', else 1 */{  /* register char *	p; JF unused */  /* register int		length; JF unused */	/* Length of string we read, excluding */				/* trailing '\0' implied by closing quote. */  /* register char *	where; JF unused */  /* register fragS *	fragP; JF unused */  register int c;  /*   * The following awkward logic is to parse ZERO or more strings,   * comma seperated. Recall a string expression includes spaces   * before the opening '\"' and spaces after the closing '\"'.   * We fake a leading ',' if there is (supposed to be)   * a 1st, expression. We keep demanding expressions for each   * ','.   */  if (is_it_end_of_statement())    {      c = 0;			/* Skip loop. */      ++ input_line_pointer;	/* Compensate for end of loop. */    }  else    {      c = ',';			/* Do loop. */    }  for (   ;   c == ',';   c = *input_line_pointer ++)    {      SKIP_WHITESPACE();      if (* input_line_pointer == '\"')	{	  ++ input_line_pointer; /* -> 1st char of string. */	  while ( (c = next_char_of_string()) >= 0)	    {	      FRAG_APPEND_1_CHAR( c );	    }	  if (append_zero)	    {	      FRAG_APPEND_1_CHAR( 0 );	    }	  know( input_line_pointer [-1] == '\"' );	}      else	{	  as_warn( "Expected \"-ed string" );	}      SKIP_WHITESPACE();    }  -- input_line_pointer;  demand_empty_rest_of_line();}				/* stringer() */static intnext_char_of_string (){  register int c;  c = * input_line_pointer ++;  switch (c)    {    case '\"':      c = -1;      break;    case '\\':      switch (c = * input_line_pointer ++)	{	case 'b':	  c = '\b';	  break;	case 'f':	  c = '\f';	  break;	case 'n':	  c = '\n';	  break;	case 'r':	  c = '\r';	  break;	case 't':	  c = '\t';	  break;	case '\\':	case '"':	  break;		/* As itself. */	case '0':	case '1':	case '2':	case '3':	case '4':	case '5':	case '6':	case '7':	case '8':	case '9':	  {	    long int number;	    for (number = 0;   isdigit(c);   c = * input_line_pointer ++)	      {		number = number * 8 + c - '0';	      }	    c = number;	  }	  -- input_line_pointer;	  break;	case '\n':/*	  as_fatal( "Unterminated string - use app!" ); *//* To be compatible with BSD 4.2 as: give the luser a linefeed!! */	  c = '\n';	  break;	default:	  as_warn( "Bad escaped character in string, '?' assumed" );	  c = '?';	  break;	}      break;    default:      break;    }  return (c);}static segTget_segmented_expression ( expP )     register expressionS *	expP;{  register segT		retval;  if ( (retval = expression( expP )) == SEG_PASS1 || retval == SEG_NONE || retval == SEG_BIG )    {      as_warn("Expected address expression: absolute 0 assumed");      retval = expP -> X_seg = SEG_ABSOLUTE;      expP -> X_add_number   = 0;      expP -> X_add_symbol   = expP -> X_subtract_symbol = 0;    }  return (retval);		/* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */}static segTget_known_segmented_expression ( expP )     register expressionS *	expP;{  register segT		retval;  register char *	name1;  register char *	name2;  if (   (retval = get_segmented_expression (expP)) == SEG_UNKNOWN      )    {      name1 = expP -> X_add_symbol ? expP -> X_add_symbol -> sy_name : "";      name2 = expP -> X_subtract_symbol ? expP -> X_subtract_symbol -> sy_name : "";      if ( name1 && name2 )	{	  as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",		  name1, name2);	}      else	{	  as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",		  name1 ? name1 : name2);	}      retval = expP -> X_seg = SEG_ABSOLUTE;      expP -> X_add_number   = 0;      expP -> X_add_symbol   = expP -> X_subtract_symbol = NULL;    } know(   retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE );  return (retval);}				/* get_known_segmented_expression() *//* static */ long int /* JF was static, but can't be if the MD pseudos are to use it */get_absolute_expression (){  expressionS	exp;  register segT s;  if ( (s = expression(& exp)) != SEG_ABSOLUTE )    {      if ( s != SEG_NONE )	{	  as_warn( "Bad Absolute Expression, absolute 0 assumed.");	}      exp . X_add_number = 0;    }  return (exp . X_add_number);}static char			/* return terminator */get_absolute_expression_and_terminator( val_pointer)     long int *		val_pointer; /* return value of expression */{  * val_pointer = get_absolute_expression ();  return ( * input_line_pointer ++ );}/* *			demand_copy_C_string() * * Like demand_copy_string, but return NULL if the string contains any '\0's. * Give a warning if that happens. */static char *demand_copy_C_string (len_pointer)     int *	len_pointer;{  register char *	s;  if (s = demand_copy_string (len_pointer))    {      register int	len;      for (len = * len_pointer;	   len > 0;	   len--)	{	  if (* s == 0)	    {	      s = 0;	      len = 1;	      * len_pointer = 0;	      as_warn( "This string may not contain \'\\0\'" );	    }	}    }  return (s);}/* *			demand_copy_string() * * Demand string, but return a safe (=private) copy of the string. * Return NULL if we can't read a string here. */static char *demand_copy_string (lenP)     int *	lenP;{  register int		c;  register int		len;	   char *	retval;  len = 0;  SKIP_WHITESPACE();  if (* input_line_pointer == '\"')    {      input_line_pointer ++;	/* Skip opening quote. */      while ( (c = next_char_of_string()) >= 0 ) {	  obstack_1grow ( &notes, c );	  len ++;	}      /* JF this next line is so demand_copy_C_string will return a null         termanated string. */      obstack_1grow(&notes,'\0');      retval=obstack_finish( &notes);  } else {      as_warn( "Missing string" );      retval = NULL;      ignore_rest_of_line ();    }  * lenP = len;  return (retval);}/* *		is_it_end_of_statement() * * In:	Input_line_pointer -> next character. * * Do:	Skip input_line_pointer over all whitespace. * * Out:	TRUE if input_line_pointer -> end-of-line. */static intis_it_end_of_statement(){  SKIP_WHITESPACE();  return (is_end_of_line [* input_line_pointer]);}voidequals(sym_name)char *sym_name;{  register struct symbol * symbolP; /* symbol we are working with */  input_line_pointer++;  if(*input_line_pointer=='=')    input_line_pointer++;  while(*input_line_pointer==' ' || *input_line_pointer=='\t')    input_line_pointer++;  if(sym_name[0]=='.' && sym_name[1]=='\0') {    /* Turn '. = mumble' into a .org mumble */    register segT segment;    expressionS exp;    register char *p;    segment = get_known_segmented_expression(& exp);    if ( ! need_pass_2 ) {      if (segment != now_seg && segment != SEG_ABSOLUTE)        as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",                seg_name [(int) segment], seg_name [(int) now_seg]);      p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,                    exp.X_add_number, (char *)0);      * p = 0;    } /* if (ok to make frag) */  } else {    symbolP=symbol_find_or_make(sym_name);    pseudo_set(symbolP);  }}/* end: read.c */

⌨️ 快捷键说明

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