Пример #1
0
int main(int argc, char **argv)
{
	unsigned int test = 1;
	unsigned char *x;
	int macro = 0, debug = 0, help = 0, j;

	for (j = 1; j < argc; j++) {
		if (Strchr(argv[j], 'm')) macro = 1;
		if (Strchr(argv[j], 'd')) debug = 1;
		if (Strchr(argv[j], 'h')) help = 1;
	}

	if (help) {
		printf(	"-m	macro output\n"
			"-d	debug\n"
			"-h	help\n");
		return 0;
	}
		
	x = (unsigned char*) &test;

	if (*x == 0x00) {
		if (macro)
			printf("__BIG_ENDIAN_BITFIELD\n");
		else
			printf("big endian\n");
	}
	else if (*x == 0x01) {
		if (macro)
			printf("__LITTLE_ENDIAN_BITFIELD\n");
		else
			printf("little endian\n");
	} else {
		printf("\nWARNING!!! byteorder exception\n\n");
		debug = 1;
	}

	if (debug) {
        //printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
		printf("sizeof(unsigned int) = %zu\n", sizeof(unsigned int));
		printf("unsigned int test = 1;\n");
		printf("in memory as: ");
		for (j = 0; j < sizeof(unsigned int); j++)
			printf("%02x ", x[j]);
		printf("\n");
	}
	return 0;
}
Пример #2
0
/*
 * This routine takes the current input command line "line" and
 * searches for any possible macro declarations.  These are
 * present in the line as "$#" where '#' is a single digit
 * number from 0 to 9.  If a macro argument is found, it is
 * either substituted with the value on the same line as the
 * macro call (if it was present) or silently replaced with an
 * empty string.
 *
 * The user order of macro substitutions runs from the 1st to 9th
 * and then the 0th value.  Internally, the array runs from 0 to 9.
 * Thus, when a macro argument is found, it's integer value
 * will need to be shifted to account for the difference.  This
 * is done with a simple mod operation:
 * Internal order is: $0, $1, ..., $8, $9;
 * User sees order as: $1, $2, ..., $9, $0.
 *
 * This routine uses the input string "string" to copy the argument
 * substituted line into, so make sure it is large enough to hold
 * everything!  Also, this function returns a pointer to "string"
 * in the same fashion as strcpy().  There is no check to make sure
 * that the size of macarg[] is sufficient to cover all input
 * arguments.  This is a quiet assumption.  Also, macarg should
 * be declared "const char *macarg[]" but because it is a pointer to
 * an open array, I have trouble doing this.
 *
 */
static char *domacsubs(char *string, const char *line, char *macarg[])
{
    register int j, k;
    register char *s, *ptr, *arg;

    if (Strchr(line, '$') == (char *)NULL) {   /* No arguments to sub. */
      (void)Strcpy(string, line);     /* Simply return a copy of line. */
    } else {
      s = (char *)line;
      ptr = string;
      while (*s) {                      /* Parse through input string. */
        if (*s != '$') {                /* If not special character... */
          *ptr++ = *s++;                /* ...copy regular characters; */
        } else {                /* otherwise, get the argument number. */
          j = (*(s+1)) - '0';      /* Convert next char to an integer. */
          if ((j < 0) || (j > 9)) {       /* Not a macro substitution. */
            *ptr++ = *s++;                      /* Just a regular '$'. */
          } else {
#if 1
            if ( *(s+2) ) {             /* see if next char */
                k = *(s+2) - '0';       /* is a digit */
                if (k>=0 && k<=9) {     /* and if so */
                    j = j*10 + k;       /* allow two digit parameters */
                    k = 1;              /* remember we had 2 digits */
                } else
                    k = 0;
            } else 
                k = 0;
            if (j >= MAXARG) {
                wipoutput(stderr, "$%d too large a reference\n",j);
                return NULL;
            }
            j = (j==0 ? 9 : j-1);
#else
            j = (j + 9) % 10;       /* This is where order is shifted. */
            k = 0;
#endif
            /*
             *  If the macro argument is not present, then quietly
             *  skip over the request.  If it is present (macarg[j]
             *  != Null), then substitute the argument value now.
             */
            if (macarg[j] != Null) {     /* If a value exists, then... */
              arg = (char *)macarg[j];  /* ...substitute the argument. */
              while (*arg)
                *ptr++ = *arg++;
            }
            s++;                                 /* Skip over the '$'. */
            s++;                                 /* Skip over the '#'. */
            if (k) s++;                     /* and one more if needed. */
          }                           /* If (0 <= j <= 9) conditional. */
        }                               /* If (*s != '$') conditional. */
      }                                            /* While (*s) loop. */
      *ptr = Null;                   /* Make sure it ends with a Null. */
    }                               /* if (!Strchr(line, '$')) branch. */

    return(string);
}
Пример #3
0
void wipdecode(const char *string, char *outstr, size_t maxout)
{
    char *ptr, *tmptr, *savptr;
    char ch;
    char tempstr[BUFSIZ], variable[BUFSIZ];
    int nsig, nopen;
    double arg;
    LOGICAL error;

    ptr = (char *)string;
    if (Strchr(string, ESC) != (char *)NULL) {
      arg = wipgetvar("nsig", &error);
      nsig = NINT(arg);        /* Tells how to format a user variable. */
      tmptr = tempstr;
      while (*ptr) {
        if (*ptr != ESC) {
          *tmptr++ = *ptr++;               /* Just copy the character. */
          continue;                         /* Get the next character. */
        }            /* At this point an ESC character has been found. */
        ch = *ptr++;                        /* save the ESC character. */
        if (*ptr != '[') {  /* No user variable here, so just store... */
          *tmptr++ = ch;        /* ...the two characters and continue. */
          *tmptr++ = *ptr++;           /* This is so "\\" gets passed. */
          continue;                         /* Get the next character. */
        }        /* At this point a user variable flag has been found. */
        ptr++;                          /* Increment ptr past the '['. */
        savptr = variable;       /* Set up user variable name pointer. */
        nopen = 1;              /* Initialize the number of open '['s. */
        while ((*ptr) && (nopen)) {         /* Get user variable name. */
          if (*ptr == '[') nopen++;
          if (*ptr == ']') nopen--;
          if (nopen) *savptr++ = *ptr++;
        }
        if (*ptr != Null) ptr++;                 /* Skip over last ']' */
        *savptr = Null;        /* Skip last ']'; add terminating Null. */
        if (wipisstring(variable)) {          /* User string variable. */
          savptr = wipgetstring(variable);    /* Find string variable. */
          if (savptr == (char *)NULL) savptr = "";     /* Error check. */
        } else {                            /* Standard user variable. */
          arg = wipevaluate(variable, &error);  /* Find user variable. */
          savptr = wipfpfmt(arg, nsig);           /* Format the value. */
        }
        while ((*savptr != Null) && (isspace(*savptr)))
          savptr++;                       /* Strip off leading blanks. */
        while (*savptr) *tmptr++ = *savptr++;    /* Include the value. */
      }                                 /* End of "while (*ptr)" loop. */
      *tmptr = Null;              /* Terminate the string with a Null. */
      ptr = tempstr;        /* Assign the work pointer to this string. */
    }                           /* End of "(domacs == TRUE)" if block. */

    if (Strlen(ptr) >= maxout)
      wipoutput(stderr, "Decoded string overflows output string size.\n");

    (void)Strncpy(outstr, ptr, maxout);
    outstr[maxout-1] = Null;       /* Make sure it is Null terminated. */

    return;
}
Пример #4
0
void Swig_extend_unused_check(void) {
  Iterator ki;

  if (!extendhash) return;
  for (ki = First(extendhash); ki.key; ki = Next(ki)) {
    if (!Strchr(ki.key,'<')) {
      SWIG_WARN_NODE_BEGIN(ki.item);
      Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
      SWIG_WARN_NODE_END(ki.item);
    }
  }
}
Пример #5
0
Arg *
parse(Rune *s)
{
	Arg *a;
	Rune *p;

	p = Strchr(s, ':');
	if (p == nil)
		sysfatal("`%S' no colon", s);
	*p = '\0';
	a = emalloc(sizeof(*a));
	a->name = convert(s);
	a->val = convert(p+1);
	a->next = nil;
	return a;
}
Пример #6
0
String *Swig_string_strip(String *s) {
  String *ns;
  if (!Len(s)) {
    ns = NewString(s);
  } else {
    const char *cs = Char(s);
    const char *ce = Strchr(cs, ']');
    if (*cs != '[' || !ce) {
      ns = NewString(s);
    } else {
      String *fmt = NewStringf("%%.%ds", ce-cs-1);
      String *prefix = NewStringf(fmt, cs+1);
      if (0 == Strncmp(ce+1, prefix, Len(prefix))) {
        ns = NewString(ce+1+Len(prefix));
      } else {
        ns = NewString(ce+1);
      }
    }
  }
  return ns;
}
Пример #7
0
/*
 * The main glob() routine: compiles the pattern (optionally processing
 * quotes), calls glob1() to do the real pattern matching, and finally
 * sorts the list (unless unsorted operation is requested).  Returns 0
 * if things went well, nonzero if errors occurred.  It is not an error
 * to find no matches.
 */
