xref: /openbsd/gnu/usr.bin/perl/feature.h (revision 4bdff4be)
1 /* -*- buffer-read-only: t -*-
2    !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
3    This file is built by regen/feature.pl.
4    Any changes made here will be lost!
5  */
6 
7 
8 #ifndef PERL_FEATURE_H_
9 #define PERL_FEATURE_H_
10 
11 #if defined(PERL_CORE) || defined (PERL_EXT)
12 
13 #define HINT_FEATURE_SHIFT	26
14 
15 #define FEATURE_BAREWORD_FILEHANDLES_BIT    0x0001
16 #define FEATURE_BITWISE_BIT                 0x0002
17 #define FEATURE___SUB___BIT                 0x0004
18 #define FEATURE_MYREF_BIT                   0x0008
19 #define FEATURE_DEFER_BIT                   0x0010
20 #define FEATURE_EVALBYTES_BIT               0x0020
21 #define FEATURE_MORE_DELIMS_BIT             0x0040
22 #define FEATURE_FC_BIT                      0x0080
23 #define FEATURE_INDIRECT_BIT                0x0100
24 #define FEATURE_ISA_BIT                     0x0200
25 #define FEATURE_MULTIDIMENSIONAL_BIT        0x0400
26 #define FEATURE_POSTDEREF_QQ_BIT            0x0800
27 #define FEATURE_REFALIASING_BIT             0x1000
28 #define FEATURE_SAY_BIT                     0x2000
29 #define FEATURE_SIGNATURES_BIT              0x4000
30 #define FEATURE_STATE_BIT                   0x8000
31 #define FEATURE_SWITCH_BIT                  0x10000
32 #define FEATURE_TRY_BIT                     0x20000
33 #define FEATURE_UNIEVAL_BIT                 0x40000
34 #define FEATURE_UNICODE_BIT                 0x80000
35 
36 #define FEATURE_BUNDLE_DEFAULT	0
37 #define FEATURE_BUNDLE_510	1
38 #define FEATURE_BUNDLE_511	2
39 #define FEATURE_BUNDLE_515	3
40 #define FEATURE_BUNDLE_523	4
41 #define FEATURE_BUNDLE_527	5
42 #define FEATURE_BUNDLE_535	6
43 #define FEATURE_BUNDLE_CUSTOM	(HINT_FEATURE_MASK >> HINT_FEATURE_SHIFT)
44 
45 #define CURRENT_HINTS \
46     (PL_curcop == &PL_compiling ? PL_hints : PL_curcop->cop_hints)
47 #define CURRENT_FEATURE_BUNDLE \
48     ((CURRENT_HINTS & HINT_FEATURE_MASK) >> HINT_FEATURE_SHIFT)
49 
50 #define FEATURE_IS_ENABLED_MASK(mask)                   \
51   ((CURRENT_HINTS & HINT_LOCALIZE_HH)                \
52     ? (PL_curcop->cop_features & (mask)) : FALSE)
53 
54 /* The longest string we pass in.  */
55 #define MAX_FEATURE_LEN (sizeof("bareword_filehandles")-1)
56 
57 #define FEATURE_FC_IS_ENABLED \
58     ( \
59 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
60 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
61      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
62 	 FEATURE_IS_ENABLED_MASK(FEATURE_FC_BIT)) \
63     )
64 
65 #define FEATURE_ISA_IS_ENABLED \
66     ( \
67 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_535 \
68      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
69 	 FEATURE_IS_ENABLED_MASK(FEATURE_ISA_BIT)) \
70     )
71 
72 #define FEATURE_SAY_IS_ENABLED \
73     ( \
74 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \
75 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
76      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
77 	 FEATURE_IS_ENABLED_MASK(FEATURE_SAY_BIT)) \
78     )
79 
80 #define FEATURE_TRY_IS_ENABLED \
81     ( \
82 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
83 	 FEATURE_IS_ENABLED_MASK(FEATURE_TRY_BIT) \
84     )
85 
86 #define FEATURE_DEFER_IS_ENABLED \
87     ( \
88 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
89 	 FEATURE_IS_ENABLED_MASK(FEATURE_DEFER_BIT) \
90     )
91 
92 #define FEATURE_STATE_IS_ENABLED \
93     ( \
94 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \
95 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
96      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
97 	 FEATURE_IS_ENABLED_MASK(FEATURE_STATE_BIT)) \
98     )
99 
100 #define FEATURE_SWITCH_IS_ENABLED \
101     ( \
102 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \
103 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_527) \
104      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
105 	 FEATURE_IS_ENABLED_MASK(FEATURE_SWITCH_BIT)) \
106     )
107 
108 #define FEATURE_BITWISE_IS_ENABLED \
109     ( \
110 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_527 && \
111 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
112      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
113 	 FEATURE_IS_ENABLED_MASK(FEATURE_BITWISE_BIT)) \
114     )
115 
116 #define FEATURE_INDIRECT_IS_ENABLED \
117     ( \
118 	CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_527 \
119      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
120 	 FEATURE_IS_ENABLED_MASK(FEATURE_INDIRECT_BIT)) \
121     )
122 
123 #define FEATURE_EVALBYTES_IS_ENABLED \
124     ( \
125 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
126 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
127      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
128 	 FEATURE_IS_ENABLED_MASK(FEATURE_EVALBYTES_BIT)) \
129     )
130 
131 #define FEATURE_SIGNATURES_IS_ENABLED \
132     ( \
133 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_535 \
134      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
135 	 FEATURE_IS_ENABLED_MASK(FEATURE_SIGNATURES_BIT)) \
136     )
137 
138 #define FEATURE___SUB___IS_ENABLED \
139     ( \
140 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
141 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
142      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
143 	 FEATURE_IS_ENABLED_MASK(FEATURE___SUB___BIT)) \
144     )
145 
146 #define FEATURE_REFALIASING_IS_ENABLED \
147     ( \
148 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
149 	 FEATURE_IS_ENABLED_MASK(FEATURE_REFALIASING_BIT) \
150     )
151 
152 #define FEATURE_POSTDEREF_QQ_IS_ENABLED \
153     ( \
154 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_523 && \
155 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
156      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
157 	 FEATURE_IS_ENABLED_MASK(FEATURE_POSTDEREF_QQ_BIT)) \
158     )
159 
160 #define FEATURE_UNIEVAL_IS_ENABLED \
161     ( \
162 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
163 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
164      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
165 	 FEATURE_IS_ENABLED_MASK(FEATURE_UNIEVAL_BIT)) \
166     )
167 
168 #define FEATURE_MYREF_IS_ENABLED \
169     ( \
170 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
171 	 FEATURE_IS_ENABLED_MASK(FEATURE_MYREF_BIT) \
172     )
173 
174 #define FEATURE_UNICODE_IS_ENABLED \
175     ( \
176 	(CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_511 && \
177 	 CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535) \
178      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
179 	 FEATURE_IS_ENABLED_MASK(FEATURE_UNICODE_BIT)) \
180     )
181 
182 #define FEATURE_MULTIDIMENSIONAL_IS_ENABLED \
183     ( \
184 	CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_527 \
185      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
186 	 FEATURE_IS_ENABLED_MASK(FEATURE_MULTIDIMENSIONAL_BIT)) \
187     )
188 
189 #define FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED \
190     ( \
191 	CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535 \
192      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
193 	 FEATURE_IS_ENABLED_MASK(FEATURE_BAREWORD_FILEHANDLES_BIT)) \
194     )
195 
196 #define FEATURE_MORE_DELIMS_IS_ENABLED \
197     ( \
198 	CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
199 	 FEATURE_IS_ENABLED_MASK(FEATURE_MORE_DELIMS_BIT) \
200     )
201 
202 
203 #define SAVEFEATUREBITS() SAVEI32(PL_compiling.cop_features)
204 
205 #define CLEARFEATUREBITS() (PL_compiling.cop_features = 0)
206 
207 #define STOREFEATUREBITSHH(hh) \
208   (hv_stores((hh), "feature/bits", newSVuv(PL_compiling.cop_features)))
209 
210 #define FETCHFEATUREBITSHH(hh)                              \
211   STMT_START {                                              \
212       SV **fbsv = hv_fetchs((hh), "feature/bits", FALSE);   \
213       PL_compiling.cop_features = fbsv ? SvUV(*fbsv) : 0;   \
214   } STMT_END
215 
216 #endif /* PERL_CORE or PERL_EXT */
217 
218 #ifdef PERL_IN_OP_C
219 PERL_STATIC_INLINE void
220 S_enable_feature_bundle(pTHX_ SV *ver)
221 {
222     SV *comp_ver = sv_newmortal();
223     PL_hints = (PL_hints &~ HINT_FEATURE_MASK)
224 	     | (
225 		  (sv_setnv(comp_ver, 5.035),
226 		   vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
227 			? FEATURE_BUNDLE_535 :
228 		  (sv_setnv(comp_ver, 5.027),
229 		   vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
230 			? FEATURE_BUNDLE_527 :
231 		  (sv_setnv(comp_ver, 5.023),
232 		   vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
233 			? FEATURE_BUNDLE_523 :
234 		  (sv_setnv(comp_ver, 5.015),
235 		   vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
236 			? FEATURE_BUNDLE_515 :
237 		  (sv_setnv(comp_ver, 5.011),
238 		   vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
239 			? FEATURE_BUNDLE_511 :
240 		  (sv_setnv(comp_ver, 5.009005),
241 		   vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
242 			? FEATURE_BUNDLE_510 :
243 			  FEATURE_BUNDLE_DEFAULT
244 	       ) << HINT_FEATURE_SHIFT;
245     /* special case */
246     assert(PL_curcop == &PL_compiling);
247     if (FEATURE_UNICODE_IS_ENABLED) PL_hints |=  HINT_UNI_8_BIT;
248     else			    PL_hints &= ~HINT_UNI_8_BIT;
249 }
250 #endif /* PERL_IN_OP_C */
251 
252 #ifdef PERL_IN_MG_C
253 
254 #define magic_sethint_feature(keysv, keypv, keylen, valsv, valbool) \
255     S_magic_sethint_feature(aTHX_ (keysv), (keypv), (keylen), (valsv), (valbool))
256 PERL_STATIC_INLINE void
257 S_magic_sethint_feature(pTHX_ SV *keysv, const char *keypv, STRLEN keylen,
258                         SV *valsv, bool valbool) {
259     if (keysv)
260       keypv = SvPV_const(keysv, keylen);
261 
262     if (memBEGINs(keypv, keylen, "feature_")) {
263         const char *subf = keypv + (sizeof("feature_")-1);
264         U32 mask = 0;
265         switch (*subf) {
266         case '_':
267             if (keylen == sizeof("feature___SUB__")-1
268                  && memcmp(subf+1, "_SUB__", keylen - sizeof("feature_")) == 0) {
269                 mask = FEATURE___SUB___BIT;
270                 break;
271             }
272             return;
273 
274         case 'b':
275             if (keylen == sizeof("feature_bareword_filehandles")-1
276                  && memcmp(subf+1, "areword_filehandles", keylen - sizeof("feature_")) == 0) {
277                 mask = FEATURE_BAREWORD_FILEHANDLES_BIT;
278                 break;
279             }
280             else if (keylen == sizeof("feature_bitwise")-1
281                  && memcmp(subf+1, "itwise", keylen - sizeof("feature_")) == 0) {
282                 mask = FEATURE_BITWISE_BIT;
283                 break;
284             }
285             return;
286 
287         case 'd':
288             if (keylen == sizeof("feature_defer")-1
289                  && memcmp(subf+1, "efer", keylen - sizeof("feature_")) == 0) {
290                 mask = FEATURE_DEFER_BIT;
291                 break;
292             }
293             return;
294 
295         case 'e':
296             if (keylen == sizeof("feature_evalbytes")-1
297                  && memcmp(subf+1, "valbytes", keylen - sizeof("feature_")) == 0) {
298                 mask = FEATURE_EVALBYTES_BIT;
299                 break;
300             }
301             return;
302 
303         case 'f':
304             if (keylen == sizeof("feature_fc")-1
305                  && memcmp(subf+1, "c", keylen - sizeof("feature_")) == 0) {
306                 mask = FEATURE_FC_BIT;
307                 break;
308             }
309             return;
310 
311         case 'i':
312             if (keylen == sizeof("feature_indirect")-1
313                  && memcmp(subf+1, "ndirect", keylen - sizeof("feature_")) == 0) {
314                 mask = FEATURE_INDIRECT_BIT;
315                 break;
316             }
317             else if (keylen == sizeof("feature_isa")-1
318                  && memcmp(subf+1, "sa", keylen - sizeof("feature_")) == 0) {
319                 mask = FEATURE_ISA_BIT;
320                 break;
321             }
322             return;
323 
324         case 'm':
325             if (keylen == sizeof("feature_more_delims")-1
326                  && memcmp(subf+1, "ore_delims", keylen - sizeof("feature_")) == 0) {
327                 mask = FEATURE_MORE_DELIMS_BIT;
328                 break;
329             }
330             else if (keylen == sizeof("feature_multidimensional")-1
331                  && memcmp(subf+1, "ultidimensional", keylen - sizeof("feature_")) == 0) {
332                 mask = FEATURE_MULTIDIMENSIONAL_BIT;
333                 break;
334             }
335             else if (keylen == sizeof("feature_myref")-1
336                  && memcmp(subf+1, "yref", keylen - sizeof("feature_")) == 0) {
337                 mask = FEATURE_MYREF_BIT;
338                 break;
339             }
340             return;
341 
342         case 'p':
343             if (keylen == sizeof("feature_postderef_qq")-1
344                  && memcmp(subf+1, "ostderef_qq", keylen - sizeof("feature_")) == 0) {
345                 mask = FEATURE_POSTDEREF_QQ_BIT;
346                 break;
347             }
348             return;
349 
350         case 'r':
351             if (keylen == sizeof("feature_refaliasing")-1
352                  && memcmp(subf+1, "efaliasing", keylen - sizeof("feature_")) == 0) {
353                 mask = FEATURE_REFALIASING_BIT;
354                 break;
355             }
356             return;
357 
358         case 's':
359             if (keylen == sizeof("feature_say")-1
360                  && memcmp(subf+1, "ay", keylen - sizeof("feature_")) == 0) {
361                 mask = FEATURE_SAY_BIT;
362                 break;
363             }
364             else if (keylen == sizeof("feature_signatures")-1
365                  && memcmp(subf+1, "ignatures", keylen - sizeof("feature_")) == 0) {
366                 mask = FEATURE_SIGNATURES_BIT;
367                 break;
368             }
369             else if (keylen == sizeof("feature_state")-1
370                  && memcmp(subf+1, "tate", keylen - sizeof("feature_")) == 0) {
371                 mask = FEATURE_STATE_BIT;
372                 break;
373             }
374             else if (keylen == sizeof("feature_switch")-1
375                  && memcmp(subf+1, "witch", keylen - sizeof("feature_")) == 0) {
376                 mask = FEATURE_SWITCH_BIT;
377                 break;
378             }
379             return;
380 
381         case 't':
382             if (keylen == sizeof("feature_try")-1
383                  && memcmp(subf+1, "ry", keylen - sizeof("feature_")) == 0) {
384                 mask = FEATURE_TRY_BIT;
385                 break;
386             }
387             return;
388 
389         case 'u':
390             if (keylen == sizeof("feature_unicode")-1
391                  && memcmp(subf+1, "nicode", keylen - sizeof("feature_")) == 0) {
392                 mask = FEATURE_UNICODE_BIT;
393                 break;
394             }
395             else if (keylen == sizeof("feature_unieval")-1
396                  && memcmp(subf+1, "nieval", keylen - sizeof("feature_")) == 0) {
397                 mask = FEATURE_UNIEVAL_BIT;
398                 break;
399             }
400             return;
401 
402         default:
403             return;
404         }
405         if (valsv ? SvTRUE(valsv) : valbool)
406             PL_compiling.cop_features |= mask;
407         else
408             PL_compiling.cop_features &= ~mask;
409     }
410 }
411 #endif /* PERL_IN_MG_C */
412 
413 #endif /* PERL_FEATURE_H_ */
414 
415 /* ex: set ro: */
416