1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* $NetBSD: histedit.c,v 1.34 2003/10/27 06:19:29 lukem Exp $ */ 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*- 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1993 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The Regents of the University of California. All rights reserved. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Kenneth Almquist. 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met: 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * documentation and/or other materials provided with the distribution. 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * may be used to endorse or promote products derived from this software 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * without specific prior written permission. 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE. 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/cdefs.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: histedit.c,v 1.34 2003/10/27 06:19:29 lukem Exp $"); 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* not lint */ 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h> 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <paths.h> 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Editline and history functions (and glue). 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h" 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "parser.h" 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "var.h" 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h" 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "main.h" 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h" 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mystring.h" 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "myhistedit.h" 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h" 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef SMALL 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "eval.h" 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h" 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAXHISTLOOPS 4 /* max recursions through fc */ 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DEFEDITOR "ed" /* default editor *should* be $EDITOR */ 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectHistory *hist; /* history cookie */ 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectEditLine *el; /* editline cookie */ 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint displayhist; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FILE *el_in, *el_out; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC const char *fc_replace(const char *, char *, char *); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef DEBUG 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern FILE *tracefile; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Set history and editing status. Called whenever the status may 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * have changed (figures out what to do). 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthistedit(void) 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE *el_err; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define editing (Eflag || Vflag) 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (iflag) { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!hist) { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * turn history on 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hist = history_init(); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hist != NULL) 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sethistsize(histsizeval()); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("sh: can't initialize history\n"); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * turn editing on 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *term, *shname; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el_in == NULL) 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_in = fdopen(0, "r"); 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el_out == NULL) 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_out = fdopen(2, "w"); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el_in == NULL || el_out == NULL) 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto bad; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_err = el_out; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if DEBUG 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tracefile) 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_err = tracefile; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project term = lookupvar("TERM"); 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (term) 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setenv("TERM", term, 1); 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsetenv("TERM"); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project shname = arg0; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (shname[0] == '-') 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project shname++; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el = el_init(shname, el_in, el_out, el_err); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el != NULL) { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hist) 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_set(el, EL_HIST, history, hist); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_set(el, EL_PROMPT, getprompt); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_set(el, EL_SIGNAL, 1); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbad: 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("sh: can't initialize editing\n"); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!editing && el) { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_end(el); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el = NULL; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el) { 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (Vflag) 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_set(el, EL_EDITOR, "vi"); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (Eflag) 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_set(el, EL_EDITOR, "emacs"); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_source(el, NULL); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el) { /* no editing if not interactive */ 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el_end(el); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project el = NULL; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hist) { 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project history_end(hist); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hist = NULL; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsethistsize(const char *hs) 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int histsize; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project HistEvent he; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hist != NULL) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hs == NULL || *hs == '\0' || 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (histsize = atoi(hs)) < 0) 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project histsize = 100; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project history(hist, &he, H_SETSIZE, histsize); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetterm(const char *term) 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el != NULL && term != NULL) 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el_set(el, EL_TERMINAL, term) != 0) { 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outfmt(out2, "sh: Can't set terminal type %s\n", term); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outfmt(out2, "sh: Using dumb terminal settings.\n"); 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinputrc(argc, argv) 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int argc; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char **argv; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc != 2) { 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("usage: inputrc file\n"); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el != NULL) { 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (el_source(el, argv[1])) { 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("inputrc: failed\n"); 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("sh: inputrc ignored, not editing\n"); 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This command is provided since POSIX decided to standardize 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the Korn shell fc command. Oh well... 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthistcmd(int argc, char **argv) 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ch; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *editor = NULL; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project HistEvent he; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int lflg = 0, nflg = 0, rflg = 0, sflg = 0; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, retval; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *firststr, *laststr; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int first, last, direction; 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *pat = NULL, *repl; /* ksh "fc old=new" crap */ 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static int active = 0; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct jmploc jmploc; 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct jmploc *volatile savehandler; 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char editfile[MAXPATHLEN + 1]; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE *efp; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef __GNUC__ 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Avoid longjmp clobbering */ 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &editor; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &lflg; 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &nflg; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &rflg; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &sflg; 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &firststr; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &laststr; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &pat; 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &repl; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &efp; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &argc; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) &argv; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hist == NULL) 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("history not active"); 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 1) 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("missing history argument"); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project optreset = 1; optind = 1; /* initialize getopt */ 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (not_fcnumber(argv[optind]) && 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (ch = getopt(argc, argv, ":e:lnrs")) != -1) 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch ((char)ch) { 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'e': 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project editor = optionarg; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'l': 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project lflg = 1; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nflg = 1; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'r': 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rflg = 1; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 's': 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sflg = 1; 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ':': 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("option -%c expects argument", optopt); 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '?': 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("unknown option: -%c", optopt); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc -= optind, argv += optind; 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If executing... 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (lflg == 0 || editor || sflg) { 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project lflg = 0; /* ignore */ 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project editfile[0] = '\0'; 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Catch interrupts to reset active counter and 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * cleanup temp files. 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (setjmp(jmploc.loc)) { 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = 0; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*editfile) 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(editfile); 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handler = savehandler; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project longjmp(handler->loc, 1); 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project savehandler = handler; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handler = &jmploc; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (++active > MAXHISTLOOPS) { 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = 0; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project displayhist = 0; 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("called recursively too many times"); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Set editor. 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sflg == 0) { 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (editor == NULL && 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (editor = bltinlookup("FCEDIT", 1)) == NULL && 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (editor = bltinlookup("EDITOR", 1)) == NULL) 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project editor = DEFEDITOR; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (editor[0] == '-' && editor[1] == '\0') { 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sflg = 1; /* no edit */ 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project editor = NULL; 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If executing, parse [old=new] now 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (lflg == 0 && argc > 0 && 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ((repl = strchr(argv[0], '=')) != NULL)) { 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pat = argv[0]; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *repl++ = '\0'; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argc--, argv++; 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * determine [first] and [last] 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (argc) { 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 0: 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firststr = lflg ? "-16" : "-1"; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project laststr = "-1"; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 1: 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firststr = argv[0]; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project laststr = lflg ? "-1" : argv[0]; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 2: 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project firststr = argv[0]; 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project laststr = argv[1]; 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("too many args"); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Turn into event numbers. 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project first = str_to_event(firststr, 0); 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project last = str_to_event(laststr, 1); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rflg) { 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i = last; 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project last = first; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project first = i; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * XXX - this should not depend on the event numbers 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * always increasing. Add sequence numbers or offset 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * to the history element in next (diskbased) release. 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project direction = first < last ? H_PREV : H_NEXT; 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If editing, grab a temp file. 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (editor) { 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; /* easier */ 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(editfile, sizeof(editfile), "%s_shXXXXXX", _PATH_TMP); 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((fd = mkstemp(editfile)) < 0) 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("can't create temporary file %s", editfile); 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((efp = fdopen(fd, "w")) == NULL) { 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("can't allocate stdio buffer for temp"); 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Loop through selected history events. If listing or executing, 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * do it now. Otherwise, put into temp file and call the editor 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * after. 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The history interface needs rethinking, as the following 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * convolutions will demonstrate. 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project history(hist, &he, H_FIRST); 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, H_NEXT_EVENT, first); 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;retval != -1; retval = history(hist, &he, direction)) { 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (lflg) { 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!nflg) 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%5d ", he.num); 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(he.str); 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *s = pat ? 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fc_replace(he.str, pat, repl) : he.str; 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sflg) { 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (displayhist) { 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str(s); 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project evalstring(strcpy(stalloc(strlen(s) + 1), s), 0); 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (displayhist && hist) { 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * XXX what about recursive and 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * relative histnums. 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project history(hist, &he, H_ENTER, s); 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fputs(s, efp); 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * At end? (if we were to lose last, we'd sure be 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * messed up). 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (he.num == last) 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (editor) { 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *editcmd; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(efp); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(editcmd, "%s %s", editor, editfile); 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project evalstring(editcmd, 0); /* XXX - should use no JC command */ 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project readcmdfile(editfile); /* XXX - should read back - quick tst */ 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(editfile); 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (lflg == 0 && active > 0) 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project --active; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (displayhist) 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project displayhist = 0; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC const char * 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfc_replace(const char *s, char *p, char *r) 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *dest; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int plen = strlen(p); 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STARTSTACKSTR(dest); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*s) { 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*s == *p && strncmp(s, p, plen) == 0) { 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*r) 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC(*r++, dest); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s += plen; 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p = '\0'; /* so no more matches */ 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC(*s++, dest); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STACKSTRNUL(dest); 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dest = grabstackstr(dest); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (dest); 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnot_fcnumber(char *s) 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s == NULL) 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*s == '-') 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s++; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (!is_number(s)); 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstr_to_event(const char *str, int last) 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project HistEvent he; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *s = str; 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int relative = 0; 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, retval; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, H_FIRST); 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (*s) { 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '-': 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project relative = 1; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /*FALLTHROUGH*/ 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '+': 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s++; 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (is_number(s)) { 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i = atoi(s); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (relative) { 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (retval != -1 && i--) { 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, H_NEXT); 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (retval == -1) 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, H_LAST); 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, H_NEXT_EVENT, i); 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (retval == -1) { 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the notion of first and last is 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * backwards to that of the history package 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project last ? H_FIRST : H_LAST); 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (retval == -1) 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("history number %s not found (internal error)", 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str); 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pattern 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = history(hist, &he, H_PREV_STR, str); 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (retval == -1) 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("history pattern not found: %s", str); 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (he.num); 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecthistcmd(int argc, char **argv) 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("not compiled with history support"); 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinputrc(int argc, char **argv) 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("not compiled with history support"); 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 541