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

📄 cmd.c.svn-base

📁 解码器是基于短语的统计机器翻译系统的核心模块
💻 SVN-BASE
字号:
#include	<stdio.h>#include	<stdlib.h>#include	<ctype.h>#include	<string.h>#include	"cmd.h"static Enum_T	BoolEnum[] = {	{	"FALSE",	0	},	{	"TRUE",		1	},	{	0,		0	}};#ifdef	NEEDSTRDUPchar	*strdup();#endif#define	FALSE	0#define	TRUE	1#define	LINSIZ		10240#define	MAXPARAM	256static char	*GetLine(),		**str2array();static int	Scan(),		SetParam(),		SetEnum(),		SetSubrange(),		SetStrArray(),		SetGte(),		SetLte(),		CmdError(),		EnumError(),		SubrangeError(),		GteError(),		LteError(),		PrintParam(),		PrintEnum(),		PrintStrArray();static Cmd_T	cmds[MAXPARAM+1];static char	*SepString = " \t\n";#if defined(__STDC__)#include	<stdarg.h>int DeclareParams(char *ParName, ...)#else#include	<varargs.h>int DeclareParams(ParName, va_alist)char	*ParName;va_dcl#endif{	va_list		args;	static int	ParamN = 0;	int		j,			c;	char		*s;#if defined(__STDC__)	va_start(args, ParName);#else	va_start(args);#endif	for(;ParName;) {		if(ParamN==MAXPARAM) {			fprintf(stderr, "Too many parameters !!\n");			break;		}		for(j=0,c=1; j<ParamN&&(c=strcmp(cmds[j].Name,ParName))<0; j++)			;		if(!c) {			fprintf(stderr,				"Warning: parameter \"%s\" declared twice.\n",				ParName);		}		for(c=ParamN; c>j; c--) {			cmds[c] = cmds[c-1];		}		cmds[j].Name = ParName;		cmds[j].Type = va_arg(args, int);		cmds[j].Val = va_arg(args, void *);		switch(cmds[j].Type) {		case CMDENUMTYPE:	/* get the pointer to Enum_T struct  */			cmds[j].p = va_arg(args, void *);			break;		case CMDSUBRANGETYPE:	/* get the two extremes		     */			cmds[j].p = (void*) calloc(2, sizeof(int));			((int*)cmds[j].p)[0] = va_arg(args, int);			((int*)cmds[j].p)[1] = va_arg(args, int);			break;		case CMDGTETYPE:	/* get lower or upper bound	     */		case CMDLTETYPE:			cmds[j].p = (void*) calloc(1, sizeof(int));			((int*)cmds[j].p)[0] = va_arg(args, int);			break;		case CMDSTRARRAYTYPE:	/* get the separators string	     */			cmds[j].p = (s=va_arg(args, char*))				    ? (void*)strdup(s) : 0;			break;		case CMDBOOLTYPE:			cmds[j].Type = CMDENUMTYPE;			cmds[j].p = BoolEnum;			break;		case CMDDOUBLETYPE:	/* nothing else is needed	     */		case CMDINTTYPE:		case CMDSTRINGTYPE:			break;		default:			fprintf(stderr, "%s: %s %d %s \"%s\"\n",				"DeclareParam()", "Unknown Type",				cmds[j].Type, "for parameter", cmds[j].Name);			exit(1);		}		ParamN++;		ParName = va_arg(args, char *);	}	cmds[ParamN].Name = NULL;	va_end(args);	return 0;}int GetParams(n, a, CmdFileName)int	*n;char	***a;char	*CmdFileName;{	char	*Line,		*ProgName;	int	argc = *n;	char	**argv = *a,		*s;	FILE	*fp;	int	IsPipe;#ifdef	MSDOS#define	PATHSEP '\\'	char	*dot = NULL;#else#define	PATHSEP '/'#endif	if(!(Line=malloc(LINSIZ))) {		fprintf(stderr, "GetParams(): Unable to alloc %d bytes\n",			LINSIZ);		exit(1);	}	if((ProgName=strrchr(*argv, PATHSEP))) {		++ProgName;	} else {		ProgName = *argv;	}#ifdef	MSDOS	if(dot=strchr(ProgName, '.')) *dot = 0;#endif	--argc;	++argv;	for(;;) {		if(argc && argv[0][0]=='-' && argv[0][1]=='=') {			CmdFileName = argv[0]+2;			++argv;			--argc;		}		if(!CmdFileName) {			break;		}		IsPipe = !strncmp(CmdFileName, "@@", 2);		fp = IsPipe		     ? popen(CmdFileName+2, "r")		     : strcmp(CmdFileName, "-")		       ? fopen(CmdFileName, "r")		       : stdin;		if(!fp) {			fprintf(stderr, "Unable to open command file %s\n",				CmdFileName);			exit(1);		}		while(GetLine(fp, LINSIZ, Line) && strcmp(Line, "\\End")) {			if(Scan(ProgName, cmds, Line)) {				CmdError(Line);			}		}		if(fp!=stdin) {			if(IsPipe) pclose(fp); else fclose(fp);		}		CmdFileName = NULL;	}	while(argc && **argv=='-' && (s=strchr(*argv, '='))) {		*s = ' ';		sprintf(Line, "%s/%s", ProgName, *argv+1);		*s = '=';		if(Scan(ProgName, cmds, Line)) CmdError(*argv);		--argc;		++argv;	}	*n = argc;	*a = argv;#ifdef MSDOS	if(dot) *dot = '.';#endif	free(Line);	return 0;}int PrintParams(ValFlag, fp)int	ValFlag;FILE	*fp;{	int	i;	fflush(fp);	if(ValFlag) {		fprintf(fp, "Parameters Values:\n");	} else {		fprintf(fp, "Parameters:\n");	}	for(i=0; cmds[i].Name; i++) PrintParam(cmds+i, ValFlag, fp);	fprintf(fp, "\n");	fflush(fp);	return 0;}int SPrintParams(a, pfx)char	***a,	*pfx;{	int	l,		n;	Cmd_T	*cmd;	if(!pfx) pfx="";	l = strlen(pfx);	for(n=0, cmd=cmds; cmd->Name; cmd++) n += !!cmd->ArgStr;	a[0] = calloc(n, sizeof(char*));	for(n=0, cmd=cmds; cmd->Name; cmd++) {		if(!cmd->ArgStr) continue;		a[0][n] = malloc(strlen(cmd->Name)+strlen(cmd->ArgStr)+l+2);		sprintf(a[0][n], "%s%s=%s", pfx, cmd->Name, cmd->ArgStr);		++n;	}	return n;}static int CmdError(opt)char	*opt;{	fprintf(stderr, "Invalid option \"%s\"\n", opt);	fprintf(stderr, "This program expectes the following parameters:\n");	PrintParams(FALSE, stderr);	exit(0);}static int PrintParam(cmd, ValFlag, fp)Cmd_T	*cmd;int	ValFlag;FILE	*fp;{	fprintf(fp, "%4s", "");	switch(cmd->Type) {	case CMDDOUBLETYPE:		fprintf(fp, "%s", cmd->Name);		if(ValFlag) fprintf(fp, ": %22.15e", *(double *)cmd->Val);		fprintf(fp, "\n");		break;	case CMDENUMTYPE:		PrintEnum(cmd, ValFlag, fp);		break;	case CMDINTTYPE:	case CMDSUBRANGETYPE:	case CMDGTETYPE:	case CMDLTETYPE:		fprintf(fp, "%s", cmd->Name);		if(ValFlag) fprintf(fp, ": %d", *(int *)cmd->Val);		fprintf(fp, "\n");		break;	case CMDSTRINGTYPE:		fprintf(fp, "%s", cmd->Name);		if(ValFlag) {			if(*(char **)cmd->Val) {				fprintf(fp, ": \"%s\"", *(char **)cmd->Val);			} else {				fprintf(fp, ": %s", "NULL");			}		}		fprintf(fp, "\n");		break;	case CMDSTRARRAYTYPE:		PrintStrArray(cmd, ValFlag, fp);		break;	default:		fprintf(stderr, "%s: %s %d %s \"%s\"\n",			"PrintParam",			"Unknown Type",			cmd->Type,			"for parameter",			cmd->Name);		exit(1);	}	return 0;}static char *GetLine(fp, n, Line)FILE	*fp;int	n;char	*Line;{	int	j,		l,		offs=0;	for(;;) {		if(!fgets(Line+offs, n-offs, fp)) {			return NULL;		}		if(Line[offs]=='#') continue;		l = strlen(Line+offs)-1;		Line[offs+l] = 0;		for(j=offs; Line[j] && isspace(Line[j]); j++, l--)			;		if(l<1) continue;		if(j > offs) {			char	*s = Line+offs,				*q = Line+j;			while((*s++=*q++))				;		}		if(Line[offs+l-1]=='\\') {			offs += l;			Line[offs-1] = ' ';		} else {			break;		}	}	return Line;}static int Scan(ProgName, cmds, Line)char	*ProgName,	*Line;Cmd_T	*cmds;{	char	*q,		*p;	int	i,		hl,		HasToMatch = FALSE,		c0,		c;	p = Line+strspn(Line, SepString);	if(!(hl=strcspn(p, SepString))) {		return 0;	}	if((q=strchr(p, '/')) && q-p<hl) {		*q = 0;		if(strcmp(p, ProgName)) {			*q = '/';			return 0;		}		*q = '/';		HasToMatch=TRUE;		p = q+1;	}	if(!(hl = strcspn(p, SepString))) {		return 0;	}	c0 = p[hl];	p[hl] = 0;	for(i=0, c=1; cmds[i].Name&&(c=strcmp(cmds[i].Name, p))<0; i++)		;	p[hl] = c0;	if(!c) return SetParam(cmds+i, p+hl+strspn(p+hl, SepString));	return HasToMatch && c;}static int SetParam(cmd, s)Cmd_T	*cmd;char	*s;{	if(!*s && cmd->Type != CMDSTRINGTYPE) {		fprintf(stderr,			"WARNING: No value specified for parameter \"%s\"\n",			cmd->Name);		return 0;	}	switch(cmd->Type) {	case CMDDOUBLETYPE:		if(sscanf(s, "%lf", (double*)cmd->Val)!=1) {			fprintf(stderr,				"Float value required for parameter \"%s\"\n",				cmd->Name);			exit(1);		}		break;	case CMDENUMTYPE:		SetEnum(cmd, s);		break;	case CMDINTTYPE:		if(sscanf(s, "%d", (int*)cmd->Val)!=1) {			fprintf(stderr,				"Integer value required for parameter \"%s\"\n",				cmd->Name);			exit(1);		}		break;	case CMDSTRINGTYPE:		*(char **)cmd->Val = (strcmp(s, "<NULL>") && strcmp(s, "NULL"))				     ? strdup(s)				     : 0;		break;	case CMDSTRARRAYTYPE:		SetStrArray(cmd, s);		break;	case CMDGTETYPE:		SetGte(cmd, s);		break;	case CMDLTETYPE:		SetLte(cmd, s);		break;	case CMDSUBRANGETYPE:		SetSubrange(cmd, s);		break;	default:		fprintf(stderr, "%s: %s %d %s \"%s\"\n",			"SetParam",			"Unknown Type",			cmd->Type,			"for parameter",			cmd->Name);		exit(1);	}	cmd->ArgStr = strdup(s);	return 0;}static int SetEnum(cmd, s)Cmd_T	*cmd;char	*s;{	Enum_T	*en;	for(en=(Enum_T *)cmd->p; en->Name; en++) {		if(*en->Name && !strcmp(s, en->Name)) {			*(int *) cmd->Val = en->Idx;			return 0;		}	}	return EnumError(cmd, s);}static int SetSubrange(cmd, s)Cmd_T	*cmd;char	*s;{	int	n;	if(sscanf(s, "%d", &n)!=1) {		fprintf(stderr,			"Integer value required for parameter \"%s\"\n",			cmd->Name);		exit(1);	}	if(n < *(int *)cmd->p || n > *((int *)cmd->p+1)) {		return SubrangeError(cmd, n);	}	*(int *)cmd->Val = n;	return 0;}static int SetGte(cmd, s)Cmd_T	*cmd;char	*s;{	int	n;	if(sscanf(s, "%d", &n)!=1) {		fprintf(stderr,			"Integer value required for parameter \"%s\"\n",			cmd->Name);		exit(1);	}	if(n<*(int *)cmd->p) {		return GteError(cmd, n);	}	*(int *)cmd->Val = n;	return 0;}static int SetStrArray(cmd, s)Cmd_T	*cmd;char	*s;{	*(char***)cmd->Val = str2array(s, (char*)cmd->p);	return 0;}static int SetLte(cmd, s)Cmd_T	*cmd;char	*s;{	int	n;	if(sscanf(s, "%d", &n)!=1) {		fprintf(stderr,			"Integer value required for parameter \"%s\"\n",			cmd->Name);		exit(1);	}	if(n > *(int *)cmd->p) {		return LteError(cmd, n);	}	*(int *)cmd->Val = n;	return 0;}static int EnumError(cmd, s)Cmd_T	*cmd;char	*s;{	Enum_T	*en;	fprintf(stderr,		"Invalid value \"%s\" for parameter \"%s\"\n", s, cmd->Name);	fprintf(stderr, "Valid values are:\n");	for(en=(Enum_T *)cmd->p; en->Name; en++) {		if(*en->Name) {			fprintf(stderr, "    %s\n", en->Name);		}	}	fprintf(stderr, "\n");	exit(1);}static int GteError(cmd, n)Cmd_T	*cmd;int	n;{	fprintf(stderr,		"Value %d out of range for parameter \"%s\"\n", n, cmd->Name);	fprintf(stderr, "Valid values must be greater than or equal to  %d\n",		*(int *)cmd->p);	exit(1);}static int LteError(cmd, n)Cmd_T	*cmd;int	n;{	fprintf(stderr,		"Value %d out of range for parameter \"%s\"\n", n, cmd->Name);	fprintf(stderr, "Valid values must be less than or equal to  %d\n",		*(int *)cmd->p);	exit(1);}static int SubrangeError(cmd, n)Cmd_T	*cmd;int	n;{	fprintf(stderr,		"Value %d out of range for parameter \"%s\"\n", n, cmd->Name);	fprintf(stderr, "Valid values range from %d to %d\n",		*(int *)cmd->p, *((int *)cmd->p+1));	exit(1);}static int PrintEnum(cmd, ValFlag, fp)Cmd_T	*cmd;int	ValFlag;FILE	*fp;{	Enum_T	*en;	fprintf(fp, "%s", cmd->Name);	if(ValFlag) {		for(en=(Enum_T *)cmd->p; en->Name; en++) {			if(*en->Name && en->Idx==*(int *)cmd->Val) {				fprintf(fp, ": %s", en->Name);			}		}	}	fprintf(fp, "\n");	return 0;}static int PrintStrArray(cmd, ValFlag, fp)Cmd_T	*cmd;int	ValFlag;FILE	*fp;{	char	*indent,		**s = *(char***)cmd->Val;	int	l = 4+strlen(cmd->Name);	fprintf(fp, "%s", cmd->Name);	indent = malloc(l+2);	memset(indent, ' ', l+1);	indent[l+1] = 0;	if(ValFlag) {		fprintf(fp, ": %s", s ? (*s ? *s++ : "NULL") : "");		if(s) while(*s) {			fprintf(fp, "\n%s %s", indent, *s++);		}	}	free(indent);	fprintf(fp, "\n");	return 0;}static char **str2array(s, sep)char	*s,	*sep;{	char	*p,		**a;	int	n = 0,		l;	if(!sep) sep = SepString;	p = s += strspn(s, sep);	while(*p) {		p += strcspn(p, sep);		p += strspn(p, sep);		++n;	}	a = calloc(n+1, sizeof(char *));	p = s;	n = 0;	while(*p) {		l = strcspn(p, sep);		a[n] = malloc(l+1);		memcpy(a[n], p, l);		a[n][l] = 0;		++n;		p += l;		p += strspn(p, sep);	}	return a;}

⌨️ 快捷键说明

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