Numworks Epsilon  1.4.1
Graphing Calculator Operating System
argcheck.c
Go to the documentation of this file.
1 /*
2  * This file is part of the MicroPython 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 
27 #include <stdlib.h>
28 #include <assert.h>
29 
30 #include "py/runtime.h"
31 
32 void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) {
33  // TODO maybe take the function name as an argument so we can print nicer error messages
34 
35  if (n_kw && !takes_kw) {
38  } else {
39  mp_raise_TypeError("function does not take keyword arguments");
40  }
41  }
42 
43  if (n_args_min == n_args_max) {
44  if (n_args != n_args_min) {
47  } else {
49  "function takes %d positional arguments but %d were given",
50  n_args_min, n_args));
51  }
52  }
53  } else {
54  if (n_args < n_args_min) {
57  } else {
59  "function missing %d required positional arguments",
60  n_args_min - n_args));
61  }
62  } else if (n_args > n_args_max) {
65  } else {
67  "function expected at most %d arguments, got %d",
68  n_args_max, n_args));
69  }
70  }
71  }
72 }
73 
74 void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
75  size_t pos_found = 0, kws_found = 0;
76  for (size_t i = 0; i < n_allowed; i++) {
77  mp_obj_t given_arg;
78  if (i < n_pos) {
79  if (allowed[i].flags & MP_ARG_KW_ONLY) {
80  goto extra_positional;
81  }
82  pos_found++;
83  given_arg = pos[i];
84  } else {
85  mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qst), MP_MAP_LOOKUP);
86  if (kw == NULL) {
87  if (allowed[i].flags & MP_ARG_REQUIRED) {
90  } else {
92  "'%q' argument required", allowed[i].qst));
93  }
94  }
95  out_vals[i] = allowed[i].defval;
96  continue;
97  } else {
98  kws_found++;
99  given_arg = kw->value;
100  }
101  }
102  if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_BOOL) {
103  out_vals[i].u_bool = mp_obj_is_true(given_arg);
104  } else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_INT) {
105  out_vals[i].u_int = mp_obj_get_int(given_arg);
106  } else {
107  assert((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_OBJ);
108  out_vals[i].u_obj = given_arg;
109  }
110  }
111  if (pos_found < n_pos) {
112  extra_positional:
115  } else {
116  // TODO better error message
117  mp_raise_TypeError("extra positional arguments given");
118  }
119  }
120  if (kws_found < kws->used) {
123  } else {
124  // TODO better error message
125  mp_raise_TypeError("extra keyword arguments given");
126  }
127  }
128 }
129 
130 void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
131  mp_map_t kw_args;
132  mp_map_init_fixed_table(&kw_args, n_kw, args + n_pos);
133  mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals);
134 }
135 
137  mp_raise_TypeError("argument num/types mismatch");
138 }
139 
140 #if MICROPY_CPYTHON_COMPAT
141 NORETURN void mp_arg_error_unimpl_kw(void) {
142  mp_raise_NotImplementedError("keyword argument(s) not yet implemented - use normal args instead");
143 }
144 #endif
#define assert(e)
Definition: assert.h:9
#define MICROPY_ERROR_REPORTING_TERSE
Definition: mpconfig.h:521
NORETURN void mp_raise_NotImplementedError(const char *msg)
Definition: runtime.c:1468
NORETURN void mp_arg_error_unimpl_kw(void)
const mp_obj_type_t mp_type_TypeError
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt,...)
Definition: objexcept.c:380
void mp_map_init_fixed_table(mp_map_t *map, size_t n, const mp_obj_t *table)
Definition: map.c:86
void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals)
Definition: argcheck.c:74
#define MP_OBJ_NEW_QSTR(qst)
Definition: obj.h:92
void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw)
Definition: argcheck.c:32
mp_int_t mp_obj_get_int(mp_const_obj_t arg)
Definition: obj.c:225
mp_obj_t u_obj
Definition: runtime.h:49
mp_map_elem_t * mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind)
Definition: map.c:138
void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals)
Definition: argcheck.c:130
#define MICROPY_ERROR_REPORTING
Definition: mpconfigport.h:32
#define NULL
Definition: stddef.h:4
mp_obj_t value
Definition: obj.h:343
args
Definition: i18n.py:175
#define NORETURN
Definition: mpconfig.h:1268
Definition: obj.h:356
mp_arg_val_t defval
Definition: runtime.h:56
#define nlr_raise(val)
Definition: nlr.h:89
NORETURN void mp_arg_error_terse_mismatch(void)
Definition: argcheck.c:136
uint64_t mp_obj_t
Definition: obj.h:39
NORETURN void mp_raise_TypeError(const char *msg)
Definition: runtime.c:1460
bool mp_obj_is_true(mp_obj_t arg)
Definition: obj.c:108
bool u_bool
Definition: runtime.h:47
mp_int_t u_int
Definition: runtime.h:48