www.pudn.com > hos-v4_os.rar > read.cpp


// --------------------------------------------------------------------------- 
//  Hyper Operating System V4  コンフィギュレーター                            
//    データ読み込みクラス                                                     
//                                                                             
//                                    Copyright (C) 1998-2002 by Project HOS   
//                                    http://sourceforge.jp/projects/hos/      
// --------------------------------------------------------------------------- 
 
 
#include  
#include  
#include  
#include  
#include "defercd.h" 
#include "read.h" 
 
 
// コンストラクタ 
CRead::CRead(FILE *fp, const char *name) 
{ 
	m_fpRead    = fp; 
	m_iPhysicalLineNum = m_iLogicalLineNum = 1; 
	m_blLineTop = true; 
	strncpy(m_szLogicalInputFile, name, MAX_PATH - 1); 
	m_szLogicalInputFile[MAX_PATH - 1] = '\0'; 
} 
 
 
// デストラクタ 
CRead::~CRead() 
{ 
} 
 
 
// 1ステート読み込み 
int CRead::ReadState(char *szState) 
{ 
	bool blEsc   = false; 
	bool blSpace = true;	// true で始めて先頭の空白を読み飛ばす 
	int  iCount = 0; 
	int  iErr; 
	int  c; 
 
	for ( ; ; ) 
	{ 
		// 1文字読み込み 
		if ( (c = fgetc(m_fpRead)) == EOF ) 
		{ 
			if ( blEsc || iCount != 0 ) 
			{ 
				iErr = CFG_ERR_EOF;	// 予期せぬEOF 
			} 
			else 
			{ 
				iErr = CFG_ERR_COMPLETE;	// 完了 
			} 
			break; 
		} 
 
		// サイズチェック 
		if ( iCount >= READ_MAX_STATE - 1 ) 
		{ 
			iErr = CFG_ERR_STATE_LEN; 
			break; 
		} 
 
		// 行頭が # ならスキップ 
		if ( m_blLineTop && c == '#' ) 
		{ 
                       iErr = SkipPreProcessorLine(szState, iCount); 
			if ( iErr != CFG_ERR_OK ) 
			{ 
				break; 
			} 
			continue; 
		} 
 
		// 改行文字の処理 
		if ( c == '\n' ) 
		{ 
			m_iPhysicalLineNum++; 
			m_iLogicalLineNum++; 
			m_blLineTop = true; 
		} 
		else 
		{ 
			m_blLineTop = false; 
		} 
 
		// 空白文字のスキップ 
		if ( isspace(c) || c == '\n' ) 
		{ 
			if ( !blSpace ) 
			{ 
				szState[iCount++] = ' '; 
				blSpace = true; 
			} 
			continue; 
		} 
		blSpace = false; 
 
		// 文字列の処理 
		if ( c == '\"' || c == '\'' ) 
		{ 
			szState[iCount++] = c; 
			iErr = ReadString(c, szState, iCount); 
			if ( iErr != CFG_ERR_OK ) 
			{ 
				break; 
			} 
			continue; 
		} 
 
		// ステート完了文字なら 
		if ( c == ';' ) 
		{ 
			iErr = CFG_ERR_OK; 
			break; 
		} 
 
		// 文字の読み込み 
		szState[iCount++] = c; 
	} 
 
	// 末尾の空白文字削除 
	if ( iCount > 0 && szState[iCount - 1] == ' ' ) 
	{ 
		iCount--; 
	} 
 
	szState[iCount] = '\0'; 
 
	return iErr; 
} 
 
 
// プリプロセッサラインのスキップ 
int CRead::SkipPreProcessorLine(char* szText, int iCountOrg) 
{ 
	int  c; 
	int iCount = iCountOrg; 
	long tmpLineNum; 
	char *p1, *p2; 
 
	for ( ; ; ) 
	{ 
		// 1文字読み込み 
		if ( (c = fgetc(m_fpRead)) == EOF ) 
		{ 
			return CFG_ERR_OK; 
		} 
 
		// サイズチェック 
		if ( iCount >= READ_MAX_STATE - 1 ) 
		{ 
			return CFG_ERR_STATE_LEN; 
		} 
 
		// 行末のチェック 
		if ( c == '\n' ) 
		{ 
			m_iPhysicalLineNum++; 
			m_iLogicalLineNum++; 
 
			szText[iCount] = '\0'; 
 
			// #line 123 "filename" 
			// # 123 "filename" 
			// の形式のどちらでも受け付ける 
			if (strncmp(&szText[iCountOrg], "line", 4) == 0) 
				iCountOrg += 4; 
 
			// #line123 
			// #12 
			// などを排除 
			if (!isspace(szText[iCountOrg])) 
				return CFG_ERR_OK; 
 
			// 行番号読み込み 
			tmpLineNum = strtol(&szText[iCountOrg], &p1, 10); 
			if (p1 == &szText[iCountOrg]) 
				return CFG_ERR_OK; 
 
			// # 123a 
			// など行番号の後ろに余分なものがついている場合を排除 
			if (!isspace(*p1) && *p1 != '\0') 
				return CFG_ERR_OK; 
 
			// 読み込んだ行番号を反映 
			m_iLogicalLineNum = tmpLineNum; 
 
			// ファイル名を探す 
			while (isspace(*p1)) 
				p1++; 
			if (*p1 != '\"') 
				return CFG_ERR_OK; 
			p1++; 
			p2 = strchr(p1, '\"'); 
			if (p2 == NULL) 
				return CFG_ERR_OK; 
			*p2 = '\0'; 
 
			// ファイル名を反映 
			strncpy(m_szLogicalInputFile, p1, MAX_PATH - 1); 
			m_szLogicalInputFile[MAX_PATH - 1] = '\0'; 
 
			return CFG_ERR_OK; 
		} 
 
		// 文字の読み込み 
		szText[iCount++] = c; 
	} 
} 
 
 
// 文字列読み込み 
int CRead::ReadString(int cDelimiter, char* szText, int& iCount) 
{ 
	bool blEsc  = false; 
	int c; 
 
	for ( ; ; ) 
	{ 
		// 1文字読み込み 
		if ( (c = fgetc(m_fpRead)) == EOF ) 
		{ 
			return CFG_ERR_EOF;	// 予期せぬEOF 
		} 
 
		// サイズチェック 
		if ( iCount >= READ_MAX_STATE - 1 ) 
		{ 
			return CFG_ERR_STATE_LEN; 
		} 
 
		// 改行チェック 
		if ( c == '\n' ) 
		{ 
			return CFG_ERR_CR;		// 不正な改行 
		} 
 
		// 文字の設定 
		szText[iCount++] = c; 
 
		// \ の次は無条件にスキップ 
		if ( blEsc ) 
		{ 
			blEsc  = false; 
			continue; 
		} 
 
		// \ のチェック 
		if ( c == '\\' ) 
		{ 
			blEsc  = true; 
			continue; 
		} 
 
		blEsc  = false; 
 
		// デリミタ文字なら完了 
		if ( c == cDelimiter ) 
		{ 
			return CFG_ERR_OK; 
		} 
	} 
} 
 
 
// --------------------------------------------------------------------------- 
//  Copyright (C) 1998-2002 by Project HOS                                     
// ---------------------------------------------------------------------------