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

📄 preprocessor.c

📁 51模拟器 51模拟器 51模拟器
💻 C
字号:
//#include"vars.c"#include"gas51.h"#define IS_NOT_DEFINED 0#define IS_DEFINED 1int need_preprocessing=1; //Flag to indicate that file still requires preprocessing...'1' means 'YES' and '0' means 'NO'FILE * line_splice(FILE *);    //implemented...char * join_line(FILE **fpsrc,char *buff);  //implemented...char * substr(char *str,int pos,int length); //implemented...int pat_index(char *text, char *pattern);   //INDEX //implemented...char * insert(char *text,int pos,char *string); //INSERT      //implemented...char * delete(char *text,int pos,int length); //DELETE        //implemented...char * replace_all(char *text,char *symbol,char *replacement); //REPLACE_ALL...char * trim(char *text); //TRIMMING FUNCTION...FILE * expand_macro(FILE *srcfile,char *macro,char *expansion); //REPLACE_ALL_IN_FILE		char dest[80];void dump_file(FILE *);void gas51_perror();FILE * include_file(char *arg,FILE *file,long pos);int pat_index(char *,char *);char * remove_all_spaces(char *);FILE * preprocess(char *file_to_preprocess)   //function to preprocess the assembly file...{	FILE *fp;	char buff[240]={0},line[240];	char *buff_cleaned;	char directive_arg[15],directive_expansion[15],directive_name[15],directive_symbol[15]  ;	int i,j,l;	fp=fopen(file_to_preprocess,"r");	//gas51_line_no = 0;		while(need_preprocessing)		{		while( fgets(buff,80,fp) )  {		//gas51_line_no++;		for(i=0;i<=strlen(buff);i++)		{			    if(buff[i]==';')		    	break;	    		}		buff[i]='\0' ;            if(pat_index(buff,"#include")) /****EXTREMELY IMPORTANT!!!  there must be NO SPACE BETWEEN the '#' and 'include' ...**/			{			buff_cleaned = remove_all_spaces(buff) ;   			for(i=9,j=0;i<=strlen(buff_cleaned);i++,j++) // in this case filename starts from 10th location or 9th index...				directive_arg[j]=buff_cleaned[i] ;						directive_arg[strlen(directive_arg)-1] = '\0' ;  //to replace the last '>' with NULL...						fp=include_file(directive_arg,fp,ftell(fp));   			rewind(fp);			}					    //else            //	if(pat_index(buff,"#define")) /****EXTREMELY IMPORTANT!!!  there must be NO SPACE BETWEEN the '#' and 'define' ...**/	    //	{	   // 	}				}fp=line_splice(fp); //line_splice need not be as complicated as defined below using recursion...		    // if last char is a '\' then simply inserting a leading ';' in next line solves the whole problem		    // line remains a comment as well as line number info remains intact...		    // this will be replaced by the simpler version in the next release of gas51... cmanta ;)rewind(fp);   // preparing for macro expansion...while(fgets(buff,240,fp)){	//gas51_line_no++;		for(i=0;i<=strlen(buff);i++)		{			    if(buff[i]==';')		    	break;	    		}		buff[i]='\0' ;	if(pat_index(buff,"#define")) /****EXTREMELY IMPORTANT!!!  there must be NO SPACE BETWEEN the '#' and 'define' ...**/    	{    		sscanf(buff,"%s%s%s",directive_name,directive_symbol,directive_expansion);		fp=expand_macro(fp,directive_symbol,directive_expansion);		rewind(fp);			}	    }rewind(fp); // rewinding pointer before checking for more preprocessor directives...while(fgets(buff,240,fp)){	//gas51_line_no++;		for(i=0;i<=strlen(buff);i++)		{			    if(buff[i]==';')		    	break;	    		}		buff[i]='\0' ;	if( (pat_index(buff,"#define")) || (pat_index(buff,"#include"))   ||  (pat_index(buff,"#ifdef"))  ) /****EXTREMELY IMPORTANT!!!  there must be NO SPACE BETWEEN the '#' and 'define'..., list all directives here...*/  		    	{		need_preprocessing=1;  // file still requires preprocessing...so continue iterating... 			rewind(fp);  // rewinding pointer for next iteration...		break;	}		else		need_preprocessing=0;  // loop will not run the next time...}}  ///////////////////////dump_file(fp);  // this dumps the temporary file...just debugging purpose...no need to rewind pointer..dump does this automatically....//fclose(fp);return fp;}int pat_index(char *src_str,char *substr){	int i=0,j=0,k=0,retval=0;	int len_substr , len_src_str ;	char temp_str[10];	len_substr = strlen(substr) ;	len_src_str = strlen(src_str) ;	for(i=0;i<(len_src_str - len_substr);i++)    {    		for(j=0,k=i;k<i+len_substr;j++,k++)  {		temp_str[j]=src_str[k] ;	}		temp_str[j] = '\0' ;	if(!strcasecmp(temp_str,substr))	{		retval=i+1;  //we have to increment i here coz arrays start with 0 but column no. in		break;	     //a file starts with 1...		}	else 		retval=0;				} 			return retval;}FILE * include_file(char *file_to_include,FILE *newfp, long pos){	FILE *fpsrc,*fptemp,*fpdest;	  	int i=0,newfd;		char *fname1, *fname2 ,buff[80] ,tempbuff[40];//tempnambuff[12]="gas51XXXXXX";	char const1[]="/usr/include/gas51/" ;		//extern int gas51_sys_errlist[100];	char const2[]="./" ;		fname1=strcat(const1 ,file_to_include)  ;		fname2=strcat(const2 ,file_to_include) ;	// fptemp points to .asm file, fpdest points to .asm.tmp file,	if ( ((fpsrc=fopen(fname1 ,"r")) )  ||  ( (fpsrc=fopen(fname2,"r")) ))	{       		// code to include file contents goes here...				rewind(newfp);		fptemp=newfp;   //sourcefile..		fpdest=tmpfile();  //destination file ...		while(1)		{			fgets(buff,80,fptemp) ;			if(  (ftell(fptemp)) == pos  )				break;			else				fprintf(fpdest,"%s",buff);			}									//fseek(fptemp,pos,SEEK_SET);			fprintf(fpdest,"; EXTRA LINE ADDED BY gas51 TO COMPENSATE FOR LINE NUMBER INFO DUE TO '#include'...\n");				/* PART OF NEW PLAN TO EMBED ASSEMBLER INFO IN FILE ITSELF...*/		fprintf(fpdest,"%c %s :start\n",187,file_to_include);		//fprintf(fpdest,"--------------------INCLUDE FILE %s BELOW-----------------------\n",file_to_include);						while( fgets(buff,80,fpsrc)  )		{			fprintf(fpdest,"%s",buff);						}					//fprintf(fpdest,"--------------------END OF INCLUDE FILE %s-----------------------\n",file_to_include);		fprintf(fpdest,"%c %s :end\n",187,file_to_include);						fseek(fptemp,pos,SEEK_SET);				while( fgets(buff,80,fptemp)  )		{			fprintf(fpdest,"%s",buff);						}							fclose(fpsrc);		fclose(fptemp);				return fpdest;					}				else			{		gas51_errno = 0 ;  // 0 -> code for file not found!!		gas51_perror() ;		exit(1) ;			}		}char * remove_all_spaces(char *buff_to_clean){	int i,j,k;	static char cleaned_buff[80];	for(i=0,j=0;i<strlen(buff_to_clean);i++)	{		if(buff_to_clean[i]!=' ' && buff_to_clean[i]!='\t' && buff_to_clean[i]!='\n' && buff_to_clean[i]!='\r' )			{				cleaned_buff[j] = buff_to_clean[i];				j++;			}		else 			continue;	}	cleaned_buff[j]= '\0' ;	return cleaned_buff ;}			char * trim(char *buff_to_trim){	int i,j;	char *trimmed_buff;	char tempbuff[40];		trimmed_buff=malloc(40);	trimmed_buff[0]='\0' ; //initialising buffer with a null string...//	for(i=0,j=0;i<strlen(buff_to_trim);)          //this function cuts all words and pastes them with a single space in between...	//for(;;)//	{		i=0;		j=0;		while( (buff_to_trim[i]==' ') || (buff_to_trim[i]=='\t') || (buff_to_trim[i]=='\n') )			i++;		while( (buff_to_trim[i]!=' ') && (buff_to_trim[i]!='\t' ) && (buff_to_trim[i]!='\n') && (buff_to_trim[i]!='\0'))		{			tempbuff[j]=buff_to_trim[i];			i++;			j++;			}				tempbuff[j]='\0';		strcat(trimmed_buff,tempbuff);		strcat(trimmed_buff," ");				while( (buff_to_trim[i]==' ') || (buff_to_trim[i]=='\t') || (buff_to_trim[i]=='\n') )			i++;				for(j=0;i<strlen(buff_to_trim);i++,j++)			tempbuff[j]=buff_to_trim[i];								tempbuff[j]='\0' ;		strcpy(tempbuff,remove_all_spaces(tempbuff));		strcat(trimmed_buff,tempbuff);				//	}		//strcpy(gas51_generic_string,trimmed_buff);		return trimmed_buff;	}void gas51_perror(){	printf("gas51: %s : %d : %s \n", gas51_file_being_assembled, gas51_line_no, gas51_errlist[gas51_errno]);	exit(1);	}//void insert_into_define_list(char *Directive_Symbol, char *Directive_Expansion , int flag )//{//	gas51_define_list *tempStruct,*tempPtr;			/* forming the define structure prior to insertion into the linked list...*/	/*	tempStruct = (gas51_define_list *)malloc(sizeof(gas51_define_list)) ;	tempStruct->symbol = Directive_Symbol ;	tempStruct->expansion = Directive_Expansion ; 	tempStruct->flag = IS_DEFINED ;	tempStruct->next = NULL ;	tempPtr = &head ;	while(tempPtr->next)	{	   tempPtr = tempPtr->next ;	}			tempPtr = tempStruct ;	head.next = tempPtr ;			}*/void dump_file(FILE *fp){	char buff[80];	rewind(fp);	while( fgets(buff,80,fp))		printf("%s",buff);}FILE * line_splice(FILE *fpsrc){	// uses join_line function recursively...	FILE *fpdest;	int i;	char buff[80],*tempbuff;	char tempfile[30];	rewind(fpsrc);		//strcpy(tempfile,filename);	//strcat(tempfile,".pp1.tmp");	//fpsrc = fopen(filename,"r");	fpdest=tmpfile();	//fpdest = fopen(tempfile,"w" );	while( fgets(buff,80,fpsrc) )	{	// buff[strlen-2] points to the second last element of buff and buff[strlen-1] points to the 		  // last..and buff[strlen] points to the terminating '\0'  		if(buff[strlen(buff)-2] == '\\' && buff[strlen(buff)-1]=='\n' )					{			buff[strlen(buff)-2] = '\0' ;			tempbuff=join_line(&fpsrc,buff);			fprintf(fpdest,"%s",tempbuff);			for(i=0;i<=gas51_no_of_slashes;i++)  //have used '<=' here coz counting is starting from 0 in loop and							  // no of slahes is one less than actual as first slash is							// detected before join_line is called...so the '=' and a lesser							// no_of_slash (less by one) compensate each other... cmanta ;)					fprintf(fpdest,"; EXTRA LINE INSERTED BY gas51 TO COMPENSATE FOR MULTI-LINE COMMENTS...\n");		}						/*buff[strlen(buff)-2] = '\0' ;			strcpy(tempbuff,buff);			fgets(buff,80,fpsrc);			strcat(tempbuff,buff);   //joining the next two lines...			fprintf(fpdest,"%s",tempbuff);  */		   		else 			fprintf(fpdest,"%s",buff);		}	//for(i=0;i<=gas51_no_of_slashes;i++)	//	fprintf(fpdest,"; EXTRA LINE INSERTED BY gas51 TO COMPENSATE FOR LINE NUMBER INFO...\n");				fclose(fpsrc);	//fclose(fpdest);	return fpdest;	}char * join_line(FILE **fpsrcptr,char *buff){	// part of line_splice implementation...	////char *tempbuff,*tempbuff2;	char tempbuff[400],tempbuff2[400];	///tempbuff = (char *)malloc(80 * sizeof(char));	///tempbuff2 = (char *)malloc(80 * sizeof(char));	strcpy(tempbuff2,buff);	//char *Local1,*Local2;			fgets(tempbuff,80,*fpsrcptr);		if(tempbuff[strlen(tempbuff)-2] == '\\' && tempbuff[strlen(tempbuff)-1]=='\n' )			{				gas51_no_of_slashes++;  //this counts the total number of backslashes in the multi-line comment...		tempbuff[strlen(tempbuff)-2] = '\0' ;		strcpy(tempbuff,join_line(fpsrcptr,tempbuff));		///tempbuff=join_line(fpsrcptr,tempbuff);			}		//free(tempbuff);	//free(tempbuff2);	return (strcat(tempbuff2,tempbuff));	}char * substr(char *srcstr,int first_pos,int length){	int i,j;	//char destbuff[80];	static char *deststr;//=destbuff;	deststr=(char *)malloc(80*sizeof(char));	for(i=first_pos-1,j=0;i<=first_pos + length-2;i++,j++)		*(deststr+j) = *(srcstr+i);	*(deststr+j) = '\0' ; 	//strcpy(gas51_generic_string,deststr);	//return gas51_generic_string ;	return deststr;}char * insert(char *text,int pos,char *string) //INSERT{	char *temp1,*temp2,*temp3 ;	temp1=malloc(80);	temp2=malloc(80);	temp3=malloc(80);	temp2 = substr(text,1,pos-1);	strcpy(temp1,temp2);	strcpy(temp2,string);	temp3=substr(text,pos,strlen(text)-pos+1);	strcat(temp2,temp3);	//strcat(temp2,substr(text,pos,strlen(text)-pos+1)); /* */	return (strcat(temp1,temp2));}char * delete(char *text,int pos,int length) //DELETE{	char *temp1,*temp2;		if(pos==0)		return text;		temp1=malloc(80);	temp2=malloc(80);		strcpy(temp1,substr(text,1,pos-1));	strcpy(temp2,substr(text,pos+length,strlen(text)-pos-length+1));	return strcat(temp1,temp2);		}char * replace_all(char *text,char *symbol,char *replacement) //REPLACE_ALL {	int k,i;	char t[81],tempreplacement[20];	char *tptr;	char *result;	tptr=t;		//the case when symbol is itself a substring of the replacement...	if(pat_index(replacement,symbol) )		{			strcpy(tempreplacement,replacement);			do			{			  for(i=0;i<strlen(tempreplacement);i++)				  (*(tempreplacement+i))++; //changing the value by 1...			}while(pat_index(replacement,tempreplacement) );					/*replacing text with temporary replacement...*/		while(k=pat_index(text,symbol))		{			tptr=delete(text,k,strlen(symbol));			text=insert(tptr,k,tempreplacement);		}		/*finally replacing temp chars with actual replacements...*/		while(k=pat_index(text,tempreplacement))		{			tptr=delete(text,k,strlen(tempreplacement));			text=insert(tptr,k,replacement);		}								}			else  //normal case when both are disjoint...	while(k=pat_index(text,symbol))	{		tptr=delete(text,k,strlen(symbol));		text=insert(tptr,k,replacement);	}			return text;}FILE * expand_macro(FILE *fpsrc,char *macro,char *expansion){	char buff[400],newbuff[400],*newbuffptr;	char part_a[200],part_b[200];	char *part_a_ptr=part_a;	char *part_b_ptr=part_b;	FILE *fpdest;	int i;	newbuffptr=newbuff;	rewind(fpsrc);	fpdest=tmpfile();	//fpdest=fopen("test.asm.pp","w+");	while(fgets(buff,400,fpsrc))	{		i=pat_index(buff,";");			if(i==0)  //no ';' found in line...		{			strcpy(part_a,buff);			strcpy(part_b,"\0");		}		else		   if(i==1)  // ';' at start of line..pure comment...		{				strcpy(part_a,"\0");			strcpy(part_b,buff);							}		   else  //for i!=0 and i!=1 i.e. ';' at middle of line...		   {				   part_a_ptr=substr(buff,1,i-1);			   part_b_ptr=substr(buff,i,strlen(buff));		   	   strcpy(part_a,part_a_ptr);		   	   strcpy(part_b,part_b_ptr);			   		   }		if(pat_index(part_a,"#define") && pat_index(part_a,macro) && pat_index(part_a,expansion) )		{			//newbuffptr=strcat(part_a,part_b);				fprintf(fpdest,"; LINE AUTOMATICALLY REPLACED BY gas51 TO COMPENSATE FOR '#define'...\n");			continue;		}		else			if(pat_index(part_a,"#ifdef") || pat_index(part_a,"#ifndef")  )		{	newbuffptr=strcat(part_a,part_b);				fprintf(fpdest,"%s",newbuffptr);		}				else				{				  newbuffptr=replace_all(part_a,macro,expansion);		          newbuffptr=strcat(newbuffptr,part_b);		  fprintf(fpdest,"%s",newbuffptr);					}					//newbuffptr=replace_all(buff,macro,expansion);			//fprintf(fpdest,"%s",newbuffptr);	}	fclose(fpsrc);	return fpdest;}

⌨️ 快捷键说明

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