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