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

📄 options.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* Check list of abbreviations. */		atmp.name = name;		if ((ap = bsearch(&atmp, abbrev,		    sizeof(abbrev) / sizeof(OABBREV) - 1,		    sizeof(OABBREV), opts_abbcmp)) != NULL) {			op = optlist + ap->offset;			goto found;		}		/* Check list of options. */		otmp.name = name;		if ((op = bsearch(&otmp, optlist,		    sizeof(optlist) / sizeof(OPTLIST) - 1,		    sizeof(OPTLIST), opts_cmp)) != NULL)			goto found;		/* Check for prefix match. */prefix:		op = opts_prefix(name);found:		if (op == NULL) {			msgq(sp, M_ERR,			    "no %s option: 'set all' gives all option values",			    name);			continue;		}		/* Find current option values. */		offset = op - optlist;		spo = sp->opts + offset;		/* Set name, value. */		switch (op->type) {		case OPT_0BOOL:		case OPT_1BOOL:			if (equals) {				msgq(sp, M_ERR,				    "set: [no]%s option doesn't take a value",				    name);				break;			}			if (op->func != NULL) {				if (op->func(sp, spo, NULL, turnoff)) {					rval = 1;					break;				}			} else if (turnoff)				O_CLR(sp, offset);			else				O_SET(sp, offset);			goto change;		case OPT_NUM:			/*			 * !!!			 * Extension to historic vi.  If the OPT_NOSTR flag is			 * set, a numeric option may be turned off by using a			 * "no" prefix, e.g. "nowrapmargin".  (We assume that			 * setting the value to 0 turns a numeric option off.)			 */			if (turnoff) {				if (F_ISSET(op, OPT_NOSTR)) {					value = 0;					goto nostr;				}				msgq(sp, M_ERR,				    "set: %s option isn't a boolean", name);				break;			}			if (!equals) {				if (!disp)					disp = SELECT_DISPLAY;				F_SET(spo, OPT_SELECTED);				break;			}			value = strtol(equals, &endp, 10);			if (*endp && !isblank(*endp)) {				msgq(sp, M_ERR,				    "set %s: illegal number %s", name, equals);				break;			}nostr:			if (op->func != NULL) {				if (op->func(sp, spo, equals, value)) {					rval = 1;					break;				}			} else				O_VAL(sp, offset) = value;			goto change;		case OPT_STR:			if (turnoff) {				msgq(sp, M_ERR,				    "set: %s option isn't a boolean", name);				break;			}			if (!equals) {				if (!disp)					disp = SELECT_DISPLAY;				F_SET(spo, OPT_SELECTED);				break;			}			if (op->func != NULL) {				if (op->func(sp, spo, equals, (u_long)0)) {					rval = 1;					break;				}			} else {				if (F_ISSET(&sp->opts[offset], OPT_ALLOCATED))					free(O_STR(sp, offset));				if ((O_STR(sp, offset) =				    strdup(equals)) == NULL) {					msgq(sp, M_SYSERR, NULL);					rval = 1;					break;				} else					F_SET(&sp->opts[offset], OPT_ALLOCATED);			}change:			if (sp->s_optchange != NULL)				(void)sp->s_optchange(sp, offset);			F_SET(&sp->opts[offset], OPT_SET);			break;		default:			abort();		}	}	if (disp != NO_DISPLAY)		opts_dump(sp, disp);	return (rval);}/* * opts_dump -- *	List the current values of selected options. */voidopts_dump(sp, type)	SCR *sp;	enum optdisp type;{	OPTLIST const *op;	int base, b_num, cnt, col, colwidth, curlen, s_num;	int numcols, numrows, row;	int b_op[O_OPTIONCOUNT], s_op[O_OPTIONCOUNT];	char nbuf[20];	/*	 * XXX	 * It's possible to get here by putting "set option" in the	 * .exrc file.  I can't think of a clean way to layer this,	 * or a reasonable check to make, so we block it here.	 */	if (sp->stdfp == NULL) {		msgq(sp, M_ERR,		    "Option display requires that the screen be initialized.");		return;	}	/*	 * Options are output in two groups -- those that fit in a column and	 * those that don't.  Output is done on 6 character "tab" boundaries	 * for no particular reason.  (Since we don't output tab characters,	 * we can ignore the terminal's tab settings.)  Ignore the user's tab	 * setting because we have no idea how reasonable it is.	 *	 * Find a column width we can live with.	 */	for (cnt = 6; cnt > 1; --cnt) {		colwidth = (sp->cols - 1) / cnt & ~(STANDARD_TAB - 1);		if (colwidth >= 10) {			colwidth =			    (colwidth + STANDARD_TAB) & ~(STANDARD_TAB - 1);			break;		}		colwidth = 0;	}	/*	 * Get the set of options to list, entering them into	 * the column list or the overflow list.	 */	for (b_num = s_num = 0, op = optlist; op->name != NULL; ++op) {		cnt = op - optlist;		/* If OPT_NEVER set, it's never displayed. */		if (F_ISSET(op, OPT_NEVER))			continue;		switch (type) {		case ALL_DISPLAY:		/* Display all. */			break;		case CHANGED_DISPLAY:		/* Display changed. */			if (!F_ISSET(&sp->opts[cnt], OPT_SET))				continue;			break;		case SELECT_DISPLAY:		/* Display selected. */			if (!F_ISSET(&sp->opts[cnt], OPT_SELECTED))				continue;			break;		default:		case NO_DISPLAY:			abort();			/* NOTREACHED */		}		F_CLR(&sp->opts[cnt], OPT_SELECTED);		curlen = strlen(op->name);		switch (op->type) {		case OPT_0BOOL:		case OPT_1BOOL:			if (!O_ISSET(sp, cnt))				curlen += 2;			break;		case OPT_NUM:			(void)snprintf(nbuf,			    sizeof(nbuf), "%ld", O_VAL(sp, cnt));			curlen += strlen(nbuf);			break;		case OPT_STR:			curlen += strlen(O_STR(sp, cnt)) + 3;			break;		}		/* Offset by two so there's a gap. */		if (curlen < colwidth - 2)			s_op[s_num++] = cnt;		else			b_op[b_num++] = cnt;	}	if (s_num > 0) {		/* Figure out the number of columns. */		numcols = (sp->cols - 1) / colwidth;		if (s_num > numcols) {			numrows = s_num / numcols;			if (s_num % numcols)				++numrows;		} else			numrows = 1;		/* Display the options in sorted order. */		for (row = 0; row < numrows;) {			for (base = row, col = 0; col < numcols; ++col) {				cnt = opts_print(sp, &optlist[s_op[base]]);				if ((base += numrows) >= s_num)					break;				(void)ex_printf(EXCOOKIE,				    "%*s", (int)(colwidth - cnt), "");			}			if (++row < numrows || b_num)				(void)ex_printf(EXCOOKIE, "\n");		}	}	for (row = 0; row < b_num;) {		(void)opts_print(sp, &optlist[b_op[row]]);		if (++row < b_num)			(void)ex_printf(EXCOOKIE, "\n");	}	(void)ex_printf(EXCOOKIE, "\n");}/* * opts_print -- *	Print out an option. */static intopts_print(sp, op)	SCR *sp;	OPTLIST const *op;{	int curlen, offset;	curlen = 0;	offset = op - optlist;	switch (op->type) {	case OPT_0BOOL:	case OPT_1BOOL:		curlen += ex_printf(EXCOOKIE,		    "%s%s", O_ISSET(sp, offset) ? "" : "no", op->name);		break;	case OPT_NUM:		curlen += ex_printf(EXCOOKIE,		     "%s=%ld", op->name, O_VAL(sp, offset));		break;	case OPT_STR:		curlen += ex_printf(EXCOOKIE,		    "%s=\"%s\"", op->name, O_STR(sp, offset));		break;	}	return (curlen);}/* * opts_save -- *	Write the current configuration to a file. */intopts_save(sp, fp)	SCR *sp;	FILE *fp;{	OPTLIST const *op;	int ch, cnt;	char *p;	for (op = optlist; op->name != NULL; ++op) {		if (F_ISSET(op, OPT_NOSAVE))			continue;		cnt = op - optlist;		switch (op->type) {		case OPT_0BOOL:		case OPT_1BOOL:			if (O_ISSET(sp, cnt))				(void)fprintf(fp, "set %s\n", op->name);			else				(void)fprintf(fp, "set no%s\n", op->name);			break;		case OPT_NUM:			(void)fprintf(fp,			    "set %s=%-3d\n", op->name, O_VAL(sp, cnt));			break;		case OPT_STR:			(void)fprintf(fp, "set ");			for (p = op->name; (ch = *p) != '\0'; ++p) {				if (isblank(ch))					(void)putc('\\', fp);				(void)putc(ch, fp);			}			(void)putc('=', fp);			for (p = O_STR(sp, cnt); (ch = *p) != '\0'; ++p) {				if (isblank(ch))					(void)putc('\\', fp);				(void)putc(ch, fp);			}			(void)putc('\n', fp);			break;		}		if (ferror(fp)) {			msgq(sp, M_ERR, "I/O error: %s", strerror(errno));			return (1);		}	}	return (0);}/* * opts_prefix -- *	Check to see if the name is the prefix of one (and only one) *	option.  If so, return the option. */static OPTLIST const *opts_prefix(name)	char *name;{	OPTLIST const *op, *save_op;	size_t len;	save_op = NULL;	len = strlen(name);	for (op = optlist; op->name != NULL; ++op) {		if (op->name[0] < name[0])			continue;		if (op->name[0] > name[0])			break;		if (!memcmp(op->name, name, len)) {			if (save_op != NULL)				return (NULL);			save_op = op;		}	}	return (save_op);}static intopts_abbcmp(a, b)        const void *a, *b;{        return(strcmp(((OABBREV *)a)->name, ((OABBREV *)b)->name));}static intopts_cmp(a, b)        const void *a, *b;{        return(strcmp(((OPTLIST *)a)->name, ((OPTLIST *)b)->name));}/* * opts_free -- *	Free all option strings */voidopts_free(sp)	SCR *sp;{	int cnt;	char *p;	for (cnt = 0; cnt < O_OPTIONCOUNT; ++cnt)		if (F_ISSET(&sp->opts[cnt], OPT_ALLOCATED)) {			p = O_STR(sp, cnt);			FREE(p, strlen(p) + 1);		}}/* * opts_copy -- *	Copy a screen's OPTION array. */intopts_copy(orig, sp)	SCR *orig, *sp;{	OPTION *op;	int cnt;	/* Copy most everything without change. */	memmove(sp->opts, orig->opts, sizeof(orig->opts));	/*	 * Allocate copies of the strings -- keep trying to reallocate	 * after ENOMEM failure, otherwise end up with more than one	 * screen referencing the original memory.	 */	for (op = sp->opts, cnt = 0; cnt < O_OPTIONCOUNT; ++cnt, ++op)		if (F_ISSET(&sp->opts[cnt], OPT_ALLOCATED) &&		    (O_STR(sp, cnt) = strdup(O_STR(sp, cnt))) == NULL) {			msgq(orig, M_SYSERR, NULL);			return (1);		}	return (0);}

⌨️ 快捷键说明

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