/* * Copyright (c) 1984, 1985, 1986 AT&T * All Rights Reserved * THIS IS UNPUBLISHED PROPRIETARY SOURCE * CODE OF AT&T. * The copyright notice above does not * evidence any actual or intended * publication of such source code. */ /* @(#)assign.c 1.1 */ /* * ASSIGN.C * * Programmer: D. G. Korn * * Owner: D. A. Lambeth * * Date: April 17, 1980 * * * * ASSIGN (NODE, STRING) * * Assign STRING to NODE. * * FASSIGN (NODE, STRING) * * Assign STRING to NODE even if readonly. * * * * See Also: asscadr(III), asslong(III), unassign(III), valup(III) */ #include "name.h" #include "flags.h" #ifdef MULTIBYTE #include "national.h" #endif /* MULTIBYTE */ void assign(); void fassign(); extern char *malloc(); extern char *strcpy(); #ifdef BSD #define strchr index #endif /* BSD */ extern char *strchr(); extern void utol(),ltou(); extern char *itos(); extern void free(); extern void rjust(); extern void failed(); #ifdef NAME_SCOPE extern struct Namnod *copy_nod(); #endif /* NAME_SCOPE */ union Namval *aget_up(); #ifdef MULTIBYTE static unsigned char *savep; static unsigned char savechars[ESS_MAXCHAR+1]; static int ja_size(); #else #define size np->namsz #endif /* MULTIBYTE */ /* * ASSIGN (NODE, STRING) * * struct Namnod *NODE; * * char *STRING; * * Assign the string given by STRING to the Namnod given by * NODE. STRING is converted according to the namflg field * of NODE before assignment. * * If NODE is an array, then the element given by the * current index is assigned to. * * Any freeable space associated with the old value of NODE * is released. * * If the copy on write,C_WRITE flag is set then the assignment * is made on a copy of the node created on the last shell tree. * */ static char forced = 0; void fassign(node,string) struct Namnod *node; char *string; { forced++; assign(node,string); forced = 0; #ifdef apollo if(attest(node,N_EXPORT)) { extern char *valup(); short namlen, vallen; char *vp = valup(node); namlen =strlen(node->namid); vallen = strlen(vp); ev_$set_var(node->namid,&namlen,vp,&vallen); } #endif /* apollo */ } void assign(node,string) struct Namnod *node; char *string; { register char *sp=string; register struct Namnod *np=node; register union Namval *up; register char *cp; #ifdef MULTIBYTE register int size; #endif /* MULTIBYTE */ register int dot = 0; #ifdef apollo /* reserve space for UNIX to host file name translation */ char pathname[256]; short pathlen; #endif /* apollo */ #ifdef NAME_SCOPE if (attest (np,C_WRITE)) np = copy_nod(np,1); #endif /* NAME_SCOPE */ up= &np->value.namval; if (forced==0 && attest (np, N_RDONLY)) failed(np->namid,wtfailed); if (attest (np, ARRAY)) up = aget_up(np,up); if (attest (np, IN_DIR)) up = up->up; if (attest (np, INT_GER)) { long l, aeval(); if (attest (np, CPOIN_TER)) { up->cp = sp; return; } l = (sp? aeval(sp) : (lastbase=10,0)); if(np->namsz == 0) np->namsz = lastbase; if (attest (np, BLT_NOD)) { (*up->fp->f_ap)(l); return; } if(up->lp==0) up->lp = (long*)malloc((unsigned)sizeof(long)); *(up->lp) = l; if(l && *sp++ == '0') np->value.namflg |= UN_SIGN; return; } if(attest (np,(N_IMPORT|N_EXPORT))==(N_IMPORT|N_EXPORT)) { /* get rid of imported value */ char *cp = strchr(np->namid,'='); if(cp) *cp = 0; pattrib(np,~N_IMPORT); } #ifdef apollo if (attest (np, A_FLAG) && sp) { /* this routine returns the host file name given the UNIX name */ /* other non-unix hosts that use file name mapping should change this */ unix_fio_$get_name(sp,pathname,&pathlen); pathname[pathlen] = 0; sp = pathname; } #endif /* apollo */ if ((attest (np, R_JUST|Z_FILL|L_JUST)) && sp) { for(;*sp == ' '|| *sp=='\t';sp++); if ((attest (np, Z_FILL)) && (attest (np, L_JUST))) for(;*sp=='0';sp++); #ifdef MULTIBYTE if(size = np->namsz) size = ja_size((unsigned char*)sp,size,attest(np,R_JUST|Z_FILL)); #endif /* MULTIBYTE */ } if ((!attest (np, N_FREE|N_ALLOC)) && (up->cp != NULL)) free(up->cp); if (attest (np, N_ALLOC)) cp = up->cp; else { np->value.namflg &= ~N_FREE; if (sp) cp = malloc(((unsigned)((dot=strlen(sp))>size?dot:size)+1)); else cp = NULL; up->cp = cp; } if (!sp) return; if (attest (np, L_TO_U)) ltou(sp,cp); else if (attest (np, U_TO_L)) utol(sp,cp); else strcpy (cp, sp); if (attest (np, R_JUST) && attest (np, Z_FILL)) rjust(cp,size,'0'); else if (attest (np, R_JUST)) rjust(cp,size,' '); else if (attest (np, L_JUST)) { sp = strlen (cp) + cp; *(cp = (cp + size)) = 0; for (; sp < cp; *sp++ = ' '); } #ifdef MULTIBYTE /* restore original string */ if(savep) ja_restore(); #endif /* MULTIBYTE */ return; } /* * Get the Namval pointer for an array. * Allocate the space if necessary */ union Namval *aget_up(np,up) struct Namnod *np; register union Namval *up; { register int dot; register struct Nodval *nv; dot = up->aray->adot; if (dot > arsize (abound (np))) failed (itos(dot), subscript); if ((nv = up->aray->val[dot]) == NULL) { nv = (struct Nodval*)malloc ((unsigned)sizeof (struct Nodval)); nv->namflg = np->value.namflg & ~ARRAY; nv->namval.cp = NULL; up->aray->val[dot] = nv; } return(&(unmark (nv)->namval)); } #ifdef MULTIBYTE /* * handle left and right justified fields for multi-byte chars * given physical size, return a logical size which reflects the * screen width of multi-byte characters * Multi-width characters replaced by spaces if they cross the boundary * is non-zero for right justified fields */ static int ja_size(str,size,type) unsigned char *str; int size; { register unsigned char *cp = str; register int c; register int n = size; int oldn; while(c = *cp++) { oldn = n; /* find character set number */ c = echarset(c); /* allow room for excess input bytes */ if(c) { n += (in_csize(c)-out_csize(c)+(c>=2)); cp += (in_csize(c)-(c==1)); } size -= out_csize(c); if(size<=0 && type==0) break; } /* check for right justified fields that need truncating */ if(size <0) { if(type==0) { /* left justified and character crosses field boundary */ n = oldn; /* save boundary char and replace with spaces */ size = in_csize(c)+(c>2); savechars[size] = 0; while(size--) { savechars[size] = *--cp; *cp = ' '; } savep = cp; } size = -size; if(type) n -= (ja_size(str,size,0)-size); } return(n); } int ja_restore() { register unsigned char *cp = savechars; while(*cp) *savep++ = *cp++; savep = 0; } #endif /* MULTIBYTE */