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