print.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Copyright (c) 1982-2007 AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* by AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * echo [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print [-nrps] [-f format] [-u filenum] [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * printf format [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <stak.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "name.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "streval.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <tmx.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ctype.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ccode.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunion types_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short h;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sflong_t ll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t ld;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin float f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int *ip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct printf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sffmt_t hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int argsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int intvar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **nextarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char cescape;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int extend(Sfio_t*,void*, Sffmt_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char preformat[] = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *genformat(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int fmtvecho(const char*, struct printf*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct print
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *options;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char raw;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char echon;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* nullarg[] = { 0, 0 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Need to handle write failures to avoid locking output pool
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int outexceptf(Sfio_t* iop, int mode, void* data, Sfdisc_t* dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==SF_DPOP || mode==SF_FINAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==SF_WRITE && (errno!= EINTR || sh.trapnote))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int save = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpurge(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpool(iop,NIL(Sfio_t*),SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = save;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_badwrite,sffileno(iop));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_ECHOPRINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int B_echo(int argc, char *argv[],void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char bsd_univ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct print prdata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.options = sh_optecho+5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.raw = prdata.echon = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.sh = (Shell_t*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(argc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This mess is because /bin/echo on BSD is different */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!prdata.sh->universe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *universe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(universe=astconf("UNIVERSE",0,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bsd_univ = (strcmp(universe,"ucb")==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.sh->universe = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!bsd_univ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(b_print(0,argv,&prdata));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.options = sh_optecho;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.raw = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argv[1] && *argv[1]=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(argv[1],"-n")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.echon = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_ECHOE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(strcmp(argv[1],"-e")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.raw = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(strcmp(argv[1],"-ne")==0 || strcmp(argv[1],"-en")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.raw = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.echon = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ECHOE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(b_print(0,argv,&prdata));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ECHOPRINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint b_printf(int argc, char *argv[],void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct print prdata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(argc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&prdata,0,sizeof(prdata));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.sh = (Shell_t*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prdata.options = sh_optprintf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(b_print(-1,argv,&prdata));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * argc==0 when called from echo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * argc==-1 when called from printf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint b_print(int argc, char *argv[], void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *outfile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int exitval=0,n, fd = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shell_t *shp = (Shell_t*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *options, *msg = e_file+4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *format = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int sflag = 0, nflag=0, rflag=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options = sh_optprint;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nflag = rflag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct print *pp = (struct print*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp = pp->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin options = pp->options;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nflag = pp->echon;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rflag = pp->raw;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n = optget(argv,options))) switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nflag++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'p':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = shp->coutpipe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = e_query;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = opt_info.arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* print to history file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_histinit())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_history);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sffileno(shp->hist_ptr->histfp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sflag++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rflag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rflag = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = (int)strtol(opt_info.arg,&opt_info.arg,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*opt_info.arg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(fd<0 || fd >= shp->lim.open_max)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(sh.inuse_bits&(1<<fd)) && (sh_inuse(fd) || (shp->hist_ptr && fd==sffileno(shp->hist_ptr->histfp))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The following is for backward compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if OPT_VERSION >= 19990123
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(opt_info.name,"-R")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(opt_info.option,"-R")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rflag = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special case test for -Rn */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strchr(argv[-1],'n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nflag++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argv && strcmp(*argv,"-n")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nflag++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors || (argc<0 && !(format = *argv++)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinskip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = genformat(format);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle special case of '-' operand for print */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc>0 && *argv && strcmp(*argv,"-")==0 && strcmp(argv[-1],"--"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinskip2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EBADF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(n=shp->fdstatus[fd]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sh_iocheckfd(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(n&IOWRITE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't print error message for stdout for compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),msg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(outfile=shp->sftable[fd]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdisc_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_NOTRACK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = SF_WRITE|((n&IOREAD)?SF_READ:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->sftable[fd] = outfile = sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fd,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_NOTRACK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpool(outfile,shp->outpool,SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp = new_of(Sfdisc_t,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->exceptf = outexceptf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->seekf = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->writef = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->readf = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(outfile,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* turn off share to guarantee atomic writes for printf */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sfset(outfile,SF_SHARE|SF_PUBLIC,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* printf style print */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *pool;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct printf pdata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&pdata, 0, sizeof(pdata));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.sh = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.hdr.version = SFIO_VERSION;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.hdr.extf = extend;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.nextarg = argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_STOPOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pool=sfpool(sfstderr,NIL(Sfio_t*),SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->trapnote&SH_SIGSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.hdr.form = format;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%!",&pdata);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while(*pdata.nextarg && pdata.nextarg!=argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pdata.nextarg == nullarg && pdata.argsize>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(outfile,stakptr(staktell()),pdata.argsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpool(sfstderr,pool,SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitval = pdata.err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* echo style print */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_echolist(outfile,rflag,argv) && !nflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hist_flush(shp->hist_ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n&SF_SHARE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(outfile,SF_SHARE|SF_PUBLIC,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(outfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(exitval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * echo the argument list onto <outfile>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <raw> is non-zero then \ is not a special character.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 0 for \c otherwise 1.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_echolist(Sfio_t *outfile, int raw, char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct printf pdata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.cescape = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pdata.err = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(!pdata.cescape && (cp= *argv++))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!raw && (n=fmtvecho(cp,&pdata))>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(outfile,stakptr(staktell()),n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,cp,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(!pdata.cescape);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * modified version of stresc for generating formats
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char strformat(char *s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = t = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*s==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = chresc(s - 1, &p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c>UCHAR_MAX && mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t += wctomb(t, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '%';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '%';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 'Z';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t - b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *genformat(char *format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(preformat);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(format);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = (char*)stakfreeze(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strformat(fp+sizeof(preformat)-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *fmthtml(const char *string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp = string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c, offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *(unsigned char*)cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((s=mbsize(cp-1)) > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += (s-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='<')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("&lt;");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("&gt;");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("&amp;");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("&quot;");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("&apos;");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("&nbsp;");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!isprint(c) && c!='\n' && c!='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd,"&#%X;",CCMAPC(c,CC_NATIVE,CC_ASCII));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(stakptr(offset));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void *fmtbase64(char *string, ssize_t *sz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np = nv_open(string, NiL, NV_VARNAME|NV_NOASSIGN|NV_NOADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static union types_t number;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = nv_getnum(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_DOUBLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(Sfdouble_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.ld = d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_SHORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(float);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.f = (float)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(double);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.d = (double)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(Sflong_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.ll = (Sflong_t)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_SHORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.h = (short)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.i = (int)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sz = size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)&number);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_BINARY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_RAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_BINARY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_RAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((size = nv_size(np))==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = strlen(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sz = size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* lastchar = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int neg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t longmin = LDBL_LLONG_MIN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t longmax = LDBL_LLONG_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int format = fe->fmt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fold = fe->base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin union types_t* value = (union types_t*)v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct printf* pp = (struct printf*)fe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* argp = *pp->nextarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->flags |= SFFMT_VALUE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!argp || format=='Z')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->flags &= ~SFFMT_LONG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THROUGH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'H':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'P':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'R':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Z':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->base = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->flags &= ~SFFMT_LONG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'g':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'A':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'F':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'G':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(SFFMT_LDOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ld = 0.;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->d = 0.;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ip = &pp->intvar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'T':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 'd';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = tmxgettime();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!strchr("DdXxoUu",format))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_formspec,format);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 'd';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'p':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->p = (char**)strtol(argp,&lastchar,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(argp,sh.var_tree,NV_VARNAME|NV_NOASSIGN|NV_NOARRAY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (np->nvalue.lp = new_of(int32_t,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *np->nvalue.lp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sizeof(int)==sizeof(int32_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ip = (int*)np->nvalue.lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int32_t sl = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ip = (int*)(((char*)np->nvalue.lp) + (*((char*)&sl) ? 0 : sizeof(int)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'H':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'P':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'R':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(format=='s' && fe->base>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->p = pp->nextarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->nextarg = nullarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->base = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->flags &= ~SFFMT_LONG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fe->base >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->c = *argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->flags &= ~SFFMT_LONG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'x':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'X':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'U':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin longmax = LDBL_ULLONG_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '.':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fe->size==2 && strchr("bcsqHPRQTZ",*fe->form))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = ((unsigned char*)argp)[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'd':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'D':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(*argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\'':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '"':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = ((unsigned char*)argp)[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = sh_strnum(argp,&lastchar,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(d<longmin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_overflow,argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->err = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = longmin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(d>longmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_overflow,argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->err = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = longmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = (Sflong_t)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lastchar == *pp->nextarg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = *argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastchar = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(neg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = -value->ll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = sizeof(value->ll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'g':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'A':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'F':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'G':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = sh_strnum(*pp->nextarg,&lastchar,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(SFFMT_LDOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ld = d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = sizeof(value->ld);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->d = d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = sizeof(value->d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = (Sflong_t)strelapsed(*pp->nextarg,&lastchar,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'T':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = (Sflong_t)tmxdate(*pp->nextarg,&lastchar,TMX_NOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 'd';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = sizeof(value->ll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_formspec,format);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (format == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->i = value->ll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*lastchar)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_argtype,format);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->err = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->nextarg++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(format)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Z':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 'c';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->base = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=fmtvecho(value->s,pp))>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->nextarg == nullarg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->argsize = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = stakptr(staktell());
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = (char*)fmtbase64(value->s, &fe->size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'H':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = fmthtml(value->s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = sh_fmtqf(value->s, !!(fe->flags & SFFMT_ALTER), fold);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'P':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *s = fmtmatch(value->s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!s || *s==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_badregexp,value->s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'R':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = fmtre(value->s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*value->s==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_badregexp,value->s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fe->n_str>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 'd';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = sizeof(value->ll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = fmtelapsed(value->ll, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'T':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fe->n_str>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = fe->t_str[fe->n_str];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->t_str[fe->n_str] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = fmttmx(fe->t_str, value->ll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->t_str[fe->n_str] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else value->s = fmttmx(NIL(char*), value->ll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->fmt = 's';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fe->size = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * construct System V echo string out of <cp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If there are not escape sequences, returns -1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Otherwise, puts null terminated result on stack, but doesn't freeze it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns length of output.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int fmtvecho(const char *string, struct printf *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp = string, *cpmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int chlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((chlen = mbsize(cp)) > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Skip over multibyte characters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += chlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((c= *cp++)==0 || c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *cp++) && (c!='\\'));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = --cp - string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakwrite((void*)string,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(; c= *cp; cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mbwide() && ((chlen = mbsize(cp)) > 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakwrite(cp,chlen);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += (chlen-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( c=='\\') switch(*++cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ('a'==97?'\033':39); /* ASCII/EBCDIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\a';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\b';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->cescape++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->nextarg = nullarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\f';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\v';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 't':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\t';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '0':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cpmax = cp + 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(++cp<cpmax && *cp>='0' && *cp<='7')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c <<= 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= (*cp-'0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = staktell()-offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}