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

📄 csv.cpp

📁 GNU ccScript is a C++ class framework for creating a virtual machine execution system for use with a
💻 CPP
字号:
// Copyright (C) 2005 David Sugar, Tycho Softworks.//  // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccScript.  If you copy code from other releases into a copy of GNU// ccScript, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccScript, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "script3.h"#include <cc++/slog.h>#include <cstdio>namespace ccscript3Extension {using namespace std;using namespace ost;	class CSVArrayThread : public ScriptThread{private:	Symbol *sym;	char csvbuf[1024];#ifdef	WIN32	HANDLE fh;	#else	int fd;#endif	void run(void);public:	CSVArrayThread(ScriptInterp *interp, Symbol *s);	~CSVArrayThread();};	class CSVThread : public ScriptThread{private:	char csvbuf[1024];#ifdef	WIN32	HANDLE fh;#else	int fd;#endif		void run(void);public:	CSVThread(ScriptInterp *interp);	~CSVThread();};	class CSVChecks : public ScriptChecks{public:	const char *chkCSV(Line *line, ScriptImage *img);	const char *chkCSVArray(Line *line, ScriptImage *img);	const char *chkCSVExpand(Line *line, ScriptImage *img);};class CSVMethods : public ScriptMethods{public:	bool scrCSV(void);	bool scrCSVArray(void);	bool scrCSVExpand(void);};CSVThread::CSVThread(ScriptInterp *interp) :ScriptThread(interp, 0){#ifdef	WIN32	fh = INVALID_HANDLE_VALUE;#else	fd = -1;#endif}CSVArrayThread::CSVArrayThread(ScriptInterp *interp, Symbol *s) :ScriptThread(interp, 0){#ifdef	WIN32	fh = INVALID_HANDLE_VALUE;#else	fd = -1;#endif	sym = s;}CSVThread::~CSVThread(){	terminate();#ifdef	WIN32	if(fh != INVALID_HANDLE_VALUE)		CloseHandle(fh);#else	if(fd > -1)		::close(fd);#endif}CSVArrayThread::~CSVArrayThread(){        terminate();#ifdef	WIN32		if(fh != INVALID_HANDLE_VALUE)			CloseHandle(fh);#else        if(fd > -1)                ::close(fd);#endif}static Script::Define runtime[] = {	{"csv", false, (Script::Method)&CSVMethods::scrCSV,		(Script::Check)&CSVChecks::chkCSV},        {"csvarray", false, (Script::Method)&CSVMethods::scrCSVArray,                (Script::Check)&CSVChecks::chkCSVArray},        {"csvexpand", false, (Script::Method)&CSVMethods::scrCSVExpand,                (Script::Check)&CSVChecks::chkCSVExpand},	{NULL, false, NULL, NULL}};	static ScriptBinder bindCSV(runtime);void CSVArrayThread::run(void){        unsigned len = 0;        const char *v;        char path[128];	unsigned idx = 0;	Array *a = (Array *)&sym->data;	for(;;)	{		v = NULL;		switch(sym->type)		{		case symARRAY:			if(idx < a->count && idx < a->tail)		v = sym->data + sizeof(Array) + idx * (a->rec + 1);			++idx;			break;		case symSTACK:			if(a->tail != a->head)			{				idx = a->tail;				if(a->tail == 0)					a->tail = a->count - 1;				else					--a->tail;		v = sym->data + sizeof(Array) + idx * (a->rec + 1);			}			break;		case symFIFO:			if(a->head != a->tail)			{				v = sym->data + a->head * (a->rec + 1) + sizeof(Array);				if(++a->head >= a->count)					a->head = 0;			}		default:			break;		}		if(!v)			break;		if(len)                        snprintf(csvbuf + len, sizeof(csvbuf) - len - 3,                                ",\'%s\'", v);                else                        snprintf(csvbuf, sizeof(csvbuf) - 3, "\'%s\'", v);		len = (unsigned)strlen(csvbuf);	}    if(!len)		exit("csv-empty");    csvbuf[len++] = '\r';    csvbuf[len++] = '\n';    snprintf(path, sizeof(path), "%s/%s.csv",            Script::log_prefix, interp->getMember());#ifdef	WIN32	DWORD wc;	fh = CreateFile(path, GENERIC_WRITE, 0, 		NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);	if(fh == INVALID_HANDLE_VALUE)			exit("csv-failed");	SetFilePointer(fh, 0, NULL, FILE_END);	WriteFile(fh, csvbuf, len, &wc, NULL);#else    fd = ::open(path, O_APPEND | O_CREAT | O_WRONLY, 0660);    if(fd < 0)            exit("csv-failed");    if(::write(fd, csvbuf, len) < len)	exit("csv-failed");#endif    exit(NULL);}void CSVThread::run(void){	unsigned len = 0;	const char *v;	char path[128];	lock();		while(NULL != (v = interp->getValue(NULL)))	{		if(len)			snprintf(csvbuf + len, sizeof(csvbuf) - len - 3,				",\'%s\'", v);		else			snprintf(csvbuf, sizeof(csvbuf) - 3, "\'%s\'", v);		len = (unsigned)strlen(csvbuf);		release();		Thread::yield();		lock();	}	release();	if(!len)		exit("csv-empty");	csvbuf[len++] = '\r';	csvbuf[len++] = '\n';	snprintf(path, sizeof(path), "%s/%s.csv", Script::log_prefix, interp->getMember());#ifdef	WIN32	DWORD wc;	fh = CreateFile(path, GENERIC_WRITE, 0, 		NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);	if(fh == INVALID_HANDLE_VALUE)			exit("csv-failed");	SetFilePointer(fh, 0, NULL, FILE_END);	WriteFile(fh, csvbuf, len, &wc, NULL);#else	fd = ::open(path, O_APPEND | O_CREAT | O_WRONLY, 0660);	if(fd < 0)		exit("csv-failed");	if(::write(fd, csvbuf, len) < len)		exit("csv-failed");#endif	exit(NULL);}	bool CSVMethods::scrCSV(void){	release();	new CSVThread(dynamic_cast<ScriptInterp*>(this));	return false;}bool CSVMethods::scrCSVExpand(void){	const char *cp = getOption();	Symbol *sym = mapSymbol(cp, 0);	Symbol *dest;	unsigned size = symsize;	unsigned offset = 0;	unsigned len = 0, idx = 0;	Array *a;	cp = getKeyword("size");	if(cp)		size = atoi(cp);	cp = getKeyword("offset");	if(cp)		offset = atoi(cp);        if(!sym)        {                error("no-array");                return true;        }        switch(sym->type)        {        case symARRAY:        case symFIFO:        case symSTACK:                break;        default:                error("invalid-array");                return true;        }	cp = getOption();	dest = mapSymbol(cp, size);	if(!dest)	{		error("destination-missing");		return true;	}	if(dest->type != symINITIAL && dest->type != symNORMAL)	{		error("destination-invalid");		return true;	}	dest->type = symNORMAL;	dest->data[0] = 0;	a = (Array *)&sym->data;	for(;;)	{		cp = NULL;                switch(sym->type)                {                case symARRAY:                        if(idx < a->count && idx < a->tail)                		cp = sym->data + sizeof(Array) + idx * (a->rec + 1);                        ++idx;                        break;                case symSTACK:                        if(a->tail != a->head)                        {                                idx = a->tail;                                if(a->tail == 0)                                        a->tail = a->count - 1;                                else                                        --a->tail;                		cp = sym->data + sizeof(Array) + idx * (a->rec + 1);                        }                        break;                case symFIFO:                        if(a->head != a->tail)                        {                		cp = sym->data + a->head * (a->rec + 1) + sizeof(Array);                                if(++a->head >= a->count)                                        a->head = 0;                        }		default:                        break;		}		if(!cp)			break;		if(offset)		{			--offset;			continue;		}                if(len)                        snprintf(dest->data + len, dest->size - len,                                ",\'%s\'", cp);                else                        snprintf(dest->data, dest->size, 				"\'%s\'", cp);                len = (unsigned)strlen(dest->data);	}	advance();	return true;}bool CSVMethods::scrCSVArray(void){	const char *cp = getOption();	Symbol *sym = mapSymbol(cp, 0);	if(!sym)	{		error("no-array");		return true;	}	switch(sym->type)	{	case symARRAY:	case symFIFO:	case symSTACK:		break;	default:		error("invalid-array");		return true;	}	release();	new CSVArrayThread(dynamic_cast<ScriptInterp *>(this), sym);	return false;}const char *CSVChecks::chkCSV(Line *line, ScriptImage *img){		if(!getMember(line))		return "csv requires .filename";			if(hasKeywords(line))		return "csv uses no keywords";			if(!line->argc)		return "csv requires arguments";			return NULL;}const char *CSVChecks::chkCSVExpand(Line *line, ScriptImage *img){        const char *cp;	unsigned idx = 0;        if(getMember(line))                return "csvexpand has no members";        if(!useKeywords(line, "=size=offset"))                return "invalid keyword for csvexpand";	cp = getOption(line, &idx);	if(!cp)                return "csvexpand requires two arguments";        if(*cp != '%' && *cp != '&')                return "csvexpand requires variable argument";        cp = getOption(line, &idx);        if(!cp)                return "csvexpand requires destination variable";        if(*cp != '%' && *cp != '&')                return "csvexpand requires variable destination";	cp = getOption(line, &idx);	if(cp)		return "too many arguments for csvexpand";	        return NULL;}const char *CSVChecks::chkCSVArray(Line *line, ScriptImage *img){	const char *cp;        if(!getMember(line))                return "csvarray requires .filename";        if(hasKeywords(line))                return "csvarray uses no keywords";        if(line->argc != 1)                return "csvarray requires one arguments";	cp = line->args[0];	if(*cp != '%' && *cp != '&')		return "csvarray requires variable argument";        return NULL;}};

⌨️ 快捷键说明

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