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

📄 properfile.cpp

📁 porting scintilla to qt
💻 CPP
字号:
#include <stdlib.h>#include <string.h>#include <ctype.h>#include <stdio.h>#include <fcntl.h>#include <time.h>#include <locale.h>#if WIN32#else#include <unistd.h>#endif#include "Platform.h"#include "properfile.h"#include "filepath.h"#include "PropSet.h"#include "Scintilla.h"bool PropSetFile::caseSensitiveFilenames = false;PropSetFile::PropSetFile(bool lowerKeys_) : lowerKeys(lowerKeys_) {}PropSetFile::~PropSetFile() {}/** * Get a line of input. If end of line escaped with '\\' then continue reading. */static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len){	bool continuation = true;	s[0] = '\0';	while ((len > 1) && lenData > 0) {		char ch = *fpc;		fpc++;		lenData--;		if ((ch == '\r') || (ch == '\n')) {			if (!continuation) {				if ((lenData > 0) && (ch == '\r') && ((*fpc) == '\n')) {					// munch the second half of a crlf					fpc++;					lenData--;				}				*s = '\0';				return true;			}		} else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {			continuation = true;			if ((lenData > 1) && ((*fpc == '\r') && (*(fpc+1) == '\r') || (*fpc == '\n') && (*(fpc+1) == '\n')))				continuation = false;			else if ((lenData > 2) && ((*fpc == '\r') && (*(fpc+1) == '\n') && (*(fpc+2) == '\n' || *(fpc+2) == '\r')))				continuation = false;		} else {			continuation = false;			*s++ = ch;			*s = '\0';			len--;		}	}	return false;}static bool IsSpaceOrTab(char ch){	return (ch == ' ') || (ch == '\t');}static bool IsCommentLine(const char *line){	while (IsSpaceOrTab(*line)) ++line;	return (*line == '#');}bool PropSetFile::ReadLine(const char *lineBuffer, bool ifIsTrue, FilePath directoryForImports,	FilePath imports[], int sizeImports){	//UnSlash(lineBuffer);	if (!IsSpaceOrTab(lineBuffer[0]))    // If clause ends with first non-indented line		ifIsTrue = true;	if (isprefix(lineBuffer, "if ")) {		const char *expr = lineBuffer + strlen("if") + 1;		ifIsTrue = GetInt(expr) != 0;	} else if (isprefix(lineBuffer, "import ") && directoryForImports.IsSet()) {		SString importName(lineBuffer + strlen("import") + 1);		importName += ".properties";		FilePath importPath(importName.c_str());		if(imports){			for (int i = 0; i < sizeImports; i++) {				if (!imports[i].IsSet()) {					imports[i] = importPath;					break;				}			}		}/*		FilePath importPath(directoryForImports, FilePath(importName.c_str()));		if (Read(importPath, directoryForImports, imports, sizeImports)) {			if (imports) {				for (int i = 0; i < sizeImports; i++) {					if (!imports[i].IsSet()) {						imports[i] = importPath;						break;					}				}			}		}		*/	} else if (ifIsTrue && !IsCommentLine(lineBuffer)) {		Set(lineBuffer);	}	return ifIsTrue;}void PropSetFile::ReadFromMemory(const char *data, int len, FilePath directoryForImports,FilePath imports[], int sizeImports){	const char *pd = data;	char lineBuffer[60000];	bool ifIsTrue = true;	while (len > 0) {		GetFullLine(pd, len, lineBuffer, sizeof(lineBuffer));		if (lowerKeys) {			for (int i=0; lineBuffer[i] && (lineBuffer[i] != '='); i++) {				if ((lineBuffer[i] >= 'A') && (lineBuffer[i] <= 'Z')) {					lineBuffer[i] = static_cast<char>(lineBuffer[i] - 'A' + 'a');				}			}		}		ifIsTrue = ReadLine(lineBuffer, ifIsTrue, directoryForImports, imports, sizeImports);	}}bool PropSetFile::Read(FilePath filename, FilePath directoryForImports,	FilePath imports[], int sizeImports){	FILE *rcfile = filename.Open(fileRead);	if (rcfile) {		char propsData[60000];		int lenFile = static_cast<int>(fread(propsData, 1, sizeof(propsData), rcfile));		fclose(rcfile);		const char *data = propsData;		if (memcmp(data, "\xef\xbb\xbf", 3) == 0) {			data += 3;			lenFile -= 3;		}		ReadFromMemory(data, lenFile, directoryForImports, imports, sizeImports);		return true;	}	return false;}void PropSetFile::SetInteger(const char *key, sptr_t i){	char tmp[32];	sprintf(tmp, "%d", static_cast<int>(i));	Set(key, tmp);}static inline char MakeUpperCase(char ch){	if (ch < 'a' || ch > 'z')		return ch;	else		return static_cast<char>(ch - 'a' + 'A');}static bool StringEqual(const char *a, const char *b, size_t len, bool caseSensitive){	if (caseSensitive) {		for (size_t i = 0; i < len; i++) {			if (a[i] != b[i])				return false;		}	} else {		for (size_t i = 0; i < len; i++) {			if (MakeUpperCase(a[i]) != MakeUpperCase(b[i]))				return false;		}	}	return true;}// Match file names to patterns allowing for a '*' suffix or prefix.static bool MatchWild(const char *pattern, size_t lenPattern, const char *fileName, bool caseSensitive){	size_t lenFileName = strlen(fileName);	if (lenFileName == lenPattern) {		if (StringEqual(pattern, fileName, lenFileName, caseSensitive)) {			return true;		}	}	if (lenFileName >= lenPattern-1) {		if (pattern[0] == '*') {			// Matching suffixes			return StringEqual(pattern+1, fileName + lenFileName - (lenPattern-1), lenPattern-1, caseSensitive);		} else if (pattern[lenPattern-1] == '*') {			// Matching prefixes			return StringEqual(pattern, fileName, lenPattern-1, caseSensitive);		}	}	return false;}SString PropSetFile::GetWildUsingStart(const PropSet &psStart, const char *keybase, const char *filename){	for (int root = 0; root < hashRoots; root++) {		for (Property *p = props[root]; p; p = p->next) {			if (isprefix(p->key, keybase)) {				char *orgkeyfile = p->key + strlen(keybase);				char *keyfile = NULL;				if (strncmp(orgkeyfile, "$(", 2) == 0) {					const char *cpendvar = strchr(orgkeyfile, ')');					if (cpendvar) {						SString var(orgkeyfile, 2, cpendvar-orgkeyfile);						SString s = psStart.GetExpanded(var.c_str());						keyfile = StringDup(s.c_str());					}				}				char *keyptr = keyfile;				if (keyfile == NULL)					keyfile = orgkeyfile;				for (;;) {					char *del = strchr(keyfile, ';');					if (del == NULL)						del = keyfile + strlen(keyfile);					if (MatchWild(keyfile, del - keyfile, filename, caseSensitiveFilenames)) {						delete []keyptr;						return p->val;					}					if (*del == '\0')						break;					keyfile = del + 1;				}				delete []keyptr;				if (0 == strcmp(p->key, keybase)) {					return p->val;				}			}		}	}	if (superPS) {		// Failed here, so try in super property set		return static_cast<PropSetFile *>(superPS)->GetWildUsingStart(psStart, keybase, filename);	} else {		return "";	}}SString PropSetFile::GetWild(const char *keybase, const char *filename){	return GetWildUsingStart(*this, keybase, filename);}// GetNewExpand does not use Expand as it has to use GetWild with the filename for each// variable reference found.SString PropSetFile::GetNewExpand(const char *keybase, const char *filename){	char *base = StringDup(GetWild(keybase, filename).c_str());	char *cpvar = strstr(base, "$(");	int maxExpands = 1000;	// Avoid infinite expansion of recursive definitions	while (cpvar && (maxExpands > 0)) {		const char *cpendvar = strchr(cpvar, ')');		if (cpendvar) {			int lenvar = cpendvar - cpvar - 2;  	// Subtract the $()			char *var = StringDup(cpvar + 2, lenvar);			SString val = GetWild(var, filename);			if (0 == strcmp(var, keybase))				val.clear(); // Self-references evaluate to empty string			size_t newlenbase = strlen(base) + val.length() - lenvar;			char *newbase = new char[newlenbase];			strncpy(newbase, base, cpvar - base);			strcpy(newbase + (cpvar - base), val.c_str());			strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1);			delete []var;			delete []base;			base = newbase;		}		cpvar = strstr(base, "$(");		maxExpands--;	}	SString sret = base;	delete []base;	return sret;}/** * Initiate enumeration. */bool PropSetFile::GetFirst(char **key, char **val){	for (int i = 0; i < hashRoots; i++) {		for (Property *p = props[i]; p; p = p->next) {			if (p) {				*key = p->key;				*val = p->val;				enumnext = p->next; // GetNext will begin here ...				enumhash = i;		  // ... in this block				return true;			}		}	}	return false;}/** * Continue enumeration. */bool PropSetFile::GetNext(char ** key, char ** val){	bool firstloop = true;	// search begins where we left it : in enumhash block	for (int i = enumhash; i < hashRoots; i++) {		if (!firstloop)			enumnext = props[i]; // Begin with first property in block		// else : begin where we left		firstloop = false;		for (Property *p = enumnext; p; p = p->next) {			if (p) {				*key = p->key;				*val = p->val;				enumnext = p->next; // for GetNext				enumhash = i;				return true;			}		}	}	return false;}

⌨️ 快捷键说明

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