perl 5.0 alpha 3
[p5sagit/p5-mst-13.2.git] / do / assign
CommitLineData
79072805 1int
2do_assign(arg,gimme,arglast)
3register ARG *arg;
4int gimme;
5int *arglast;
6{
7
8 register STR **st = stack->ary_array;
9 STR **firstrelem = st + arglast[1] + 1;
10 STR **firstlelem = st + arglast[0] + 1;
11 STR **lastrelem = st + arglast[2];
12 STR **lastlelem = st + arglast[1];
13 register STR **relem;
14 register STR **lelem;
15
16 register STR *TARG;
17 register ARRAY *ary;
18 register int makelocal;
19 HASH *hash;
20 int i;
21
22 makelocal = (arg->arg_flags & AF_LOCAL) != 0;
23 localizing = makelocal;
24 delaymagic = DM_DELAY; /* catch simultaneous items */
25
26 /* If there's a common identifier on both sides we have to take
27 * special care that assigning the identifier on the left doesn't
28 * clobber a value on the right that's used later in the list.
29 */
30 if (arg->arg_flags & AF_COMMON) {
31 for (relem = firstrelem; relem <= lastrelem; relem++) {
32 /*SUPPRESS 560*/
33 if (TARG = *relem)
34 *relem = str_mortal(TARG);
35 }
36 }
37 relem = firstrelem;
38 lelem = firstlelem;
39 ary = Null(ARRAY*);
40 hash = Null(HASH*);
41 while (lelem <= lastlelem) {
42 TARG = *lelem++;
43 if (TARG->str_state >= SS_HASH) {
44 if (TARG->str_state == SS_ARY) {
45 if (makelocal)
46 ary = saveary(TARG->str_u.str_stab);
47 else {
48 ary = stab_array(TARG->str_u.str_stab);
49 ary->ary_fill = -1;
50 }
51 i = 0;
52 while (relem <= lastrelem) { /* gobble up all the rest */
53 TARG = Str_new(28,0);
54 if (*relem)
55 str_sset(TARG,*relem);
56 *(relem++) = TARG;
57 (void)astore(ary,i++,TARG);
58 }
59 }
60 else if (TARG->str_state == SS_HASH) {
61 char *tmps;
62 STR *tmpstr;
63 int magic = 0;
64 STAB *tmpstab = TARG->str_u.str_stab;
65
66 if (makelocal)
67 hash = savehash(TARG->str_u.str_stab);
68 else {
69 hash = stab_hash(TARG->str_u.str_stab);
70 if (tmpstab == envstab) {
71 magic = 'E';
72 environ[0] = Nullch;
73 }
74 else if (tmpstab == sigstab) {
75 magic = 'S';
76#ifndef NSIG
77#define NSIG 32
78#endif
79 for (i = 1; i < NSIG; i++)
80 signal(i, SIG_DFL); /* crunch, crunch, crunch */
81 }
82#ifdef SOME_DBM
83 else if (hash->tbl_dbm)
84 magic = 'D';
85#endif
86 hclear(hash, magic == 'D'); /* wipe any dbm file too */
87
88 }
89 while (relem < lastrelem) { /* gobble up all the rest */
90 if (*relem)
91 TARG = *(relem++);
92 else
93 TARG = &str_no, relem++;
94 tmps = str_get(TARG);
95 tmpstr = Str_new(29,0);
96 if (*relem)
97 str_sset(tmpstr,*relem); /* value */
98 *(relem++) = tmpstr;
99 (void)hstore(hash,tmps,TARG->str_cur,tmpstr,0);
100 if (magic) {
101 str_magic(tmpstr, tmpstab, magic, tmps, TARG->str_cur);
102 stabset(tmpstr->str_magic, tmpstr);
103 }
104 }
105 }
106 else
107 fatal("panic: do_assign");
108 }
109 else {
110 if (makelocal)
111 saveitem(TARG);
112 if (relem <= lastrelem) {
113 str_sset(TARG, *relem);
114 *(relem++) = TARG;
115 }
116 else {
117 str_sset(TARG, &str_undef);
118 if (gimme == G_ARRAY) {
119 i = ++lastrelem - firstrelem;
120 relem++; /* tacky, I suppose */
121 astore(stack,i,TARG);
122 if (st != stack->ary_array) {
123 st = stack->ary_array;
124 firstrelem = st + arglast[1] + 1;
125 firstlelem = st + arglast[0] + 1;
126 lastlelem = st + arglast[1];
127 lastrelem = st + i;
128 relem = lastrelem + 1;
129 }
130 }
131 }
132 STABSET(TARG);
133 }
134 }
135 if (delaymagic & ~DM_DELAY) {
136 if (delaymagic & DM_UID) {
137#ifdef HAS_SETREUID
138 (void)setreuid(uid,euid);
139#else /* not HAS_SETREUID */
140#ifdef HAS_SETRUID
141 if ((delaymagic & DM_UID) == DM_RUID) {
142 (void)setruid(uid);
143 delaymagic =~ DM_RUID;
144 }
145#endif /* HAS_SETRUID */
146#ifdef HAS_SETEUID
147 if ((delaymagic & DM_UID) == DM_EUID) {
148 (void)seteuid(uid);
149 delaymagic =~ DM_EUID;
150 }
151#endif /* HAS_SETEUID */
152 if (delaymagic & DM_UID) {
153 if (uid != euid)
154 fatal("No setreuid available");
155 (void)setuid(uid);
156 }
157#endif /* not HAS_SETREUID */
158 uid = (int)getuid();
159 euid = (int)geteuid();
160 }
161 if (delaymagic & DM_GID) {
162#ifdef HAS_SETREGID
163 (void)setregid(gid,egid);
164#else /* not HAS_SETREGID */
165#ifdef HAS_SETRGID
166 if ((delaymagic & DM_GID) == DM_RGID) {
167 (void)setrgid(gid);
168 delaymagic =~ DM_RGID;
169 }
170#endif /* HAS_SETRGID */
171#ifdef HAS_SETEGID
172 if ((delaymagic & DM_GID) == DM_EGID) {
173 (void)setegid(gid);
174 delaymagic =~ DM_EGID;
175 }
176#endif /* HAS_SETEGID */
177 if (delaymagic & DM_GID) {
178 if (gid != egid)
179 fatal("No setregid available");
180 (void)setgid(gid);
181 }
182#endif /* not HAS_SETREGID */
183 gid = (int)getgid();
184 egid = (int)getegid();
185 }
186 }
187 delaymagic = 0;
188 localizing = FALSE;
189 if (gimme == G_ARRAY) {
190 i = lastrelem - firstrelem + 1;
191 if (ary || hash)
192 Copy(firstrelem, firstlelem, i, STR*);
193 return arglast[0] + i;
194 }
195 else {
196 str_numset(ARGTARG,(double)(arglast[2] - arglast[1]));
197 *firstlelem = ARGTARG;
198 return arglast[0] + 1;
199 }
200}
201