Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / flight / libraries / PyMite / vm / img.c
blobad0bb03dca95acf8b43ca5cceb0fcee47c884228
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__ 0x07
20 /**
21 * \file
22 * \brief Image routines
24 * Created to eliminate a circular include
25 * among mem, string and obj.
29 #include "pm.h"
33 * Searches for a module's name in a contiguous array of images
34 * in the given namespace starting at the given address.
35 * A module's name is stored in the last index of the names tuple of an image.
37 static PmReturn_t
38 img_findInPath(uint8_t *cname, uint8_t cnamelen, PmMemSpace_t memspace,
39 uint8_t const **paddr)
41 uint8_t const *imgtop;
42 PmType_t type;
43 uint16_t len;
44 int16_t size = 0;
45 uint8_t i = 0;
47 /* Addr is top of img */
48 imgtop = *paddr;
50 /* Get img's type byte */
51 type = (PmType_t)mem_getByte(memspace, paddr);
53 /* Search all sequential images */
54 while (type == OBJ_TYPE_CIM)
56 /* Use size field to calc addr of next potential img */
57 size = mem_getWord(memspace, paddr);
59 /* Point to names tuple */
60 *paddr = imgtop + CI_NAMES_FIELD;
62 /* Ensure it's a tuple */
63 type = (PmType_t)mem_getByte(memspace, paddr);
64 C_ASSERT(type == OBJ_TYPE_TUP);
66 /* Scan to last name in tuple (it's the module's name) */
67 i = mem_getByte(memspace, paddr) - (uint8_t)1;
68 for (; i > 0; i--)
70 /* Ensure obj is a string */
71 type = (PmType_t)mem_getByte(memspace, paddr);
72 C_ASSERT(type == OBJ_TYPE_STR);
74 /* Skip the length of the string */
75 len = mem_getWord(memspace, paddr);
76 (*paddr) += len;
79 /* Ensure it's a string */
80 type = (PmType_t)mem_getByte(memspace, paddr);
81 C_ASSERT(type == OBJ_TYPE_STR);
83 /* If strings match, return the address of this image */
84 if ((cnamelen == mem_getWord(memspace, paddr))
85 && (PM_RET_OK == mem_cmpn(cname, cnamelen, memspace, paddr)))
87 *paddr = imgtop;
88 return PM_RET_OK;
91 /* Calc imgtop for next iteration */
92 imgtop += size;
94 /* Point to next potential img */
95 *paddr = imgtop;
97 /* Check if another img follows this one */
98 type = (PmType_t)mem_getByte(memspace, paddr);
100 return PM_RET_NO;
104 PmReturn_t
105 img_findInPaths(pPmObj_t pname, PmMemSpace_t *r_memspace,
106 uint8_t const **r_imgaddr)
108 uint8_t i;
109 PmReturn_t retval = PM_RET_NO;
111 /* Search in each path in the paths */
112 for (i = 0; i < gVmGlobal.imgPaths.pathcount; i++)
114 *r_imgaddr = gVmGlobal.imgPaths.pimg[i];
115 *r_memspace = gVmGlobal.imgPaths.memspace[i];
116 retval = img_findInPath(((pPmString_t)pname)->val,
117 ((pPmString_t)pname)->length,
118 *r_memspace, r_imgaddr);
119 if (retval == PM_RET_NO)
121 continue;
123 else if (retval == PM_RET_OK)
125 break;
127 else
129 return retval;
133 return retval;
137 PmReturn_t
138 img_appendToPath(PmMemSpace_t memspace, uint8_t const * const paddr)
140 uint8_t i;
142 if (gVmGlobal.imgPaths.pathcount >= PM_NUM_IMG_PATHS)
144 return PM_RET_NO;
147 i = gVmGlobal.imgPaths.pathcount;
149 gVmGlobal.imgPaths.memspace[i] = memspace;
150 gVmGlobal.imgPaths.pimg[i] = paddr;
151 gVmGlobal.imgPaths.pathcount++;
153 return PM_RET_OK;