1*35180Smarc /*
2*35180Smarc 
3*35180Smarc  *      Copyright (c) 1984, 1985, 1986 AT&T
4*35180Smarc  *      All Rights Reserved
5*35180Smarc 
6*35180Smarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35180Smarc  *      CODE OF AT&T.
8*35180Smarc  *      The copyright notice above does not
9*35180Smarc  *      evidence any actual or intended
10*35180Smarc  *      publication of such source code.
11*35180Smarc 
12*35180Smarc  */
13*35180Smarc /* @(#)assign.c	1.1 */
14*35180Smarc 
15*35180Smarc /*
16*35180Smarc  *   ASSIGN.C
17*35180Smarc  *
18*35180Smarc  *   Programmer:  D. G. Korn
19*35180Smarc  *
20*35180Smarc  *        Owner:  D. A. Lambeth
21*35180Smarc  *
22*35180Smarc  *         Date:  April 17, 1980
23*35180Smarc  *
24*35180Smarc  *
25*35180Smarc  *
26*35180Smarc  *   ASSIGN (NODE, STRING)
27*35180Smarc  *
28*35180Smarc  *        Assign STRING to NODE.
29*35180Smarc  *
30*35180Smarc  *   FASSIGN (NODE, STRING)
31*35180Smarc  *
32*35180Smarc  *        Assign STRING to NODE even if readonly.
33*35180Smarc  *
34*35180Smarc  *
35*35180Smarc  *
36*35180Smarc  *   See Also:  asscadr(III), asslong(III), unassign(III), valup(III)
37*35180Smarc  */
38*35180Smarc 
39*35180Smarc #include	"name.h"
40*35180Smarc #include        "flags.h"
41*35180Smarc #ifdef MULTIBYTE
42*35180Smarc #include        "national.h"
43*35180Smarc #endif /* MULTIBYTE */
44*35180Smarc 
45*35180Smarc void	assign();
46*35180Smarc void	fassign();
47*35180Smarc 
48*35180Smarc extern char *malloc();
49*35180Smarc extern char *strcpy();
50*35180Smarc #ifdef BSD
51*35180Smarc #define strchr index
52*35180Smarc #endif	/* BSD */
53*35180Smarc extern char	*strchr();
54*35180Smarc extern void	utol(),ltou();
55*35180Smarc extern char	*itos();
56*35180Smarc extern void	free();
57*35180Smarc extern void	rjust();
58*35180Smarc extern void	failed();
59*35180Smarc #ifdef NAME_SCOPE
60*35180Smarc extern struct Namnod *copy_nod();
61*35180Smarc #endif	/* NAME_SCOPE */
62*35180Smarc union Namval *aget_up();
63*35180Smarc 
64*35180Smarc #ifdef MULTIBYTE
65*35180Smarc static unsigned char *savep;
66*35180Smarc static unsigned char savechars[ESS_MAXCHAR+1];
67*35180Smarc static int ja_size();
68*35180Smarc #else
69*35180Smarc #define size	 np->namsz
70*35180Smarc #endif /* MULTIBYTE */
71*35180Smarc 
72*35180Smarc /*
73*35180Smarc  *   ASSIGN (NODE, STRING)
74*35180Smarc  *
75*35180Smarc  *        struct Namnod *NODE;
76*35180Smarc  *
77*35180Smarc  *        char *STRING;
78*35180Smarc  *
79*35180Smarc  *   Assign the string given by STRING to the Namnod given by
80*35180Smarc  *   NODE.  STRING is converted according to the namflg field
81*35180Smarc  *   of NODE before assignment.
82*35180Smarc  *
83*35180Smarc  *   If NODE is an array, then the element given by the
84*35180Smarc  *   current index is assigned to.
85*35180Smarc  *
86*35180Smarc  *   Any freeable space associated with the old value of NODE
87*35180Smarc  *   is released.
88*35180Smarc  *
89*35180Smarc  *   If the copy on write,C_WRITE flag is set then the assignment
90*35180Smarc  *   is made on a copy of the node created on the last shell tree.
91*35180Smarc  *
92*35180Smarc  */
93*35180Smarc 
94*35180Smarc static char forced = 0;
95*35180Smarc 
fassign(node,string)96*35180Smarc void fassign(node,string)
97*35180Smarc struct Namnod *node;
98*35180Smarc char *string;
99*35180Smarc {
100*35180Smarc 	forced++;
101*35180Smarc 	assign(node,string);
102*35180Smarc 	forced = 0;
103*35180Smarc #ifdef apollo
104*35180Smarc 	if(attest(node,N_EXPORT))
105*35180Smarc 	{
106*35180Smarc 		extern char *valup();
107*35180Smarc 		short namlen, vallen;
108*35180Smarc 		char *vp = valup(node);
109*35180Smarc 		namlen =strlen(node->namid);
110*35180Smarc 		vallen = strlen(vp);
111*35180Smarc 		ev_$set_var(node->namid,&namlen,vp,&vallen);
112*35180Smarc 	}
113*35180Smarc #endif /* apollo */
114*35180Smarc }
115*35180Smarc 
assign(node,string)116*35180Smarc void assign(node,string)
117*35180Smarc struct Namnod *node;
118*35180Smarc char *string;
119*35180Smarc {
120*35180Smarc 	register char *sp=string;
121*35180Smarc 	register struct Namnod *np=node;
122*35180Smarc 	register union Namval *up;
123*35180Smarc 	register char *cp;
124*35180Smarc #ifdef MULTIBYTE
125*35180Smarc 	register int size;
126*35180Smarc #endif /* MULTIBYTE */
127*35180Smarc 	register int dot = 0;
128*35180Smarc #ifdef apollo
129*35180Smarc 	/* reserve space for UNIX to host file name translation */
130*35180Smarc 	char pathname[256];
131*35180Smarc 	short pathlen;
132*35180Smarc #endif	/* apollo */
133*35180Smarc #ifdef NAME_SCOPE
134*35180Smarc 	if (attest (np,C_WRITE))
135*35180Smarc 		np = copy_nod(np,1);
136*35180Smarc #endif	/* NAME_SCOPE */
137*35180Smarc 	up= &np->value.namval;
138*35180Smarc 	if (forced==0 && attest (np, N_RDONLY))
139*35180Smarc 		failed(np->namid,wtfailed);
140*35180Smarc 	if (attest (np, ARRAY))
141*35180Smarc 		up = aget_up(np,up);
142*35180Smarc 	if (attest (np, IN_DIR))
143*35180Smarc 		up = up->up;
144*35180Smarc 	if (attest (np, INT_GER))
145*35180Smarc 	{
146*35180Smarc 		long l, aeval();
147*35180Smarc 		if (attest (np, CPOIN_TER))
148*35180Smarc 		{
149*35180Smarc 			up->cp = sp;
150*35180Smarc 			return;
151*35180Smarc 		}
152*35180Smarc 		l = (sp? aeval(sp) : (lastbase=10,0));
153*35180Smarc 		if(np->namsz == 0)
154*35180Smarc 			np->namsz = lastbase;
155*35180Smarc 		if (attest (np, BLT_NOD))
156*35180Smarc 		{
157*35180Smarc 			(*up->fp->f_ap)(l);
158*35180Smarc 			return;
159*35180Smarc 		}
160*35180Smarc 		if(up->lp==0)
161*35180Smarc 			up->lp = (long*)malloc((unsigned)sizeof(long));
162*35180Smarc 		*(up->lp) = l;
163*35180Smarc 		if(l && *sp++ == '0')
164*35180Smarc 			np->value.namflg |= UN_SIGN;
165*35180Smarc 		return;
166*35180Smarc 	}
167*35180Smarc 	if(attest (np,(N_IMPORT|N_EXPORT))==(N_IMPORT|N_EXPORT))
168*35180Smarc 	{
169*35180Smarc 		/* get rid of imported value */
170*35180Smarc 		char *cp = strchr(np->namid,'=');
171*35180Smarc 		if(cp)
172*35180Smarc 			*cp = 0;
173*35180Smarc 		pattrib(np,~N_IMPORT);
174*35180Smarc 	}
175*35180Smarc #ifdef apollo
176*35180Smarc 	if (attest (np, A_FLAG) && sp)
177*35180Smarc 	{
178*35180Smarc 		/* this routine returns the host file name given the UNIX name */
179*35180Smarc 		/* other non-unix hosts that use file name mapping should change this */
180*35180Smarc 		unix_fio_$get_name(sp,pathname,&pathlen);
181*35180Smarc 		pathname[pathlen] = 0;
182*35180Smarc 		sp = pathname;
183*35180Smarc 	}
184*35180Smarc #endif	/* apollo */
185*35180Smarc 	if ((attest (np, R_JUST|Z_FILL|L_JUST)) && sp)
186*35180Smarc 	{
187*35180Smarc 		for(;*sp == ' '|| *sp=='\t';sp++);
188*35180Smarc         	if ((attest (np, Z_FILL)) && (attest (np, L_JUST)))
189*35180Smarc 			for(;*sp=='0';sp++);
190*35180Smarc #ifdef MULTIBYTE
191*35180Smarc 		if(size = np->namsz)
192*35180Smarc 			size = ja_size((unsigned char*)sp,size,attest(np,R_JUST|Z_FILL));
193*35180Smarc #endif /* MULTIBYTE */
194*35180Smarc 	}
195*35180Smarc 	if ((!attest (np, N_FREE|N_ALLOC)) && (up->cp != NULL))
196*35180Smarc 		free(up->cp);
197*35180Smarc 	if (attest (np, N_ALLOC))
198*35180Smarc 		cp = up->cp;
199*35180Smarc 	else
200*35180Smarc 	{
201*35180Smarc         	np->value.namflg &= ~N_FREE;
202*35180Smarc         	if (sp)
203*35180Smarc 			 cp = malloc(((unsigned)((dot=strlen(sp))>size?dot:size)+1));
204*35180Smarc 		else
205*35180Smarc 			cp = NULL;
206*35180Smarc 		up->cp = cp;
207*35180Smarc 	}
208*35180Smarc 	if (!sp)
209*35180Smarc 		return;
210*35180Smarc 	if (attest (np, L_TO_U))
211*35180Smarc 		ltou(sp,cp);
212*35180Smarc 	else if (attest (np, U_TO_L))
213*35180Smarc 		utol(sp,cp);
214*35180Smarc 	else
215*35180Smarc         	strcpy (cp, sp);
216*35180Smarc 	if (attest (np, R_JUST) && attest (np, Z_FILL))
217*35180Smarc 		rjust(cp,size,'0');
218*35180Smarc 	else if (attest (np, R_JUST))
219*35180Smarc 		rjust(cp,size,' ');
220*35180Smarc 	else if (attest (np, L_JUST))
221*35180Smarc         {
222*35180Smarc          	sp = strlen (cp) + cp;
223*35180Smarc 		*(cp = (cp + size)) = 0;
224*35180Smarc 		for (; sp < cp; *sp++ = ' ');
225*35180Smarc          }
226*35180Smarc #ifdef MULTIBYTE
227*35180Smarc 	/* restore original string */
228*35180Smarc 	if(savep)
229*35180Smarc 		ja_restore();
230*35180Smarc #endif /* MULTIBYTE */
231*35180Smarc 	return;
232*35180Smarc }
233*35180Smarc 
234*35180Smarc 
235*35180Smarc /*
236*35180Smarc  * Get the Namval pointer for an array.
237*35180Smarc  * Allocate the space if necessary
238*35180Smarc  */
239*35180Smarc 
aget_up(np,up)240*35180Smarc union Namval *aget_up(np,up)
241*35180Smarc struct Namnod *np;
242*35180Smarc register union Namval *up;
243*35180Smarc {
244*35180Smarc 	register int dot;
245*35180Smarc 	register struct Nodval *nv;
246*35180Smarc 	dot = up->aray->adot;
247*35180Smarc 	if (dot > arsize (abound (np)))
248*35180Smarc    		failed (itos(dot), subscript);
249*35180Smarc 	if ((nv = up->aray->val[dot]) == NULL)
250*35180Smarc 	{
251*35180Smarc 		nv = (struct Nodval*)malloc ((unsigned)sizeof (struct Nodval));
252*35180Smarc 		nv->namflg = np->value.namflg & ~ARRAY;
253*35180Smarc 		nv->namval.cp = NULL;
254*35180Smarc 		up->aray->val[dot] = nv;
255*35180Smarc 	}
256*35180Smarc 	return(&(unmark (nv)->namval));
257*35180Smarc }
258*35180Smarc 
259*35180Smarc #ifdef MULTIBYTE
260*35180Smarc /*
261*35180Smarc  * handle left and right justified fields for multi-byte chars
262*35180Smarc  * given physical size, return a logical size which reflects the
263*35180Smarc  * screen width of multi-byte characters
264*35180Smarc  * Multi-width characters replaced by spaces if they cross the boundary
265*35180Smarc  * <type> is non-zero for right justified  fields
266*35180Smarc  */
267*35180Smarc 
ja_size(str,size,type)268*35180Smarc static int ja_size(str,size,type)
269*35180Smarc unsigned char *str;
270*35180Smarc int size;
271*35180Smarc {
272*35180Smarc 	register unsigned char *cp = str;
273*35180Smarc 	register int c;
274*35180Smarc 	register int n = size;
275*35180Smarc 	int oldn;
276*35180Smarc 	while(c = *cp++)
277*35180Smarc 	{
278*35180Smarc 		oldn = n;
279*35180Smarc 		/* find character set number */
280*35180Smarc 		c = echarset(c);
281*35180Smarc 		/* allow room for excess input bytes */
282*35180Smarc 		if(c)
283*35180Smarc 		{
284*35180Smarc 			n += (in_csize(c)-out_csize(c)+(c>=2));
285*35180Smarc 			cp += (in_csize(c)-(c==1));
286*35180Smarc 		}
287*35180Smarc 		size -= out_csize(c);
288*35180Smarc 		if(size<=0 && type==0)
289*35180Smarc 			break;
290*35180Smarc 	}
291*35180Smarc 	/* check for right justified fields that need truncating */
292*35180Smarc 	if(size <0)
293*35180Smarc 	{
294*35180Smarc 		if(type==0)
295*35180Smarc 		{
296*35180Smarc 			/* left justified and character crosses field boundary */
297*35180Smarc 			n = oldn;
298*35180Smarc 			/* save boundary char and replace with spaces */
299*35180Smarc 			size = in_csize(c)+(c>2);
300*35180Smarc 			savechars[size] = 0;
301*35180Smarc 			while(size--)
302*35180Smarc 			{
303*35180Smarc 				savechars[size] = *--cp;
304*35180Smarc 				*cp = ' ';
305*35180Smarc 			}
306*35180Smarc 			savep = cp;
307*35180Smarc 		}
308*35180Smarc 		size = -size;
309*35180Smarc 		if(type)
310*35180Smarc 			n -= (ja_size(str,size,0)-size);
311*35180Smarc 	}
312*35180Smarc 	return(n);
313*35180Smarc }
314*35180Smarc 
ja_restore()315*35180Smarc int ja_restore()
316*35180Smarc {
317*35180Smarc 	register unsigned char *cp = savechars;
318*35180Smarc 	while(*cp)
319*35180Smarc 		*savep++ = *cp++;
320*35180Smarc 	savep = 0;
321*35180Smarc }
322*35180Smarc #endif /* MULTIBYTE */
323