This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perlretut: "-" is sometimes a metacharacter
[perl5.git] / dquote.c
1 /*    dquote.c
2  *
3  * This file contains functions that are related to
4  * parsing double-quotish expressions.
5  *
6 */
7
8 #include "EXTERN.h"
9 #define PERL_IN_DQUOTE_C
10 #include "perl.h"
11 #include "dquote_inline.h"
12
13 /* XXX Add documentation after final interface and behavior is decided */
14 /* May want to show context for error, so would pass S_grok_bslash_c(pTHX_ const char* current, const char* start, const bool output_warning)
15     U8 source = *current;
16 */
17
18 char
19 Perl_grok_bslash_c(pTHX_ const char source, const bool output_warning)
20 {
21
22     U8 result;
23
24     if (! isPRINT_A(source)) {
25         Perl_croak(aTHX_ "%s",
26                         "Character following \"\\c\" must be printable ASCII");
27     }
28     else if (source == '{') {
29         const char control = toCTRL('{');
30         if (isPRINT_A(control)) {
31             /* diag_listed_as: Use "%s" instead of "%s" */
32             Perl_croak(aTHX_ "Use \"%c\" instead of \"\\c{\"", control);
33         }
34         else {
35             Perl_croak(aTHX_ "Sequence \"\\c{\" invalid");
36         }
37     }
38
39     result = toCTRL(source);
40     if (output_warning && isPRINT_A(result)) {
41         U8 clearer[3];
42         U8 i = 0;
43         if (! isWORDCHAR(result)) {
44             clearer[i++] = '\\';
45         }
46         clearer[i++] = result;
47         clearer[i++] = '\0';
48
49         Perl_ck_warner(aTHX_ packWARN(WARN_SYNTAX),
50                         "\"\\c%c\" is more clearly written simply as \"%s\"",
51                         source,
52                         clearer);
53     }
54
55     return result;
56 }
57
58 bool
59 Perl_grok_bslash_o(pTHX_ char **s, UV *uv, const char** error_msg,
60                       const bool output_warning, const bool strict,
61                       const bool silence_non_portable,
62                       const bool UTF)
63 {
64
65 /*  Documentation to be supplied when interface nailed down finally
66  *  This returns FALSE if there is an error which the caller need not recover
67  *  from; otherwise TRUE.  In either case the caller should look at *len [???].
68  *  It guarantees that the returned codepoint, *uv, when expressed as
69  *  utf8 bytes, would fit within the skipped "\o{...}" bytes.
70  *  On input:
71  *      s   is the address of a pointer to a NULL terminated string that begins
72  *          with 'o', and the previous character was a backslash.  At exit, *s
73  *          will be advanced to the byte just after those absorbed by this
74  *          function.  Hence the caller can continue parsing from there.  In
75  *          the case of an error, this routine has generally positioned *s to
76  *          point just to the right of the first bad spot, so that a message
77  *          that has a "<--" to mark the spot will be correctly positioned.
78  *      uv  points to a UV that will hold the output value, valid only if the
79  *          return from the function is TRUE
80  *      error_msg is a pointer that will be set to an internal buffer giving an
81  *          error message upon failure (the return is FALSE).  Untouched if
82  *          function succeeds
83  *      output_warning says whether to output any warning messages, or suppress
84  *          them
85  *      strict is true if this should fail instead of warn if there are
86  *          non-octal digits within the braces
87  *      silence_non_portable is true if to suppress warnings about the code
88  *          point returned being too large to fit on all platforms.
89  *      UTF is true iff the string *s is encoded in UTF-8.
90  */
91     char* e;
92     STRLEN numbers_len;
93     I32 flags = PERL_SCAN_ALLOW_UNDERSCORES
94                 | PERL_SCAN_DISALLOW_PREFIX
95                 /* XXX Until the message is improved in grok_oct, handle errors
96                  * ourselves */
97                 | PERL_SCAN_SILENT_ILLDIGIT;
98
99 #ifdef DEBUGGING
100     char *start = *s - 1;
101     assert(*start == '\\');
102 #endif
103
104     PERL_ARGS_ASSERT_GROK_BSLASH_O;
105
106
107     assert(**s == 'o');
108     (*s)++;
109
110     if (**s != '{') {
111         *error_msg = "Missing braces on \\o{}";
112         return FALSE;
113     }
114
115     e = strchr(*s, '}');
116     if (!e) {
117         (*s)++;  /* Move past the '{' */
118         while (isOCTAL(**s)) { /* Position beyond the legal digits */
119             (*s)++;
120         }
121         *error_msg = "Missing right brace on \\o{";
122         return FALSE;
123     }
124
125     (*s)++;    /* Point to expected first digit (could be first byte of utf8
126                   sequence if not a digit) */
127     numbers_len = e - *s;
128     if (numbers_len == 0) {
129         (*s)++;    /* Move past the } */
130         *error_msg = "Number with no digits";
131         return FALSE;
132     }
133
134     if (silence_non_portable) {
135         flags |= PERL_SCAN_SILENT_NON_PORTABLE;
136     }
137
138     *uv = grok_oct(*s, &numbers_len, &flags, NULL);
139     /* Note that if has non-octal, will ignore everything starting with that up
140      * to the '}' */
141
142     if (numbers_len != (STRLEN) (e - *s)) {
143         if (strict) {
144             *s += numbers_len;
145             *s += (UTF) ? UTF8SKIP(*s) : (STRLEN) 1;
146             *error_msg = "Non-octal character";
147             return FALSE;
148         }
149         else if (output_warning) {
150             Perl_ck_warner(aTHX_ packWARN(WARN_DIGIT),
151             /* diag_listed_as: Non-octal character '%c'.  Resolved as "%s" */
152                         "Non-octal character '%c'.  Resolved as \"\\o{%.*s}\"",
153                         *(*s + numbers_len),
154                         (int) numbers_len,
155                         *s);
156         }
157     }
158
159     /* Return past the '}' */
160     *s = e + 1;
161
162     return TRUE;
163 }
164
165 bool
166 Perl_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg,
167                       const bool output_warning, const bool strict,
168                       const bool silence_non_portable,
169                       const bool UTF)
170 {
171
172 /*  Documentation to be supplied when interface nailed down finally
173  *  This returns FALSE if there is an error which the caller need not recover
174  *  from; otherwise TRUE.
175  *  It guarantees that the returned codepoint, *uv, when expressed as
176  *  utf8 bytes, would fit within the skipped "\x{...}" bytes.
177  *
178  *  On input:
179  *      s   is the address of a pointer to a NULL terminated string that begins
180  *          with 'x', and the previous character was a backslash.  At exit, *s
181  *          will be advanced to the byte just after those absorbed by this
182  *          function.  Hence the caller can continue parsing from there.  In
183  *          the case of an error, this routine has generally positioned *s to
184  *          point just to the right of the first bad spot, so that a message
185  *          that has a "<--" to mark the spot will be correctly positioned.
186  *      uv  points to a UV that will hold the output value, valid only if the
187  *          return from the function is TRUE
188  *      error_msg is a pointer that will be set to an internal buffer giving an
189  *          error message upon failure (the return is FALSE).  Untouched if
190  *          function succeeds
191  *      output_warning says whether to output any warning messages, or suppress
192  *          them
193  *      strict is true if anything out of the ordinary should cause this to
194  *          fail instead of warn or be silent.  For example, it requires
195  *          exactly 2 digits following the \x (when there are no braces).
196  *          3 digits could be a mistake, so is forbidden in this mode.
197  *      silence_non_portable is true if to suppress warnings about the code
198  *          point returned being too large to fit on all platforms.
199  *      UTF is true iff the string *s is encoded in UTF-8.
200  */
201     char* e;
202     STRLEN numbers_len;
203     I32 flags = PERL_SCAN_DISALLOW_PREFIX;
204 #ifdef DEBUGGING
205     char *start = *s - 1;
206     assert(*start == '\\');
207 #endif
208
209     PERL_ARGS_ASSERT_GROK_BSLASH_X;
210
211     assert(**s == 'x');
212     (*s)++;
213
214     if (strict || ! output_warning) {
215         flags |= PERL_SCAN_SILENT_ILLDIGIT;
216     }
217
218     if (**s != '{') {
219         STRLEN len = (strict) ? 3 : 2;
220
221         *uv = grok_hex(*s, &len, &flags, NULL);
222         *s += len;
223         if (strict && len != 2) {
224             if (len < 2) {
225                 *s += (UTF) ? UTF8SKIP(*s) : 1;
226                 *error_msg = "Non-hex character";
227             }
228             else {
229                 *error_msg = "Use \\x{...} for more than two hex characters";
230             }
231             return FALSE;
232         }
233         return TRUE;
234     }
235
236     e = strchr(*s, '}');
237     if (!e) {
238         (*s)++;  /* Move past the '{' */
239         while (isXDIGIT(**s)) { /* Position beyond the legal digits */
240             (*s)++;
241         }
242         /* XXX The corresponding message above for \o is just '\\o{'; other
243          * messages for other constructs include the '}', so are inconsistent.
244          */
245         *error_msg = "Missing right brace on \\x{}";
246         return FALSE;
247     }
248
249     (*s)++;    /* Point to expected first digit (could be first byte of utf8
250                   sequence if not a digit) */
251     numbers_len = e - *s;
252     if (numbers_len == 0) {
253         if (strict) {
254             (*s)++;    /* Move past the } */
255             *error_msg = "Number with no digits";
256             return FALSE;
257         }
258         *s = e + 1;
259         *uv = 0;
260         return TRUE;
261     }
262
263     flags |= PERL_SCAN_ALLOW_UNDERSCORES;
264     if (silence_non_portable) {
265         flags |= PERL_SCAN_SILENT_NON_PORTABLE;
266     }
267
268     *uv = grok_hex(*s, &numbers_len, &flags, NULL);
269     /* Note that if has non-hex, will ignore everything starting with that up
270      * to the '}' */
271
272     if (strict && numbers_len != (STRLEN) (e - *s)) {
273         *s += numbers_len;
274         *s += (UTF) ? UTF8SKIP(*s) : 1;
275         *error_msg = "Non-hex character";
276         return FALSE;
277     }
278
279     /* Return past the '}' */
280     *s = e + 1;
281
282     return TRUE;
283 }
284
285 /*
286  * ex: set ts=8 sts=4 sw=4 et:
287  */