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

📄 lnscan.c

📁 < 虚拟机设计与实现>>的 windows版本
💻 C
字号:
#include "lnscan.h"

#include "cmdline.h"
#include "common.h"
#include "error.h"

static FILE * iFptr;					/*pointer to assembly code file*/
static char iFname[FNAME_SIZE];		/*name of assembly code file*/
static char inBuffer[BUFFER_SIZE];		/*buffer for input from assembly file*/
static int	nInBuffer;					/*number of bytes in inBuffer*/
static int	inBufferPos;				/*index into inBuffer: 0 -> nInBuffer-1 */
static unsigned long inLine;			/*current line in file*/

int fillInputBuffer();
char getInputChar();
void prep(char ch, char *str);

int LineScanner_init()
{
	if ((inputFile == NULL) || (strlen(inputFile) == 0))
	{ 
		INPUT_SCAN_DEBUG0("LineScanner_init(): file name empty\n");
		return FALSE; 
	}
	else
	{  
		strncpy(iFname, inputFile, FNAME_SIZE);
		iFname[FNAME_SIZE - 1] = '\0';
		INPUT_SCAN_DEBUG1("LineScanner(): opened %s\n", iFname);
	}

	iFptr = fopen(iFname, "rb");
	if (iFptr == NULL)
	{ 
		printf("LineScanner_init(): could not open %s\n", iFname); 
		return FALSE; 
	}
	inLine = 1;
	if (fillInputBuffer() == FALSE)
		return FALSE;
	return TRUE;

}

void LineScanner_free()
{
	if (iFptr != NULL)
	{
		if (fclose(iFptr))
		{ 
			printf("LineScanner_free(): ");
			printf("could not close %s\n",iFname);  
		}
		iFptr = NULL;
	}
	else
	{
		INPUT_SCAN_DEBUG0("LineScanner_free(): null file pointer\n"); 
	}
	INPUT_SCAN_DEBUG0("LineScanner_free(): closed file\n"); 
	return;

}

char getInputChar()
{ 
	inBufferPos++;

	/*
	if read entire buffer (0 - (nInBuffer-1)) 
	and are at the char following the end (nInBuffer) 
	then fill in a new one
	*/

	if (inBufferPos == nInBuffer)
	{
		INPUT_SCAN_DEBUG0("getInputBufferChar(): hit end, filling buffer\n");
		fillInputBuffer();
		inBufferPos++;	/*fillInputBuffer set to -1*/
	}

	/*if at very last char of buffer, look at last char for EOF flag*/
	if (inBufferPos == nInBuffer - 1)
	{
		if (inBuffer[inBufferPos] == IN_END)
		{
			INPUT_SCAN_DEBUG0("getInputBufferChar():hit EOF\n");
			/*make sure always stay at end, if call again*/
			/*防备某个程序员在读到IN_END后还傻乎乎地继续调用getInputChar(). */
			inBufferPos--; 
			return IN_END;
		}
	}

	return inBuffer[inBufferPos];
	
} /*end getInputChar*/

struct Line getInputLine()
{
	struct Line line;
	char ch;
	int i;
	
	i = 0;
	line.end = FALSE;
	line.fName = iFname; 

	/*get first non-whitspace character*/
	ch = getInputChar();

	while ((ch == '\n') || (ch == '\r'))
	{ 
		if (ch == '\n')
		{ 
			inLine++; 
		}
		ch = getInputChar(); 
	}

	/*keep reading until hit end of line, file, or buffer*/
	while ((ch != '\n') && (ch != IN_END) && (i < LINE_SIZE - 1))
	{
		if (ch == '\r')
		{ 
			ch = getInputChar(); 
		}
		else
		{
			line.src[i] = ch;
			ch = getInputChar();
			i++;
		}
	}

	if (ch == IN_END)
	{ 
		line.end = TRUE; 
	}

	line.src[i] = '\0';
	line.line = inLine;
	inLine++; 
	INPUT_SCAN_DEBUG1("getInputLine(): scanned %s\n", line.src); 
	return line;

} /*end getInputLine*/

void printScannedLine(struct Line *lptr)
{
	printf("file=%s ", (*lptr).fName);
	printf("line=%lu ", (*lptr).line);
	printf("text=%s\n", (*lptr).src);
	return;

}  /*end printScannedLine*/

int fillInputBuffer()
{
	int nbytes;

	nbytes = 0;
	nbytes = fread(inBuffer, sizeof(char), BUFFER_SIZE, iFptr);

	/*if nbytes is less than BUFFER_SIZE, have hit EOF or have an error*/
	if (nbytes < BUFFER_SIZE)
	{
		if (feof(iFptr) == 0)
		{ 
			ERROR1("fillInputBuffer(): error reading from %s\n", iFname); 
			return FALSE; 
		}
		else
		{
			/*add a byte to buffer size and set it to IN_END*/
			nInBuffer = nbytes + 1;
			inBuffer[nInBuffer - 1] = IN_END;
			INPUT_SCAN_DEBUG0("fillInputBuffer(): hit EOF filling buffer\n");
		}
	}
	else
	{
		nInBuffer = BUFFER_SIZE;
	}

	INPUT_SCAN_DEBUG1("fillInputBuffer(): read %d bytes\n", nInBuffer);

	inBufferPos = -1;  /*init for first call to getInputChar()*/
	return TRUE;

}

void test_LineScanner()
{
	struct Line ln;
	
	ln = getInputLine();
	while (ln.end != TRUE)
	{
		printScannedLine(&ln);
		ln = getInputLine();
	}
	if (strlen(ln.src) != 0)
		printScannedLine(&ln);

	return;

} /*end test*/

⌨️ 快捷键说明

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