2 protect - read or adjust protect status for a variable or named block
5 protect(var [, N [, depth])
6 protect(nblk [, N [, depth]])
11 N integer, abs(N) < 65536
12 depth nonnegative integer
17 The protection status of the association of an lvalue A with
18 its value is represented by a nonnegative integer less than 2^16.
19 The current value sts of this status is returned by protect(A).
20 Each nonzero bit of the low eight bits of sts corresponds to a
21 builtin kind of protection as follows:
26 2 no change of A by assignment
27 4 no change of type value of A
28 8 no error value for A
30 32 no relocation for A or its elements
34 For example, A having protection status 65 = 1 + 64 prevents
35 execution of assignments of the forms A = expression and V = A
36 where V is an lvalue. Attempting either of these assignments
37 will return an error value and leave the value of A or V unchanged.
39 Initally, when created, any lvalue A has zero status corresponding
40 to "no protection". This may be restored at any time by protect(A, 0).
42 If N is positive and A does not already have the protection
43 corresponding to a nonzero bit of N, protect(A, N) adds that
44 protection to the status of A. For example, if protect(A) is 65,
45 protect(A, 17) will add the no-copy-to protection so that the
46 new protection status of A will be 81 = 1 + 16 + 64.
48 Similarly, if N is negative and A has the protection corresponding
49 to a nonzero bit of abs(N), protect(A,N) will remove that kind of
50 protection. For example if protect(A) = 65, then protect(A, -17)
51 will remove the no-assign-to protection and the new value of
52 protect(A) will be 64. Note that protect(A, -65535) has the same
53 effect as protect(A, 0).
55 For the purposes of this function, the depth of a global or local
56 variable is zero; if A has depth d and the value of A is a list,
57 matrix, object or association, its elements have depth d + 1.
61 ; X = mat[3] = {1, list(2,3), mat[2] = {obj point, obj point} }
63 X has depth 0; X[0], X[1] and X[2] have depth 1; X[1][0], X[1][1],
64 X[2][0] and X[2][1] have depth 2; X[2][0].x, X[2][0].y, X[2][1].x
65 and X[2][1].y have depth 3. For any lvalue A, protect(A, N, depth)
66 applies protect(A, N) to A and to all elements, elements of
67 elements, etc., up tothe stated depth. In the above example,
68 protect(X, 20, 2) gives no-type-change and no-copy-to protection
69 to 8 of the listed lvalues, but not to the components of the
70 objects X[2][0] and X[2][1]; With any d >= 3, protect(X, 20, d)
71 would give that protection the 12 listed lvalues.
73 If B is a variable with positive status and assignment of B to A is
74 permitted, execution of the assignment A = B adds to the protections
75 of A all protections of B that A does not already have. Except when
76 the value returned is the result of the evqluation of an lvalue with
77 positive status, calc's builtin operators and functions return values
78 with zero protection status. For example, whatever the protection
79 statuses of X and Y, X + sqrt(Y) will have zero status, but
80 t ? X : Y may have nonzero status. The list, matrix, object or
81 association returned by the use of list, mat, obj or assoc will have
82 zero status, but any element specified by an lvalue will receive
83 its status; e.g. after L = list(X, X^2) , protect(L[0]) equals
84 protect(X) and both protect(L) and protect(L[1]) are zero.
86 Users may define functions that return values with positive status, e.g.
88 ; define noassigntovalue(x) {protect(x,1); return x};
89 ; S = noassigntovalue(42);
91 will result in S having the value 42 and no-assign-to protection.
92 By using a backquote with a variable as argument, an even simpler
95 ; define noassignto(x) = protect(x, 1);
97 gives no-assign-to protection to the variable; i.e. noassignto(`A)
98 achieves the same as protect(A,1).
100 In the brief descriptions above of builtin kinds of protectiopn,
101 "assign" refers to use of '=' as in A = expr to assign the value
102 of expr to A, and in A = {..., expr, ...} to assign the value of expr
103 to some component of A, and to the assignments implicit in
104 quomod(x, y, A, B), and pre or post ++ or --. Swapping of lvalues is
105 prevented if either value has no-assign-to or no-assign-from
106 protection. (Swapping of octets is prevented if at least one of
107 them is in a string or block with no-copy-to or no-copy-from
110 "Copying" refers to initialization using {...} and to the operations
111 copy and blkcpy as applied to strings, blocks, lists and matrices.
112 Although A = {..., expr, ...) assigns the value of expr to an
113 elment of A, it is also regarded as copying to A. Thus, initialization
114 of A may be prevented either by giving no-copy-to protection to A or
115 no-assignment=to protection to the elements of A. Assignments to and
116 from characters or octets in strings or blocks are also regarded as
117 copying to or from the string or block. For example, after
118 A = "abc", protect(A,16) would prevent the assignment A[0] = 'x'.
119 (Note that in this example, A[0] is not an lvalue in the sense
120 normally understood - the only values it can have are nonnegative
121 integers less than 256. The only kinds of protection relevant to an
122 octet are the no-copy-to, no-copy-from and no-change protections of
123 the string or block in which the octet resides.)
125 The no-relocate protection applies to lists and blocks. For lists,
126 it refers to the operations push, pop, append, remove, insert and
127 delete. For example, if A = list(2,3,5,7), protect(A, 32) will
128 prevent any change in the content or size of the list.
129 No-relocation protection of a block prevents reallocation of the
130 memory used by a block and the freeing of a named block, For example,
131 if a block B has maxsize 256, then after:
135 copy(A, B) will fail if the copying would cause size(B) to equal or
136 exceed 256; if B is a named block, blkfree(B) will not be permitted.
138 The elements of the list returned by list(...) will initially have zero
139 protection status except when an argument is an lvalue with positive
140 status, in which case the corresponding element will receive that
141 status. E.g., L = list(A,B) will result in L[0] having status
142 protect(A) and L[1] having status protect(B). L itself will have
143 the status L had before the assignment. There is a similar copying
144 of protection status when "= { ... }" initialization is used for
145 matrices, lists or objects. For example, except when A or B has
146 no-assign-from protection, M = mat [2] = {A,B} or mat M[2] = {A,B}
147 will result in M[0] and M[1] having statuses protect(A) and
148 protect(B) respectively. (If A or B has no-assign-from protection,
149 mat[2] = {A,B} returns an error value.)
151 Although M = mat[2] = {...} and mat M[2] = {...} do the same thing,
152 these are different from (M = mat[2]) = {...} and (mat M[3]) = {...}.
153 In the former pair of statements, the result of mat[2] = {...} is being
154 assigned to M. In the latter statments, a matrix with zero elements is
155 being assigned to M and then that matrix is being "reinitialized". Both
156 will fail if M has no-asssign-to protection, but only the latter
157 would be prevented by M having no-copy-to protection.
159 When the functions which mave move elements like of sort, reverse,
160 swap, insert, pop, remove, push and append. are evaluated, the
161 protection statuses move with the values, e.g. if among the values
162 and elements involved, there is just one with value 42, then the
163 lvalue to which the value 42 is moved will get the status the lvalue
164 with value 42 had before the evaluation of the function. This is
165 relevant to evaluation of expressions like A = sort(A),
166 append(A, pop(A)), insert(A,2,B,C). Note that when pop(A) is first
167 evaluated it is located on the stack calc uses for calculating
168 expressions rather than being the value of an lvalue. With an
169 explicit assignment like X = pop(A) or the implied assignment in
170 append(A, pop(A)), it becomes the value of an lvalue.
172 Users may use higher bits values for other kinds of protection or
173 simply to store information about an lvalue and its current value.
174 For example 1024 might be used to indicate that the lvalue is always
175 to have positive value. Then code for evaluating a function might
178 ; if (protect(A) & 1024 && B <= 0) {
179 ;; return newerror("Prohibited assignment");
183 When an operation forbidden by a particular bit in the protection
184 status of A is attempted, an error value is created but unless this
185 causes errcount to exceed errmax, the only immediate evidence
186 for the error might be the incrementing of errcount. Sometimes the
187 failure causes the return of the error value; e.g. swap(A,B) if
188 not permitted returns an appropriate error value rather than the
189 null value. If the value of A is a number and A has no-type-change
190 protection, A = "abc" returns an error value. The error-number of
191 the most recent error value is returned by errno(), a string
192 describing it by strerror().
194 A named block may be referred to by using the blocks() or blk()
195 functions, or by assigning it to a variable A and then using either
196 A or *A. In the latter cases, protect(A, sts) sets the status for
197 the variable A; protect(*A, sts) assigns the status for the named
198 block. For example, protect(*A,16) will prevent any copying to the
199 named block; protect(A,16) will prevent any copying to the named block
200 only when it is referred to by A.
210 "No-assign-to destination for assign"
218 "No-assign-from source for assign"
229 "No-type-change destination for assign"
234 "No-assign-to-or-from argument for swap"
244 ; A = mat[4] = {1,2,3,4}
250 "No-copy-to destination variable"
257 "No-relocate for list append"
264 "No-relocate destination variable"
266 ; A = blk("alpha") = {1,2,3,4,5}
272 "No-copy-to destination named block"
281 assign, copy, blk, error, errno, strerror
283 ## Copyright (C) 1999-2006 Landon Curt Noll
285 ## Calc is open software; you can redistribute it and/or modify it under
286 ## the terms of the version 2.1 of the GNU Lesser General Public License
287 ## as published by the Free Software Foundation.
289 ## Calc is distributed in the hope that it will be useful, but WITHOUT
290 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
291 ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
292 ## Public License for more details.
294 ## A copy of version 2.1 of the GNU Lesser General Public License is
295 ## distributed with calc under the filename COPYING-LGPL. You should have
296 ## received a copy with calc; if not, write to Free Software Foundation, Inc.
297 ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
299 ## @(#) $Revision: 30.1 $
300 ## @(#) $Id: protect,v 30.1 2007/03/16 11:10:42 chongo Exp $
301 ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/protect,v $
303 ## Under source code control: 1997/07/10 22:38:44
304 ## File existed as early as: 1997
306 ## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
307 ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/