print.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
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* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * echo [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print [-nrps] [-f format] [-u filenum] [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * printf format [arg...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *genformat(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *options;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* nullarg[] = { 0, 0 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Need to handle write failures to avoid locking output pool
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int outexceptf(Sfio_t* iop, int mode, void* data, Sfdisc_t* dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==SF_WRITE && (errno!= EINTR || sh.trapnote))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_badwrite,sffileno(iop));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char bsd_univ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This mess is because /bin/echo on BSD is different */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *universe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(strcmp(argv[1],"-ne")==0 || strcmp(argv[1],"-en")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ECHOE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ECHOPRINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * argc==0 when called from echo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * argc==-1 when called from printf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* print to history file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(sh.inuse_bits&(1<<fd)) && (sh_inuse(fd) || (shp->hist_ptr && fd==sffileno(shp->hist_ptr->histfp))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The following is for backward compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special case test for -Rn */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors || (argc<0 && !(format = *argv++)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle special case of '-' operand for print */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc>0 && *argv && strcmp(*argv,"-")==0 && strcmp(argv[-1],"--"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't print error message for stdout for compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->sftable[fd] = outfile = sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fd,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* turn off share to guarantee atomic writes for printf */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* printf style print */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* echo style print */
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 register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * modified version of stresc for generating formats
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char strformat(char *s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = t = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t += wctomb(t, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '%';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '%';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t - b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *(unsigned char*)cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='<')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np = nv_open(string, NiL, NV_VARNAME|NV_NOASSIGN|NV_NOADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(float);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.f = (float)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(double);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.d = (double)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.h = (short)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number.i = (int)d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)&number);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int neg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THROUGH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(argp,sh.var_tree,NV_VARNAME|NV_NOASSIGN|NV_NOARRAY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sizeof(int)==sizeof(int32_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ip = (int*)(((char*)np->nvalue.lp) + (*((char*)&sl) ? 0 : sizeof(int)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\'':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = (Sflong_t)strelapsed(*pp->nextarg,&lastchar,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->ll = (Sflong_t)tmxdate(*pp->nextarg,&lastchar,TMX_NOW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value->s = sh_fmtqf(value->s, !!(fe->flags & SFFMT_ALTER), fold);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!s || *s==0)
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.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int fmtvecho(const char *string, struct printf *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Skip over multibyte characters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);