Skip to content

Commit 50ccfd8

Browse files
authored
rclpy_init() passes command line arguments to rcl_init() (#179)
* rclpy_init() passes command line arguments to rcl_init() * comment that exception is already raised * Fix windows warning about data loss * Pass NULL when num_args == 0
1 parent f6b5291 commit 50ccfd8

File tree

1 file changed

+56
-7
lines changed

1 file changed

+56
-7
lines changed

rclpy/src/rclpy/_rclpy.c

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,63 @@ rclpy_trigger_guard_condition(PyObject * Py_UNUSED(self), PyObject * args)
155155
* Raises RuntimeError if rcl could not be initialized
156156
*/
157157
static PyObject *
158-
rclpy_init(PyObject * Py_UNUSED(self), PyObject * Py_UNUSED(args))
158+
rclpy_init(PyObject * Py_UNUSED(self), PyObject * args)
159159
{
160-
// TODO(esteve): parse args
161-
rcl_ret_t ret = rcl_init(0, NULL, rcl_get_default_allocator());
162-
if (ret != RCL_RET_OK) {
163-
PyErr_Format(PyExc_RuntimeError,
164-
"Failed to init: %s", rcl_get_error_string_safe());
165-
rcl_reset_error();
160+
// Expect one argument which is a list of strings
161+
PyObject * pyargs;
162+
if (!PyArg_ParseTuple(args, "O", &pyargs)) {
163+
// Exception raised
164+
return NULL;
165+
}
166+
167+
pyargs = PySequence_List(pyargs);
168+
if (NULL == pyargs) {
169+
// Exception raised
170+
return NULL;
171+
}
172+
Py_ssize_t pysize_num_args = PyList_Size(pyargs);
173+
if (pysize_num_args > INT_MAX) {
174+
PyErr_Format(PyExc_OverflowError, "Too many arguments");
175+
return NULL;
176+
}
177+
int num_args = (int)pysize_num_args;
178+
179+
rcl_allocator_t allocator = rcl_get_default_allocator();
180+
char ** arg_values = NULL;
181+
bool have_args = true;
182+
if (num_args > 0) {
183+
arg_values = allocator.allocate(sizeof(char *) * num_args, allocator.state);
184+
if (NULL == arg_values) {
185+
PyErr_Format(PyExc_MemoryError, "Failed to allocate space for arguments");
186+
Py_DECREF(pyargs);
187+
return NULL;
188+
}
189+
190+
for (int i = 0; i < num_args; ++i) {
191+
// Returns borrowed reference, do not decref
192+
PyObject * pyarg = PyList_GetItem(pyargs, i);
193+
if (NULL == pyarg) {
194+
have_args = false;
195+
break;
196+
}
197+
// Borrows a pointer, do not free arg_values[i]
198+
arg_values[i] = PyUnicode_AsUTF8(pyarg);
199+
}
200+
}
201+
202+
if (have_args) {
203+
rcl_ret_t ret = rcl_init(num_args, arg_values, allocator);
204+
if (ret != RCL_RET_OK) {
205+
PyErr_Format(PyExc_RuntimeError, "Failed to init: %s", rcl_get_error_string_safe());
206+
rcl_reset_error();
207+
}
208+
}
209+
if (NULL != arg_values) {
210+
allocator.deallocate(arg_values, allocator.state);
211+
}
212+
Py_DECREF(pyargs);
213+
214+
if (PyErr_Occurred()) {
166215
return NULL;
167216
}
168217
Py_RETURN_NONE;

0 commit comments

Comments
 (0)