da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
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 * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define putenv ___putenv
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "lexstates.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "timeout.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/externs"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "streval.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define NVCACHE 8 /* must be a power of 2 */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define Empty ((char*)(e_sptbnl+3))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *savesub = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_lib_pathnative && _lib_uwin_path
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _lib_pathnative 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int uwin_path(const char*, char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpathnative(const char* path, char* buf, size_t siz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return uwin_path(path, buf, siz);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_pathnative */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void attstore(Namval_t*,void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef _ENV_H
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner static void pushnam(Namval_t*,void*);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner static char *staknam(Namval_t*, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ltou(char*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void utol(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void rightjust(char*, int, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *lastdot(char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct adata
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *tp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char **argnam;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int attsize;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *attval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct sh_type
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void *previous;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t **nodes;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *rp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short numnodes;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short maxnodes;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /*SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if NVCACHE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Namcache
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Cache_entry
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *root;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Dt_t *last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int flags;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short size;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short len;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin } entries[NVCACHE];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short index;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin short ok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static struct Namcache nvcache;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar nv_local = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef _ENV_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void(*nullscan)(Namval_t*,void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if ( SFIO_VERSION <= 20010201L )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define _data data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define mbchar(p) (*(unsigned char*)p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ======== name value pair routines ======== */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shnodes.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *getbuf(size_t len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static size_t buflen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buflen < len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buflen==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buf = (char*)malloc(len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buf = (char*)realloc(buf,len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buflen = len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _ENV_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_envput(Env_t* ep,Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namarr_t *ap = nv_arrayptr(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->nelem&ARRAY_UNDEF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,"0",0L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(val=nv_getsub(np)) || strcmp(val,"0"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(val = nv_getval(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('=');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(val);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_add(ep,stakptr(offset),ENV_STRDUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * output variable name in format for re-input
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_outname(Sfio_t *out, char *name, int len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *cp=name, *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c, offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sp= strchr(cp,'['))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len>0 && cp+len <= sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(out,cp,++sp-cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(c= *sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp=='[' || *sp==']' || *sp=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(out,sh_fmtq(stakptr(offset)),-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(out,']');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = sp-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(out,cp,len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(out,cp,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamval_t *nv_addnode(Namval_t* np, int remove)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct sh_type *sp = (struct sh_type*)sh.mktype;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int i;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *name=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp->numnodes==0 && !nv_isnull(np) && sh.last_table)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* could be an redefine */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *root = nv_dict(sh.last_table);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->rp = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,root,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_search(sp->rp->nvname,root,NV_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp->numnodes && memcmp(np->nvname,NV_CLASS,sizeof(NV_CLASS)-1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin name = (sp->nodes[0])->nvname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin i = strlen(name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(memcmp(np->nvname,name,i))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp->rp && sp->numnodes)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* check for a redefine */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(name && np->nvname[i]=='.' && np->nvname[i+1]=='_' && np->nvname[i+2]==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->rp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *root = nv_dict(sh.last_table);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(sp->nodes[0],root,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtinsert(root,sp->rp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_redef,sp->nodes[0]->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(i=0; i < sp->numnodes; i++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np == sp->nodes[i])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(remove)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(++i < sp->numnodes)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->nodes[i-1] = sp->nodes[i];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->numnodes--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(remove)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp->numnodes==sp->maxnodes)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->maxnodes += 20;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->nodes = (Namval_t**)realloc(sp->nodes,sizeof(Namval_t*)*sp->maxnodes);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->nodes[sp->numnodes++] = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * given a list of assignments, determine <name> is on the list
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin returns a pointer to the argnod on the list or NULL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstruct argnod *nv_onlist(struct argnod *arg, const char *name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int len = strlen(name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(;arg; arg=arg->argnxt.ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*arg->argval==0 && arg->argchn.ap && !(arg->argflag&~(ARG_APPEND|ARG_QUOTED|ARG_MESSAGE)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = ((struct fornod*)arg->argchn.ap)->fornam;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = arg->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(memcmp(cp,name,len)==0 && (cp[len]==0 || cp[len]=='='))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(arg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Perform parameter assignment for a linked list of parameters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <flags> contains attributes for the parameters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzvoid nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namval_t *np, *mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *trap=shp->st.trap[SH_DEBUGTRAP];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *prefix = shp->prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int traceon = (sh_isoption(SH_XTRACE)!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int array = (flags&(NV_ARRAY|NV_IARRAY));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namarr_t *ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Namref nr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int maketype = flags&NV_TYPE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct sh_type shtp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(maketype)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shtp.previous = shp->mktype;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->mktype=(void*)&shtp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shtp.numnodes=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shtp.maxnodes = 20;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shtp.rp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shtp.nodes =(Namval_t**)malloc(shtp.maxnodes*sizeof(Namval_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF*/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flags &= ~(NV_TYPE|NV_ARRAY|NV_IARRAY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_ALLEXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_EXPORT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~(NV_IDENT|NV_EXPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_VARNAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;arg; arg=arg->argnxt.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->used_pos = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(arg->argflag&ARG_MAC)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = sh_mactrim(shp,arg->argval,(flags&NV_NOREF)?-3:-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*arg->argval==0 && arg->argchn.ap && !(arg->argflag&~(ARG_APPEND|ARG_QUOTED|ARG_MESSAGE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flag = (NV_VARNAME|NV_ARRAY|NV_ASSIGN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int sub=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct fornod *fp=(struct fornod*)arg->argchn.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *tp=fp->fortre;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag |= (flags&(NV_NOSCOPE|NV_STATIC));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(arg->argflag&ARG_QUOTED)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = sh_mactrim(shp,fp->fornam,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fp->fornam;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.line = fp->fortyp-shp->st.firstline;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!array && tp->tre.tretyp!=TLST && tp->com.comset && !tp->com.comarg && tp->com.comset->argval[0]==0 && tp->com.comset->argval[1]=='[')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz array |= (tp->com.comset->argflag&ARG_MESSAGE)?NV_IARRAY:NV_ARRAY;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fn_depth && (Namval_t*)tp->com.comnamp==SYSTYPESET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= NV_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(prefix && tp->com.comset && *cp=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(prefix,shp->var_tree,flag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isvtree(np) && !nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = stakfreeze(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(cp,shp->var_tree,flag|NV_ASSIGN);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(typ && !array && (nv_isnull(np) || nv_isarray(np)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_settype(np,typ,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&NV_STATIC) && !nv_isnull(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto check_type;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(array && (!(ap=nv_arrayptr(np)) || !ap->hdr.type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(arg->argflag&ARG_APPEND))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(array&NV_ARRAY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setarray(np,nv_associative);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_ARRAY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(array && tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto check_type;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for array assignment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp->tre.tretyp!=TLST && tp->com.comarg && !tp->com.comset && !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int argc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *last_root = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char **argv = sh_argbuild(shp,&argc,&tp->com,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_root = last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->mktype && shp->dot_depth==0 && np==((struct sh_type*)shp->mktype)->nodes[0])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->mktype = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),"%s: not a known type name",argv[0]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(arg->argflag&ARG_APPEND))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isarray(np) || ((ap=nv_arrayptr(np)) && (ap->nelem&ARRAY_MASK)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setvec(np,(arg->argflag&ARG_APPEND),argc,argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon || trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *name = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(arg->argflag&ARG_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = '+';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,name,(char*)0,argv,(arg->argflag&ARG_APPEND)|ARG_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trace(NIL(char**),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,name,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr,"=( ",3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp= *argv++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,sh_fmtq(cp),' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr,")\n",2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto check_type;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((tp->tre.tretyp&COMMSK)==TFUN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp->tre.tretyp==TLST || !tp->com.comset || tp->com.comset->argval[0]!='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp->tre.tretyp!=TLST && !tp->com.comnamp && tp->com.comset && tp->com.comset->argval[0]==0 && tp->com.comset->argchn.ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(prefix)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = stakcopy(nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp->com.comset->argval[1]=='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((arg->argflag&ARG_APPEND) && (!nv_isarray(np) || (nv_aindex(np)>=0)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(array&NV_IARRAY) && !(tp->com.comset->argflag&ARG_MESSAGE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_setarray(np,nv_associative);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_setlist(tp->com.comset,flags,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp->com.comset->argval[1]!='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_setvtree(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_close(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto check_type;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp!='.' && *cp!='[' && strchr(cp,'['))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(cp,shp->var_tree,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(arg->argflag&ARG_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((sub=nv_aimax(np)) < 0 && nv_arrayptr(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_badappend,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sub>=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sub++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isnull(np) && np->nvalue.cp!=Empty && !nv_isvtree(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sub=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np->nvalue.cp && np->nvalue.cp!=Empty && !nv_type(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np,NV_EXPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(arg->argflag&ARG_APPEND))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np,NV_EXPORT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sh_isoption(SH_BASH) && !(array&NV_IARRAY) && !nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setarray(np,nv_associative);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin skip:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sub>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(stkstd,"%s[%d]",prefix?nv_name(np):cp,sub);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = stakfreeze(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,(char*)0,ARRAY_ADD|ARRAY_FILL|sub);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(prefix)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = stakcopy(nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->prefix)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*shp->prefix=='_' && shp->prefix[1]=='.' && nv_isref(L_ARGNOD))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(stkstd,"%s%s",nv_name(L_ARGNOD->nvalue.nrp->np),shp->prefix+1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->prefix = stkfreeze(stkstd,1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memset(&nr,0,sizeof(nr));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(&node,L_ARGNOD,sizeof(node));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz L_ARGNOD->nvalue.nrp = &nr;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nr.np = np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nr.root = shp->last_root;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nr.table = shp->last_table;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz L_ARGNOD->nvflag = NV_REF|NV_NOFREE;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz L_ARGNOD->nvfun = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec(tp,sh_isstate(SH_ERREXIT));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->prefix)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvalue.nrp = node.nvalue.nrp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvflag = node.nvflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvfun = node.nvfun;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np) && (mp=nv_opensub(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(tp->tre.tretyp==TLST)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!tp->lst.lstlef || !tp->lst.lstlef->tre.tretyp==TCOM || tp->lst.lstlef->com.comarg || tp->lst.lstlef->com.comset && tp->lst.lstlef->com.comset->argval[0]!='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tp = tp->lst.lstrit;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!nv_isarray(np) && !typ && (tp->com.comarg || !tp->com.comset || tp->com.comset->argval[0]!='['))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_setvtree(np);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(tp->com.comarg || tp->com.comset)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner np->nvfun->dsize = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto check_type;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = arg->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(cp,shp->var_tree,flags);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np->nvfun && (flags&NV_NOREF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->used_pos)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_PARAM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_PARAM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon || trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *sp=cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *name=nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sub=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int append = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sub = savesub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp=lastdot(sp,'='))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp[-1]=='+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin append = ARG_APPEND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trace(NIL(char**),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_outname(sfstderr,name,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"[%s]",sh_fmtq(sub));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(append)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstderr,'+');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"=%s\n",sh_fmtq(cp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *av[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[0] = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,name,sub,av,append);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin check_type:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(maketype)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_open(shtp.nodes[0]->nvname,shp->var_tree,NV_ASSIGN|NV_VARNAME|NV_NOADD|NV_NOFAIL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_mktype(shtp.nodes,shtp.numnodes);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)shtp.nodes);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->mktype = shtp.previous;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin maketype = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nr.np == np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvalue.nrp = node.nvalue.nrp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvflag = node.nvflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin L_ARGNOD->nvfun = node.nvfun;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy the subscript onto the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void stak_subscript(const char *sub, int last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('[');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *sub++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[' || c==']' || c=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('\\');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(last);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * construct a new name from a prefix and base name on the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *copystack(const char *prefix, register const char *name, const char *sub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int last=0,offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(prefix);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*stakptr(staktell()-1)=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(staktell()-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*name=='.' && name[1]=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = staktell()+2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*name!='[' && *name!='.' && *name!='=' && *name!='+')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakputc('.');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*name=='.' && (name[1]=='=' || name[1]==0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_checkid(stakptr(last),(char*)0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(staktell()-2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stak_subscript(sub,']');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(stakptr(offset));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * grow this stack string <name> by <n> bytes and move from cp-1 to end
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * right by <n>. Returns beginning of string on the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *stack_extend(const char *cname, char *cp, int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *name = (char*)cname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = name - stakptr(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m = cp-name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(strlen(name)+n+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = stakptr(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = name + m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = strlen(cp)+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(m-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[n+m]=cp[m];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp=(char*)name, *sp, *xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np=0, *nq=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *fp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long mode, add=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int copy=1,isref,top=0,noscope=(flags&NV_NOSCOPE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(root==shp->var_tree)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dtvnext(root))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin top = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!dp->disc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin copy = dp->nofree&1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(c = *(unsigned char*)(sp = cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '[':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_NOARRAY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->last = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_endsubscript((Namval_t*)0,sp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp==name || sp[-1]=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(sp = cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '.':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_IDENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(root==shp->var_tree)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_EXPORT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!copy && !(flags&NV_NOREF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = sp-name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copy = cp-name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->nofree |= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = copystack((const char*)0, name,(const char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)name+copy;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (char*)name+c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '+':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin isref = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->last = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = (c=='.' || (flags&NV_NOADD))?add:NV_ADD;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&NV_NOSCOPE) && c!='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode |= HASH_NOSCOPE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(top)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Ufunction *rp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((rp=shp->st.real_fun) && !rp->sdict && (flags&NV_STATIC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *dp = dtview(shp->var_tree,(Dt_t*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rp->sdict = dtopen(&_Nvdisc,Dtoset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(rp->sdict,shp->var_base);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(shp->var_tree,rp->sdict);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np = nv_search(name,shp->var_tree,0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->var_tree->walk == shp->var_base)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nq = np;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if((flags&NV_NOSCOPE) && *cp!='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin root = shp->var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,(Dt_t*)0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin root = shp->var_tree->walk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flags |= NV_NOSCOPE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin noscope = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rp && rp->sdict && (flags&NV_STATIC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin root = rp->sdict;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np && shp->var_tree->walk==shp->var_tree)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,shp->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np || shp->var_tree->walk!=root)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_search(name,root,HASH_NOSCOPE|NV_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np || (np = nv_search(name,root,mode)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin isref = nv_isref(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(top)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq==np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_NOSCOPE;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz root = shp->var_base;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isnull(np) && c!='.' && (np->nvfun=nv_cover(nq)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvname = nq->nvname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(add && nv_isnull(np) && c=='.' && cp[1]!='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setvtree(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin top = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sub=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if NVCACHE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nvcache.ok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.') /* don't optimize */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if((flags&NV_NOREF) && (c!='[' && *cp!='.'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c && !(flags&NV_NOADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unref(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(nv_isref(np) && np->nvalue.cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = nv_reftree(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_root = root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = nv_reftable(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sub = nv_refsub(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_refnode(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sub && c!='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,sub,0L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_NOSCOPE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin noscope = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isref(np) && (c=='[' || c=='.' || !(flags&NV_ASSIGN)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_noref,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sub && c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==nq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~(noscope?0:NV_NOSCOPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (cp-sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copy = strlen(cp=nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->nofree |= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = copystack(cp,sp,sub);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (char*)name + copy;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sp+c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!noscope)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_NOREF;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_isnull(np))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_onattr(np,NV_NOFREE);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_root = root;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(*cp && cp[1]=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='.' && (cp[1]==0 || cp[1]=='=' || cp[1]=='+'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_local = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp[-1]=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nq && *sp=='[' && *cp==0 && cp[-1]==']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * for backward compatibility
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * evaluate subscript for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * possible side effects
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_arith(sp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = ']';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[' || (c=='.' && nv_isarray(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *sub=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz mode &= ~HASH_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namarr_t *ap = nv_arrayptr(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int scan = ap?(ap->nelem&ARRAY_SCAN):0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = mode|nv_isarray(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mode && (flags&NV_ARRAY) && ((c=sp[1])=='*' || c=='@') && sp[2]==']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* not implemented yet */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->last = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n&NV_ADD)&&(flags&NV_ARRAY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= ARRAY_FILL;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_ASSIGN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n |= NV_ADD;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = nv_endsubscript(np,sp,n|(flags&NV_ASSIGN));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(scan)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putsub(np,NIL(char*),ARRAY_SCAN);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((c = *cp)=='.' || (c=='[' && nv_isarray(np)) || (n&ARRAY_FILL) || (flags&NV_ARRAY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m = cp-sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sub = m?nv_getsub(np):0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(m && !(n&NV_ADD))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sub = "0";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(sub)+2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!copy)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copy = cp-name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->nofree |= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = copystack((const char*)0, name,(const char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)name+copy;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = cp-m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n <= m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(sp+1,sub,n-2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp[n-1] = ']';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n < m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp=strcpy(sp+n,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r = n-m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = sp-name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = stack_extend(name, cp-1, r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (char*)name + m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp = '[';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(sp+1,sub,n-2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp[n-1] = ']';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sp+n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==0 && mode && (n=nv_aindex(np))>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,(char*)0,n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n==0 && (c==0 || (c=='[' && !nv_isarray(np))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* subscript must be 0*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = sh_arith(sp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = ']';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->last = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np) && (c=='[' || c=='.' || (flags&NV_ARRAY)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(nq = nv_opensub(np)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namarr_t *ap = nv_arrayptr(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sub && (flags&NV_NOADD))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = mode|((flags&NV_NOADD)?0:NV_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!ap && (n&NV_ADD))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,sub,ARRAY_FILL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = nv_arrayptr(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n && ap && !ap->table)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->table = dtopen(&_Nvdisc,Dtoset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap && ap->table && (nq=nv_search(sub,ap->table,n)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nq->nvenv = (char*)np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nq && nv_isnull(nq))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nq = nv_arraychild(np,nq,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='.' && !nv_isvtree(nq))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_NOADD)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_setvtree(nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(memcmp(cp,"[0]",3))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* ignore [0] */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->last = cp += 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==0 && (flags&NV_MOVE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),ARRAY_UNDEF);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.' && (fp=np->nvfun))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(; fp; fp=fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc && fp->disc->createf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((nq = (*fp->disc->createf)(np,cp+1,flags,fp)) == np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin add = NV_ADD;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->last_table = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np=nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((c = *(sp=cp=dp->last=fp->last))==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np) && sp[-1]!=']')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,NIL(char*),ARRAY_UNDEF);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c=='[');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c!='.' || cp[1]=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->last = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c = mbchar(cp)) && !isaletter(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(xp=cp, c=mbchar(cp), isaname(c));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * delete the node <np> from the dictionary <root> and clear from the cache
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if <root> is NULL, only the cache is cleared
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if flags does not contain NV_NOFREE, the node is freed
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid nv_delete(Namval_t* np, Dt_t *root, int flags)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if NVCACHE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Cache_entry *xp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(c=0,xp=nvcache.entries ; c < NVCACHE; xp= &nvcache.entries[++c])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(xp->np==np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->root = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(root)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(dtdelete(root,np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sfstderr,"%s not deleted\n",nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync(sfstderr);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Put <arg> into associative memory.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_ARRAY then follow array to next subscript
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOARRAY then subscript is not allowed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOSCOPE then use the current scope only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_ASSIGN then assignment is allowed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_IDENT then name must be an identifier
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_VARNAME then name must be a valid variable name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOADD then node will not be added if not found
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOREF then don't follow reference
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOFAIL then don't generate an error message on failure
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * If <flags> & NV_STATIC then unset before an assignment
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * If <flags> & NV_UNJUST then unset attributes before assignment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * SH_INIT is only set while initializing the environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_open(const char *name, Dt_t *root, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp=(char*)name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int append=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *msg = e_varname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *fname = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *funroot;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if NVCACHE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Cache_entry *xp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_NVOPEN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&fun,0,sizeof(fun));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = shp->namespace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!root)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin root = shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_root = root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(root==shp->fun_tree)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_NOREF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = e_badfun;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((np=shp->namespace) || strchr(name,'.'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = cp = copystack(np?nv_name(np):0,name,(const char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fname = strrchr(cp,'.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fname = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fun.nofree |= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_IDENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin funroot = root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin root = shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(flags&(NV_IDENT|NV_VARNAME|NV_ASSIGN)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long mode = ((flags&NV_NOADD)?0:NV_ADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_NOSCOPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode |= HASH_SCOPE|HASH_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_search(name,root,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np && !(flags&NV_REF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = nv_reftable(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_refnode(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(shp->prefix && (flags&NV_ASSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin name = cp = copystack(shp->prefix,name,(const char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fun.nofree |= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(root==shp->alias_tree)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = e_aliname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *(unsigned char*)cp++) && (c!='=') && (c!='/') &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (c>=0x200 || !(c=sh_lexstates[ST_NORM][c]) || c==S_EPAT || c==S_COLON));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell && c=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = sh_subaliastree(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c= *--cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_search(name, root, (flags&NV_NOADD)?0:NV_ADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_IDENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = e_ident;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *++cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= NV_NOREF;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(root==shp->var_tree)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin root = shp->var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c= !isaletter(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if NVCACHE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(c=0,xp=nvcache.entries ; c < NVCACHE; xp= &nvcache.entries[++c])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(xp->root!=root)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*name==*xp->name && (flags&(NV_ARRAY|NV_NOSCOPE))==xp->flags && memcmp(xp->name,name,xp->len)==0 && (name[xp->len]==0 || name[xp->len]=='=' || name[xp->len]=='+'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_NVHITS);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = xp->np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = (char*)name+xp->len;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,NIL(char*),ARRAY_UNDEF);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = xp->last_table;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->last_root = xp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto nocache;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nvcache.ok = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_create(name, root, flags, &fun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fun.last;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if NVCACHE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np && nvcache.ok && cp[-1]!=']')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp = &nvcache.entries[nvcache.index];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *sp = strchr(name,*cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto nocache;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->len = sp-name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->len = strlen(name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = roundof(xp->len+1,32);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c > xp->size)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(xp->size==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->name = malloc(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->name = realloc(xp->name,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->size = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(xp->name,name,xp->len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->name[xp->len] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->root = root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->np = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->last_table = shp->last_table;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz xp->last_root = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp->flags = (flags&(NV_ARRAY|NV_NOSCOPE));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nvcache.index = (nvcache.index+1)&(NVCACHE-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinnocache:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nvcache.ok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ((flags&NV_NOSCOPE)?HASH_NOSCOPE:0)|((flags&NV_NOADD)?0:NV_ADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fname = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_search(name, funroot, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fname = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*cp=='.' && cp[1]=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin append |= NV_NODISC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp+=2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*cp=='+' && cp[1]=='=')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin append |= NV_APPEND;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinskip:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np && shp->mktype)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_addnode(np,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='=' && np && (flags&NV_ASSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_INIT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, cp, NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==PWDNOD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_TAGGED);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *sub=0, *prefix= shp->prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int isref;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&NV_STATIC) && !shp->mktype)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isnull(np))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->prefix = prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin isref = nv_isref(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_XTRACE) && nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sub = nv_getsub(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = msg==e_aliname? 0: (append | (flags&NV_EXPORT));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(isref)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(np,NV_REF);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!append && (flags&NV_UNJUST))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_offattr(np,NV_LJUST|NV_RJUST|NV_ZFILL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np->nvsize = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, cp, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(isref)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_search((char*)np,shp->var_base,HASH_BUCKET))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->last_root = shp->var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_setref(np,(Dt_t*)0,NV_VARNAME);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savesub = sub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np, flags&NV_ATTRIBUTES);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_NOFAIL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = e_noparent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = e_noarray;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),msg,name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fun.nofree&1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int ja_size(char*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static void ja_restore(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *savep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char savechars[8+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put value <string> into name-value node <np>.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <np> is an array, then the element given by the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * current index is assigned to.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> contains NV_RDONLY, readonly attribute is ignored
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> contains NV_INTEGER, string is a pointer to a number
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> contains NV_NOFREE, previous value is freed, and <string>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * becomes value of node and <flags> becomes attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_putval(register Namval_t *np, const char *string, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *sp=string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register union Value *up;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int dot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_local = nv_local;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin union Value u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flags&NV_RDONLY) && nv_isattr (np, NV_RDONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The following could cause the shell to fork if assignment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * would cause a side effect
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.subshell && !nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = sh_assignok(np,1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np->nvfun && np->nvfun->disc && !(flags&NV_NODISC) && !nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This function contains disc */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,sp,flags,np->nvfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp && ((flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_envput(sh.env,np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* called from disc, assign the actual value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_NODISC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&(NV_NOREF|NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np->nvalue.cp && np->nvalue.cp!=sp && !nv_isattr(np,NV_NOFREE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)np->nvalue.cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = (char*)sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setattr(np,(flags&~NV_RDONLY)|NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up= &np->nvalue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INT16P) == NV_INT16)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np->nvalue.up || !nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin up = &u;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin up->up = &np->nvalue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np->nvalue.up && nv_isarray(np) && nv_arrayptr(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin up = np->nvalue.up;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(up && up->cp==Empty)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin up->cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_IMPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr (np, NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np, NV_DOUBLE) == NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG) && sizeof(double)<sizeof(Sfdouble_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t ld, old=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ld = *((Sfdouble_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ld = *((float*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ld = *((double*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ld = sh_arith(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!up->ldp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->ldp = new_of(Sfdouble_t,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = *(up->ldp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *(up->ldp) = old?ld+old:ld;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double d,od=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (double)(*(Sfdouble_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (double)(*(float*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = *(double*)sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = sh_arith(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!up->dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->dp = new_of(double,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin od = *(up->dp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *(up->dp) = od?d+od:d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG) && sizeof(int32_t)<sizeof(Sflong_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sflong_t ll=0,oll=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&NV_DOUBLE) == NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((Sfdouble_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((float*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((double*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_UNSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((Sfulong_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((uint16_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((uint32_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((Sflong_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((uint16_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((uint32_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = (Sflong_t)sh_arith(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!up->llp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->llp = new_of(Sflong_t,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oll = *(up->llp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(up->llp) = ll+oll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int32_t l=0,ol=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&NV_DOUBLE) == NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sflong_t ll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((Sfdouble_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((float*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *((double*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = (int32_t)ll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_UNSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = *((Sfulong_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = *((uint16_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = *(uint32_t*)sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = *((Sflong_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_SHORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = *((int16_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = *(int32_t*)sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t ld = sh_arith(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ld<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = (int32_t)ld;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = (uint32_t)ld;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_size(np) <= 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr (np, NV_SHORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int16_t s=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_APPEND)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s = *up->sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *(up->sp) = s+(int16_t)l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!up->lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->lp = new_of(int32_t,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ol = *(up->lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(up->lp) = l+ol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *tofree=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_pathnative
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buff[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_pathnative */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags&NV_DOUBLE)==NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_LONG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"%.*Lg",LDBL_DIG,*((Sfdouble_t*)sp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"%.*g",DBL_DIG,*((double*)sp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(flags&NV_UNSIGN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_LONG)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%I*lu",sizeof(Sfulong_t),*((Sfulong_t*)sp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%lu",(unsigned long)((flags&NV_SHORT)?*((uint16_t*)sp):*((uint32_t*)sp)));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_LONG)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%I*ld",sizeof(Sflong_t),*((Sflong_t*)sp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%ld",(long)((flags&NV_SHORT)?*((int16_t*)sp):*((int32_t*)sp)));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfstruse(sh.strbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np, NV_HOST|NV_INTEGER)==NV_HOST && sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _lib_pathnative
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the host file name given the UNIX name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathnative(sp,buff,sizeof(buff));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff[1]==':' && buff[2]=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buff[2] = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*buff>='A' && *buff<='Z')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *buff += 'a'-'A';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_pathnative */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((nv_isattr(np, NV_RJUST|NV_ZFILL|NV_LJUST)) && sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;*sp == ' '|| *sp=='\t';sp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((nv_isattr(np,NV_ZFILL)) && (nv_isattr(np,NV_LJUST)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;*sp=='0';sp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = nv_size(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = ja_size((char*)sp,size,nv_isattr(np,NV_RJUST|NV_ZFILL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!up->cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_APPEND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flags&NV_APPEND) && !nv_isattr(np,NV_BINARY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(up->cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = stakptr(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np, NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* delay free in case <sp> points into free region */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tofree = up->cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_BINARY) && !(flags&NV_RAW))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tofree = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(nv_isattr(np,NV_LJUST|NV_RJUST) && nv_isattr(np,NV_LJUST|NV_RJUST)!=(NV_LJUST|NV_RJUST))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tofree = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dot = strlen(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if (_AST_VERSION>=20030127L)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_BINARY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oldsize = (flags&NV_APPEND)?nv_size(np):0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_RAW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tofree)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)tofree);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(np,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->cp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_ZFILL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = nv_size(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = oldsize + (3*dot/4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)malloc(size+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(np,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(oldsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)cp,(void*)up->cp,oldsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->cp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size <= oldsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dot = base64decode(sp,dot, (void**)0, cp+oldsize, size-oldsize,(void**)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dot += oldsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_ZFILL) || nv_size(np)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_ZFILL) && (size>dot))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset((void*)&cp[dot],0,size-dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(size==0 && nv_isattr(np,NV_HOST)!=NV_HOST &&nv_isattr(np,NV_LJUST|NV_RJUST|NV_ZFILL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,size=dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(size > dot)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dot = size;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(nv_isattr(np,NV_LJUST|NV_RJUST)==NV_LJUST && dot>size)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dot = size;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(size==0 || tofree || !(cp=(char*)up->cp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = (char*)malloc(((unsigned)dot+1));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp[dot] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(np,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->cp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int c = cp[dot];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(cp,sp,dot);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp[dot]=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LTOU))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ltou(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr (np, NV_UTOL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin utol(cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp[dot] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_RJUST) && nv_isattr(np, NV_ZFILL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rightjust(cp,size,'0');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(nv_isattr(np, NV_LJUST|NV_RJUST)==NV_RJUST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rightjust(cp,size,' ');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(nv_isattr(np, NV_LJUST|NV_RJUST)==NV_LJUST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = strlen (cp) + cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = cp+size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; dp < cp; *dp++ = ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore original string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(savep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ja_restore();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tofree && tofree!=Empty)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)tofree);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!was_local && ((flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_envput(sh.env,np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Right-justify <str> so that it contains no more than
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <size> characters. If <str> contains fewer than <size>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * characters, left-pad with <fill>. Trailing blanks
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * in <str> will be ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If the leftmost digit in <str> is not a digit, <fill>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * will default to a blank.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void rightjust(char *str, int size, int fill)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp,*sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ignore trailing blanks */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(cp=str+n;n && *--cp == ' ';n--);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n > size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(str+n) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (sp = str, cp = str+n-size; sp <= str+size; *sp++ = *cp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else *(sp = str+size) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (sp > str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--sp = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp = *cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!isdigit(*str))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fill = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sp>str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--sp = fill;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * handle left and right justified fields for multi-byte chars
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * given physical size, return a logical size which reflects the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * screen width of multi-byte characters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Multi-width characters replaced by spaces if they cross the boundary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <type> is non-zero for right justified fields
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int ja_size(char *str,int size,int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c, n=size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int outsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *oldcp=cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oldn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wchar_t w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldn = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = mbchar(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outsize = mbwidth(w);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size -= outsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = cp-oldcp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n += (c-outsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldcp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size<=0 && type==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for right justified fields that need truncating */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size <0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* left justified and character crosses field boundary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = oldn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save boundary char and replace with spaces */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savechars[size] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(size--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savechars[size] = cp[size];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[size] = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savep = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = -size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= (ja_size(str,size,0)-size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static void ja_restore(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = savechars;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *savep++ = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef _ENV_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *staknam(register Namval_t *np, char *value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *p,*q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = stakalloc(strlen(nv_name(np))+(value?strlen(value):0)+2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p=strcopy(q,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(p,value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(q);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put the name and attribute into value of attributes variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _ENV_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void attstore(register Namval_t *np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag, c = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(nv_isattr(np,NV_EXPORT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = nv_isattr(np,NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('=');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flag&NV_DOUBLE) == NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* export doubles as integers for ksh88 compatibility */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakputc(c+NV_INTEGER|(flag&~(NV_DOUBLE|NV_EXPNOTE)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c+flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c += nv_size(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void attstore(register Namval_t *np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag = np->nvflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct adata *ap = (struct adata*)data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->tp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flag&NV_EXPORT) || (flag&NV_FUNCT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= (NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->attval++ = '=';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flag&NV_DOUBLE) == NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* export doubles as integers for ksh88 compatibility */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *ap->attval++ = ' '+ NV_INTEGER|(flag&~(NV_DOUBLE|NV_EXPNOTE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->attval = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->attval++ = ' '+flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->attval = ' ' + nv_size(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->attval = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->attval = strcopy(++ap->attval,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef _ENV_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void pushnam(Namval_t *np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct adata *ap = (struct adata*)data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->tp = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(nv_isattr(np,NV_IMPORT) && np->nvenv)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner *ap->argnam++ = np->nvenv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(value=nv_getval(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->argnam++ = staknam(np,value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->attsize += (strlen(nv_name(np))+4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Generate the environment list for the child.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _ENV_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar **sh_envgen(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset,tell;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **er;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_delete(sh.env,"_");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin er = env_get(sh.env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(e_envmarker);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tell = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_scan(sh.var_tree, attstore,(void*)0,0,(NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tell ==staktell())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--er = stakfreeze(1)+offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(er);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar **sh_envgen(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **er;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int namec;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct adata data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = sh_getinterp();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data.sh = shp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data.tp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* L_ARGNOD gets generated automatically as full path name of command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(L_ARGNOD,NV_EXPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin data.attsize = 6;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin namec = nv_scan(shp->var_tree,nullscan,(void*)0,NV_EXPORT,NV_EXPORT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin namec += shp->nenv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin er = (char**)stakalloc((namec+4)*sizeof(char*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin data.argnam = (er+=2) + shp->nenv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->nenv)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy((void*)er,environ,shp->nenv*sizeof(char*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree, pushnam,&data,NV_EXPORT, NV_EXPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *data.argnam = (char*)stakalloc(data.attsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = data.attval = strcopy(*data.argnam,e_envmarker);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree, attstore,&data,0,(NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *data.attval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp!=data.attval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin data.argnam++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *data.argnam = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(er);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct scan
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void (*scanfn)(Namval_t*, void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int scanmask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int scanflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int scancount;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *scandata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int scanfilter(Dt_t *dict, void *arg, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np = (Namval_t*)arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int k=np->nvflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct scan *sp = (struct scan*)data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct adata *tp = (struct adata*)sp->scandata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(dict);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!is_abuiltin(np) && tp && tp->tp && nv_type(np)!=tp->tp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /*SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp->scanmask?(k&sp->scanmask)==sp->scanflags:(!sp->scanflags || (k&sp->scanflags)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np->nvalue.cp && !np->nvfun && !nv_isattr(np,~NV_DEFAULT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp->scanfn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),0L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*sp->scanfn)(np,sp->scandata);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp->scancount++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Walk through the name-value pairs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <mask> is non-zero, then only nodes with (nvflags&mask)==flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * are visited
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mask> is zero, and <flags> non-zero, then nodes with one or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * more of <flags> is visited
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mask> and <flags> are zero, then all nodes are visted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_scan(Dt_t *root, void (*fn)(Namval_t*,void*), void *data,int mask, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *base=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct scan sdata;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int (*hashfn)(Dt_t*, void*, void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sdata.scanmask = mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sdata.scanflags = flags&~NV_NOSCOPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sdata.scanfn = fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sdata.scancount = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sdata.scandata = data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashfn = scanfilter;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_NOSCOPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = dtview((Dt_t*)root,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtwalk(root, hashfn,&sdata);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtview((Dt_t*)root,base);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sdata.scancount);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create a new environment scope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_scope(Shell_t *shp, struct argnod *envlist, int fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Dt_t *newscope, *newroot=shp->var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Ufunction *rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newscope = dtopen(&_Nvdisc,Dtoset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(envlist)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(newscope,(Dt_t*)shp->var_tree);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = newscope;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_setlist(envlist,NV_EXPORT|NV_NOSCOPE|NV_IDENT|NV_ASSIGN,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!fun)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = dtview(newscope,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((rp=shp->st.real_fun) && rp->sdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(rp->sdict,newroot);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin newroot = rp->sdict;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtview(newscope,(Dt_t*)newroot);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree = newscope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Remove freeable local space associated with the nvalue field
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * of nnod. This includes any strings representing the value(s) of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * node, as well as its dope vector, if it is an array.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_envnolocal (register Namval_t *np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(data);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np==VERSIONNOD && nv_isref(np))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np==L_ARGNOD)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_EXPORT) && nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp = nv_getval(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = strdup(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_EXPORT|NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_isref(np) && np!=VERSIONNOD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_NOFREE|NV_REF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)np->nvalue.nrp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),ARRAY_UNDEF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _nv_unset(np,NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setattr(np,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np,cp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Currently this is a dummy, but someday will be needed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * for reference counting
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_close(Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void table_unset(Shell_t *shp, register Dt_t *root, int flags, Dt_t *oroot)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namval_t *np,*nq, *npnext;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(np=(Namval_t*)dtfirst(root);np;np=npnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isref(np))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz free((void*)np->nvalue.nrp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np->nvalue.cp = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np->nvflag = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nq=dtsearch(oroot,np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_cover(nq))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int subshell = shp->subshell;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->subshell = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(nq, NV_INTEGER))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sfdouble_t d = nv_getnum(nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(nq,(char*)&d,NV_LDOUBLE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(shp->test&4)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putval(nq, strdup(nv_getval(nq)), NV_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(nq, nv_getval(nq), NV_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->subshell = subshell;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvfun = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(nq,NV_EXPORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_envput(shp->env,nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin npnext = (Namval_t*)dtnext(root,np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_root = root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isvtree(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int len = strlen(np->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((nq=npnext) && memcmp(np->nvname,nq->nvname,len)==0 && nq->nvname[len]=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin npnext = (Namval_t*)dtnext(root,nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(nq,flags);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(nq,root,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _nv_unset(np,flags);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,root,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set the value of <np> to 0, and nullify any attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * that <np> may have had. Free any freeable space occupied
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * by the value of <np>. If <np> denotes an array member, it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * will retain its attributes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <flags> can contain NV_RDONLY to override the readonly attribute
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * being cleared.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * <flags> can contain NV_EXPORT to override preserve nvenv
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid _nv_unset(register Namval_t *np,int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register union Value *up;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flags&NV_RDONLY) && nv_isattr (np,NV_RDONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_afunction(np) && np->nvalue.ip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct slnod *slp = (struct slnod*)(np->nvenv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(slp && !nv_isattr(np,NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Ufunction *rq,*rp = np->nvalue.rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* free function definition */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *name=nv_name(np),*cp= strrchr(name,'.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *npv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin npv = nv_open(name,shp->var_tree,NV_NOARRAY|NV_VARNAME|NV_NOADD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(npv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setdisc(npv,cp,NIL(Namval_t*),(Namfun_t*)npv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rp->fname && shp->fpathdict && (rq = (struct Ufunction*)nv_search(rp->fname,shp->fpathdict,0)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rq->np != np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtdelete(shp->fpathdict,rq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(rq = (struct Ufunction*)dtnext(shp->fpathdict,rq));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rp->sdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *mp, *nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(mp=(Namval_t*)dtfirst(rp->sdict);mp;mp=nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nq = dtnext(rp->sdict,mp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(mp,NV_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(mp,rp->sdict,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dtclose(rp->sdict);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakdelete(slp->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)np->nvalue.ip);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.ip = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell && !nv_isnull(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = sh_assignok(np,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_NODISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np->nvfun && !nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This function contains disc */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,NIL(char*),flags,np->nvfun);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* called from disc, assign the actual value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_isattr(np,NV_INT16P) == NV_INT16)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np->nvalue.cp = nv_isarray(np)?Empty:0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto done;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np) && np->nvalue.cp!=Empty && np->nvfun)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin up = np->nvalue.up;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin up = &np->nvalue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(up && up->cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(up->cp!=Empty && !nv_isattr(np, NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)up->cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up->cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isarray(np) || !nv_arrayptr(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isref(np) && !nv_isattr(np,NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)np->nvalue.nrp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_MINIMAL) || nv_isattr(np,NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_EXPORT) && !strchr(np->nvname,'['))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin env_delete(shp->env,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flags&NV_EXPORT) || nv_isattr(np,NV_IMPORT|NV_EXPORT)==(NV_IMPORT|NV_EXPORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvenv = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setattr(np,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setattr(np,NV_MINIMAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,(Dt_t*)0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the node pointer in the highest level scope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamval_t *sh_scoped(Shell_t *shp, register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!dtvnext(shp->var_tree))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(dtsearch(shp->var_tree,np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return space separated list of names of variables in given tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *tableval(Dt_t *root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static Sfio_t *out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int first=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *base = dtview(root,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(out)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(out,(Sfoff_t)0,SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = sfnew((Sfio_t*)0,(char*)0,-1,-1,SF_WRITE|SF_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(np=(Namval_t*)dtfirst(root);np;np=(Namval_t*)dtnext(root,np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(out,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(out,np->nvname,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(out,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtview(root,base);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)out->_data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct optimize
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t hdr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct optimize *next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct optimize *opt_free;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void optimize_clear(Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct optimize *op = (struct optimize*)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,(Namfun_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;op && op->np==np; op=op->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(op->ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *op->ptr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->ptr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_optimize(Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin optimize_clear(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namfun_t *clone_optimize(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((Namfun_t*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t optimize_disc = {sizeof(struct optimize),put_optimize,0,0,0,0,clone_optimize};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_optimize(Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct optimize *op, *xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np==SH_LINENO)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.argaddr = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(fp=np->nvfun; fp; fp = fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp->disc && (fp->disc->getnum || fp->disc->getval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc== &optimize_disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((xp= (struct optimize*)fp) && xp->ptr==sh.argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(op = opt_free)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_free = op->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op=(struct optimize*)calloc(1,sizeof(struct optimize));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->ptr = sh.argaddr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->np = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->hdr.disc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->next = xp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp->next = op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->hdr.disc = &optimize_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->next = (struct optimize*)sh.optlist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.optlist = (void*)op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,&op->hdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_optclear(Shell_t *shp, void *old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct optimize *op,*opnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(op=(struct optimize*)shp->optlist; op; op = opnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opnext = op->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(op->ptr && op->hdr.disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(op->np,&op->hdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(op->np,(Namfun_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op->next = opt_free;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_free = op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->optlist = old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define optimize_clear(np,fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Return a pointer to a character string that denotes the value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * of <np>. If <np> refers to an array, return a pointer to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the value associated with the current index.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If the value of <np> is an integer, the string returned will
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * be overwritten by the next call to nv_getval.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <np> has no value, 0 is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *nv_getval(register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register union Value *up= &np->nvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int numeric;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_local && sh.argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_optimize(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((!np->nvfun || !np->nvfun->disc) && !nv_isattr(np,NV_ARRAY|NV_INTEGER|NV_FUNCT|NV_REF|NV_TABLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np->nvalue.cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.last_table = nv_reftable(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_name(nv_refnode(np)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np->nvfun && np->nvfun->disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_getv(np, np->nvfun));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin numeric = ((nv_isattr (np, NV_INTEGER)) != 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(numeric)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sflong_t ll;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!up->cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("0");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr (np,NV_DOUBLE)==NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t ld;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *format;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ld = *up->ldp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr (np,NV_EXPNOTE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = "%.*Lg";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(nv_isattr (np,NV_HEXFLOAT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin format = "%.*La";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = "%.*Lf";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,format,nv_size(np),ld);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = *up->dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr (np,NV_EXPNOTE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = "%.*g";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(nv_isattr (np,NV_HEXFLOAT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin format = "%.*a";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin format = "%.*f";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,format,nv_size(np),d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfstruse(sh.strbuf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_UNSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr (np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *(Sfulong_t*)up->llp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr (np,NV_SHORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INT16P)==NV_INT16P)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ll = *(uint16_t*)(up->sp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ll = (uint16_t)up->s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *(uint32_t*)(up->lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr (np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *up->llp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr (np,NV_SHORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INT16P)==NV_INT16P)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ll = *up->sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ll = up->s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ll = *(up->lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((numeric=nv_size(np))==10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_UNSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"%I*u",sizeof(ll),ll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfstruse(sh.strbuf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin numeric = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fmtbasell(ll,numeric, numeric&&numeric!=10));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if (_AST_VERSION>=20030127L)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if NV_RAW flag is on, return pointer to binary data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise, base64 encode the data and return this string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(up->cp && nv_isattr(np,NV_BINARY) && !nv_isattr(np,NV_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char *ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int size= nv_size(np), insize=(4*size)/3+size/45+8;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner base64encode(up->cp, size, (void**)0, cp=getbuf(insize), insize, (void**)&ep);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner *ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((numeric=nv_size(np)) && up->cp && up->cp[numeric])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp = getbuf(numeric+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(cp,up->cp,numeric);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[numeric]=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ((char*)up->cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t nv_getnum(register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register union Value *up;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfdouble_t r=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_local && sh.argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_optimize(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_istable(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_number,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np->nvfun && np->nvfun->disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_getn(np, np->nvfun));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isref(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin str = nv_refsub(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_refnode(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(str)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,str,0L);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr (np, NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin up= &np->nvalue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!up->lp || up->cp==Empty)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(nv_isattr(np, NV_DOUBLE)==NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = *up->ldp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = *up->dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np, NV_UNSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = (Sflong_t)*((Sfulong_t*)up->llp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np, NV_SHORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INT16P)==NV_INT16P)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = (Sflong_t)(*(uint16_t*)up->sp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = (Sflong_t)((uint16_t)up->s);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = *((uint32_t*)up->lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = *up->llp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np, NV_SHORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INT16P)==NV_INT16P)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = *up->sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = up->s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = *up->lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((str=nv_getval(np)) && *str!=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np->nvfun || nv_isattr(np,NV_LJUST|NV_RJUST|NV_ZFILL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*str=='0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = sh_arith(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Give <np> the attributes <newatts,> and change its current
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value to conform to <newatts>. The <size> of left and right
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * justified fields may be given.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_newattr (register Namval_t *np, unsigned newatts, int size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namarr_t *ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oldsize,oldatts;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namfun_t *fp= (newatts&NV_NODISC)?np->nvfun:0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *prefix = sh.prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin newatts &= ~NV_NODISC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for restrictions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED) && ((sp=nv_name(np))==nv_name(PATHNOD) || sp==nv_name(SHELLNOD) || sp==nv_name(ENVNOD) || sp==nv_name(FPATHNOD)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle attributes that do not change data separately */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = np->nvflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(newatts&NV_EXPORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_IMPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(((n^newatts)&NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* record changes to the environment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n&NV_EXPORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env_delete(sh.env,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_envput(sh.env,np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz oldsize = nv_size(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((size==oldsize|| (n&NV_INTEGER)) && ((n^newatts)&~NV_NOCHANGE)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np, ~NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np, newatts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* for an array, change all the elements */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((ap=nv_arrayptr(np)) && ap->nelem>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),ARRAY_SCAN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldsize = nv_size(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldatts = np->nvflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvfun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap) /* add element to prevent array deletion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nelem++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,oldsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvflag = oldatts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp = nv_getval(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_ZFILL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*sp=='0') sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)malloc((n=strlen (sp)) + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(cp, sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nelem &= ~ARRAY_SCAN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp=nv_opensub(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(mp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvalue.cp = Empty;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nelem |= ARRAY_SCAN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(np);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(size==0 && (newatts&NV_HOST)!=NV_HOST && (newatts&(NV_LJUST|NV_RJUST|NV_ZFILL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvflag &= NV_ARRAY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvflag |= newatts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval (np, cp, NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(ap && nv_nextsub(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvfun = fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nelem--;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh.prefix = prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *oldgetenv(const char *string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char c0,c1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp, *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **av = environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!string || (c0= *string)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c1=*++string)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c1= '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp = *av++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp[0]!=c0 || cp[1]!=c1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*sp && *sp++ == *++cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp==0 && *++cp=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)(cp+1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version of getenv uses the hash storage to access environment values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerchar *sh_getenv(const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*@
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assume name!=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin@*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh.var_tree)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#if 0
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(name[0] == 'P' && name[1] == 'A' && name[2] == 'T' && name[3] == 'H' && name[4] == 0 || name[0] == 'L' && ((name[1] == 'C' || name[1] == 'D') && name[2] == '_' || name[1] == 'A' && name[1] == 'N') || name[0] == 'V' && name[1] == 'P' && name[2] == 'A' && name[3] == 'T' && name[4] == 'H' && name[5] == 0 || name[0] == '_' && name[1] == 'R' && name[2] == 'L' && name[3] == 'D' || name[0] == '_' && name[1] == 'A' && name[2] == 'S' && name[3] == 'T' && name[4] == '_')
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#endif
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(oldgetenv(name));
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if((np = nv_search(name,sh.var_tree,0)) && nv_isattr(np,NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_getval(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#ifndef _NEXT_SOURCE
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner/*
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Some dynamic linkers will make this file see the libc getenv(),
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * so sh_getenv() is used for the astintercept() callback. Plain
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * getenv() is provided for static links.
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerchar *getenv(const char *name)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return sh_getenv(name);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _NEXT_SOURCE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef putenv
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version of putenv uses the hash storage to assign environment values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint putenv(const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(name,sh.var_tree,NV_EXPORT|NV_IDENT|NV_NOARRAY|NV_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!strchr(name,'='))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Override libast setenviron().
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerchar* sh_setenviron(const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(name,sh.var_tree,NV_EXPORT|NV_IDENT|NV_NOARRAY|NV_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strchr(name,'='))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_getval(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner/*
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Same linker dance as with getenv() above.
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerchar* setenviron(const char *name)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return sh_setenviron(name);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner}
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * convert <str> to upper case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ltou(register char *str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(; c= *((unsigned char*)str); str++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(islower(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *str = toupper(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * convert <str> to lower case
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void utol(register char *str)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(; c= *((unsigned char*)str); str++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(isupper(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *str = tolower(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * normalize <cp> and return pointer to subscript if any
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if <eq> is specified, return pointer to first = not in a subscript
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *lastdot(register char *cp, int eq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *ep=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(eq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*cp==']')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='[')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((ep=sh_checkid(ep+1,cp)) < cp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp=strcpy(ep,cp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(eq && c == '=')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(cp-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(eq?0:ep);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint nv_rename(register Namval_t *np, int flags)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namval_t *mp=0,*nr=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int index= -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *last_table = shp->last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *last_root = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *hp = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *prefix=shp->prefix,*nvenv = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_PARAM) && shp->st.prevst)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(hp=(Dt_t*)shp->st.prevst->save_tree))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hp = dtvnext(shp->var_tree);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(cp=nv_getval(np)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_MOVE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_varname,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lastdot(cp,0) && nv_isattr(np,NV_MINIMAL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_varname,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np) && !(mp=nv_opensub(np)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin index=nv_aindex(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!hp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hp = shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(nr = nv_open(cp, hp, flags|NV_ARRAY|NV_NOREF|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hp = shp->var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(shp->last_root)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hp = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nr)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr= nv_open(cp, hp, flags|NV_NOREF|((flags&NV_MOVE)?0:NV_NOFAIL));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->prefix = prefix;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nr)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isvtree(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!mp && index>=0 && nv_isvtree(nr))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(shp->strbuf,"%s[%d]%c",nv_name(np),index,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* create a virtual node */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp = nv_open(sfstruse(shp->strbuf),shp->var_tree,NV_VARNAME|NV_ADD|NV_ARRAY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvenv = (void*)np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nvenv = (char*)np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = mp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nr==np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(index<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp = nv_getval(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = strdup(cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!nv_isattr(np,NV_MINIMAL))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np->nvenv = nvenv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nr==np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,(char*)0, index);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(np,cp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prev_table = shp->last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prev_root = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = last_table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_root = last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_clone(nr,np,(flags&NV_MOVE)|NV_COMVAR);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_MOVE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(nr,(Dt_t*)0,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Create a reference node from <np> to $np in dictionary <hp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_setref(register Namval_t *np, Dt_t *hp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namval_t *nq, *nr=0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char *ep,*cp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Dt_t *root = shp->last_root;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namarr_t *ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(cp=nv_getval(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(np,NV_REF);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((ep = lastdot(cp,0)) && nv_isattr(np,NV_MINIMAL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!hp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hp = shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(nr = nq = nv_open(cp, hp, flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz hp = shp->last_root==shp->var_tree?shp->var_tree:shp->var_base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(shp->last_root)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin hp = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nq && ep && nv_isarray(nq) && !nv_getsub(nq))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_endsubscript(nq,ep-1,NV_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nr)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr= nq = nv_open(cp, hp, flags);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz hp = shp->last_root;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->last_root == shp->var_tree && root!=shp->var_tree)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz _nv_unset(np,NV_RDONLY);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_onattr(np,NV_REF);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(1),e_globalref,nv_name(np));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nr==np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->namespace && nv_dict(shp->namespace)==hp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* bind to earlier scope, or add to global scope */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(hp=dtvnext(hp)) || (nq=nv_search((char*)np,hp,NV_ADD|HASH_BUCKET))==np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nq && !ep && (ap=nv_arrayptr(nq)) && !(ap->nelem&(ARRAY_UNDEF|ARRAY_SCAN)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ep = nv_getsub(nq);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* cause subscript evaluation and return result */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(nq))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep = nv_getsub(nq);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep[strlen(ep)-1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(nr, ep, 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep[strlen(ep)-1] = ']';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nq = nv_opensub(nr))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nq = nr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,(Dt_t*)0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.nrp = newof(0,struct Namref,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.nrp->np = nq;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.nrp->root = hp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.nrp->sub = strdup(ep);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.nrp->table = shp->last_table;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_REF|NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get the scope corresponding to <index>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * whence uses the same values as lseeek()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinShscope_t *sh_getscope(int index, int whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct sh_scoped *sp, *topmost;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_CUR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = &sh.st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((struct sh_scoped*)sh.topscope != sh.st.self)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin topmost = (struct sh_scoped*)sh.topscope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin topmost = &(sh.st);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = topmost;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(whence==SEEK_SET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n =0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sp = sp->prevst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin index = n - index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = topmost;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(index < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Shscope_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(index-- && (sp = sp->prevst));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Shscope_t*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make <scoped> the top scope and return previous scope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinShscope_t *sh_setscope(Shscope_t *scope)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shscope_t *old = (Shscope_t*)sh.st.self;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sh.st.self = sh.st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st = *((struct sh_scoped*)scope);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.var_tree = scope->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SH_PATHNAMENOD->nvalue.cp = sh.st.filename;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SH_FUNNAMENOD->nvalue.cp = sh.st.funname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_unscope(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Dt_t *root = shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *dp = dtview(root,(Dt_t*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin table_unset(shp,root,NV_RDONLY|NV_NOSCOPE,dp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.real_fun && dp==shp->st.real_fun->sdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp = dtview(dp,(Dt_t*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.real_fun->sdict->view = dp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->var_tree=dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(root);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The inverse of creating a reference node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_unref(register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *nq;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_NOFREE|NV_REF);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!np->nvalue.nrp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nq = nv_refnode(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)np->nvalue.nrp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = strdup(nv_name(nq));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(fp=nq->nvfun; fp; fp = fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc== &optimize_disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin optimize_clear(nq,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * These following are for binary compatibility with the old hash library
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * They will be removed someday
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(__IMPORT__) && defined(__EXPORT__)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define extern __EXPORT__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef hashscope
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern Dt_t *hashscope(Dt_t *root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dtvnext(root));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef hashfree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern Dt_t *hashfree(Dt_t *root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *dp = dtvnext(root);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(root);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef hashname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char *hashname(void *obj)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np = (Namval_t*)obj;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef hashlook
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void *hashlook(Dt_t *root, const char *name, int mode,int size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)nv_search(name,root,mode));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *nv_name(register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *table;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_abuiltin(np) || is_afunction(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isattr(np,NV_MINIMAL|NV_EXPORT) && np->nvenv)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *nq= sh.last_table, *mp= (Namval_t*)np->nvenv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np==sh.last_table)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.last_table = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(mp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%s[%s]",nv_name(mp),np->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%s.%s",nv_name(mp),np->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.last_table = nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(sfstruse(sh.strbuf));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_istable(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.last_table = nv_parent(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.last_table = nv_create(np,0, NV_LAST,(Namfun_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(fp= np->nvfun ; fp; fp=fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc && fp->disc->namef)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==sh.last_table)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.last_table = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((*fp->disc->namef)(np,fp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(table=sh.last_table) || *np->nvname=='.' || table==sh.namespace || np==table)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_name(table);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"%s.%s",cp,np->nvname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfstruse(sh.strbuf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_lastdict(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh.last_table);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef nv_context
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns the data context for a builtin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *nv_context(Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)np->nvfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DISABLE /* proto workaround */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_isnull DISABLE (register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_isnull(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef nv_setsize
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_setsize(register Namval_t *np, int size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oldsize = nv_size(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvsize = size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(oldsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinShell_t *nv_shell(Namval_t *np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namfun_t *fp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(fp=np->nvfun;fp;fp=fp->next)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!fp->disc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((Shell_t*)fp->last);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef nv_unset
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid nv_unset(register Namval_t *np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}