VIS

src/cmd/cmdFile.c File Reference

#include "cmdInt.h"
Include dependency graph for cmdFile.c:

Go to the source code of this file.

Defines

#define ESC   '\033'
#define BEEP   '\007'
#define HIST   '%'
#define SUBST   '^'
#define STDIN   0
#define STDOUT   1

Functions

EXTERN char * readline (char *)
EXTERN void add_history (char *)
static int getnum (char **linep)
static char * getarg (char *line, int num)
static char * bad_event (int n)
static char * do_subst (char *dest, char *new_)
static void print_prompt (char *prompt)
FILE * Cmd_FileOpen (char *fileName, char *mode, char **realFileName_p, int silent)
char * CmdFgetsFilec (char *buf, int size, FILE *stream, char *prompt)
char * CmdHistorySubstitution (char *line, int *changed)

Variables

static char rcsid[] UNUSED = "$Id: cmdFile.c,v 1.24 2009/04/11 18:25:50 fabio Exp $"
static char visHistChar = HIST
static char * seperator = " \t\n;"

Define Documentation

#define BEEP   '\007'

Definition at line 54 of file cmdFile.c.

#define ESC   '\033'

Definition at line 53 of file cmdFile.c.

#define HIST   '%'

Definition at line 55 of file cmdFile.c.

#define STDIN   0

Definition at line 58 of file cmdFile.c.

#define STDOUT   1

Definition at line 59 of file cmdFile.c.

#define SUBST   '^'

Definition at line 56 of file cmdFile.c.


Function Documentation

EXTERN void add_history ( char *  )

Here is the caller graph for this function:

static char * bad_event ( int  n) [static]

Function********************************************************************

Synopsis [required]

Description [optional]

SideEffects [required]

SeeAlso [optional]

Definition at line 847 of file cmdFile.c.

{
  (void) fprintf(vis_stderr, "** cmd error: Event %d not found\n", n);
  return(NIL(char));
}

Here is the caller graph for this function:

FILE* Cmd_FileOpen ( char *  fileName,
char *  mode,
char **  realFileName_p,
int  silent 
)

AutomaticEnd Function********************************************************************

Synopsis [Opens the file with the given mode.]

