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