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