/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* Copyright (c) 1981 Regents of the University of California */ #include "ex.h" #include "ex_temp.h" #include "ex_tty.h" /* * Set command. */ unsigned char optname[ONMSZ]; void set(void) { unsigned char *cp; struct option *op; int c; bool no; extern short ospeed; #ifdef TRACE int k, label; line *tmpadr; #endif setnoaddr(); if (skipend()) { if (peekchar() != EOF) ignchar(); propts(); return; } do { cp = optname; do { if (cp < &optname[ONMSZ - 2]) *cp++ = getchar(); } while (isalnum(peekchar())); *cp = 0; cp = optname; if (eq("all", cp)) { if (inopen) pofix(); prall(); goto next; } no = 0; #ifdef TRACE /* * General purpose test code for looking at address of those * invisible marks (as well as the visible ones). */ if (eq("marks", cp)) { viprintf("Marks Address\n\r"); viprintf(" \n"); viprintf("\n"); for (k = 0; k <= 25; k++) viprintf("Mark:%c\t%d\n", k+'a', names[k]); goto next; } /* * General purpose test code for looking at * named registers. */ if (eq("named",cp)) { if (inopen) pofix(); shownam(); goto next; } /* * General purpose test code for looking at * numbered registers. */ if (eq("nbrreg",cp)) { if (inopen) pofix(); shownbr(); goto next; } /* * General purpose test code for looking at addresses * in the edit and save areas of VI. */ if (eq("buffers",cp)) { if (inopen) pofix(); viprintf("\nLabels Address Contents\n"); viprintf("====== ======= ========"); for (tmpadr = zero; tmpadr <= dol; tmpadr++) { label =0; if (tmpadr == zero) { viprintf("ZERO:\t"); label = 2; } if (tmpadr == one) { if (label > 0) viprintf("\nONE:\t"); else viprintf("ONE:\t"); label = 1; } if (tmpadr == dot) { if (label > 0) viprintf("\nDOT:\t"); else viprintf("DOT:\t"); label = 1; } if (tmpadr == undap1) { if (label > 0) viprintf("\nUNDAP1:\t"); else viprintf("UNDAP1:\t"); label = 1; } if (tmpadr == undap2) { if (label > 0) viprintf("\nUNDAP2:\t"); else viprintf("UNDAP2:\t"); label = 1; } if (tmpadr == unddel) { if (label > 0) viprintf("\nUNDDEL:\t"); else viprintf("UNDDEL:\t"); label = 1; } if (tmpadr == dol) { if (label > 0) viprintf("\nDOL:\t"); else viprintf("DOL:\t"); label = 1; } for (k=0; k<=25; k++) if (names[k] == (*tmpadr &~ 01)) { if (label > 0) viprintf( "\nMark:%c\t%d\t", k+'a', names[k]); else viprintf( "Mark:%c\t%d\t", k+'a', names[k]); label=1; } if (label == 0) continue; if (label == 2) viprintf("%d\n", tmpadr); else { viprintf("%d\t", tmpadr); getaline(*tmpadr); pline(lineno(tmpadr)); putchar('\n'); } } for (tmpadr = dol+1; tmpadr <= unddol; tmpadr++) { label =0; if (tmpadr == dol+1) { viprintf("DOL+1:\t"); label = 1; } if (tmpadr == unddel) { if (label > 0) viprintf("\nUNDDEL:\t"); else viprintf("UNDDEL:\t"); label = 1; } if (tmpadr == unddol) { if (label > 0) viprintf("\nUNDDOL:\t"); else viprintf("UNDDOL:\t"); label = 1; } for (k=0; k<=25; k++) if (names[k] == (*tmpadr &~ 01)) { if (label > 0) viprintf( "\nMark:%c\t%d\t", k+'a', names[k]); else viprintf( "Mark:%c\t%d\t", k+'a', names[k]); label=1; } if (label == 0) continue; if (label == 2) viprintf("%d\n", tmpadr); else { viprintf("%d\t", tmpadr); getaline(*tmpadr); pline(lineno(tmpadr)); putchar('\n'); } } goto next; } #endif if (cp[0] == 'n' && cp[1] == 'o' && cp[2] != 'v') { cp += 2; no++; } /* Implement w300, w1200, and w9600 specially */ if (eq(cp, "w300")) { if (ospeed >= B1200) { dontset: (void)getchar(); /* = */ (void)getnum(); /* value */ continue; } cp = (unsigned char *)"window"; } else if (eq(cp, "w1200")) { if (ospeed < B1200 || ospeed >= B2400) goto dontset; cp = (unsigned char *)"window"; } else if (eq(cp, "w9600")) { if (ospeed < B2400) goto dontset; cp = (unsigned char *)"window"; } for (op = options; op < &options[vi_NOPTS]; op++) if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp)) break; if (op->oname == 0) serror(value(vi_TERSE) ? (unsigned char *) gettext("%s: No such option") : (unsigned char *) gettext("%s: No such option - 'set all' gives all option values"), cp); c = skipwh(); if (peekchar() == '?') { ignchar(); printone: propt(op); noonl(); goto next; } if (op->otype == ONOFF) { op->ovalue = 1 - no; if (op == &options[vi_PROMPT]) oprompt = 1 - no; goto next; } if (no) serror((unsigned char *) gettext("Option %s is not a toggle"), op->oname); if (c != 0 || setend()) goto printone; if (getchar() != '=') serror(value(vi_TERSE) ? (unsigned char *) gettext("Missing =") : (unsigned char *) gettext("Missing = in assignment to option %s"), op->oname); switch (op->otype) { case NUMERIC: if (!isdigit(peekchar())) error(value(vi_TERSE) ? gettext("Digits required") : gettext("Digits required after =")); op->ovalue = getnum(); if (value(vi_TABSTOP) <= 0) value(vi_TABSTOP) = TABS; if (op == &options[vi_WINDOW]) { if (value(vi_WINDOW) >= lines) value(vi_WINDOW) = lines-1; vsetsiz(value(vi_WINDOW)); } break; case STRING: case OTERM: cp = optname; while (!setend()) { if (cp >= &optname[ONMSZ]) error(value(vi_TERSE) ? gettext("String too long") : gettext("String too long in option assignment")); /* adb change: allow whitepace in strings */ if( (*cp = getchar()) == '\\') if( peekchar() != EOF) *cp = getchar(); cp++; } *cp = 0; if (op->otype == OTERM) { /* * At first glance it seems like we shouldn't care if the terminal type * is changed inside visual mode, as long as we assume the screen is * a mess and redraw it. However, it's a much harder problem than that. * If you happen to change from 1 crt to another that both have the same * size screen, it's OK. But if the screen size if different, the stuff * that gets initialized in vop() will be wrong. This could be overcome * by redoing the initialization, e.g. making the first 90% of vop into * a subroutine. However, the most useful case is where you forgot to do * a setenv before you went into the editor and it thinks you're on a dumb * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode. * This loses because the first part of vop calls oop in this case. */ if (inopen) error(gettext("Can't change type of terminal from within open/visual")); unterm(); setterm(optname); } else { CP(op->osvalue, optname); op->odefault = 1; } break; } next: flush(); } while (!skipend()); eol(); } void unterm(void) { /* * All terminal mapped statements must be deleted. * All user-defined mapped statements, cap=descr, * are left unchanged. */ int i; for (i=0; i < MAXNOMACS; i++) { /* * Unmap any terminal-defined arrow keys */ if (arrows[i].cap && arrows[i].descr && strcmp(arrows[i].cap, arrows[i].descr)) addmac(arrows[i].cap, NOSTR, NOSTR, arrows); /* * Unmap any terminal-defined function keys */ if (immacs[i].cap && immacs[i].descr && strcmp(immacs[i].cap, immacs[i].descr)) addmac(immacs[i].cap, NOSTR, NOSTR, immacs); } } int setend(void) { return (iswhite(peekchar()) || endcmd(peekchar())); } void prall(void) { int incr = (vi_NOPTS + 2) / 3; int rows = incr; struct option *op = options; for (; rows; rows--, op++) { propt(op); gotab(24); propt(&op[incr]); if (&op[2*incr] < &options[vi_NOPTS]) { gotab(56); propt(&op[2 * incr]); } putNFL(); } } void propts(void) { struct option *op; for (op = options; op < &options[vi_NOPTS]; op++) { if (op == &options[vi_TTYTYPE]) continue; switch (op->otype) { case ONOFF: case NUMERIC: if (op->ovalue == op->odefault) continue; break; case STRING: if (op->odefault == 0) continue; break; } propt(op); putchar(' '); } noonl(); flush(); } void propt(struct option *op) { unsigned char *name; name = (unsigned char *)op->oname; switch (op->otype) { case ONOFF: viprintf("%s%s", op->ovalue ? "" : "no", name); break; case NUMERIC: viprintf("%s=%d", name, op->ovalue); break; case STRING: case OTERM: viprintf("%s=%s", name, op->osvalue); break; } }