blob: 6bd880d92a2d2aa03a519154940dbae9c96f49ac [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
2 * This file is part of the Micro Python project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
Damien George136f6752014-01-07 14:54:15 +000027#include "mpconfig.h"
Paul Sokolovsky59c675a2014-06-21 22:43:22 +030028#include "misc.h"
Damien92c06562013-10-22 22:32:27 +010029#include "repl.h"
30
Damien George58ebde42014-05-21 20:32:59 +010031#if MICROPY_HELPER_REPL
Damien George136f6752014-01-07 14:54:15 +000032
Damien George969a6b32014-12-10 22:07:04 +000033STATIC bool str_startswith_word(const char *str, const char *head) {
Damien George42f3de92014-10-03 17:44:14 +000034 mp_uint_t i;
Damien92c06562013-10-22 22:32:27 +010035 for (i = 0; str[i] && head[i]; i++) {
36 if (str[i] != head[i]) {
37 return false;
38 }
39 }
Damien George8cc96a32013-12-30 18:23:50 +000040 return head[i] == '\0' && (str[i] == '\0' || !unichar_isalpha(str[i]));
Damien92c06562013-10-22 22:32:27 +010041}
42
Damien George97790452014-04-08 11:04:29 +000043bool mp_repl_continue_with_input(const char *input) {
44 // check for blank input
45 if (input[0] == '\0') {
46 return false;
Damien92c06562013-10-22 22:32:27 +010047 }
48
Damien George97790452014-04-08 11:04:29 +000049 // check if input starts with a certain keyword
50 bool starts_with_compound_keyword =
51 input[0] == '@'
52 || str_startswith_word(input, "if")
53 || str_startswith_word(input, "while")
54 || str_startswith_word(input, "for")
55 || str_startswith_word(input, "try")
56 || str_startswith_word(input, "with")
57 || str_startswith_word(input, "def")
58 || str_startswith_word(input, "class")
59 ;
60
61 // check for unmatched open bracket or triple quote
62 // TODO don't look at triple quotes inside single quotes
Damien92c06562013-10-22 22:32:27 +010063 int n_paren = 0;
64 int n_brack = 0;
65 int n_brace = 0;
Damien Georgea28507a2014-04-07 13:01:30 +010066 int in_triple_quote = 0;
Damien George97790452014-04-08 11:04:29 +000067 const char *i;
68 for (i = input; *i; i++) {
69 switch (*i) {
Damien92c06562013-10-22 22:32:27 +010070 case '(': n_paren += 1; break;
71 case ')': n_paren -= 1; break;
72 case '[': n_brack += 1; break;
73 case ']': n_brack -= 1; break;
74 case '{': n_brace += 1; break;
75 case '}': n_brace -= 1; break;
Damien George97790452014-04-08 11:04:29 +000076 case '\'':
77 if (in_triple_quote != '"' && i[1] == '\'' && i[2] == '\'') {
78 i += 2;
79 in_triple_quote = '\'' - in_triple_quote;
80 }
81 break;
Damien Georgea28507a2014-04-07 13:01:30 +010082 case '"':
Damien George97790452014-04-08 11:04:29 +000083 if (in_triple_quote != '\'' && i[1] == '"' && i[2] == '"') {
84 i += 2;
85 in_triple_quote = '"' - in_triple_quote;
Damien Georgea28507a2014-04-07 13:01:30 +010086 }
87 break;
Damien92c06562013-10-22 22:32:27 +010088 }
89 }
Damien George97790452014-04-08 11:04:29 +000090
91 // continue if unmatched brackets or quotes
92 if (n_paren > 0 || n_brack > 0 || n_brace > 0 || in_triple_quote != 0) {
93 return true;
94 }
95
Damien George73c79b92014-04-08 11:33:28 +000096 // continue if last character was backslash (for line continuation)
97 if (i[-1] == '\\') {
98 return true;
99 }
100
Damien George97790452014-04-08 11:04:29 +0000101 // continue if compound keyword and last line was not empty
102 if (starts_with_compound_keyword && i[-1] != '\n') {
103 return true;
104 }
105
106 // otherwise, don't continue
107 return false;
Damien92c06562013-10-22 22:32:27 +0100108}
Damien George136f6752014-01-07 14:54:15 +0000109
Damien George58ebde42014-05-21 20:32:59 +0100110#endif // MICROPY_HELPER_REPL