bash-20130308 additional cleanup

This commit is contained in:
Chet Ramey
2013-03-26 21:01:59 -04:00
parent e632a17a4f
commit f8fa1b65b9
110 changed files with 0 additions and 15054 deletions
-379
View File
@@ -1,379 +0,0 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static const char sccsid[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95";
#endif /* not lint */
#include <config.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include "bashansi.h"
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
#endif
#if !defined (_POSIX2_LINE_MAX)
# define _POSIX2_LINE_MAX 2048
#endif
static int cflag;
static char dchar;
static int dflag;
static int fflag;
static int sflag;
static int autostart, autostop, maxval;
static char positions[_POSIX2_LINE_MAX + 1];
static int c_cut __P((FILE *, char *));
static int f_cut __P((FILE *, char *));
static int get_list __P((char *));
static char *_cut_strsep __P((char **, const char *));
int
cut_builtin(list)
WORD_LIST *list;
{
FILE *fp;
int (*fcn) __P((FILE *, char *)) = NULL;
int ch;
fcn = NULL;
dchar = '\t'; /* default delimiter is \t */
/* Since we don't support multi-byte characters, the -c and -b
options are equivalent, and the -n option is meaningless. */
reset_internal_getopt ();
while ((ch = internal_getopt (list, "b:c:d:f:sn")) != -1)
switch(ch) {
case 'b':
case 'c':
fcn = c_cut;
if (get_list(list_optarg) < 0)
return (EXECUTION_FAILURE);
cflag = 1;
break;
case 'd':
dchar = *list_optarg;
dflag = 1;
break;
case 'f':
fcn = f_cut;
if (get_list(list_optarg) < 0)
return (EXECUTION_FAILURE);
fflag = 1;
break;
case 's':
sflag = 1;
break;
case 'n':
break;
case '?':
default:
builtin_usage();
return (EX_USAGE);
}
list = loptend;
if (fflag) {
if (cflag) {
builtin_usage();
return (EX_USAGE);
}
} else if (!cflag || dflag || sflag) {
builtin_usage();
return (EX_USAGE);
}
if (list) {
while (list) {
fp = fopen(list->word->word, "r");
if (fp == 0) {
builtin_error("%s", list->word->word);
return (EXECUTION_FAILURE);
}
ch = (*fcn)(fp, list->word->word);
(void)fclose(fp);
if (ch < 0)
return (EXECUTION_FAILURE);
list = list->next;
}
} else {
ch = (*fcn)(stdin, "stdin");
if (ch < 0)
return (EXECUTION_FAILURE);
}
return (EXECUTION_SUCCESS);
}
static int
get_list(list)
char *list;
{
int setautostart, start, stop;
char *pos;
char *p;
/*
* set a byte in the positions array to indicate if a field or
* column is to be selected; use +1, it's 1-based, not 0-based.
* This parser is less restrictive than the Draft 9 POSIX spec.
* POSIX doesn't allow lists that aren't in increasing order or
* overlapping lists. We also handle "-3-5" although there's no
* real reason too.
*/
for (; (p = _cut_strsep(&list, ", \t")) != NULL;) {
setautostart = start = stop = 0;
if (*p == '-') {
++p;
setautostart = 1;
}
if (isdigit((unsigned char)*p)) {
start = stop = strtol(p, &p, 10);
if (setautostart && start > autostart)
autostart = start;
}
if (*p == '-') {
if (isdigit((unsigned char)p[1]))
stop = strtol(p + 1, &p, 10);
if (*p == '-') {
++p;
if (!autostop || autostop > stop)
autostop = stop;
}
}
if (*p) {
builtin_error("[-cf] list: illegal list value");
return -1;
}
if (!stop || !start) {
builtin_error("[-cf] list: values may not include zero");
return -1;
}
if (stop > _POSIX2_LINE_MAX) {
builtin_error("[-cf] list: %d too large (max %d)",
stop, _POSIX2_LINE_MAX);
return -1;
}
if (maxval < stop)
maxval = stop;
for (pos = positions + start; start++ <= stop; *pos++ = 1);
}
/* overlapping ranges */
if (autostop && maxval > autostop)
maxval = autostop;
/* set autostart */
if (autostart)
memset(positions + 1, '1', autostart);
return 0;
}
/* ARGSUSED */
static int
c_cut(fp, fname)
FILE *fp;
char *fname;
{
int ch, col;
char *pos;
ch = 0;
for (;;) {
pos = positions + 1;
for (col = maxval; col; --col) {
if ((ch = getc(fp)) == EOF)
return;
if (ch == '\n')
break;
if (*pos++)
(void)putchar(ch);
}
if (ch != '\n') {
if (autostop)
while ((ch = getc(fp)) != EOF && ch != '\n')
(void)putchar(ch);
else
while ((ch = getc(fp)) != EOF && ch != '\n');
}
(void)putchar('\n');
}
return (0);
}
static int
f_cut(fp, fname)
FILE *fp;
char *fname;
{
int ch, field, isdelim;
char *pos, *p, sep;
int output;
char lbuf[_POSIX2_LINE_MAX + 1];
for (sep = dchar; fgets(lbuf, sizeof(lbuf), fp);) {
output = 0;
for (isdelim = 0, p = lbuf;; ++p) {
if (!(ch = *p)) {
builtin_error("%s: line too long.", fname);
return -1;
}
/* this should work if newline is delimiter */
if (ch == sep)
isdelim = 1;
if (ch == '\n') {
if (!isdelim && !sflag)
(void)printf("%s", lbuf);
break;
}
}
if (!isdelim)
continue;
pos = positions + 1;
for (field = maxval, p = lbuf; field; --field, ++pos) {
if (*pos) {
if (output++)
(void)putchar(sep);
while ((ch = *p++) != '\n' && ch != sep)
(void)putchar(ch);
} else {
while ((ch = *p++) != '\n' && ch != sep)
continue;
}
if (ch == '\n')
break;
}
if (ch != '\n') {
if (autostop) {
if (output)
(void)putchar(sep);
for (; (ch = *p) != '\n'; ++p)
(void)putchar(ch);
} else
for (; (ch = *p) != '\n'; ++p);
}
(void)putchar('\n');
}
return (0);
}
/*
* Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
* On return, *stringp points past the last NUL written (if there might
* be further tokens), or is NULL (if there are definitely no more tokens).
*
* If *stringp is NULL, strsep returns NULL.
*/
static char *
_cut_strsep(stringp, delim)
register char **stringp;
register const char *delim;
{
register char *s;
register const char *spanp;
register int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
static char *cut_doc[] = {
"Select portions of lines.",
"",
"Select portions of each line (as specified by LIST) from each FILE",
"(by default, the standard input), and write them to the standard output.",
"Items specified by LIST are either column positions or fields delimited",
"by a special character. Column numbering starts at 1.",
(char *)0
};
struct builtin cut_struct = {
"cut",
cut_builtin,
BUILTIN_ENABLED,
cut_doc,
"cut -b list [-n] [file ...] OR cut -c list [file ...] OR cut -f list [-s] [-d delim] [file ...]",
0
};
File diff suppressed because it is too large Load Diff
-214
View File
@@ -1,214 +0,0 @@
/* getconf.h -- replacement definitions for ones the system doesn't provide. */
#ifndef _GETCONF_H
#define _GETCONF_H
/* Some systems do not define these; use POSIX.2 minimum recommended values. */
#ifndef _POSIX2_COLL_WEIGHTS_MAX
# define _POSIX2_COLL_WEIGHTS_MAX 2
#endif
/* If we're on a posix system, but the system doesn't define the necessary
constants, use posix.1 minimum values. */
#if defined (_POSIX_VERSION)
#ifndef _POSIX_ARG_MAX
# define _POSIX_ARG_MAX 4096
#endif
#ifndef _POSIX_CHILD_MAX
# define _POSIX_CHILD_MAX 6
#endif
#ifndef _POSIX_LINK_MAX
# define _POSIX_LINK_MAX 8
#endif
#ifndef _POSIX_MAX_CANON
# define _POSIX_MAX_CANON 255
#endif
#ifndef _POSIX_MAX_INPUT
# define _POSIX_MAX_INPUT 255
#endif
#ifndef _POSIX_NAME_MAX
# define _POSIX_NAME_MAX 14
#endif
#ifndef _POSIX_NGROUPS_MAX
# define _POSIX_NGROUPS_MAX 0
#endif
#ifndef _POSIX_OPEN_MAX
# define _POSIX_OPEN_MAX 16
#endif
#ifndef _POSIX_PATH_MAX
# define _POSIX_PATH_MAX 255
#endif
#ifndef _POSIX_PIPE_BUF
# define _POSIX_PIPE_BUF 512
#endif
#ifndef _POSIX_SSIZE_MAX
# define _POSIX_SSIZE_MAX 32767
#endif
#ifndef _POSIX_STREAM_MAX
# define _POSIX_STREAM_MAX 8
#endif
#ifndef _POSIX_TZNAME_MAX
# define _POSIX_TZNAME_MAX 3
#endif
#ifndef _POSIX2_BC_BASE_MAX
# define _POSIX2_BC_BASE_MAX 99
#endif
#ifndef _POSIX2_BC_DIM_MAX
# define _POSIX2_BC_DIM_MAX 2048
#endif
#ifndef _POSIX2_BC_SCALE_MAX
# define _POSIX2_BC_SCALE_MAX 99
#endif
#ifndef _POSIX2_BC_STRING_MAX
# define _POSIX2_BC_STRING_MAX 1000
#endif
#ifndef _POSIX2_EQUIV_CLASS_MAX
# define _POSIX2_EQUIV_CLASS_MAX 2
#endif
#ifndef _POSIX2_EXPR_NEST_MAX
# define _POSIX2_EXPR_NEST_MAX 32
#endif
#ifndef _POSIX2_LINE_MAX
# define _POSIX2_LINE_MAX 2048
#endif
#ifndef _POSIX2_RE_DUP_MAX
# define _POSIX2_RE_DUP_MAX 255
#endif
/* configurable system variables */
#if !defined (HAVE_SYSCONF)
#ifndef _SC_ARG_MAX
# define _SC_ARG_MAX 1
# define _SC_CHILD_MAX 2
# define _SC_CLK_TCK 3
# define _SC_NGROUPS_MAX 4
# define _SC_OPEN_MAX 5
# define _SC_JOB_CONTROL 6
# define _SC_SAVED_IDS 7
# define _SC_VERSION 8
# define _SC_BC_BASE_MAX 9
# define _SC_BC_DIM_MAX 10
# define _SC_BC_SCALE_MAX 11
# define _SC_BC_STRING_MAX 12
# define _SC_COLL_WEIGHTS_MAX 13
# define _SC_EXPR_NEST_MAX 14
# define _SC_LINE_MAX 15
# define _SC_RE_DUP_MAX 16
#if 0
# define _SC_2_VERSION 17
# define _SC_2_C_BIND 18
# define _SC_2_C_DEV 19
# define _SC_2_CHAR_TERM 20
# define _SC_2_FORT_DEV 21
# define _SC_2_FORT_RUN 22
# define _SC_2_LOCALEDEF 23
# define _SC_2_SW_DEV 24
# define _SC_2_UPE 25
#endif /* 0 */
# define _SC_STREAM_MAX 26
# define _SC_TZNAME_MAX 27
#endif /* !_SC_ARG_MAX */
#endif /* !HAVE_SYSCONF */
/* configurable pathname variables */
#if !defined (HAVE_PATHCONF)
#ifndef _PC_LINK_MAX
#define _PC_LINK_MAX 1
#define _PC_MAX_CANON 2
#define _PC_MAX_INPUT 3
#define _PC_NAME_MAX 4
#define _PC_PATH_MAX 5
#define _PC_PIPE_BUF 6
#define _PC_CHOWN_RESTRICTED 7
#define _PC_NO_TRUNC 8
#define _PC_VDISABLE 9
#endif /* !_PC_LINK_MAX */
#endif /* !HAVE_PATHCONF */
#endif /* _POSIX_VERSION */
#ifndef _CS_PATH
# define _CS_PATH 1
#endif
/* ANSI/ISO C, POSIX.1-200x, XPG 4.2 (and later) C language type limits.
Defined only if the system include files don't. Assume a 32-bit
environment with signed 8-bit characters. */
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
#ifndef CHAR_MAX
# define CHAR_MAX 127
#endif
#ifndef CHAR_MIN
# define CHAR_MIN -128
#endif
#ifndef INT_BIT
# define INT_BIT (sizeof (int) * CHAR_BIT)
#endif
#ifndef INT_MAX
# define INT_MAX 2147483647
#endif
#ifndef INT_MIN
# define INT_MIN (-2147483647-1)
#endif
#ifndef LONG_BIT
# define LONG_BIT (sizeof (long int) * CHAR_BIT)
#endif
#ifndef LONG_MAX
# define LONG_MAX 2147483647L
#endif
#ifndef LONG_MIN
# define LONG_MIN (-2147483647L-1L)
#endif
#ifndef SCHAR_MAX
# define SCHAR_MAX CHAR_MAX
#endif
#ifndef SCHAR_MIN
# define SCHAR_MIN CHAR_MIN
#endif
#ifndef SHRT_MAX
# define SHRT_MAX 32767
#endif
#ifndef SHRT_MIN
# define SHRT_MIN (-32768)
#endif
#ifndef UCHAR_MAX
# define UCHAR_MAX 255
#endif
#ifndef UINT_MAX
# define UINT_MAX 4294967295U
#endif
#ifndef ULONG_MAX
# define ULONG_MAX 4294967295UL
#endif
#ifndef USHRT_MAX
# define UCHAR_MAX 65535
#endif
/* assume size_t is `unsigned int'; ssize_t is `int' */
#ifndef SIZE_MAX
# define SIZE_MAX UINT_MAX
#endif
#ifndef SSIZE_MAX
# define SSIZE_MAX INT_MAX
#endif
#ifndef WORD_BIT
# define WORD_BIT (sizeof (int) * CHAR_BIT)
#endif
#endif /* _GETCONF_H */
-516
View File
@@ -1,516 +0,0 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if !defined(BUILTIN) && !defined(SHELL)
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#endif
#ifndef lint
static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93";
#endif /* not lint */
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include "bashansi.h"
#include "shell.h"
#include "builtins.h"
#include "stdc.h"
#if !defined (errno)
extern int errno;
#endif
static char sbuf[1024];
static int sblen;
/* Gee, I wish sprintf could be reliably counted upon to return the
number of characters written :-( */
#define PF(f, func) \
do { \
if (fieldwidth) \
if (precision) \
sprintf(sbuf, f, fieldwidth, precision, func); \
else \
sprintf(sbuf, f, fieldwidth, func); \
else if (precision) \
sprintf(sbuf, f, precision, func); \
else \
sprintf(sbuf, f, func); \
spaddstr (sbuf, strlen (sbuf)); \
} while (0)
static int asciicode __P((void));
static void escape __P((char *));
static int getchr __P((void));
static double getdouble __P((void));
static int getint __P((int *));
static int getlong __P((long *));
static char *getstr __P((void));
static char *mklong __P((char *, int));
static void usage __P((void));
static char **gargv;
static char *outstr;
static int outsize;
static int outind;
int sprintf_builtin ();
static int sprintf_main ();
static void spaddstr ();
extern char *this_command_name;
extern char *single_quote ();
extern char **make_builtin_argv ();
static char *sprintf_doc[] = {
"Format arguments and assign result to variable.",
"",
"sprintf formats and outputs its arguments, after the second, under control",
"of the format and assigns the result to the variable named by its first",
"argument. The format is a character string which contains three types",
"of objects: plain characters, which are simply copied to the output string,",
"character escape sequences which are converted and copied to the output",
"string, and format specifications, each of which causes printing of the",
"next successive argument. In addition to the standard sprintf(3) formats,",
"%b means to expand escapes in the corresponding argument, and %q means",
"to quote the argument in a way that can be reused as shell input. Each",
"one of the format specifications must not expand to more than 1024",
"characters, though there is no limit on the total size of the output",
"string.",
(char *)NULL
};
struct builtin sprintf_struct = {
"sprintf",
sprintf_builtin,
BUILTIN_ENABLED,
sprintf_doc,
"sprintf var format [arguments]",
(char *)0
};
int
sprintf_builtin (list)
WORD_LIST *list;
{
int c, r;
char **v, *varname;
WORD_LIST *l;
SHELL_VAR *var;
if (list == 0)
{
builtin_usage ();
return (EXECUTION_FAILURE);
}
varname = list->word->word;
list = list->next;
if (legal_identifier (varname) == 0)
{
builtin_error ("%s: not a legal variable name", varname);
return (EXECUTION_FAILURE);
}
outind = 0;
if (outstr == 0)
outstr = xmalloc (outsize = 64);
outstr[0] = '\0';
v = make_builtin_argv (list, &c);
r = sprintf_main (c, v);
free (v);
var = bind_variable (varname, outstr, 0);
if (readonly_p (var))
{
builtin_error ("%s: readonly variable", varname);
return (EXECUTION_FAILURE);
}
return r;
}
static void
spaddstr(str, len)
char *str;
int len;
{
RESIZE_MALLOCED_BUFFER (outstr, outind, len, outsize, 64);
strcpy (outstr + outind, str);
outind += len;
}
static int
sprintf_main(argc, argv)
int argc;
char *argv[];
{
extern int optind;
static char *skip1, *skip2;
int ch, end, fieldwidth, precision;
char convch, nextch, *format, *fmt, *start;
while ((ch = getopt(argc, argv, "")) != EOF)
switch (ch) {
case '?':
default:
usage();
return (1);
}
argc -= optind;
argv += optind;
if (argc < 1) {
usage();
return (1);
}
/*
* Basic algorithm is to scan the format string for conversion
* specifications -- once one is found, find out if the field
* width or precision is a '*'; if it is, gather up value. Note,
* format strings are reused as necessary to use up the provided
* arguments, arguments of zero/null string are provided to use
* up the format string.
*/
skip1 = "#-+ 0";
skip2 = "*0123456789";
escape(fmt = format = *argv); /* backslash interpretation */
gargv = ++argv;
for (;;) {
end = 0;
/* find next format specification */
next: for (start = fmt;; ++fmt) {
if (!*fmt) {
/* avoid infinite loop */
if (end == 1) {
warnx("missing format character",
NULL, NULL);
return (1);
}
end = 1;
if (fmt > start)
(void)printf("%s", start);
if (!*gargv)
return (0);
fmt = format;
goto next;
}
/* %% prints a % */
if (*fmt == '%') {
if (*++fmt != '%')
break;
*fmt++ = '\0';
(void)printf("%s", start);
goto next;
}
}
/* skip to field width */
for (; strchr(skip1, *fmt); ++fmt);
if (*fmt == '*') {
if (getint(&fieldwidth))
return (1);
} else
fieldwidth = 0;
/* skip to possible '.', get following precision */
for (; strchr(skip2, *fmt); ++fmt);
if (*fmt == '.')
++fmt;
if (*fmt == '*') {
if (getint(&precision))
return (1);
} else
precision = 0;
/* skip to conversion char */
for (; strchr(skip2, *fmt); ++fmt);
if (!*fmt) {
warnx("missing format character", NULL, NULL);
return (1);
}
convch = *fmt;
nextch = *++fmt;
*fmt = '\0';
switch(convch) {
case 'c': {
char p;
p = getchr();
PF(start, p);
break;
}
case 's': {
char *p;
p = getstr();
PF(start, p);
break;
}
case 'b': { /* expand escapes in argument */
char *p;
p = getstr();
escape(p);
PF("%s", p);
break;
}
case 'q': { /* print with shell single quoting */
char *p, *p2;
p = getstr();
p2 = single_quote(p);
PF("%s", p2);
free(p2);
break;
}
case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
long p;
char *f;
if ((f = mklong(start, convch)) == NULL)
return (1);
if (getlong(&p))
return (1);
PF(f, p);
break;
}
case 'e': case 'E': case 'f': case 'g': case 'G': {
double p;
p = getdouble();
PF(start, p);
break;
}
default:
warnx("illegal format character", NULL, NULL);
return (1);
}
*fmt = nextch;
}
/* NOTREACHED */
}
static char *
mklong(str, ch)
char *str;
int ch;
{
static char copy[64];
int len;
len = strlen(str) + 2;
memmove(copy, str, len - 3);
copy[len - 3] = 'l';
copy[len - 2] = ch;
copy[len - 1] = '\0';
return (copy);
}
static void
escape(fmt)
register char *fmt;
{
register char *store;
register int value, c;
for (store = fmt; c = *fmt; ++fmt, ++store) {
if (c != '\\') {
*store = c;
continue;
}
switch (*++fmt) {
case '\0': /* EOS, user error */
*store = '\\';
*++store = '\0';
return;
case '\\': /* backslash */
case '\'': /* single quote */
*store = *fmt;
break;
case 'a': /* bell/alert */
*store = '\7';
break;
case 'b': /* backspace */
*store = '\b';
break;
case 'c':
return;
case 'e':
case 'E':
*store = '\033';
break;
case 'f': /* form-feed */
*store = '\f';
break;
case 'n': /* newline */
*store = '\n';
break;
case 'r': /* carriage-return */
*store = '\r';
break;
case 't': /* horizontal tab */
*store = '\t';
break;
case 'v': /* vertical tab */
*store = '\13';
break;
/* octal constant */
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
for (c = 3, value = 0;
c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) {
value <<= 3;
value += *fmt - '0';
}
--fmt;
*store = value;
break;
default:
*store = *fmt;
break;
}
}
*store = '\0';
}
static int
getchr()
{
if (!*gargv)
return ('\0');
return ((int)**gargv++);
}
static char *
getstr()
{
if (!*gargv)
return ("");
return (*gargv++);
}
static char *Number = "+-.0123456789";
static int
getint(ip)
int *ip;
{
long val;
if (getlong(&val))
return (1);
if (val > INT_MAX) {
warnx("%s: %s", *gargv, strerror(ERANGE));
return (1);
}
*ip = val;
return (0);
}
static int
getlong(lp)
long *lp;
{
long val;
char *ep;
if (!*gargv) {
*lp = 0;
return (0);
}
if (strchr(Number, **gargv)) {
errno = 0;
val = strtol(*gargv, &ep, 0);
if (*ep != '\0') {
warnx("%s: illegal number", *gargv, NULL);
return (1);
}
if (errno == ERANGE)
if (val == LONG_MAX) {
warnx("%s: %s", *gargv, strerror(ERANGE));
return (1);
}
if (val == LONG_MIN) {
warnx("%s: %s", *gargv, strerror(ERANGE));
return (1);
}
*lp = val;
++gargv;
return (0);
}
*lp = (long)asciicode();
return (0);
}
static double
getdouble()
{
if (!*gargv)
return ((double)0);
if (strchr(Number, **gargv))
return (atof(*gargv++));
return ((double)asciicode());
}
static int
asciicode()
{
register int ch;
ch = **gargv;
if (ch == '\'' || ch == '"')
ch = (*gargv)[1];
++gargv;
return (ch);
}
static void
usage()
{
(void)fprintf(stderr, "usage: printf format [arg ...]\n");
}
-185
View File
@@ -1,185 +0,0 @@
/*
* Originally from
* http://www.excessus.demon.co.uk/misc-hacks/index.html#xtitle
*/
/*
* Made into a loadable builtin by chet@po.cwru.edu.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#ifdef BASH_BUILTIN
#include "shell.h"
#include "builtins.h"
#include "bashgetopt.h"
#endif
#ifdef BASH_BUILTIN
int xtitle_builtin(WORD_LIST *list)
#else
int main(int argc, char *argv[])
#endif
{
int query = 0;
int fd;
int openned = 0;
#ifdef BASH_BUILTIN
reset_internal_getopt();
#endif
for (;;) {
#ifdef BASH_BUILTIN
int i;
i = internal_getopt(list, "q");
#else
int i = getopt(argc, argv, "q");
#endif
if (i < 0)
break;
switch (i) {
case 'q':
query = 1;
break;
default:
#ifdef BASH_BUILTIN
builtin_usage();
#else
fprintf(stderr, "usage: xtitle [-q] [string]\n");
#endif
return (1);
}
}
#ifdef BASH_BUILTIN
if (!query && loptend == 0) {
#else
if (!query && optind == argc) {
#endif
fprintf(stderr, "xtitle: no string to set\n");
return (1);
}
{
char *t = getenv("TERM");
if (!t || strncmp(t, "xterm", 5))
return (0);
}
if (isatty(0))
fd = 0;
else {
fd = open("/dev/tty", O_RDWR);
if (fd < 0) {
fprintf(stderr, "xtitle: couldn't open terminal: %s", strerror(errno));
return (1);
}
openned = 1;
}
if (!query) {
#ifdef BASH_BUILTIN
WORD_LIST *l = loptend;
char sp = ' ';
write(fd, "\33]0;", 4);
while (l) {
write(fd, l->word->word, strlen(l->word->word));
if (l->next)
write(fd, &sp, 1);
l = l->next;
}
write(fd, "\33\\", 2);
#else
int i;
char sp = ' ';
write(fd, "\33]0;", 4);
for (i = optind; i < argc; i++) {
write(fd, argv[i], strlen(argv[i]));
if (i < argc - 1)
write(fd, &sp, 1);
}
write(fd, "\33\\", 2);
#endif
} else {
struct termios o, n;
char hack;
int state = 0;
tcgetattr(fd, &o);
n = o;
n.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
n.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
n.c_cflag &= ~(CSIZE|PARENB);
n.c_cflag |= CS8;
tcsetattr(fd, TCSAFLUSH, &n);
write(fd, "\33[21t", 5);
while (state != -1) {
if (read(fd, &hack, 1) < 1)
break;
switch (state) {
case 0:
if (hack == '\33') state = 1;
break;
case 1:
if (hack == ']') state = 2; else state = 0;
break;
case 2:
if (hack == 'l') state = 3; else state = 0;
break;
case 3:
if (hack == '\33') state = 4; else putchar(hack);
break;
case 4:
if (hack == '\\') { state = -1; putchar('\n'); }
else { putchar('\33'); putchar(hack); state = 3; }
break;
}
}
tcsetattr(fd, TCSAFLUSH, &o);
}
if (openned)
close(fd);
return (0);
}
#ifdef BASH_BUILTIN
static char *xtitle_doc[] = {
"Set xterm window title.",
"",
"Either set or read the title of the current xterm window. With the",
"-q option, writes the current xterm title to standard output. Without",
"the -q option, sets the xterm title to be the arguments given,",
"separated by space characters. [By Mark Wooding, mdw@nsict.org]",
0
};
struct builtin xtitle_struct = {
"xtitle",
xtitle_builtin,
BUILTIN_ENABLED,
xtitle_doc,
"xtitle [-q] [arguments]",
0
};
#endif