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

📄 read.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/*- * This code is derived from software copyrighted by the Free Software * Foundation. * * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. */#ifndef lintstatic char sccsid[] = "@(#)read.c	6.4 (Berkeley) 5/8/91";#endif /* not lint *//* read.c - read a source file -   Copyright (C) 1986,1987 Free Software Foundation, Inc.This file is part of GAS, the GNU Assembler.GAS is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GAS is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GAS; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#define MASK_CHAR (0xFF)	/* If your chars aren't 8 bits, you will				   change this a bit.  But then, GNU isn't				   spozed to run on your machine anyway.				   (RMS is so shortsighted sometimes.)				 */#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)				/* This is the largest known floating point */				/* format (for now). It will grow when we */				/* do 4361 style flonums. *//* Routines that read assembler source text to build spagetti in memory. *//* Another group of these functions is in the as-expr.c module */#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include "as.h"#include "read.h"#include "md.h"#include "hash.h"#include "obstack.h"#include "frags.h"#include "flonum.h"#include "struc-symbol.h"#include "expr.h"#include "symbols.h"#ifdef SPARC#include "sparc.h"#define OTHER_ALIGN#endif#ifdef I860#include "i860.h"#endifchar *	input_line_pointer;	/* -> next char of source file to parse. */#if BITS_PER_CHAR != 8The following table is indexed by [ (char) ] and will break ifa char does not have exactly 256 states (hopefully 0:255!) !#endifconst char				/* used by is_... macros. our ctype[] */lex_type [256] = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* @ABCDEFGHIJKLMNO */  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* PQRSTUVWXYZ[\]^_ */  0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,       /* _!"#$%&'()*+,-./ */  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,       /* 0123456789:;<=>? */  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,       /* @ABCDEFGHIJKLMNO */  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3,       /* PQRSTUVWXYZ[\]^_ */  0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,       /* `abcdefghijklmno */  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,       /* pqrstuvwxyz{|}~. */  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };/* * In: a character. * Out: TRUE if this character ends a line. */#define _ (0)const char is_end_of_line [256] = { _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, _, /* @abcdefghijklmno */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, /* 0123456789:;<=>? */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /*                  */ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _  /*                  */};#undef _				/* Functions private to this file. */void			equals();void			big_cons();void			cons();static char*		demand_copy_C_string();static char*		demand_copy_string();void			demand_empty_rest_of_line();void			float_cons();long int		get_absolute_expression();static char		get_absolute_expression_and_terminator();static segT		get_known_segmented_expression();void			ignore_rest_of_line();static int		is_it_end_of_statement();static void		pobegin();static void		pseudo_set();static void		stab();static void		stringer();extern char line_comment_chars[];static char *	buffer_limit;	/* -> 1 + last char in buffer. */static char *	bignum_low;	/* Lowest char of bignum. */static char *	bignum_limit;	/* 1st illegal address of bignum. */static char *	bignum_high;	/* Highest char of bignum. */				/* May point to (bignum_start-1). */				/* Never >= bignum_limit. */static char *old_buffer = 0;	/* JF a hack */static char *old_input;static char *old_limit;#ifndef WORKING_DOT_WORDstruct broken_word *broken_words;int new_broken_words = 0;#endifstatic void grow_bignum ();static int next_char_of_string ();voidread_begin(){  pobegin();  obstack_begin( &notes, 5000 );#define BIGNUM_BEGIN_SIZE (16)  bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);  bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;}/* set up pseudo-op tables */static struct hash_control *po_hash = NULL;			/* use before set up: NULL-> address error */void	s_abort(),	s_align(),	s_comm(),	s_data();void	s_desc(),	s_even(),	s_file(),	s_fill();void	s_globl(),	s_lcomm(),	s_line(),	s_lsym();void	s_org(),	s_set(),	s_space(),	s_text();#ifdef VMSchar const_flag = 0;void s_const();#endif#ifdef DONTDEFvoid	s_gdbline(),	s_gdblinetab();void	s_gdbbeg(),	s_gdbblock(),	s_gdbend(),	s_gdbsym();#endifvoid	stringer();void	cons();void	float_cons();void	big_cons();void	stab();static const pseudo_typeSpotable[] ={  { "abort",	s_abort,	0	},  { "align",	s_align,	0	},  { "ascii",	stringer,	0	},  { "asciz",	stringer,	1	},  { "byte",	cons,		1	},  { "comm",	s_comm,		0	},#ifdef VMS  { "const",	s_const,	0	},#endif  { "data",	s_data,		0	},  { "desc",	s_desc,		0	},  { "double",	float_cons,	'd'	},  { "file",	s_file,		0	},  { "fill",	s_fill,		0	},  { "float",	float_cons,	'f'	},#ifdef DONTDEF  { "gdbbeg",	s_gdbbeg,	0	},  { "gdbblock",	s_gdbblock,	0	},  { "gdbend",	s_gdbend,	0	},  { "gdbsym",	s_gdbsym,	0	},  { "gdbline",	s_gdbline,	0	},  { "gdblinetab",s_gdblinetab,	0	},#endif  { "globl",	s_globl,	0	},  { "int",	cons,		4	},  { "lcomm",	s_lcomm,	0	},  { "line",	s_line,		0	},  { "long",	cons,		4	},  { "lsym",	s_lsym,		0	},  { "octa",	big_cons,	16	},  { "org",	s_org,		0	},  { "quad",	big_cons,	8	},  { "set",	s_set,		0	},  { "short",	cons,		2	},  { "single",	float_cons,	'f'	},  { "space",	s_space,	0	},  { "stabd",	stab,		'd'	},  { "stabn",	stab,		'n'	},  { "stabs",	stab,		's'	},  { "text",	s_text,		0	},#ifndef SPARC  { "word",	cons,		2	},#endif  { NULL}	/* end sentinel */};static voidpobegin(){  char *	errtxt;		/* error text */  const pseudo_typeS * pop;  po_hash = hash_new();  errtxt = "";			/* OK so far */  for (pop=potable; pop->poc_name && !*errtxt; pop++)    {      errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);    }  for(pop=md_pseudo_table; pop->poc_name && !*errtxt; pop++)      errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);  if (*errtxt)    {      as_fatal ("error constructing pseudo-op table");    }}				/* pobegin() *//*			read_a_source_file() * * File has already been opened, and will be closed by our caller. * * We read the file, putting things into a web that * represents what we have been reading. */voidread_a_source_file (buffer)     char *	buffer;		/* 1st character of each buffer of lines is here. */{  register char		c;  register char *	s;	/* string of symbol, '\0' appended */  register int		temp;  /* register struct frag * fragP; JF unused */	/* a frag we just made */  pseudo_typeS	*pop;#ifdef DONTDEF  void gdb_block_beg();  void gdb_block_position();  void gdb_block_end();  void gdb_symbols_fixup();#endif  subseg_new (SEG_TEXT, 0);  while ( buffer_limit = input_scrub_next_buffer (&buffer) )    {				/* We have another line to parse. */      know( buffer_limit [-1] == '\n' ); /* Must have a sentinel. */      input_line_pointer = buffer; contin:	/* JF this goto is my fault I admit it.  Someone brave please re-write		   the whole input section here?  Pleeze??? */      while ( input_line_pointer < buffer_limit )	{			/* We have more of this buffer to parse. */	  /*	   * We now have input_line_pointer -> 1st char of next line.	   * If input_line_pointer [-1] == '\n' then we just	   * scanned another line: so bump line counters.	   */	  if (input_line_pointer [-1] == '\n')	    {	      bump_line_counters ();	    }	  /*	   * We are at the begining of a line, or similar place.	   * We expect a well-formed assembler statement.	   * A "symbol-name:" is a statement.	   *	   * Depending on what compiler is used, the order of these tests	   * may vary to catch most common case 1st.	   * Each test is independent of all other tests at the (top) level.	   * PLEASE make a compiler that doesn't use this assembler.	   * It is crufty to waste a compiler's time encoding things for this	   * assembler, which then wastes more time decoding it.	   * (And communicating via (linear) files is silly!	   * If you must pass stuff, please pass a tree!)	   */	  if ( (c= * input_line_pointer ++) == '\t' || c == ' ' || c=='\f')	    {	      c = * input_line_pointer ++;	    }	  know( c != ' ' );	/* No further leading whitespace. */	  /*	   * C is the 1st significant character.	   * Input_line_pointer points after that character.	   */	  if ( is_name_beginner(c) )	    {			/* want user-defined label or pseudo/opcode */	      s = -- input_line_pointer;	      c = get_symbol_end(); /* name's delimiter */	      /*	       * C is character after symbol.	       * That character's place in the input line is now '\0'.	       * S points to the beginning of the symbol.	       *   [In case of pseudo-op, s -> '.'.]	       * Input_line_pointer -> '\0' where c was.	       */	      if ( c == ':' )		{		  if (flagseen['g'])		    /* set line number for function definition */		    funcstab(s);		  colon(s);	/* user-defined label */		  * input_line_pointer ++ = ':'; /* Put ':' back for error messages' sake. */				/* Input_line_pointer -> after ':'. */		  SKIP_WHITESPACE();		}	      else if(c=='=' || input_line_pointer[1]=='=')		/* JF deal with FOO=BAR */	        {		  equals(s);		  demand_empty_rest_of_line();		}	      else		{		/* expect pseudo-op or machine instruction */		  if ( *s=='.' )		    {		      /*		       * PSEUDO - OP.		       *		       * WARNING: c has next char, which may be end-of-line.		       * We lookup the pseudo-op table with s+1 because we		       * already know that the pseudo-op begins with a '.'.		       */		      pop= (pseudo_typeS *) hash_find (po_hash, s+1);		      /* Print the error msg now, while we still can */		      if(!pop)			  as_bad("Unknown pseudo-op:  '%s'",s);				/* Put it back for error messages etc. */		      * input_line_pointer = c;				/* The following skip of whitespace is compulsory. */				/* A well shaped space is sometimes all that seperates keyword from operands. */		      if ( c == ' ' || c == '\t' )			{	/* Skip seperator after keyword. */			  input_line_pointer ++;			}		      /*		       * Input_line is restored.		       * Input_line_pointer -> 1st non-blank char		       * after pseudo-operation.		       */		        if(!pop) {			  ignore_rest_of_line();			  break;			}			else			  (*pop->poc_handler)(pop->poc_val);		    }		  else		    {		/* machine instruction */		      /* If source file debugging, emit a stab. */		      if (flagseen['g'])			linestab();		      /* WARNING: c has char, which may be end-of-line. */		      /* Also: input_line_pointer -> `\0` where c was. */		      * input_line_pointer = c;		      while ( ! is_end_of_line [* input_line_pointer] )			{			  input_line_pointer ++;			}		      c = * input_line_pointer;		      * input_line_pointer = '\0';		      md_assemble (s);	/* Assemble 1 instruction. */		      * input_line_pointer ++ = c;		      /* We resume loop AFTER the end-of-line from this instruction */		    }		/* if (*s=='.') */		}		/* if c==':' */	      continue;	    }			/* if (is_name_beginner(c) */	  if ( is_end_of_line [c] )	    {			/* empty statement */	      continue;	    }	  if ( isdigit(c) )	    {			/* local label  ("4:") */	      temp = c - '0';#ifdef SUN_ASM_SYNTAX	      if( *input_line_pointer=='$')		input_line_pointer++;#endif	      if ( * input_line_pointer ++ == ':' )		{		  local_colon (temp);		}	      else		{		  as_bad( "Spurious digit %d.", temp);		  input_line_pointer -- ;		  ignore_rest_of_line();		}	      continue;	    }	  if(c && index(line_comment_chars,c)) {	/* Its a comment.  Better say APP or NO_APP */		char *ends;		char *strstr();		char	*new_buf;		char	*new_tmp;		int	new_length;		char	*tmp_buf = 0;		extern char *scrub_string,*scrub_last_string;		int	scrub_from_string();		void	scrub_to_string();		bump_line_counters();		s=input_line_pointer;		if(strncmp(s,"APP\n",4))			continue;	/* We ignore it */		s+=4;		ends=strstr(s,"#NO_APP\n");		if(!ends) {			int	tmp_len;			int	num;			/* The end of the #APP wasn't in this buffer.  We			   keep reading in buffers until we find the #NO_APP			   that goes with this #APP  There is one.  The specs 			   guarentee it. . .*/			tmp_len=buffer_limit-s;			tmp_buf=xmalloc(tmp_len);			bcopy(s,tmp_buf,tmp_len);			do {				new_tmp = input_scrub_next_buffer(&buffer);				if(!new_tmp)					break;				else					buffer_limit = new_tmp;				input_line_pointer = buffer;				ends = strstr(buffer,"#NO_APP\n");				if(ends)					num=ends-buffer;				else					num=buffer_limit-buffer;				tmp_buf=xrealloc(tmp_buf,tmp_len+num);				bcopy(buffer,tmp_buf+tmp_len,num);				tmp_len+=num;			} while(!ends);			input_line_pointer= ends ? ends+8 : NULL;			s=tmp_buf;			ends=s+tmp_len;		} else {			input_line_pointer=ends+8;		}		new_buf=xmalloc(100);		new_length=100;		new_tmp=new_buf;		scrub_string=s;		scrub_last_string = ends;		for(;;) {			int ch;			ch=do_scrub_next_char(scrub_from_string,scrub_to_string);			if(ch==EOF) break;			*new_tmp++=ch;			if(new_tmp==new_buf+new_length) {				new_buf=xrealloc(new_buf,new_length+100);				new_tmp=new_buf+new_length;				new_length+=100;			}		}		if(tmp_buf)			free(tmp_buf);		old_buffer=buffer;		old_input=input_line_pointer;		old_limit=buffer_limit;		buffer=new_buf;		input_line_pointer=new_buf;		buffer_limit=new_tmp;		continue;	  }	  as_bad("Junk character %d.",c);	  ignore_rest_of_line();	}			/* while (input_line_pointer<buffer_limit )*/	if(old_buffer) {		bump_line_counters();		if(old_input == 0)			return;		buffer=old_buffer;		input_line_pointer=old_input;		buffer_limit=old_limit;		old_buffer = 0;		goto contin;	}    }				/* while (more bufrers to scan) */}				/* read_a_source_file() */voids_abort(){	as_fatal(".abort detected.  Abandoning ship.");}#ifdef OTHER_ALIGN

⌨️ 快捷键说明

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