1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-04 12:24:11 +01:00
LibrePilot/flight/libraries/PyMite/vm/img.c

155 lines
3.9 KiB
C
Raw Normal View History

/*
# This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
#
# This file is part of the PyMite VM.
# The PyMite VM is free software: you can redistribute it and/or modify
# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
#
# The PyMite VM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
# is seen in the file COPYING in this directory.
*/
#undef __FILE_ID__
#define __FILE_ID__ 0x07
/**
* \file
* \brief Image routines
*
* Created to eliminate a circular include
* among mem, string and obj.
*/
#include "pm.h"
/*
* Searches for a module's name in a contiguous array of images
* in the given namespace starting at the given address.
* A module's name is stored in the last index of the names tuple of an image.
*/
static PmReturn_t
img_findInPath(uint8_t *cname, uint8_t cnamelen, PmMemSpace_t memspace,
uint8_t const **paddr)
{
uint8_t const *imgtop;
PmType_t type;
uint16_t len;
int16_t size = 0;
uint8_t i = 0;
/* Addr is top of img */
imgtop = *paddr;
/* Get img's type byte */
type = (PmType_t)mem_getByte(memspace, paddr);
/* Search all sequential images */
while (type == OBJ_TYPE_CIM)
{
/* Use size field to calc addr of next potential img */
size = mem_getWord(memspace, paddr);
/* Point to names tuple */
*paddr = imgtop + CI_NAMES_FIELD;
/* Ensure it's a tuple */
type = (PmType_t)mem_getByte(memspace, paddr);
C_ASSERT(type == OBJ_TYPE_TUP);
/* Scan to last name in tuple (it's the module's name) */
i = mem_getByte(memspace, paddr) - (uint8_t)1;
for (; i > 0; i--)
{
/* Ensure obj is a string */
type = (PmType_t)mem_getByte(memspace, paddr);
C_ASSERT(type == OBJ_TYPE_STR);
/* Skip the length of the string */
len = mem_getWord(memspace, paddr);
(*paddr) += len;
}
/* Ensure it's a string */
type = (PmType_t)mem_getByte(memspace, paddr);
C_ASSERT(type == OBJ_TYPE_STR);
/* If strings match, return the address of this image */
if ((cnamelen == mem_getWord(memspace, paddr))
&& (PM_RET_OK == mem_cmpn(cname, cnamelen, memspace, paddr)))
{
*paddr = imgtop;
return PM_RET_OK;
}
/* Calc imgtop for next iteration */
imgtop += size;
/* Point to next potential img */
*paddr = imgtop;
/* Check if another img follows this one */
type = (PmType_t)mem_getByte(memspace, paddr);
}
return PM_RET_NO;
}
PmReturn_t
img_findInPaths(pPmObj_t pname, PmMemSpace_t *r_memspace,
uint8_t const **r_imgaddr)
{
uint8_t i;
PmReturn_t retval = PM_RET_NO;
/* Search in each path in the paths */
for (i = 0; i < gVmGlobal.imgPaths.pathcount; i++)
{
*r_imgaddr = gVmGlobal.imgPaths.pimg[i];
*r_memspace = gVmGlobal.imgPaths.memspace[i];
retval = img_findInPath(((pPmString_t)pname)->val,
((pPmString_t)pname)->length,
*r_memspace, r_imgaddr);
if (retval == PM_RET_NO)
{
continue;
}
else if (retval == PM_RET_OK)
{
break;
}
else
{
return retval;
}
}
return retval;
}
PmReturn_t
img_appendToPath(PmMemSpace_t memspace, uint8_t const * const paddr)
{
uint8_t i;
if (gVmGlobal.imgPaths.pathcount >= PM_NUM_IMG_PATHS)
{
return PM_RET_NO;
}
i = gVmGlobal.imgPaths.pathcount;
gVmGlobal.imgPaths.memspace[i] = memspace;
gVmGlobal.imgPaths.pimg[i] = paddr;
gVmGlobal.imgPaths.pathcount++;
return PM_RET_OK;
}