mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
155 lines
3.9 KiB
C
155 lines
3.9 KiB
C
/*
|
|
# 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;
|
|
}
|