LP-89 - Port OP_15.05.01 fixes. Release notes:
[librepilot.git] / flight / libraries / PyMite / vm / tuple.c
blobdcf25f8f3513e0a9fb34c84c32a8b70fe417d905
1 /*
2 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
4 # This file is part of the PyMite VM.
5 # The PyMite VM is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
8 # The PyMite VM is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
12 # is seen in the file COPYING in this directory.
16 #undef __FILE_ID__
17 #define __FILE_ID__ 0x13
20 /**
21 * \file
22 * \brief Tuple Object Type
24 * Tuple object type operations.
28 #include "pm.h"
31 /* The follwing value should match that in pmImgCreator.py */
32 #define MAX_TUPLE_LEN 253
35 PmReturn_t
36 tuple_loadFromImg(PmMemSpace_t memspace,
37 uint8_t const **paddr, pPmObj_t *r_ptuple)
39 PmReturn_t retval = PM_RET_OK;
40 uint8_t i = (uint8_t)0;
41 uint8_t n = (uint8_t)0;
42 uint8_t objid;
44 /* Get num objs in tuple */
45 n = mem_getByte(memspace, paddr);
47 /* Create empty tuple */
48 retval = tuple_new(n, r_ptuple);
49 PM_RETURN_IF_ERROR(retval);
50 ((pPmTuple_t)*r_ptuple)->length = 0;
52 /* Load the next n objs into tuple */
53 heap_gcPushTempRoot((pPmObj_t)*r_ptuple, &objid);
54 for (i = (uint8_t)0; i < n; i++)
56 retval = obj_loadFromImg(memspace,
57 paddr,
58 (pPmObj_t *)&(((pPmTuple_t)*r_ptuple)->
59 val[i]));
60 if (retval != PM_RET_OK)
62 heap_gcPopTempRoot(objid);
63 return retval;
65 ((pPmTuple_t)*r_ptuple)->length++;
67 heap_gcPopTempRoot(objid);
68 return PM_RET_OK;
72 PmReturn_t
73 tuple_new(uint16_t n, pPmObj_t *r_ptuple)
75 PmReturn_t retval = PM_RET_OK;
76 uint16_t size = 0;
78 /* Raise a SystemError for a Tuple that is too large */
79 if (n > MAX_TUPLE_LEN)
81 PM_RAISE(retval, PM_RET_EX_SYS);
82 return retval;
85 /* Calc size of struct to hold tuple; (n-1) because PmTuple_t has val[1] */
86 size = sizeof(PmTuple_t) + ((n - 1) * sizeof(pPmObj_t));
88 /* Allocate a tuple */
89 retval = heap_getChunk(size, (uint8_t **)r_ptuple);
90 PM_RETURN_IF_ERROR(retval);
91 OBJ_SET_TYPE(*r_ptuple, OBJ_TYPE_TUP);
93 /* Set the number of objs in the tuple */
94 ((pPmTuple_t)*r_ptuple)->length = n;
96 /* No need to null the ptrs because they are set by the caller */
97 return retval;
101 PmReturn_t
102 tuple_replicate(pPmObj_t ptup, int16_t n, pPmObj_t *r_ptuple)
104 PmReturn_t retval = PM_RET_OK;
105 int16_t length;
106 int16_t i;
107 int16_t j;
109 /* Raise TypeError if object is not a Tuple */
110 if (OBJ_GET_TYPE(ptup) != OBJ_TYPE_TUP)
112 PM_RAISE(retval, PM_RET_EX_SYS);
113 return retval;
116 C_ASSERT(n >= 0);
118 /* Allocate the new tuple */
119 length = ((pPmTuple_t)ptup)->length;
120 retval = tuple_new(length * n, r_ptuple);
121 PM_RETURN_IF_ERROR(retval);
123 /* Copy src tuple the designated number of times */
124 for (i = 0; i < n; i++)
126 for (j = 0; j < length; j++)
128 ((pPmTuple_t)*r_ptuple)->val[length * i + j] =
129 ((pPmTuple_t)ptup)->val[j];
132 return retval;
136 PmReturn_t
137 tuple_getItem(pPmObj_t ptup, int16_t index, pPmObj_t *r_pobj)
139 PmReturn_t retval = PM_RET_OK;
141 /* Adjust for negative index */
142 if (index < 0)
144 index += ((pPmTuple_t)ptup)->length;
147 /* Raise IndexError if index is out of bounds */
148 if ((index < 0) || (index > ((pPmTuple_t)ptup)->length))
150 PM_RAISE(retval, PM_RET_EX_INDX);
153 /* Get the tuple item */
154 *r_pobj = ((pPmTuple_t)ptup)->val[index];
156 return retval;
160 #ifdef HAVE_PRINT
161 PmReturn_t
162 tuple_print(pPmObj_t ptup)
164 PmReturn_t retval = PM_RET_OK;
165 int16_t index;
167 C_ASSERT(ptup != C_NULL);
169 /* If it's not a tuple, raise TypeError */
170 if (OBJ_GET_TYPE(ptup) != OBJ_TYPE_TUP)
172 PM_RAISE(retval, PM_RET_EX_TYPE);
173 return retval;
176 plat_putByte('(');
178 for (index = 0; index < ((pPmTuple_t)ptup)->length; index++)
180 if (index != 0)
182 plat_putByte(',');
183 plat_putByte(' ');
185 retval = obj_print(((pPmTuple_t)ptup)->val[index], C_FALSE, C_TRUE);
186 PM_RETURN_IF_ERROR(retval);
189 return plat_putByte(')');
191 #endif /* HAVE_PRINT */