Description [Opens the file with the given mode (see fopen()). Tilde expansion (~user/ or ~/) is performed on the fileName, and "-" is allowed as a synonym for stdin (or stdout, depending on the mode). If the file cannot be opened, a message is reported using perror(); the silent flag, if true, suppresses this error action. In either case, A NULL file pointer is returned if any error occurs. The fileName (after tilde expansion) is returned in the pointer realFileName, if realFileName is non-empty. This is a pointer which should be free'd when you are done with it.]

SideEffects []

Definition at line 114 of file cmdFile.c.

{
  char *realFileName, *path, *user_path;
  char *lib_name;
  FILE *fp;

  if (strcmp(fileName, "-") == 0) {
    if (strcmp(mode, "w") == 0) {
      realFileName = util_strsav("stdout");
      fp = stdout;
    }
    else {
      realFileName = util_strsav("stdin");
      fp = stdin;
    }
  }
  else {
    realFileName = NIL(char);
    if (strcmp(mode, "r") == 0) {
      user_path = Cmd_FlagReadByName("open_path");
      if (user_path != NIL(char)) {
        lib_name = Vm_VisObtainLibrary();
        path = ALLOC(char, strlen(user_path)+strlen(lib_name)+10);
        (void) sprintf(path, "%s:%s", user_path, lib_name);

        /*
         * If the fileName begins with ./, ../, ~/, or /, AND the file doesn't
         * actually exist, then VIS will look in the open path (which includes
         * the sis library) for the file.  This could lead to unexpected behavior:
         * the user is looking for ./msu.genlib, and since that isn't there, the
         * users gets sis_lib/msu.genlib, and no error is reported.  The following
         * pseudo code fixes this:
         *
         * if (the beginning of file_name is : ./ || ../ || ~/ || /) {
         * realFileName = util_file_search(fileName, NIL(char), "r");
         * } else
         */
        realFileName = util_file_search(fileName, path, "r");
        FREE(path);
        FREE(lib_name);
      }
    }
    if (realFileName == NIL(char)) {
      realFileName = util_tilde_expand(fileName);
    }
    if (strcmp(mode, "r") == 0 && !util_check_file(realFileName, mode)) {
      FREE(realFileName);
      return NIL(FILE);
    }
    if ((fp = fopen(realFileName, mode)) == NIL(FILE)) {
      if (! silent) {
        perror(realFileName);
      }
    }
  }
  if (realFileName_p != 0) {
    *realFileName_p = realFileName;
  }
  else {
    FREE(realFileName);
  }
  return fp;
}

Here is the call graph for this function:

char* CmdFgetsFilec ( char *  buf,
int  size,
FILE *  stream,
char *  prompt 
)

Function********************************************************************

Synopsis [required]

Description [optional]

SideEffects [required]

SeeAlso [optional]

Definition at line 443 of file cmdFile.c.

{
#if HAVE_LIBREADLINE
  char *dupline;
  char *cleanLine;
#endif
  char *line;
  int sno;
#if !HAVE_LIBREADLINE
  int len;
#endif

  sno = fileno(stream);
  if (sno != STDIN || !isatty(sno)){
    if (prompt != NIL(char)){
      (void) print_prompt(prompt);
      (void) fflush(stdout);
    }
    return (fgets(buf, size, stream));
  } else {
#if HAVE_LIBREADLINE
    /* Effectively read one line of input printing the prompt */
    dupline = (char *)readline(prompt);
    cleanLine = removeWhiteSpaces(dupline);

    /* Check if an EOF has been read */
    if (cleanLine != NIL(char)) {
      /* If the line is non empty, add it to the history */
      if (*cleanLine) {
        add_history(cleanLine);
      }

      /* Copy the contents of cleanLine to buf, to simulate fgets */
      strncpy(buf, cleanLine, size);
      if ((int) strlen(cleanLine) >= size) {
        buf[size-1] = '\0';
      }
      line = buf;
    }
    else {
      line = NIL(char);
    }
    FREE(dupline);
#else
    /* Get rid of the trailing newline */
    if (prompt != NIL(char)){
      (void) print_prompt(prompt);
      (void) fflush(stdout);
    }
    line = fgets(buf, size, stream);
    if (line != NIL(char)) {
      len = strlen(line);
      if (len > 0 && line[len-1] == '\n') {
        line[len-1] = '\0';
      }
    }
#endif
    return line;
  }

}

Here is the call graph for this function:

char* CmdHistorySubstitution ( char *  line,
int *  changed 
)

Function********************************************************************

Synopsis [Simple history substitution routine.]

Description [Simple history substitution routine. Not, repeat NOT, the complete csh history substitution mechanism.

In the following ^ is the SUBST character and ! is the HIST character. Deals with: !! last command !stuff last command that began with "stuff" !* all but 0'th argument of last command !$ last argument of last command !:n n'th argument of last command !n repeat the n'th command !-n repeat n'th previous command ^old^new replace "old" w/ "new" in previous command

Trailing spaces are significant. Removes all initial spaces.

Returns `line' if no changes were made. Returns pointer to a static buffer if any changes were made. Sets `changed' to 1 if a history substitution took place, o/w set to 0. Returns NULL if error occurred.]

SideEffects []

Definition at line 601 of file cmdFile.c.

{
  static char buf[1024], c;
  char *value;
  char *last, *old, *new_, *start, *b, *l;
  int n, len, i, num, internal_change;

  *changed = 0;
  internal_change = 0;
  while (isspace((int)(*line))) {
    line++;
  }
  if (*line == '\0') {
    return(line);
  }
  n = array_n(vm_commandHistoryArray);
  last = (n > 0) ?
    array_fetch(char *, vm_commandHistoryArray, n - 1) : (char *) "";

  b = buf;
  if (*line == SUBST) {
    old = line + 1;
    new_ = strchr(old, SUBST);
    if (new_ == NIL(char)) {
      goto bad_modify;
    }
    *new_++ = '\0';                   /* makes change in contents of line */
    start = strstr(last, old);
    if (start == NIL(char)) {
      *--new_ = SUBST;
      bad_modify:
      (void) fprintf(vis_stderr, "** cmd error: Modifier failed\n");
      return(NIL(char));
    }
    while (last != start) {
      *b++ = *last++;
    }
    b = do_subst(b, new_);
    last += strlen(old);
    while ((*b++ = *last++)) {
    }
    *changed = 1;
    return(buf);
  }

  if ((value = Cmd_FlagReadByName("history_char")) != NIL(char)){
    visHistChar = *value;
  }

  for (l = line; (*b = *l); l++) {
    if (*l == visHistChar) {
      /*
       * If a \ immediately preceeds a HIST char, pass just HIST char
       * Otherwise pass both \ and the character.
       */
      if (l > line && l[-1] == '\\') {
        b[-1] = visHistChar;
        internal_change = 1;
        continue;
      }
      if (n == 0) {
        return(bad_event(0));
      }
      l++;
      /* Cannot use a switch since the history char is a variable !!! */
      if (*l == visHistChar){
        /* replace !! in line with last */
        b = do_subst(b, last);
      }
      else if (*l == '$'){
        /* replace !$ in line with last arg of last */
        b = do_subst(b, getarg(last, -1));
      }
      else if (*l == '*'){
        b = do_subst(b, getarg(last, -2));
      }
      else if (*l == ':'){
        /* replace !:n in line with n'th arg of last */
        l++;
        num = getnum(&l);
        new_ = getarg(last, num);
        if (new_ == NIL(char)) {
          (void) fprintf(vis_stderr, "** cmd error: Bad %c arg selector\n", visHistChar);
          return(NIL(char));
        }
        b = do_subst(b, new_);
      }
      else if (*l == '-'){
        /* replace !-n in line with n'th prev cmd */
        l++;
        num = getnum(&l);
        if (num > n || num == 0) {
          return(bad_event(n - num + 1));
        }
        b = do_subst(b, array_fetch(char *, vm_commandHistoryArray, n - num));
      }
      else {
        /* replace !n in line with n'th command */
        if (isdigit((int)(*l))) {
          num = getnum(&l);
          if (num > n || num == 0) {
            return(bad_event(num));
          }
          b = do_subst(b, array_fetch(char *, vm_commandHistoryArray, num - 1));
        }
        else {  /* replace !boo w/ last cmd beginning w/ boo */
          start = l;
          while (*l && strchr(seperator, *l) == NIL(char)) {
            l++;
          }
          c = *l;
          *l = '\0';
          len = strlen(start);
          for (i = n - 1; i >= 0; i--) {
            old = array_fetch(char *, vm_commandHistoryArray, i);
            if (strncmp(old, start, len) == 0) {
              b = do_subst(b, old);
              break;
            }
          }
          if (i < 0) {
            (void) fprintf(vis_stderr, "** cmd error: Event not found: %s\n", start);
            *l = c;
            return(NIL(char));
          }
          *l-- = c;

        }
      }
      *changed = 1;
    }
    else {
      b++;
    }
  }
  if (*changed != 0 || internal_change != 0) {
    return(buf);
  }
  return(line);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char * do_subst ( char *  dest,
char *  new_ 
) [static]

Function********************************************************************

Synopsis [required]

Description [optional]

SideEffects [required]

SeeAlso [optional]

Definition at line 867 of file cmdFile.c.

{
  while ((*dest = *new_++)) {
    dest++;
  }
  return(dest);
}

Here is the caller graph for this function:

static char * getarg ( char *  line,
int  num 
) [static]

Function********************************************************************

Synopsis [required]

Description [optional]

SideEffects [required]

SeeAlso [optional]

Definition at line 784 of file cmdFile.c.

{
  static char buf[128];
  char *b, *c;
  int i;

  if (num == -1) {
    i = 123456;
  }
  else if (num == -2) {
    i = 1;
  }
  else {
    i = num;
  }

  c = line;
  do {
    b = line = c;
    while (*line && strchr(seperator, *line) == NIL(char)) {
      line++;
    }
    c = line;
    while (*c && strchr(seperator, *c) != NIL(char)) {
      c++;
    }
    if (*c == '\0') {
      break;
    }
  } while (--i >= 0);

  if (i > 0) {
    if (num == -1) {
      return(b);
    }
    return(NIL(char));
  }
  if (num < 0) {
    return(b);
  }
  c = buf;
  do {
    *c++ = *b++;
  } while (b < line && c < &buf[127]);
  *c = '\0';
  return(buf);
}

Here is the caller graph for this function:

static int getnum ( char **  linep) [static]

AutomaticStart

Function********************************************************************

Synopsis [required]

Description [optional]

SideEffects [required]

SeeAlso [optional]

Definition at line 757 of file cmdFile.c.

{
  int num = 0;
  char *line = *linep;

  for (; isdigit((int)(*line)); line++) {
    num *= 10;
    num += *line - '0';
  }
  *linep = line - 1;
  return(num);
}

Here is the caller graph for this function:

static void print_prompt ( char *  prompt) [static]

Function********************************************************************

Synopsis [required]

Description [optional]

SideEffects [required]

SeeAlso [optional]

Definition at line 890 of file cmdFile.c.

{
  char buf[256];

  if (prompt == NIL(char)) return;

  while (*prompt != '\0') {
    if (*prompt == visHistChar) {
      (void) sprintf(buf, "%d", array_n(vm_commandHistoryArray) + 1);
      if (write(STDOUT, buf, (int) strlen(buf)) == -1) exit(-1);
    }
    else {
      if (write(STDOUT, prompt, 1) == -1) exit(-1);
    }
    prompt++;
  }
}

Here is the caller graph for this function:

EXTERN char* readline ( char *  )

CFile***********************************************************************

FileName [cmdFile.c]

PackageName [cmd]

Synopsis [File open, and file completion.]

Author [Originated from SIS]

Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. All rights reserved.

Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.

IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]

Here is the caller graph for this function:


Variable Documentation

char* seperator = " \t\n;" [static]

Definition at line 66 of file cmdFile.c.

char rcsid [] UNUSED = "$Id: cmdFile.c,v 1.24 2009/04/11 18:25:50 fabio Exp $" [static]

Definition at line 45 of file cmdFile.c.

char visHistChar = HIST [static]

Definition at line 65 of file cmdFile.c.