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 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 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 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 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 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