int
glob(const char *pattern, int flags, int (*errfunc) (const char *, int),
     glob_t *pglob)
{
    int     err, oldpathc;
    Char *bufnext, m_not;
    const unsigned char *patnext;
    int     c, not;
    Char *qpatnext, *patbuf;
    int     no_match;

    patnext = (const unsigned char *) pattern;
    if (!(flags & GLOB_APPEND)) {
	pglob->gl_pathc = 0;
	pglob->gl_pathv = NULL;
	if (!(flags & GLOB_DOOFFS))
	    pglob->gl_offs = 0;
    }
    pglob->gl_flags = flags & ~GLOB_MAGCHAR;
    pglob->gl_errfunc = errfunc;
    oldpathc = pglob->gl_pathc;
    pglob->gl_matchc = 0;

    if (pglob->gl_flags & GLOB_ALTNOT) {
	not = ALTNOT;
	m_not = M_ALTNOT;
    }
    else {
	not = NOT;
	m_not = M_NOT;
    }

    patbuf = xmalloc((strlen(pattern) + 1) * sizeof(*patbuf));
    bufnext = patbuf;

    no_match = *patnext == not;
    if (no_match)
	patnext++;

    if (flags & GLOB_QUOTE) {
	/* Protect the quoted characters */
	while ((c = *patnext++) != EOS) {
#ifdef WIDE_STRINGS
	    int len;
	    
	    len = mblen((const char *)(patnext - 1), MB_LEN_MAX);
	    if (len == -1)
		TCSH_IGNORE(mblen(NULL, 0));
	    else if (len > 1) {
		*bufnext++ = (Char) c;
		while (--len != 0)
		    *bufnext++ = (Char) (*patnext++ | M_PROTECT);
	    } else
#endif /* WIDE_STRINGS */
	    if (c == QUOTE) {
		if ((c = *patnext++) == EOS) {
		    c = QUOTE;
		    --patnext;
		}
		*bufnext++ = (Char) (c | M_PROTECT);
	    }
	    else
		*bufnext++ = (Char) c;
	}
    }
    else
	while ((c = *patnext++) != EOS)
	    *bufnext++ = (Char) c;
    *bufnext = EOS;

    bufnext = patbuf;
    qpatnext = patbuf;
    while ((c = *qpatnext++) != EOS) {
	switch (c) {
	case LBRACKET:
	    c = *qpatnext;
	    if (c == not)
		++qpatnext;
	    if (*qpatnext == EOS ||
		Strchr(qpatnext + 1, RBRACKET) == NULL) {
		*bufnext++ = LBRACKET;
		if (c == not)
		    --qpatnext;
		break;
	    }
	    pglob->gl_flags |= GLOB_MAGCHAR;
	    *bufnext++ = M_SET;
	    if (c == not)
		*bufnext++ = m_not;
	    c = *qpatnext++;
	    do {
		*bufnext++ = LCHAR(c);
		if (*qpatnext == RANGE &&
		    (c = qpatnext[1]) != RBRACKET) {
		    *bufnext++ = M_RNG;
		    *bufnext++ = LCHAR(c);
		    qpatnext += 2;
		}
	    } while ((c = *qpatnext++) != RBRACKET);
	    *bufnext++ = M_END;
	    break;
	case QUESTION:
	    pglob->gl_flags |= GLOB_MAGCHAR;
	    *bufnext++ = M_ONE;
	    break;
	case STAR:
	    pglob->gl_flags |= GLOB_MAGCHAR;
	    /* collapse adjacent stars to one [or three if globstar],
	     * to avoid exponential behavior
	     */
	    if (bufnext == patbuf || bufnext[-1] != M_ALL ||
	       ((flags & GLOB_STAR) != 0 && 
		 (bufnext - 1 == patbuf || bufnext[-2] != M_ALL ||
		 bufnext - 2 == patbuf || bufnext[-3] != M_ALL)))
		*bufnext++ = M_ALL;
	    break;
	default:
	    *bufnext++ = LCHAR(c);
	    break;
	}
    }
    *bufnext = EOS;
#ifdef DEBUG
    qprintf(patbuf);
#endif

    if ((err = glob1(patbuf, pglob, no_match)) != 0) {
	xfree(patbuf);
	return (err);
    }

    /*
     * If there was no match we are going to append the pattern 
     * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
     * and the pattern did not contain any magic characters
     * GLOB_NOMAGIC is there just for compatibility with csh.
     */
    if (pglob->gl_pathc == oldpathc && 
	((flags & GLOB_NOCHECK) || 
	 ((flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) {
	if (!(flags & GLOB_QUOTE))
	    globextend(pattern, pglob);
	else {
	    char *copy, *dest;
	    const char *src;

	    /* copy pattern, interpreting quotes */
	    copy = xmalloc(strlen(pattern) + 1);
	    dest = copy;
	    src = pattern;
	    while (*src != EOS) {
		/* Don't interpret quotes. The spec does not say we should do */
		if (*src == QUOTE) {
		    if (*++src == EOS)
			--src;
		}
		*dest++ = *src++;
	    }
	    *dest = EOS;
	    globextend(copy, pglob);
	    xfree(copy);
	}
	xfree(patbuf);
	return 0;
    }
    else if (!(flags & GLOB_NOSORT) && (pglob->gl_pathc != oldpathc))
	qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
	      pglob->gl_pathc - oldpathc, sizeof(char *), compare);
    xfree(patbuf);
    return (0);
}
Пример #8
0
/*
 * Complete the word at or before point,
 * 'what_to_do' says what to do with the completion.
 * \t   means do standard completion.
 * `?' means list the possible completions.
 * `*' means insert all of the possible completions.
 * `!' means to do standard completion, and list all possible completions if
 * there is more than one.
 *
 * Note: '*' support is not implemented
 *       '!' could never be invoked
 */
int
fn_complete(EditLine *el,
	char *(*complet_func)(const char *, int),
	char **(*attempted_completion_function)(const char *, int, int),
	const Char *word_break, const Char *special_prefixes,
	const char *(*app_func)(const char *), size_t query_items,
	int *completion_type, int *over, int *point, int *end)
{
	const TYPE(LineInfo) *li;
	Char *temp;
        char **matches;
	const Char *ctemp;
	size_t len;
	int what_to_do = '\t';
	int retval = CC_NORM;

	if (el->el_state.lastcmd == el->el_state.thiscmd)
		what_to_do = '?';

	/* readline's rl_complete() has to be told what we did... */
	if (completion_type != NULL)
		*completion_type = what_to_do;

	if (!complet_func)
		complet_func = fn_filename_completion_function;
	if (!app_func)
		app_func = append_char_function;

	/* We now look backwards for the start of a filename/variable word */
	li = FUN(el,line)(el);
	ctemp = li->cursor;
	while (ctemp > li->buffer
	    && !Strchr(word_break, ctemp[-1])
	    && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
		ctemp--;

	len = (size_t)(li->cursor - ctemp);
	temp = el_malloc((len + 1) * sizeof(*temp));
	(void)Strncpy(temp, ctemp, len);
	temp[len] = '\0';

	/* these can be used by function called in completion_matches() */
	/* or (*attempted_completion_function)() */
	if (point != NULL)
		*point = (int)(li->cursor - li->buffer);
	if (end != NULL)
		*end = (int)(li->lastchar - li->buffer);

	if (attempted_completion_function) {
		int cur_off = (int)(li->cursor - li->buffer);
		matches = (*attempted_completion_function)(
		    ct_encode_string(temp, &el->el_scratch),
		    cur_off - (int)len, cur_off);
	} else
		matches = NULL;
	if (!attempted_completion_function || 
	    (over != NULL && !*over && !matches))
		matches = completion_matches(
		    ct_encode_string(temp, &el->el_scratch), complet_func);

	if (over != NULL)
		*over = 0;

	if (matches) {
		int i;
		size_t matches_num, maxlen, match_len, match_display=1;

		retval = CC_REFRESH;
		/*
		 * Only replace the completed string with common part of
		 * possible matches if there is possible completion.
		 */
		if (matches[0][0] != '\0') {
			el_deletestr(el, (int) len);
			FUN(el,insertstr)(el,
			    ct_decode_string(matches[0], &el->el_scratch));
		}

		if (what_to_do == '?')
			goto display_matches;

		if (matches[2] == NULL &&
		    (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) {
			/*
			 * We found exact match. Add a space after
			 * it, unless we do filename completion and the
			 * object is a directory.
			 */
			FUN(el,insertstr)(el,
			    ct_decode_string((*app_func)(matches[0]),
			    &el->el_scratch));
		} else if (what_to_do == '!') {
    display_matches:
			/*
			 * More than one match and requested to list possible
			 * matches.
			 */

			for(i = 1, maxlen = 0; matches[i]; i++) {
				match_len = strlen(matches[i]);
				if (match_len > maxlen)
					maxlen = match_len;
			}
			/* matches[1] through matches[i-1] are available */
			matches_num = (size_t)(i - 1);
				
			/* newline to get on next line from command line */
			(void)fprintf(el->el_outfile, "\n");

			/*
			 * If there are too many items, ask user for display
			 * confirmation.
			 */
			if (matches_num > query_items) {
				(void)fprintf(el->el_outfile,
				    "Display all %zu possibilities? (y or n) ",
				    matches_num);
				(void)fflush(el->el_outfile);
				if (getc(stdin) != 'y')
					match_display = 0;
				(void)fprintf(el->el_outfile, "\n");
			}

			if (match_display) {
				/*
				 * Interface of this function requires the
				 * strings be matches[1..num-1] for compat.
				 * We have matches_num strings not counting
				 * the prefix in matches[0], so we need to
				 * add 1 to matches_num for the call.
				 */
				fn_display_match_list(el, matches,
				    matches_num+1, maxlen);
			}
			retval = CC_REDISPLAY;
		} else if (matches[0][0]) {
			/*
			 * There was some common match, but the name was
			 * not complete enough. Next tab will print possible
			 * completions.
			 */
			el_beep(el);
		} else {
			/* lcd is not a valid object - further specification */
			/* is needed */
			el_beep(el);
			retval = CC_NORM;
		}

		/* free elements of array and the array itself */
		for (i = 0; matches[i]; i++)
			el_free(matches[i]);
		el_free(matches);
		matches = NULL;
	}
	el_free(temp);
	return retval;
}
Пример #9
0
/* tw_result():
 *	Return what the completion action should be depending on the
 *	string
 */
static int
tw_result(const Char *act, Char **pat)
{
    int looking;
    static Char* res = NULL;
    Char *p;

    if (res != NULL)
	xfree(res), res = NULL;

    switch (act[0] & ~QUOTE) {
    case 'X':
	looking = TW_COMPLETION;
	break;
    case 'S':
	looking = TW_SIGNAL;
	break;
    case 'a':
	looking = TW_ALIAS;
	break;
    case 'b':
	looking = TW_BINDING;
	break;
    case 'c':
	looking = TW_COMMAND;
	break;
    case 'C':
	looking = TW_PATH | TW_COMMAND;
	break;
    case 'd':
	looking = TW_DIRECTORY;
	break;
    case 'D':
	looking = TW_PATH | TW_DIRECTORY;
	break;
    case 'e':
	looking = TW_ENVVAR;
	break;
    case 'f':
	looking = TW_FILE;
	break;
#ifdef COMPAT
    case 'p':
#endif /* COMPAT */
    case 'F':
	looking = TW_PATH | TW_FILE;
	break;
    case 'g':
	looking = TW_GRPNAME;
	break;
    case 'j':
	looking = TW_JOB;
	break;
    case 'l':
	looking = TW_LIMIT;
	break;
    case 'n':
	looking = TW_NONE;
	break;
    case 's':
	looking = TW_SHELLVAR;
	break;
    case 't':
	looking = TW_TEXT;
	break;
    case 'T':
	looking = TW_PATH | TW_TEXT;
	break;
    case 'v':
	looking = TW_VARIABLE;
	break;
    case 'u':
	looking = TW_USER;
	break;
    case 'x':
	looking = TW_EXPLAIN;
	break;

    case '$':
	*pat = res = Strsave(&act[1]);
	(void) strip(res);
	return(TW_VARLIST);

    case '(':
	*pat = res = Strsave(&act[1]);
	if ((p = Strchr(res, ')')) != NULL)
	    *p = '\0';
	(void) strip(res);
	return TW_WORDLIST;

    case '`':
	res = Strsave(act);
	if ((p = Strchr(&res[1], '`')) != NULL)
	    *++p = '\0';
	
	if (didfds == 0) {
	    /*
	     * Make sure that we have some file descriptors to
	     * play with, so that the processes have at least 0, 1, 2
	     * open
	     */
	    (void) dcopy(SHIN, 0);
	    (void) dcopy(SHOUT, 1);
	    (void) dcopy(SHDIAG, 2);
	}
	if ((p = globone(res, G_APPEND)) != NULL) {
	    xfree(res), res = NULL;
	    *pat = res = Strsave(p);
	    xfree(p);
	    return TW_WORDLIST;
	}
	return TW_ZERO;

    default:
	stderror(ERR_COMPCOM, short2str(act));
	return TW_ZERO;
    }

    switch (act[1] & ~QUOTE) {
    case '\0':
	return looking;

    case ':':
	*pat = res = Strsave(&act[2]);
	(void) strip(res);
	return looking;

    default:
	stderror(ERR_COMPCOM, short2str(act));
	return TW_ZERO;
    }
} /* end tw_result */
Пример #10
0
String *Swig_string_rxspencer(String *s) {
  String *res = 0;
  if (Len(s)) {
    const char *cs = Char(s);
    const char *cb;
    const char *ce;
    if (*cs == '[') {
      int retval;
      regex_t compiled;
      cb = ++cs;
      ce = skip_delim('[', ']', cb);
      if (ce) {
	char bregexp[512];
	strncpy(bregexp, cb, ce - cb);
	bregexp[ce - cb] = '\0';
	++ce;
	retval = regcomp(&compiled, bregexp, REG_EXTENDED);
	if (retval == 0) {
	  cs = ce;
	  if (*cs == '[') {
	    cb = ++cs;
	    ce = skip_delim('[', ']', cb);
	    if (ce) {
	      const char *cvalue = ce + 1;
	      int nsub = (int) compiled.re_nsub + 1;
	      regmatch_t *pmatch = (regmatch_t *) malloc(sizeof(regmatch_t) * (nsub));
	      retval = regexec(&compiled, cvalue, nsub, pmatch, 0);
	      if (retval != REG_NOMATCH) {
		char *spos = 0;
		res = NewStringWithSize(cb, ce - cb);
		spos = Strchr(res, '@');
		while (spos) {
		  char cd = *(++spos);
		  if (isdigit(cd)) {
		    char arg[8];
		    size_t len;
		    int i = cd - '0';
		    sprintf(arg, "@%d", i);
		    if (i < nsub && (len = pmatch[i].rm_eo - pmatch[i].rm_so)) {
		      char value[256];
		      strncpy(value, cvalue + pmatch[i].rm_so, len);
		      value[len] = 0;
		      Replaceall(res, arg, value);
		    } else {
		      Replaceall(res, arg, "");
		    }
		    spos = Strchr(res, '@');
		  } else if (cd == '@') {
		    spos = strchr(spos + 1, '@');
		  }
		}
	      }
	      free(pmatch);
	    }
	  }
	}
	regfree(&compiled);
      }
    }
  }
  if (!res)
    res = NewStringEmpty();
  return res;
}
Пример #11
0
static void
expbrace(Char ***nvp, Char ***elp, int size)
{
    Char **vl, **el, **nv, *s;

    vl = nv = *nvp;
    if (elp != NULL)
	el = *elp;
    else
	el = vl + blklen(vl);

    for (s = *vl; s; s = *++vl) {
	Char  **vp, **bp;

	/* leave {} untouched for find */
	if (s[0] == '{' && (s[1] == '\0' || (s[1] == '}' && s[2] == '\0')))
	    continue;
	if (Strchr(s, '{') != NULL) {
	    Char  **bl = NULL;
	    int     len;

	    if ((len = globbrace(s, &bl)) < 0)
		stderror(ERR_MISSING, -len);
	    xfree(s);
	    if (len == 1) {
		*vl-- = *bl;
		xfree(bl);
		continue;
	    }
	    if (&el[len] >= &nv[size]) {
		size_t l, e;
		l = &el[len] - &nv[size];
		size += GLOBSPACE > l ? GLOBSPACE : l;
		l = vl - nv;
		e = el - nv;
		nv = xrealloc(nv, size * sizeof(Char *));
		*nvp = nv; /* To keep cleanups working */
		vl = nv + l;
		el = nv + e;
	    }
	    /* nv vl   el     bl
	     * |  |    |      |
	     * -.--..--	      x--
	     *   |            len
	     *   vp
	     */
	    vp = vl--;
	    *vp = *bl;
	    len--;
	    for (bp = el; bp != vp; bp--)
		bp[len] = *bp;
	    el += len;
	    /* nv vl    el bl
	     * |  |     |  |
	     * -.-x  ---    --
	     *   |len
	     *   vp
	     */
	    vp++;
	    for (bp = bl + 1; *bp; *vp++ = *bp++)
		continue;
	    xfree(bl);
	}

    }
    if (elp != NULL)
	*elp = el;
}
Пример #12
0
/* CCRETVAL */
int
Inputl(void)
{
    CCRETVAL retval;
    KEYCMD  cmdnum = 0;
    unsigned char tch;		/* the place where read() goes */
    Char    ch;
    int     num;		/* how many chars we have read at NL */
    int	    expnum;
    struct varent *crct = inheredoc ? NULL : adrof(STRcorrect);
    struct varent *autol = adrof(STRautolist);
    struct varent *matchbeep = adrof(STRmatchbeep);
    struct varent *imode = adrof(STRinputmode);
    Char   *SaveChar, *CorrChar;
    int     matchval;		/* from tenematch() */
    int     nr_history_exp;     /* number of (attempted) history expansions */
    COMMAND fn;
    int curlen = 0;
    int newlen;
    int idx;
    Char *autoexpand;

    if (!MapsAreInited)		/* double extra just in case */
	ed_InitMaps();

    ClearDisp();		/* reset the display stuff */
    ResetInLine(0);		/* reset the input pointers */
    if (GettingInput)
	MacroLvl = -1;		/* editor was interrupted during input */

    if (imode && imode->vec != NULL) {
	if (!Strcmp(*(imode->vec), STRinsert))
	    inputmode = MODE_INSERT;
	else if (!Strcmp(*(imode->vec), STRoverwrite))
	    inputmode = MODE_REPLACE;
    }

#if defined(FIONREAD) && !defined(OREO)
    if (!Tty_raw_mode && MacroLvl < 0) {
# ifdef SUNOS4
	long chrs = 0;
# else /* !SUNOS4 */
	/* 
	 * *Everyone* else has an int, but SunOS wants long!
	 * This breaks where int != long (alpha)
	 */
	int chrs = 0;
# endif /* SUNOS4 */

	(void) ioctl(SHIN, FIONREAD, (ioctl_t) & chrs);
	if (chrs == 0) {
	    if (Rawmode() < 0)
		return 0;
	}
    }
#endif /* FIONREAD && !OREO */

    GettingInput = 1;
    NeedsRedraw = 0;
    tellwhat = 0;

    if (RestoreSaved) {
	copyn(InputBuf, SavedBuf.s, INBUFSIZE);/*FIXBUF*/
	LastChar = InputBuf + LastSaved;
	Cursor = InputBuf + CursSaved;
	Hist_num = HistSaved;
	HistSaved = 0;
	RestoreSaved = 0;
    }
    if (HistSaved) {
	Hist_num = HistSaved;
	GetHistLine();
	HistSaved = 0;
    }
    if (Expand) {
	(void) e_up_hist(0);
	Expand = 0;
    }
    Refresh();			/* print the prompt */

    for (num = OKCMD; num == OKCMD;) {	/* while still editing this line */
#ifdef DEBUG_EDIT
	if (Cursor > LastChar)
	    xprintf("Cursor > LastChar\r\n");
	if (Cursor < InputBuf)
	    xprintf("Cursor < InputBuf\r\n");
	if (Cursor > InputLim)
	    xprintf("Cursor > InputLim\r\n");
	if (LastChar > InputLim)
	    xprintf("LastChar > InputLim\r\n");
	if (InputLim != &InputBuf[INBUFSIZE - 2])/*FIXBUF*/
	    xprintf("InputLim != &InputBuf[INBUFSIZE-2]\r\n");
	if ((!DoingArg) && (Argument != 1))
	    xprintf("(!DoingArg) && (Argument != 1)\r\n");
	if (CcKeyMap[0] == 0)
	    xprintf("CcKeyMap[0] == 0 (maybe not inited)\r\n");
#endif

	/* if EOF or error */
	if ((num = GetNextCommand(&cmdnum, &ch)) != OKCMD) {
	    break;
	}

	if (cmdnum >= NumFuns) {/* BUG CHECK command */
#ifdef DEBUG_EDIT
	    xprintf(CGETS(6, 1, "ERROR: illegal command from key 0%o\r\n"), ch);
#endif
	    continue;		/* try again */
	}

	/* now do the real command */
	retval = (*CcFuncTbl[cmdnum]) (ch);

	/* save the last command here */
	LastCmd = cmdnum;

	/* make sure fn is initialized */
	fn = (retval == CC_COMPLETE_ALL) ? LIST_ALL : LIST;

	/* use any return value */
	switch (retval) {

	case CC_REFRESH:
	    Refresh();
	    /*FALLTHROUGH*/
	case CC_NORM:		/* normal char */
	    Argument = 1;
	    DoingArg = 0;
	    /*FALLTHROUGH*/
	case CC_ARGHACK:	/* Suggested by Rich Salz */
	    /* <*****@*****.**> */
	    curchoice = -1;
	    curlen = (int) (LastChar - InputBuf);
	    break;		/* keep going... */

	case CC_EOF:		/* end of file typed */
	    curchoice = -1;
	    curlen = (int) (LastChar - InputBuf);
	    num = 0;
	    break;

	case CC_WHICH:		/* tell what this command does */
	    tellwhat = 1;
	    *LastChar++ = '\n';	/* for the benifit of CSH */
	    num = (int) (LastChar - InputBuf);	/* number characters read */
	    break;

	case CC_NEWLINE:	/* normal end of line */
	    curlen = 0;
	    curchoice = -1;
	    matchval = 1;
	    if (crct && crct->vec != NULL && (!Strcmp(*(crct->vec), STRcmd) ||
			 !Strcmp(*(crct->vec), STRall))) {
		Char *Origin;

                PastBottom();
		Origin = Strsave(InputBuf);
		cleanup_push(Origin, xfree);
		SaveChar = LastChar;
		if (SpellLine(!Strcmp(*(crct->vec), STRcmd)) == 1) {
		    Char *Change;

                    PastBottom();
		    Change = Strsave(InputBuf);
		    cleanup_push(Change, xfree);
		    *Strchr(Change, '\n') = '\0';
		    CorrChar = LastChar;	/* Save the corrected end */
		    LastChar = InputBuf;	/* Null the current line */
		    SoundBeep();
		    printprompt(2, short2str(Change));
		    cleanup_until(Change);
		    Refresh();
		    if (xread(SHIN, &tch, 1) < 0) {
#ifdef convex
		        /*
			 * need to print error message in case file
			 * is migrated
			 */
                        if (errno)
                            stderror(ERR_SYSTEM, progname, strerror(errno));
#else
			cleanup_until(Origin);
			break;
#endif
		    }
		    ch = tch;
		    if (ch == 'y' || ch == ' ') {
			LastChar = CorrChar;	/* Restore the corrected end */
			xprintf("%s", CGETS(6, 2, "yes\n"));
		    }
		    else {
			Strcpy(InputBuf, Origin);
			LastChar = SaveChar;
			if (ch == 'e') {
			    xprintf("%s", CGETS(6, 3, "edit\n"));
			    *LastChar-- = '\0';
			    Cursor = LastChar;
			    printprompt(3, NULL);
			    ClearLines();
			    ClearDisp();
			    Refresh();
			    cleanup_until(Origin);
			    break;
			}
			else if (ch == 'a') {
			    xprintf("%s", CGETS(6, 4, "abort\n"));
		            LastChar = InputBuf;   /* Null the current line */
			    Cursor = LastChar;
			    printprompt(0, NULL);
			    Refresh();
			    cleanup_until(Origin);
			    break;
			}
			xprintf("%s", CGETS(6, 5, "no\n"));
		    }
		    flush();
		}
		cleanup_until(Origin);
	    } else if (crct && crct->vec != NULL &&
		!Strcmp(*(crct->vec), STRcomplete)) {
                if (LastChar > InputBuf && LastChar[-1] == '\n') {
                    LastChar[-1] = '\0';
                    LastChar--;
                    Cursor = LastChar;
                }
                match_unique_match = 1;  /* match unique matches */
		matchval = CompleteLine();
                match_unique_match = 0;
        	curlen = (int) (LastChar - InputBuf);
		if (matchval != 1) {
                    PastBottom();
		}
		if (matchval == 0) {
		    xprintf("%s", CGETS(6, 6, "No matching command\n"));
		} else if (matchval == 2) {
		    xprintf("%s", CGETS(6, 7, "Ambiguous command\n"));
		}
	        if (NeedsRedraw) {
		    ClearLines();
		    ClearDisp();
		    NeedsRedraw = 0;
	        }
	        Refresh();
	        Argument = 1;
	        DoingArg = 0;
		if (matchval == 1) {
                    PastBottom();
                    *LastChar++ = '\n';
                    *LastChar = '\0';
		}
        	curlen = (int) (LastChar - InputBuf);
            }
	    else
		PastBottom();

	    if (matchval == 1) {
	        tellwhat = 0;	/* just in case */
	        Hist_num = 0;	/* for the history commands */
		/* return the number of chars read */
	        num = (int) (LastChar - InputBuf);
	        /*
	         * For continuation lines, we set the prompt to prompt 2
	         */
	        printprompt(1, NULL);
	    }
	    break;

	case CC_CORRECT:
	    if (tenematch(InputBuf, Cursor - InputBuf, SPELL) < 0)
		SoundBeep();		/* Beep = No match/ambiguous */
	    curlen = Repair();
	    break;

	case CC_CORRECT_L:
	    if (SpellLine(FALSE) < 0)
		SoundBeep();		/* Beep = No match/ambiguous */
	    curlen = Repair();
	    break;


	case CC_COMPLETE:
	case CC_COMPLETE_ALL:
	case CC_COMPLETE_FWD:
	case CC_COMPLETE_BACK:
	    switch (retval) {
	    case CC_COMPLETE:
		fn = RECOGNIZE;
		curlen = (int) (LastChar - InputBuf);
		curchoice = -1;
		rotate = 0;
		break;
	    case CC_COMPLETE_ALL:
		fn = RECOGNIZE_ALL;
		curlen = (int) (LastChar - InputBuf);
		curchoice = -1;
		rotate = 0;
		break;
	    case CC_COMPLETE_FWD:
		fn = RECOGNIZE_SCROLL;
		curchoice++;
		rotate = 1;
		break;
	    case CC_COMPLETE_BACK:
		fn = RECOGNIZE_SCROLL;
		curchoice--;
		rotate = 1;
		break;
	    default:
		abort();
	    }
	    if (InputBuf[curlen] && rotate) {
		newlen = (int) (LastChar - InputBuf);
		for (idx = (int) (Cursor - InputBuf); 
		     idx <= newlen; idx++)
			InputBuf[idx - newlen + curlen] =
			InputBuf[idx];
		LastChar = InputBuf + curlen;
		Cursor = Cursor - newlen + curlen;
	    }
	    curlen = (int) (LastChar - InputBuf);


	    nr_history_exp = 0;
	    autoexpand = varval(STRautoexpand);
	    if (autoexpand != STRNULL)
		nr_history_exp += ExpandHistory();

	    /* try normal expansion only if no history references were found */
	    if (nr_history_exp == 0 ||
		Strcmp(autoexpand, STRonlyhistory) != 0) {
		/*
		 * Modified by Martin Boyer ([email protected]):
		 * A separate variable now controls beeping after
		 * completion, independently of autolisting.
		 */
		expnum = (int) (Cursor - InputBuf);
		switch (matchval = tenematch(InputBuf, Cursor-InputBuf, fn)){
		case 1:
		    if (non_unique_match && matchbeep &&
			matchbeep->vec != NULL &&
			(Strcmp(*(matchbeep->vec), STRnotunique) == 0))
			SoundBeep();
		    break;
		case 0:
		    if (matchbeep && matchbeep->vec != NULL) {
			if (Strcmp(*(matchbeep->vec), STRnomatch) == 0 ||
			    Strcmp(*(matchbeep->vec), STRambiguous) == 0 ||
			    Strcmp(*(matchbeep->vec), STRnotunique) == 0)
			    SoundBeep();
		    }
		    else
			SoundBeep();
		    break;
		default:
		    if (matchval < 0) {	/* Error from tenematch */
			curchoice = -1;
			SoundBeep();
			break;
		    }
		    if (matchbeep && matchbeep->vec != NULL) {
			if ((Strcmp(*(matchbeep->vec), STRambiguous) == 0 ||
			     Strcmp(*(matchbeep->vec), STRnotunique) == 0))
			    SoundBeep();
		    }
		    else
			SoundBeep();
		    /*
		     * Addition by David C Lawrence <*****@*****.**>: If an 
		     * attempted completion is ambiguous, list the choices.  
		     * (PWP: this is the best feature addition to tcsh I have 
		     * seen in many months.)
		     */
		    if (autol && autol->vec != NULL && 
			(Strcmp(*(autol->vec), STRambiguous) != 0 || 
					 expnum == Cursor - InputBuf)) {
			if (adrof(STRhighlight) && MarkIsSet) {
			    /* clear highlighting before showing completions */
			    MarkIsSet = 0;
			    ClearLines();
			    ClearDisp();
			    Refresh();
			    MarkIsSet = 1;
			}
			PastBottom();
			fn = (retval == CC_COMPLETE_ALL) ? LIST_ALL : LIST;
			(void) tenematch(InputBuf, Cursor-InputBuf, fn);
		    }
		    break;
		}
	    }
	    if (NeedsRedraw) {
		PastBottom();
		ClearLines();
		ClearDisp();
		NeedsRedraw = 0;
	    }
	    Refresh();
	    Argument = 1;
	    DoingArg = 0;
	    break;

	case CC_LIST_CHOICES:
	case CC_LIST_ALL:
	    if (InputBuf[curlen] && rotate) {
		newlen = (int) (LastChar - InputBuf);
		for (idx = (int) (Cursor - InputBuf); 
		     idx <= newlen; idx++)
			InputBuf[idx - newlen + curlen] =
			InputBuf[idx];
		LastChar = InputBuf + curlen;
		Cursor = Cursor - newlen + curlen;
	    }
	    curlen = (int) (LastChar - InputBuf);
	    if (curchoice >= 0)
		curchoice--;

	    fn = (retval == CC_LIST_ALL) ? LIST_ALL : LIST;
	    /* should catch ^C here... */
	    if (tenematch(InputBuf, Cursor - InputBuf, fn) < 0)
		SoundBeep();
	    Refresh();
	    Argument = 1;
	    DoingArg = 0;
	    break;


	case CC_LIST_GLOB:
	    if (tenematch(InputBuf, Cursor - InputBuf, GLOB) < 0)
		SoundBeep();
	    curlen = Repair();
	    break;

	case CC_EXPAND_GLOB:
	    if (tenematch(InputBuf, Cursor - InputBuf, GLOB_EXPAND) <= 0)
		SoundBeep();		/* Beep = No match */
	    curlen = Repair();
	    break;

	case CC_NORMALIZE_PATH:
	    if (tenematch(InputBuf, Cursor - InputBuf, PATH_NORMALIZE) <= 0)
		SoundBeep();		/* Beep = No match */
	    curlen = Repair();
	    break;

	case CC_EXPAND_VARS:
	    if (tenematch(InputBuf, Cursor - InputBuf, VARS_EXPAND) <= 0)
		SoundBeep();		/* Beep = No match */
	    curlen = Repair();
	    break;

	case CC_NORMALIZE_COMMAND:
	    if (tenematch(InputBuf, Cursor - InputBuf, COMMAND_NORMALIZE) <= 0)
		SoundBeep();		/* Beep = No match */
	    curlen = Repair();
	    break;

	case CC_HELPME:
	    xputchar('\n');
	    /* should catch ^C here... */
	    (void) tenematch(InputBuf, LastChar - InputBuf, PRINT_HELP);
	    Refresh();
	    Argument = 1;
	    DoingArg = 0;
	    curchoice = -1;
	    curlen = (int) (LastChar - InputBuf);
	    break;

	case CC_FATAL:		/* fatal error, reset to known state */
#ifdef DEBUG_EDIT
	    xprintf(CGETS(7, 8, "*** editor fatal ERROR ***\r\n\n"));
#endif				/* DEBUG_EDIT */
	    /* put (real) cursor in a known place */
	    ClearDisp();	/* reset the display stuff */
	    ResetInLine(1);	/* reset the input pointers */
	    Refresh();		/* print the prompt again */
	    Argument = 1;
	    DoingArg = 0;
	    curchoice = -1;
	    curlen = (int) (LastChar - InputBuf);
	    break;

	case CC_ERROR:
	default:		/* functions we don't know about */
	    if (adrof(STRhighlight)) {
		ClearLines();
		ClearDisp();
		Refresh();
	    }
	    DoingArg = 0;
	    Argument = 1;
	    SoundBeep();
	    flush();
	    curchoice = -1;
	    curlen = (int) (LastChar - InputBuf);
	    break;
	}
    }
    (void) Cookedmode();	/* make sure the tty is set up correctly */
    GettingInput = 0;
    flush();			/* flush any buffered output */
    return num;
}
Пример #13
0
int nt_try_fast_exec(struct command *t) {
	register Char  **pv, **av;
	register Char *dp,*sav;
	register char **tt;
	register char *f;
	register struct varent *v;
	register int hashval,i;
	register int slash;
	int rc = 0, gflag;
	Char *vp;
	Char   *blk[2];

	vp = varval(STRNTslowexec);
	if (vp != STRNULL)
		return 1;

	blk[0] = t->t_dcom[0];
	blk[1] = 0;

	// don't do backtick
	if(Strchr(t->t_dcom[0],'`') )
		return 1;


	gflag = tglob(blk);
	if (gflag) {
		pv = globall(blk, gflag);
		if (pv == 0) {
			return 1;
		}
	}
	else
		pv = saveblk(blk);

	trim(pv);

	epath = Strsave(pv[0]);
	v = adrof(STRpath);
	if (v == 0 && epath[0] != '/' && epath[0] != '.') {
		blkfree(pv);
		return 1;
	}
	slash = any(short2str(epath),'/');
	/*
	 * Glob the argument list, if necessary. Otherwise trim off the quote bits.
	 */
	av = &t->t_dcom[1];
	gflag = tglob(av);
	if (gflag) {
		av = globall(av, gflag);/*FIXRESET*/
		if (av == 0) {
			blkfree(pv);
			return 1;
		}
	}
	else
		av = saveblk(av);

	blkfree(t->t_dcom);
	t->t_dcom = blkspl(pv, av);
	xfree((ptr_t) pv);
	xfree((ptr_t) av);
	av = t->t_dcom;
	//trim(av);

	if (*av == NULL || **av == '\0')
		return 1;

	xechoit(av);/*FIXRESET*/		/* Echo command if -x */
	if (v == 0 || v->vec[0] == 0 || slash)
		pv = abspath;
	else
		pv = v->vec;

	sav = Strspl(STRslash,*av);
	hashval = hashval_extern(*av);

	i = 0;
	do {
#pragma warning(disable:4310)
		if (!slash && ABSOLUTEP(pv[0]) && havhash) {
#pragma warning(default:4310)
			if (!bit_extern(hashval,i)){
				pv++;i++;
				continue;
			}
		}
		if (pv[0][0] == 0 || eq(pv[0],STRdot)) {

			tt = short2blk(av);
			f = short2str(*av);

			rc = nt_texec(f, tt);

			blkfree((Char**)tt);
			if (!rc)
				break;
		}
		else {
			dp = Strspl(*pv,sav);
			tt = short2blk(av);
			f = short2str(dp);

			rc = nt_texec(f, tt);

			blkfree((Char**)tt);
			xfree((ptr_t)dp);
			if (!rc)
				break;
		}
		pv++;
		i++;
	}while(*pv);
	return rc;
}
Пример #14
0
/*  Returns 0 on success; 1 on error. */
int wipspool(const char *file)
{
    char *lpr, *ptr;
    char fmt[BUFSIZ];
    char outbuf[BUFSIZ];
    int okayState;

#ifdef WIPVMS
    okayState = 1;
#else
    okayState = 0;
#endif /* WIPVMS */

    if ((ptr = wipgetstring("print")) == (char *)NULL) {
        wipoutput(stderr, "HARDCOPY: Error finding printing command.\n");
        return(1);
    }

    if (wiplenc(ptr) < 1)  /* If string is empty, no printing desired. */
        return(0);

    if (Strncmp(ptr, "ignore", 6) == 0) /* Still, no printing desired. */
        return(0);

    lpr = Strcpy(outbuf, ptr);

    if ((ptr = Strchr(lpr, '&')) != (char *)NULL) {
        while(*ptr) {                      /* Remove all '&' characters. */
            if (*ptr == '&') *ptr = ' ';
            ptr++;
        }
    }

#ifdef WIPVMS
    if (Strstr(lpr, "%s") == (char *)NULL) {
        SPrintf(fmt, "%s %%s", lpr);
    } else {
        SPrintf(fmt, "%s", lpr);
    }
#else
    if (Strstr(lpr, "%s") == (char *)NULL) {
        SPrintf(fmt, "%s %%s &\n", lpr);
    } else {
        SPrintf(fmt, "%s &\n", lpr);
    }
#endif /* WIPVMS */

    /*
     *  "fmt" now contains the printer command along with a "%s" for
     *  the file name.
     */

    if ((ptr = wipleading(file)) == (char *)NULL) {
        wipoutput(stderr, "HARDCOPY: Can't get the name of the file to spool.\n");
        return(1);
    }

    SPrintf(outbuf, fmt, ptr);
    wipoutput(stdout, "HARDCOPY: Spooling command:\n %s", outbuf);
    if (System(outbuf) != okayState) {
        wipoutput(stderr, "HARDCOPY: Error spooling WIP printer file.\n");
        return(1);
    }

    return(0);
}
Пример #15
0
/*
 * Form a shell temporary file (in unit 0) from the words
 * of the shell input up to EOF or a line the same as "term".
 * Unit 0 should have been closed before this call.
 */
void
heredoc(Char *term)
{
    eChar  c;
    Char   *Dv[2];
    struct Strbuf lbuf = Strbuf_INIT, mbuf = Strbuf_INIT;
    Char    obuf[BUFSIZE + 1];
#define OBUF_END (obuf + sizeof(obuf) / sizeof (*obuf) - 1)
    Char *lbp, *obp, *mbp;
    Char  **vp;
    int    quoted;
#ifdef HAVE_MKSTEMP
    char   *tmp = short2str(shtemp);
    char   *dot = strrchr(tmp, '.');

    if (!dot)
	stderror(ERR_NAME | ERR_NOMATCH);
    strcpy(dot, TMP_TEMPLATE);

    xclose(0);
    if (mkstemp(tmp) == -1)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
#else /* !HAVE_MKSTEMP */
    char   *tmp;
# ifndef WINNT_NATIVE

again:
# endif /* WINNT_NATIVE */
    tmp = short2str(shtemp);
# if O_CREAT == 0
    if (xcreat(tmp, 0600) < 0)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
# endif
    xclose(0);
    if (xopen(tmp, O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY|O_LARGEFILE, 0600) ==
	-1) {
	int oerrno = errno;
# ifndef WINNT_NATIVE
	if (errno == EEXIST) {
	    if (unlink(tmp) == -1) {
		xfree(shtemp);
		mbp = randsuf();
		shtemp = Strspl(STRtmpsh, mbp);
		xfree(mbp);
	    }
	    goto again;
	}
# endif /* WINNT_NATIVE */
	(void) unlink(tmp);
	errno = oerrno;
 	stderror(ERR_SYSTEM, tmp, strerror(errno));
    }
#endif /* HAVE_MKSTEMP */
    (void) unlink(tmp);		/* 0 0 inode! */
    Dv[0] = term;
    Dv[1] = NULL;
    gflag = 0;
    trim(Dv);
    rscan(Dv, Dtestq);
    quoted = gflag;
    obp = obuf;
    obuf[BUFSIZE] = 0;
    inheredoc = 1;
    cleanup_push(&inheredoc, inheredoc_cleanup);
#ifdef WINNT_NATIVE
    __dup_stdin = 1;
#endif /* WINNT_NATIVE */
    cleanup_push(&lbuf, Strbuf_cleanup);
    cleanup_push(&mbuf, Strbuf_cleanup);
    for (;;) {
	Char **words;

	/*
	 * Read up a line
	 */
	lbuf.len = 0;
	for (;;) {
	    c = readc(1);	/* 1 -> Want EOF returns */
	    if (c == CHAR_ERR || c == '\n')
		break;
	    if ((c &= TRIM) != 0)
		Strbuf_append1(&lbuf, (Char) c);
	}
	Strbuf_terminate(&lbuf);

	/* Catch EOF in the middle of a line. */
	if (c == CHAR_ERR && lbuf.len != 0)
	    c = '\n';

	/*
	 * Check for EOF or compare to terminator -- before expansion
	 */
	if (c == CHAR_ERR || eq(lbuf.s, term))
	    break;

	/*
	 * If term was quoted or -n just pass it on
	 */
	if (quoted || noexec) {
	    Strbuf_append1(&lbuf, '\n');
	    Strbuf_terminate(&lbuf);
	    for (lbp = lbuf.s; (c = *lbp++) != 0;) {
		*obp++ = (Char) c;
		if (obp == OBUF_END) {
		    tmp = short2str(obuf);
		    (void) xwrite(0, tmp, strlen (tmp));
		    obp = obuf;
		}
	    }
	    continue;
	}

	/*
	 * Term wasn't quoted so variable and then command expand the input
	 * line
	 */
	Dcp = lbuf.s;
	Dvp = Dv + 1;
	mbuf.len = 0;
	for (;;) {
	    c = DgetC(DODOL);
	    if (c == DEOF)
		break;
	    if ((c &= TRIM) == 0)
		continue;
	    /* \ quotes \ $ ` here */
	    if (c == '\\') {
		c = DgetC(0);
		if (!any("$\\`", c))
		    unDgetC(c | QUOTE), c = '\\';
		else
		    c |= QUOTE;
	    }
	    Strbuf_append1(&mbuf, (Char) c);
	}
	Strbuf_terminate(&mbuf);

	/*
	 * If any ` in line do command substitution
	 */
	mbp = mbuf.s;
	if (Strchr(mbp, '`') != NULL) {
	    /*
	     * 1 arg to dobackp causes substitution to be literal. Words are
	     * broken only at newlines so that all blanks and tabs are
	     * preserved.  Blank lines (null words) are not discarded.
	     */
	    words = dobackp(mbp, 1);
	}
	else
	    /* Setup trivial vector similar to return of dobackp */
	    Dv[0] = mbp, Dv[1] = NULL, words = Dv;

	/*
	 * Resurrect the words from the command substitution each separated by
	 * a newline.  Note that the last newline of a command substitution
	 * will have been discarded, but we put a newline after the last word
	 * because this represents the newline after the last input line!
	 */
	for (vp= words; *vp; vp++) {
	    for (mbp = *vp; *mbp; mbp++) {
		*obp++ = *mbp & TRIM;
		if (obp == OBUF_END) {
		    tmp = short2str(obuf);
		    (void) xwrite(0, tmp, strlen (tmp));
		    obp = obuf;
		}
	    }
	    *obp++ = '\n';
	    if (obp == OBUF_END) {
	        tmp = short2str(obuf);
		(void) xwrite(0, tmp, strlen (tmp));
		obp = obuf;
	    }
	}
	if (words != Dv)
	    blkfree(words);
    }
    *obp = 0;
    tmp = short2str(obuf);
    (void) xwrite(0, tmp, strlen (tmp));
    (void) lseek(0, (off_t) 0, L_SET);
    cleanup_until(&inheredoc);
}
Пример #16
0
/*
 * dfollow - change to arg directory; fall back on cdpath if not valid
 */
static Char *
dfollow(Char *cp, int old)
{
    Char *dp;
    struct varent *c;
    int serrno;

    cp = old ? Strsave(cp) : globone(cp, G_ERROR);
    cleanup_push(cp, xfree);
#ifdef apollo
    if (Strchr(cp, '`')) {
	char *dptr;
	if (chdir(dptr = short2str(cp)) < 0) 
	    stderror(ERR_SYSTEM, dptr, strerror(errno));
	dp = agetcwd();
	cleanup_push(dp, xfree);
	if (dp != NULL) {
	    cleanup_until(cp);
	    return dgoto(dp);
	}
	else
	    stderror(ERR_SYSTEM, dptr, strerror(errno));
    }
#endif /* apollo */

    /*
     * if we are ignoring symlinks, try to fix relatives now.
     * if we are expading symlinks, it should be done by now.
     */ 
    dp = dnormalize(cp, symlinks == SYM_IGNORE);
    if (chdir(short2str(dp)) >= 0) {
        cleanup_until(cp);
        return dgoto(dp);
    }
    else {
        xfree(dp);
        if (chdir(short2str(cp)) >= 0) {
	    cleanup_ignore(cp);
	    cleanup_until(cp);
	    return dgoto(cp);
	}
	else if (errno != ENOENT && errno != ENOTDIR) {
	    int err;

	    err = errno;
	    stderror(ERR_SYSTEM, short2str(cp), strerror(err));
	}
	serrno = errno;
    }

    if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp)
	&& (c = adrof(STRcdpath)) && c->vec != NULL) {
	struct Strbuf buf = Strbuf_INIT;
	Char  **cdp;

	for (cdp = c->vec; *cdp; cdp++) {
	    size_t len = Strlen(*cdp);
	    buf.len = 0;
	    if (len > 0) {
		Strbuf_append(&buf, *cdp);
		if ((*cdp)[len - 1] != '/')
		    Strbuf_append1(&buf, '/');
	    }
	    Strbuf_append(&buf, cp);
	    Strbuf_terminate(&buf);
	    /*
	     * We always want to fix the directory here
	     * If we are normalizing symlinks
	     */
	    dp = dnormalize(buf.s, symlinks == SYM_IGNORE || 
				   symlinks == SYM_EXPAND);
	    if (chdir(short2str(dp)) >= 0) {
		printd = 1;
		xfree(buf.s);
		cleanup_until(cp);
		return dgoto(dp);
	    }
	    else if (chdir(short2str(cp)) >= 0) {
		printd = 1;
		xfree(dp);
		xfree(buf.s);
		cleanup_ignore(cp);
		cleanup_until(cp);
		return dgoto(cp);
	    }
	}
	xfree(buf.s);
    }
    dp = varval(cp);
    if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) {
	cleanup_until(cp);
	cp = Strsave(dp);
	printd = 1;
	return dgoto(cp);
    }
    /*
     * on login source of ~/.cshdirs, errors are eaten. the dir stack is all
     * directories we could get to.
     */
    if (!bequiet)
	stderror(ERR_SYSTEM, short2str(cp), strerror(serrno));
    cleanup_until(cp);
    return (NULL);
}