gps/GPSResources/tcpmp/common/probe.c

323 lines
6.0 KiB
C
Executable File

/*****************************************************************************
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: probe.c 607 2006-01-22 20:58:29Z picard $
*
* The Core Pocket Media Player
* Copyright (c) 2004-2005 Gabor Kovacs
*
****************************************************************************/
#include "common.h"
static NOINLINE void SkipSpace(const tchar_t** p)
{
while (IsSpace(**p)) ++(*p);
}
static NOINLINE bool_t IsToken(const tchar_t** p,const tchar_t* Name)
{
size_t Len = tcslen(Name);
SkipSpace(p);
if (tcsnicmp(*p,Name,Len)==0 && !IsAlpha((*p)[Len]))
{
(*p) += Len;
return 1;
}
return 0;
}
static NOINLINE bool_t IsSymbol(const tchar_t** p,int ch)
{
SkipSpace(p);
if (**p == ch)
{
++(*p);
return 1;
}
return 0;
}
static NOINLINE bool_t IsTokenWithParam(const tchar_t** p,const tchar_t* Name)
{
return IsToken(p,Name) && IsSymbol(p,'(');
}
static INLINE void ParamEnd(const tchar_t** p)
{
IsSymbol(p,')');
}
static NOINLINE bool_t ParamNext(const tchar_t** p)
{
if (IsSymbol(p,','))
return 1;
ParamEnd(p);
return 0;
}
static int Run(const tchar_t** p, const uint8_t** Data, int* Length);
static NOINLINE int GetOfs(const tchar_t** p, const uint8_t** Data, int* Length)
{
int Ofs = 0;
if (IsSymbol(p,'('))
{
Ofs = Run(p,Data,Length);
ParamEnd(p);
}
return Ofs;
}
static int Run(const tchar_t** p, const uint8_t** Data, int* Length)
{
int a,b,Ofs,v = 0;
assert(!IsSymbol(p,')') && !IsSymbol(p,',') && **p);
if (IsTokenWithParam(p,T("scan")))
{
const uint8_t* SaveData = *Data;
int Result = -1;
int SaveLength = *Length;
const tchar_t* Start;
int End = *Length - Run(p,Data,Length); // limit
if (End < 0)
End = 0;
ParamNext(p);
Start = *p;
while (*Length > End && Result<0)
{
*p = Start;
if (Run(p,Data,Length)) //success
Result = 1;
ParamNext(p);
if (Run(p,Data,Length) && Result<=0) //fail
Result = 0;
ParamNext(p);
Run(p,Data,Length); //step
ParamEnd(p);
}
if (Result>=0)
v = Result;
*Data = SaveData;
*Length = SaveLength;
}
else
if (IsToken(p,T("fwd")))
{
v = 1;
if (IsSymbol(p,'('))
{
v = Run(p,Data,Length);
ParamEnd(p);
}
*Length -= v;
*Data += v;
}
else
if (IsToken(p,T("le32")))
{
Ofs = GetOfs(p,Data,Length);
if (*Length >= Ofs+4)
v = LOAD32LE(*Data+Ofs);
}
else
if (IsToken(p,T("be32")))
{
Ofs = GetOfs(p,Data,Length);
if (*Length >= Ofs+4)
v = LOAD32BE(*Data+Ofs);
}
else
if (IsToken(p,T("le16")))
{
Ofs = GetOfs(p,Data,Length);
if (*Length >= Ofs+2)
v = LOAD16LE(*Data+Ofs);
}
else
if (IsToken(p,T("be16")))
{
Ofs = GetOfs(p,Data,Length);
if (*Length >= Ofs+2)
v = LOAD16BE(*Data+Ofs);
}
else
if (IsToken(p,T("text")))
{
int i;
v = 1;
for (i=0;*Length>i;++i)
{
uint8_t ch = (*Data)[i];
if (ch<32 && ch!=10 && ch!=13 && ch!=9 && ch!=26)
{
v = 0;
break;
}
}
}
else
if (IsToken(p,T("lines")))
{
int i;
v = 0;
for (i=0;*Length>i;++i)
if ((*Data)[i] == 10)
++v;
}
else
if (IsToken(p,T("length")))
{
v = *Length;
}
else
if (IsTokenWithParam(p,T("stri")))
{
v = 0;
if (IsSymbol(p,'\''))
{
int i;
v = 1;
for (i=0;**p && **p!='\'';++i,++(*p))
if (*Length<=i || toupper((*Data)[i])!=toupper(**p))
v = 0;
IsSymbol(p,'\'');
ParamEnd(p);
}
}
else
if (IsTokenWithParam(p,T("gt")))
{
a = Run(p,Data,Length);
ParamNext(p);
b = Run(p,Data,Length);
ParamEnd(p);
v = a>b;
}
else
if (IsTokenWithParam(p,T("eq")))
{
a = Run(p,Data,Length);
ParamNext(p);
b = Run(p,Data,Length);
ParamEnd(p);
v = a == b;
}
else
if (IsTokenWithParam(p,T("ne")))
{
a = Run(p,Data,Length);
ParamNext(p);
b = Run(p,Data,Length);
ParamEnd(p);
v = a != b;
}
else
if (IsTokenWithParam(p,T("mask")))
{
a = Run(p,Data,Length);
ParamNext(p);
b = Run(p,Data,Length);
ParamEnd(p);
v = a & b;
}
else
if (IsTokenWithParam(p,T("add")))
{
do
{
v += Run(p,Data,Length);
}
while (ParamNext(p));
}
else
if (IsTokenWithParam(p,T("or")))
{
do
{
if (Run(p,Data,Length))
v = 1;
}
while (ParamNext(p));
}
else
if (IsTokenWithParam(p,T("and")))
{
v = 1;
do
{
if (!Run(p,Data,Length))
v = 0;
}
while (ParamNext(p));
}
else
if (IsSymbol(p,'!'))
v = !Run(p,Data,Length);
else
if (IsSymbol(p,'~'))
v = ~Run(p,Data,Length);
else
if (IsSymbol(p,'\''))
{
int i,c[4];
c[0] = c[1] = c[2] = c[3] = '_';
for (i=0;**p && **p!='\'';++i,++(*p))
if (i<4) c[i] = **p;
IsSymbol(p,'\'');
v = FOURCCLE(c[0],c[1],c[2],c[3]);
}
else
if (IsDigit(**p) || **p=='-')
{
bool_t Neg = IsSymbol(p,'-');
if ((*p)[0] == '0' && (*p)[1] == 'x')
{
(*p)+=2;
for (;**p;++(*p))
{
int h = Hex(**p);
if (h<0) break;
v=v*16+h;
}
}
else
{
for (;IsDigit(**p);++(*p))
v = v*10 + (**p-'0');
}
if (Neg)
v = -v;
}
return v;
}
bool_t DataProbe(const void* Ptr, int Length,const tchar_t* Code)
{
const uint8_t* Data = (const uint8_t*)Ptr;
if (!Code[0])
return 0;
return Run(&Code,&Data,&Length);
}