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