parse.cxx

Go to the documentation of this file.
00001 // @(#)root/editline:$Id: parse.cxx 30194 2009-09-16 12:19:46Z axel $
00002 // Author: Mary-Louise Gill, 2009
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 /*      $NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $      */
00013 
00014 /*-
00015  * Copyright (c) 1992, 1993
00016  *      The Regents of the University of California.  All rights reserved.
00017  *
00018  * This code is derived from software contributed to Berkeley by
00019  * Christos Zoulas of Cornell University.
00020  *
00021  * Redistribution and use in source and binary forms, with or without
00022  * modification, are permitted provided that the following conditions
00023  * are met:
00024  * 1. Redistributions of source code must retain the above copyright
00025  *    notice, this list of conditions and the following disclaimer.
00026  * 2. Redistributions in binary form must reproduce the above copyright
00027  *    notice, this list of conditions and the following disclaimer in the
00028  *    documentation and/or other materials provided with the distribution.
00029  * 3. Neither the name of the University nor the names of its contributors
00030  *    may be used to endorse or promote products derived from this software
00031  *    without specific prior written permission.
00032  *
00033  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00034  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00035  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00036  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00037  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00038  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00039  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00040  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00041  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00042  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00043  * SUCH DAMAGE.
00044  */
00045 
00046 #include "compat.h"
00047 
00048 /*
00049  * parse.c: parse an SEditLine_t extended command
00050  *
00051  * commands are:
00052  *
00053  *      bind
00054  *      echotc
00055  *      edit
00056  *      gettc
00057  *      history
00058  *      settc
00059  *      setty
00060  */
00061 #include "el.h"
00062 #include "tokenizer.h"
00063 #include "builtins.h"
00064 #include <stdlib.h>
00065 
00066 
00067 /* parse_line():
00068  *      Parse a line and dispatch it.
00069  *
00070  * Convenience function to call el_parse() when you only
00071  * need to dispatch a string and don't want to mess
00072  * with tok_line() and friends.
00073  */
00074 el_protected int
00075 parse_line(EditLine_t* el, const char* line) {
00076    char** argv;
00077    int argc;
00078    Tokenizer_t* tok;
00079 
00080    tok = tok_init(NULL);
00081    tok_line(tok, line, &argc, &argv);
00082    argc = el_parse(el, argc, (const char**) argv);
00083    tok_end(tok);
00084    return argc;
00085 }
00086 
00087 
00088 /* el_parse():
00089  *      Command dispatcher
00090  */
00091 el_public int
00092 el_parse(EditLine_t* el, int argc, const char* argv[]) {
00093    const char* ptr;
00094    int i;
00095 
00096    if (argc < 1) {
00097       return -1;
00098    }
00099    ptr = strchr(argv[0], ':');
00100 
00101    if (ptr != NULL) {
00102       char* tprog;
00103       size_t l;
00104 
00105       if (ptr == argv[0]) {
00106          return 0;
00107       }
00108       l = ptr - argv[0] - 1;
00109       tprog = (char*) el_malloc(l + 1);
00110 
00111       if (tprog == NULL) {
00112          return 0;
00113       }
00114       (void) strncpy(tprog, argv[0], l);
00115       tprog[l] = '\0';
00116       ptr++;
00117       l = el_match(el->fProg, tprog);
00118       el_free(tprog);
00119 
00120       if (!l) {
00121          return 0;
00122       }
00123    } else {
00124       ptr = argv[0];
00125    }
00126 
00127 
00128    ElBuiltin_t* bi = el_builtin_by_name(ptr);
00129 
00130    if (bi) {
00131       i = (*(bi->fFunc))(el, argc, argv);
00132       return -i;
00133    }
00134    return -1;
00135 } // el_parse
00136 
00137 
00138 /* parse__escape():
00139  *      Parse a string of the form ^<char> <odigit> <char> and return
00140  *      the appropriate character or -1 if the escape is not valid
00141  */
00142 el_protected int
00143 parse__escape(const char** const ptr) {
00144    const char* p;
00145    int c;
00146 
00147    p = *ptr;
00148 
00149    if (p[1] == 0) {
00150       return -1;
00151    }
00152 
00153    if (*p == '\\') {
00154       p++;
00155 
00156       switch (*p) {
00157       case 'a':
00158          c = '\007';                    /* Bell */
00159          break;
00160       case 'b':
00161          c = '\010';                    /* Backspace */
00162          break;
00163       case 't':
00164          c = '\011';                    /* Horizontal Tab */
00165          break;
00166       case 'n':
00167          c = '\012';                    /* New Line */
00168          break;
00169       case 'v':
00170          c = '\013';                    /* Vertical Tab */
00171          break;
00172       case 'f':
00173          c = '\014';                    /* Form Feed */
00174          break;
00175       case 'r':
00176          c = '\015';                    /* Carriage Return */
00177          break;
00178       case 'e':
00179          c = '\033';                    /* Escape */
00180          break;
00181       case '0':
00182       case '1':
00183       case '2':
00184       case '3':
00185       case '4':
00186       case '5':
00187       case '6':
00188       case '7':
00189       {
00190          int cnt, ch;
00191 
00192          for (cnt = 0, c = 0; cnt < 3; cnt++) {
00193             ch = *p++;
00194 
00195             if (ch < '0' || ch > '7') {
00196                p--;
00197                break;
00198             }
00199             c = (c << 3) | (ch - '0');
00200          }
00201 
00202          if ((c & 0xffffff00) != 0) {
00203             return -1;
00204          }
00205          --p;
00206          break;
00207       }
00208       default:
00209          c = *p;
00210          break;
00211       } // switch
00212    } else if (*p == '^' && isalpha((unsigned char) p[1])) {
00213       p++;
00214       c = (*p == '?') ? '\177' : (*p & 0237);
00215    } else {
00216       c = *p;
00217    }
00218    *ptr = ++p;
00219    return c;
00220 } // parse__escape
00221 
00222 
00223 /* parse__string():
00224  *      Parse the escapes from in and put the raw string out
00225  */
00226 el_protected char*
00227 parse__string(char* out, const char* in) {
00228    char* rv = out;
00229    int n;
00230 
00231    for ( ; ;) {
00232       switch (*in) {
00233       case '\0':
00234          *out = '\0';
00235          return rv;
00236 
00237       case '\\':
00238       case '^':
00239 
00240          if ((n = parse__escape(&in)) == -1) {
00241             return NULL;
00242          }
00243          *out++ = n;
00244          break;
00245 
00246       default:
00247          *out++ = *in++;
00248          break;
00249       } // switch
00250    }
00251 } // parse__string
00252 
00253 
00254 /* parse_cmd():
00255  *      Return the command number for the command string given
00256  *      or -1 if one is not found
00257  */
00258 el_protected int
00259 parse_cmd(EditLine_t* el, const char* cmd) {
00260    ElBindings_t* b;
00261 
00262    for (b = el->fMap.fHelp; b->fName != NULL; b++) {
00263       if (strcmp(b->fName, cmd) == 0) {
00264          return b->fFunc;
00265       }
00266    }
00267    return -1;
00268 }

Generated on Tue Jul 5 14:11:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1