/*
BCU SDK bcu development enviroment
Copyright (C) 2005-2007 Martin Koegler <mkoegler@auto.tuwien.ac.at>
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
*/
#include <stdlib.h>
#include "check.h"
#include "regexp.h"
#include "symboltab.h"
bool
UsePEI (const Device & d)
{
return d.on_pei_init () || d.on_pei_message ()
|| d.on_pei_cycle ()
|| d.on_pei_user ()
|| d.on_pei_rc_even ()
|| d.on_pei_rc_odd ()
|| d.on_pei_tc ()
|| d.on_pei_tdre ()
|| d.on_pei_sci_idle ()
|| d.on_pei_spif ()
|| d.on_pei_oca ()
|| d.on_pei_ocb () || d.on_pei_ica () || d.on_pei_icb ();
}
int
UsedbyInterface (const Device & d, const String & name)
{
int i, j, k;
for (i = 0; i < d.FunctionalBlocks (); i++)
for (j = 0; j < d.FunctionalBlocks[i].Interfaces (); j++)
for (k = 0; k < d.FunctionalBlocks[i].Interfaces[j].Reference (); k++)
if (d.FunctionalBlocks[i].Interfaces[j].Reference[k] == name)
return 1;
return 0;
}
int
ObjectName (const Device & d, const String & Name)
{
int i, j;
for (i = 0; i < d.StringParameters (); i++)
if (d.StringParameters[i].Name == Name)
return 1;
for (i = 0; i < d.FloatParameters (); i++)
if (d.FloatParameters[i].Name == Name)
return 1;
for (i = 0; i < d.IntParameters (); i++)
if (d.IntParameters[i].Name == Name)
return 1;
for (i = 0; i < d.ListParameters (); i++)
if (d.ListParameters[i].Name == Name)
return 1;
for (i = 0; i < d.PollingMasters (); i++)
if (d.PollingMasters[i].Name == Name)
return 1;
for (i = 0; i < d.PollingSlaves (); i++)
if (d.PollingSlaves[i].Name == Name)
return 1;
for (i = 0; i < d.Objects (); i++)
for (j = 0; j < d.Objects[i].Propertys (); j++)
if (d.Objects[i].Propertys[j].Name == Name)
return 1;
for (i = 0; i < d.GroupObjects (); i++)
if (d.GroupObjects[i].Name == Name)
return 1;
return 0;
}
void
undefined (const char *object, const char *value, int lineno)
{
die (_("line %d: missing attribute %s of %s"), lineno, value, object);
}
void
CheckStringParameter (Device & d, StringParameter & o)
{
if (!o.Name ())
undefined ("StringParameter", "Name", o.lineno);
if (!o.MaxLength_lineno)
undefined ("StringParameter", "MaxLength", o.lineno);
if (o.MaxLength < 0)
die (_("line %d: negative string len"), o.MaxLength_lineno);
if (o.RegExp ())
if (!checkRegExp (o.RegExp ()))
die (_("line %d: invalid regular expression"), o.RegExp_lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("StringParameter", "Title", o.lineno);
if (!o.Default ())
undefined ("StringParameter", "Default", o.lineno);
if (strlen (o.Default ()) >= o.MaxLength)
die (_("line %d: default value too long"), o.Default_lineno);
if (o.RegExp ())
if (!validateString (o.RegExp (), o.Default ()))
die (_("line %d: Default does not match regular expression"),
o.Default_lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
o.Value = o.Default;
o.Value_lineno = o.Default_lineno;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.Value ())
die (_("line %d: No value defined"), o.lineno);
if (strlen (o.Value ()) >= o.MaxLength)
die (_("line %d: value too long"), o.lineno);
if (o.RegExp ())
if (!validateString (o.RegExp (), o.Value ()))
die (_("line %d: value does not match regular expression"), o.lineno);
#endif
}
void
CheckFloatParameter (Device & d, FloatParameter & o)
{
if (!o.Name ())
undefined ("FloatParameter", "Name", o.lineno);
if (!o.MinValue_lineno)
undefined ("FloatParameter", "MinValue", o.lineno);
if (!o.MaxValue_lineno)
undefined ("FloatParameter", "MaxValue", o.lineno);
if (o.MinValue > o.MaxValue)
die (_("line %d: MinValue > MaxValue"), o.MaxValue_lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("FloatParameter", "Title", o.lineno);
if (!o.Default_lineno)
undefined ("FloatParameter", "Default", o.lineno);
if (o.Default < o.MinValue)
die (_("line %d: Default< MinValue"), o.Default_lineno);
if (o.Default > o.MaxValue)
die (_("line %d: Default> MaxValue"), o.Default_lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
o.Value = o.Default;
o.Value_lineno = o.Default_lineno;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.Value_lineno)
die (_("line %d: No value defined"), o.lineno);
if (o.Value < o.MinValue)
die (_("line %d: Value< MinValue"), o.lineno);
if (o.Value > o.MaxValue)
die (_("line %d: Value> MaxValue"), o.lineno);
#endif
}
void
CheckIntParameter (Device & d, IntParameter & o)
{
if (!o.Name ())
undefined ("IntParameter", "Name", o.lineno);
if (!o.MinValue_lineno)
undefined ("IntParameter", "MinValue", o.lineno);
if (!o.MaxValue_lineno)
undefined ("IntParameter", "MaxValue", o.lineno);
if (o.MinValue > o.MaxValue)
die (_("line %d: MinValue > MaxValue"), o.MaxValue_lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("IntParameter", "Title", o.lineno);
if (!o.Default_lineno)
undefined ("IntParameter", "Default", o.lineno);
if (o.Default < o.MinValue)
die (_("line %d: Default< MinValue"), o.Default_lineno);
if (o.Default > o.MaxValue)
die (_("line %d: Default> MaxValue"), o.Default_lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
o.Value = o.Default;
o.Value_lineno = o.Default_lineno;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.Value_lineno)
die (_("line %d: No value defined"), o.lineno);
if (o.Value < o.MinValue)
die (_("line %d: Value< MinValue"), o.lineno);
if (o.Value > o.MaxValue)
die (_("line %d: Value> MaxValue"), o.lineno);
#endif
if (o.MinValue < 0)
{
int i = abs (o.MinValue);
int j = abs (o.MaxValue);
if (i < j)
j = i;
if (i <= 127)
o.SIZE = -1;
else if (i <= 32767)
o.SIZE = -2;
else if (i <= 2147483647)
o.SIZE = -3;
else
o.SIZE = -4;
}
else
{
int i = abs (o.MinValue);
int j = abs (o.MaxValue);
if (i < j)
j = i;
if (i <= 255)
o.SIZE = 1;
else if (i <= 65535)
o.SIZE = 2;
else if (i <= 4294967295U)
o.SIZE = 3;
else
o.SIZE = 4;
}
}
void
CheckListParameter (Device & d, ListParameter & o)
{
int i, df = -1, vl = -1;
if (!o.Name ())
undefined ("ListParameter", "Name", o.lineno);
if (!o.Elements_lineno)
undefined ("ListParameter", "Elements", o.lineno);
if (!o.Elements ())
die (_("line %d: no enumeration values"), o.Elements_lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("ListParameter", "Title", o.lineno);
if (!o.Default ())
undefined ("ListParameter", "Default", o.lineno);
o.ListElements.resize (o.Elements ());
for (i = 0; i < o.Elements (); i++)
{
o.ListElements[i].Name =
NewSymbol (o.Elements[i].Name, o.Elements_lineno);
o.ListElements[i].Value = o.Elements[i].Value;
if (o.Elements[i].Name == o.Default)
df = i;
if (o.Value_lineno && o.Elements[i].Name == o.Value)
vl = i;
o.Elements[i].Value = o.ListElements[i].Name;
}
if (df == -1)
die (_("line %d: unknown default value"), o.Default_lineno);
o.ListDefault = o.Elements[df].Value;
if (o.Value_lineno && vl == -1)
die (_("line %d: unknown value"), o.Value_lineno);
if (o.Value_lineno)
o.Value = o.Elements[vl].Value;
NewSymbol (o.Name + "_t", o.lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
o.Value = o.Elements[df].Value;
o.Value_lineno = o.Default_lineno;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.Value ())
undefined ("ListParameter", "Value", o.lineno);
for (i = 0; i < o.Elements (); i++)
{
if (o.Elements[i].Value == o.Value)
df = i;
}
if (df == -1)
die (_("line %d: unknown default value"), o.Default_lineno);
#endif
o.def = df;
}
void
CheckPollingMaster (Device & d, PollingMaster & o)
{
if (!o.Name ())
undefined ("PollingMaster", "Name", o.lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("PollingMaster", "Title", o.lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.PollingAddress_lineno && o.PollingCount_lineno)
die (_("line %d: missing PollingAddress"), o.lineno);
if (o.PollingAddress_lineno && !o.PollingCount_lineno)
die (_("line %d: missing PollingCount"), o.lineno);
if (o.PollingAddress_lineno && o.PollingCount_lineno)
{
if (o.PollingAddress & (~0xffff))
die (_("line %d: wrong polling address %04X"), o.lineno,
o.PollingAddress);
if (o.PollingCount < 0)
die (_("line %d: negative polling count"), o.lineno);
if (o.PollingCount > 15)
die (_("line %d: polling count>15"), o.lineno);
}
#endif
}
void
CheckPollingSlave (Device & d, PollingSlave & o)
{
if (!o.Name ())
undefined ("PollingSlave", "Name", o.lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("PollingSlave", "Title", o.lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.PollingAddress_lineno && o.PollingSlot_lineno)
die (_("line %d: missing PollingAddress"), o.lineno);
if (o.PollingAddress_lineno && !o.PollingSlot_lineno)
die (_("line %d: missing PollingSlot"), o.lineno);
if (o.PollingAddress_lineno && o.PollingSlot_lineno)
{
if (o.PollingAddress & (~0xffff))
die (_("line %d: wrong polling address %04X"), o.lineno,
o.PollingAddress);
if (o.PollingSlot < 0)
die (_("line %d: negative polling slot"), o.lineno);
if (o.PollingSlot > 15)
die (_("line %d: polling slot>15"), o.lineno);
}
#endif
}
void
CheckProperty (Device & d, Property & o, Object & o1)
{
if (!o.Name ())
undefined ("Property", "Name", o.lineno);
if (!o.MaxArrayLength_lineno)
{
o.MaxArrayLength = 1;
o.MaxArrayLength_lineno = o.lineno;
}
if (o.MaxArrayLength <= 0)
die (_("line %d: negative array size"), o.lineno);
if (o.MaxArrayLength > 0xff)
die (_("line %d: maximum array size to big"), o.lineno);
if (!o.PropertyID_lineno)
undefined ("Property", "PropertyID", o.lineno);
if (!o.Type_lineno)
undefined ("Property", "Type", o.lineno);
if (o.PropertyID & (~0xffff) || o.PropertyID == 0)
die (_("line %d: wrong Property ID %d"), o.lineno, o.PropertyID);
if (o.handler ())
NewSymbol (o.handler, o.handler_lineno);
if (!o.Writeable_lineno)
{
o.Writeable_lineno = o.lineno;
o.Writeable = 1;
}
if (!o.eeprom_lineno)
{
o.eeprom_lineno = o.lineno;
o.eeprom = 0;
}
#ifdef CHECK1
if (!o.Title ())
undefined ("Property", "Title", o.lineno);
o.ID = NewSymbol (o.Name, o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
o.Disable = 1;
o.Disable_lineno = o.lineno;
o.ReadOnly = !o.Writeable;
o.ReadOnly_lineno = o.lineno;
}
else
o.ID_lineno = o.lineno;
#endif
#ifdef CHECK2
if (!o.WriteAccess_lineno)
{
o.WriteAccess_lineno = o.lineno;
o.WriteAccess = 3;
}
if (!o.ReadAccess_lineno)
{
o.ReadAccess_lineno = o.lineno;
o.ReadAccess = 3;
}
if (o.ReadAccess < 0 || o.ReadAccess > 3)
die (_("line %d: invalid access level"), o.ReadAccess_lineno);
if (o.WriteAccess < 0 || o.WriteAccess > 3)
die (_("line %d: invalid access level"), o.WriteAccess_lineno);
#endif
if (!o.Disable_lineno)
{
o.Disable_lineno = o.lineno;
o.Disable = 0;
}
if (!o.ReadOnly_lineno)
{
o.ReadOnly_lineno = o.lineno;
o.ReadOnly = !o.Writeable;
}
}
void
CheckObject (Device & d, Object & o, int &no)
{
int i, j;
int ra, wa;
int PropCount;
if (!o.Name ())
undefined ("Object", "Name", o.lineno);
#ifdef CHECK1
o.ObjectIndex = no;
o.ObjectIndex_lineno = o.lineno;
no++;
NewSymbol (o.Name, o.lineno);
#endif
#ifdef CHECK2
#endif
if (!o.ObjectType_lineno)
undefined ("Object", "ObjectType", o.lineno);
if (o.ObjectType & (~0xffff))
die (_("line %d: wrong object type %04X"), o.lineno, o.ObjectType);
for (i = 0; i < o.Propertys (); i++)
CheckProperty (d, o.Propertys[i], o);
for (i = 0; i < o.Propertys (); i++)
for (j = i + 1; j < o.Propertys (); j++)
if (o.Propertys[i].PropertyID == o.Propertys[j].PropertyID)
die (_("line %d: duplicate property ID with %s"),
o.Propertys[i].lineno, o.Propertys[j].Name ());
#ifdef CHECK1
o.PropCount = o.Propertys ();
o.RAccess = 3;
o.WAccess = 3;
#endif
#ifdef CHECK2
ra = 4;
wa = 4;
PropCount = 0;
for (i = 0; i < o.Propertys (); i++)
{
Property & p = o.Propertys[i];
if (p.Disable)
continue;
PropCount++;
if (!p.ReadOnly)
{
if (p.WriteAccess < wa)
{
if (wa != 4)
warn (_
("line %d: inconsistent access settings for property %s"),
o.lineno, p.Name ());
wa = p.WriteAccess;
}
else if (p.WriteAccess != wa && wa != 4)
warn (_("line %d: inconsistent access settings for property %s"),
o.lineno, p.Name ());
}
if (p.ReadAccess < ra)
{
if (ra != 4)
warn (_("line %d: inconsistent access settings for property %s"),
o.lineno, p.Name ());
ra = p.ReadAccess;
}
else if (p.ReadAccess != ra && ra != 4)
warn (_("line %d: inconsistent access settings for property %s"),
o.lineno, p.Name ());
}
if (ra == 4)
ra = 3;
if (wa == 4)
wa = 3;
o.RAccess = ra;
o.WAccess = wa;
o.PropCount = PropCount;
#endif
if (o.PropCount > 255)
die (_("line %d: too many properties"), o.lineno);
}
void
CheckGroupObject (Device & d, GroupObject & o)
{
if (!o.Name ())
undefined ("GroupObject", "Name", o.lineno);
if (!o.Type_lineno)
undefined ("GroupObject", "Type", o.lineno);
#ifdef CHECK1
if (!o.Title ())
undefined ("GroupObject", "Title", o.lineno);
if (!o.StateBased_lineno)
undefined ("GroupObject", "StateBased", o.lineno);
o.ID = NewSymbol (o.Name, o.lineno);
NewSymbol (o.Name + "_no", o.lineno);
if (!UsedbyInterface (d, o.Name))
{
o.ID = 0;
}
else
o.ID_lineno = o.lineno;
if (o.on_update ())
NewSymbol (o.on_update, o.on_update_lineno);
if (o.on_update () && !o.Receiving_lineno)
{
o.Receiving = 1;
o.Receiving_lineno = o.lineno;
}
#endif
#ifdef CHECK2
if (!o.Priority_lineno)
{
o.Priority_lineno = o.lineno;
o.Priority = PRIO_LOW;
}
#endif
if (!o.Sending_lineno)
{
o.Sending = 0;
o.Sending_lineno = o.lineno;
}
if (!o.Reading_lineno)
{
o.Reading = 0;
o.Reading_lineno = o.lineno;
}
if (!o.Receiving_lineno)
{
o.Receiving = 0;
o.Receiving_lineno = o.lineno;
}
if (!o.eeprom_lineno)
{
o.eeprom_lineno = 0;
o.eeprom = 0;
}
#ifdef CHECK1
if (o.Sending)
NewSymbol (o.Name + "_transmit", o.lineno);
if (o.Reading)
NewSymbol (o.Name + "_readrequest", o.lineno);
if (o.Reading && o.Sending)
NewSymbol (o.Name + "_clear", o.lineno);
#endif
#ifdef CHECK2
if (!o.Sending && o.SendAddress_lineno)
die (_("line %d: can not send on this group object"), o.lineno);
if (!o.Reading && o.ReadRequestAddress_lineno)
die (_("line %d: can not read on this group object"), o.lineno);
if (!o.Receiving && o.ReceiveAddress ())
die (_("line %d: can not receive on this group object"), o.lineno);
#endif
}
void CheckExpressionBool (Expr * s, int l, const Device & d);
void
CheckInterface (Device & d, Interface & o)
{
#ifdef CHECK1
if (!o.Reference_lineno)
undefined ("Interface", "Reference", o.lineno);
if (!o.Reference ())
die (_("line %d: no references"), o.Reference_lineno);
o.References.resize (o.Reference ());
for (int i = 0; i < o.Reference (); i++)
{
Symbol s = FindSymbol (o.Reference[i], o.References_lineno);
o.References[i] = s.Id;
if (!ObjectName (d, o.Reference[i]))
die (_("line %d: %s referes to wrong object"), o.References_lineno,
o.Reference[i] ());
}
o.ID = NewSymbolAn (o.lineno);
o.ID_lineno = o.lineno;
if (!o.Abbreviation ())
undefined ("Interface", "Abbreviation", o.lineno);
if (!o.DPType_lineno)
undefined ("Interface", "DPType", o.lineno);
if (o.DPType < 0)
die (_("line %d: invalid DPType"), o.DPType_lineno);
if (o.InvisibleIf_lineno)
CheckExpressionBool (o.InvisibleIf, o.InvisibleIf_lineno, d);
#endif
#ifdef CHECK2
#endif
}
void
CheckFunctionalBlock (Device & d, FunctionalBlock & o)
{
int i;
#ifdef CHECK1
if (!o.Title ())
undefined ("FunctionalBlock", "Title", o.lineno);
o.ID = NewSymbolAn (o.lineno);
o.ID_lineno = o.lineno;
if (!o.ProfileID_lineno)
undefined ("FunctionalBlock", "ProfileID", o.lineno);
if (o.ProfileID <= 0)
die (_("line %d: invalid ProfileID"), o.ProfileID_lineno);
#endif
#ifdef CHECK2
#endif
for (i = 0; i < o.Interfaces (); i++)
CheckInterface (d, o.Interfaces[i]);
}
void
CheckExpressionList (Expr * s, int l, const Device & d)
{
int i, j;
if (!s || s->Type != Expr::E_IN)
die (_("line %d: no list expression"), l);
for (i = 0; i < d.ListParameters (); i++)
if (d.ListParameters[i].Name == s->s)
break;
if (i == d.ListParameters ())
die (_("line %d: undefined list parameter %s"), l, s->s ());
const ListParameter & o = d.ListParameters[i];
for (i = 0; i < s->id (); i++)
{
for (j = 0; j < o.Elements (); j++)
if (o.Elements[j].Name == s->id[i])
break;
if (j == o.Elements ())
die (_("line %d: undefined list element %s"), l, s->id[i] ());
s->id[i] = o.Elements[j].Value;
}
s->s = o.ID;
if (!o.ID_lineno)
{
int found = 0;
for (i = 0; i < s->id (); i++)
if (o.ListDefault == s->id[i])
found = 1;
Expr *s1 = new Expr;
s1->i = found;
s1->Type = Expr::E_INT;
s->op1 = s1;
s->Type = Expr::E_NOTNULL;
}
}
typedef enum
{ EX_INT, EX_FLOAT, EX_STRING } EX_Type;
EX_Type
GetExpressionType (Expr * s, int l, const Device & d)
{
int i;
EX_Type e1, e2;
if (!s)
die (_("line %d: no expression"), l);
switch (s->Type)
{
case Expr::E_PAR:
for (i = 0; i < d.StringParameters (); i++)
if (d.StringParameters[i].Name == s->s)
break;
if (d.StringParameters () != i)
{
s->s = d.StringParameters[i].ID;
if (!d.StringParameters[i].ID_lineno)
{
s->s = d.StringParameters[i].Default;
s->Type = Expr::E_STRING;
}
return EX_STRING;
}
for (i = 0; i < d.IntParameters (); i++)
if (d.IntParameters[i].Name == s->s)
break;
if (d.IntParameters () != i)
{
s->s = d.IntParameters[i].ID;
if (!d.IntParameters[i].ID_lineno)
{
s->i = d.IntParameters[i].Default;
s->Type = Expr::E_INT;
}
return EX_INT;
}
for (i = 0; i < d.FloatParameters (); i++)
if (d.FloatParameters[i].Name == s->s)
break;
if (d.FloatParameters () != i)
{
s->s = d.FloatParameters[i].ID;
if (!d.FloatParameters[i].ID_lineno)
{
s->f = d.FloatParameters[i].Default;
s->Type = Expr::E_FLOAT;
}
return EX_FLOAT;
}
die (_("line %d: undefined parameter %s"), l, s->s ());
break;
case Expr::E_INT:
return EX_INT;
case Expr::E_FLOAT:
return EX_FLOAT;
case Expr::E_STRING:
return EX_STRING;
case Expr::E_NEG:
e1 = GetExpressionType (s->op1, l, d);
if (e1 != EX_INT && e1 != EX_FLOAT)
die (_("line %d: unsupported type for negation"), l);
return e1;
case Expr::E_PLUS:
case Expr::E_MINUS:
case Expr::E_MUL:
case Expr::E_DIV:
e1 = GetExpressionType (s->op1, l, d);
if (e1 != EX_INT && e1 != EX_FLOAT)
die (_("line %d: unsupported type for aritmetic operation"), l);
e2 = GetExpressionType (s->op2, l, d);
if (e2 != EX_INT && e2 != EX_FLOAT)
die (_("line %d: unsupported type for aritmetic operation"), l);
if (e1 == EX_FLOAT)
return EX_FLOAT;
if (e2 == EX_FLOAT)
return EX_FLOAT;
return EX_INT;
case Expr::E_MOD:
e1 = GetExpressionType (s->op1, l, d);
if (e1 != EX_INT)
die (_("line %d: unsupported type for modulo operation"), l);
e2 = GetExpressionType (s->op2, l, d);
if (e2 != EX_INT)
die (_("line %d: unsupported type for modulo operation"), l);
return EX_INT;
default:
die (_("line %d: invalid expression"), l);
}
}
void
CheckExpressionCompare (Expr * s1, Expr * s2, int l, const Device & d)
{
EX_Type e1, e2;
e1 = GetExpressionType (s1, l, d);
e2 = GetExpressionType (s2, l, d);
if (e1 == EX_INT && e2 == EX_FLOAT)
e1 = EX_FLOAT;
if (e1 == EX_FLOAT && e2 == EX_INT)
e2 = EX_FLOAT;
if (e1 != e2)
die (_("line %d: different types for compare expression"), l);
}
void
CheckExpressionInt (Expr * s1, int l, const Device & d)
{
EX_Type e1;
e1 = GetExpressionType (s1, l, d);
if (e1 != EX_INT)
die (_("line %d: expect integer value"), l);
}
void
CheckExpressionBool (Expr * s, int l, const Device & d)
{
if (!s)
die (_("line %d: no expression"), l);
switch (s->Type)
{
case Expr::E_AND:
case Expr::E_OR:
CheckExpressionBool (s->op1, l, d);
CheckExpressionBool (s->op2, l, d);
break;
case Expr::E_NOT:
CheckExpressionBool (s->op1, l, d);
break;
case Expr::E_IN:
CheckExpressionList (s, l, d);
break;
case Expr::E_EQ:
case Expr::E_NE:
case Expr::E_LT:
case Expr::E_GT:
case Expr::E_LE:
case Expr::E_GE:
CheckExpressionCompare (s->op1, s->op2, l, d);
break;
case Expr::E_NOTNULL:
CheckExpressionInt (s->op1, l, d);
break;
default:
die (_("line %d: invalid expression"), l);
}
}
void
CheckDebounce (Device & d, Debounce & o)
{
if (!o.Name ())
undefined ("Debounce", "Name", o.lineno);
NewSymbol (o.Name, o.lineno);
if (o.Time_lineno < 0.5 || o.Time_lineno > 127)
die (_("line %d: debounce time not in the range of 0.5 to 127 ms"),
o.Time_lineno);
}
void
CheckTimer (Device & d, Timer & o)
{
if (!o.Name ())
undefined ("Timer", "Name", o.lineno);
NewSymbol (o.Name, o.lineno);
NewSymbol (o.Name + "_no", o.lineno);
NewSymbol (o.Name + "_set", o.lineno);
NewSymbol (o.Name + "_get", o.lineno);
NewSymbol (o.Name + "_del", o.lineno);
if (!o.Type_lineno)
undefined ("Timer", "Type", o.lineno);
switch (o.Type)
{
case TM_EnableUserTimer:
case TM_UserTimer:
o.TimerNo = d.UserTimer++;
break;
case TM_CountDownTimer:
case TM_DifferenceCounter:
case TM_SystemTimer:
case TM_MessageTimer:
case TM_MessageCyclicTimer:
o.TimerNo = d.NextTimer++;
}
switch (o.Type)
{
case TM_EnableUserTimer:
case TM_UserTimer:
if (!o.Resolution_lineno)
undefined ("Timer", "Resolution", o.lineno);
if (o.Resolution < TM_RES_133ms || o.Resolution > TM_RES_72min48s)
die (_("line %d: unsupported timer resolution"), o.Resolution_lineno);
if (o.on_expire ())
NewSymbol (o.on_expire, o.on_expire_lineno);
break;
case TM_SystemTimer:
if (o.on_expire_lineno)
die (_("line %d: on_expire not supported"), o.on_expire_lineno);
if (o.Resolution_lineno)
die (_("line %d: Resolution not supported"), o.Resolution_lineno);
break;
case TM_CountDownTimer:
if (!o.Resolution_lineno)
undefined ("Timer", "Resolution", o.lineno);
if (o.Resolution < TM_RES_0_5ms || o.Resolution > TM_RES_33s)
die (_("line %d: unsupported timer resolution"), o.Resolution_lineno);
if (o.on_expire ())
NewSymbol (o.on_expire, o.on_expire_lineno);
break;
case TM_DifferenceCounter:
if (!o.Resolution_lineno)
undefined ("Timer", "Resolution", o.lineno);
if (o.Resolution < TM_RES_0_5ms || o.Resolution > TM_RES_33s)
die (_("line %d: unsupported timer resolution"), o.Resolution_lineno);
if (o.on_expire_lineno)
die (_("line %d: on_expire not supported"), o.on_expire_lineno);
break;
case TM_MessageTimer:
if (o.on_expire_lineno)
die (_("line %d: on_expire not supported"), o.on_expire_lineno);
if (!o.Resolution_lineno)
undefined ("Timer", "Resolution", o.lineno);
if (o.Resolution < TM_RES_0_4ms || o.Resolution > TM_RES_27s)
die (_("line %d: unsupported timer resolution"), o.Resolution_lineno);
if (d.BCU == BCU_bcu12)
die (_("line %d: timertype not supported on a BCU 1"), o.Type_lineno);
break;
case TM_MessageCyclicTimer:
if (o.on_expire_lineno)
die (_("line %d: on_expire not supported"), o.on_expire_lineno);
if (!o.Resolution_lineno)
undefined ("Timer", "Resolution", o.lineno);
if (o.Resolution < TM_RES_100ms || o.Resolution > TM_RES_1min)
die (_("line %d: unsupported timer resolution"), o.Resolution_lineno);
if (d.BCU == BCU_bcu12)
die (_("line %d: timertype not supported on a BCU 1"), o.Type_lineno);
}
}
void
CheckDevice (Device & d)
{
int i;
int objno = 4;
if (!d.BCU_lineno)
undefined ("Device", "BCU", d.lineno);
d.MaskVersion = d.BCU;
for (i = 0; i < d.StringParameters (); i++)
CheckStringParameter (d, d.StringParameters[i]);
for (i = 0; i < d.FloatParameters (); i++)
CheckFloatParameter (d, d.FloatParameters[i]);
for (i = 0; i < d.IntParameters (); i++)
CheckIntParameter (d, d.IntParameters[i]);
for (i = 0; i < d.ListParameters (); i++)
CheckListParameter (d, d.ListParameters[i]);
for (i = 0; i < d.PollingMasters (); i++)
CheckPollingMaster (d, d.PollingMasters[i]);
for (i = 0; i < d.PollingSlaves (); i++)
CheckPollingSlave (d, d.PollingSlaves[i]);
for (i = 0; i < d.Objects (); i++)
CheckObject (d, d.Objects[i], objno);
for (i = 0; i < d.GroupObjects (); i++)
CheckGroupObject (d, d.GroupObjects[i]);
for (i = 0; i < d.FunctionalBlocks (); i++)
CheckFunctionalBlock (d, d.FunctionalBlocks[i]);
for (i = 0; i < d.Debounces (); i++)
CheckDebounce (d, d.Debounces[i]);
if (d.Debounces () > 1)
die (_("only one debouncer supported"));
d.UserTimer = 0;
d.NextTimer = 2;
if (d.Debounces ())
d.NextTimer = 3;
for (i = 0; i < d.Timers (); i++)
CheckTimer (d, d.Timers[i]);
if (d.NextTimer > 4)
die (_("too many system timers in used"));
if (!d.ManufacturerCode_lineno)
{
d.ManufacturerCode_lineno = d.lineno;
d.ManufacturerCode = 0xffff;
}
if (d.ManufacturerCode < 0 || d.ManufacturerCode > 0xffff)
die (_("line %d: invalid manufacturer code"), d.ManufacturerCode_lineno);
if (!d.InternalManufacturerCode_lineno)
{
d.InternalManufacturerCode_lineno = d.lineno;
d.InternalManufacturerCode = d.ManufacturerCode;
}
if (d.InternalManufacturerCode < 0 || d.InternalManufacturerCode > 0xffff)
die (_("line %d: invalid internal manufacturer code"),
d.InternalManufacturerCode_lineno);
if (!d.DeviceType_lineno)
{
d.DeviceType_lineno = d.lineno;
d.DeviceType = 0xfff0;
}
if (d.DeviceType < 0 || d.DeviceType > 0xffff)
die (_("line %d: invalid devicetype"), d.DeviceType_lineno);
if (!d.Version_lineno)
{
d.Version_lineno = d.lineno;
d.Version = 0;
}
if (d.Version < 0 || d.Version > 0xff)
die (_("line %d: invalid version"), d.Version_lineno);
if (!d.SyncRate_lineno)
{
d.SyncRate_lineno = d.lineno;
d.SyncRate = 0xff;
}
if (d.SyncRate < 0 || d.SyncRate > 0xff)
die (_("line %d: invalid sync rate"), d.SyncRate_lineno);
if (!d.PEIType_lineno)
undefined ("Device", "PEIType", d.lineno);
if (d.PEIType < 0 || d.PEIType >= 20)
die (_("line %d: invalid PEI Type"), d.PEIType_lineno);
if (!d.PortADDR_lineno)
{
d.PortADDR_lineno = d.lineno;
d.PortADDR = 0;
}
if (d.PortADDR < 0 || d.PortADDR > 0xff)
die (_("line %d: invalid PortADDR"), d.PortADDR_lineno);
if (!d.PortCDDR_lineno)
{
d.PortCDDR_lineno = d.lineno;
d.PortCDDR = 0;
}
if (d.PortCDDR < 0 || d.PortCDDR > 0xff)
die (_("line %d: invalid PortCDDR"), d.PortCDDR_lineno);
if (d.BCU1_SEC_lineno && d.BCU != BCU_bcu12)
die (_("line %d: not supported for this bcu type"), d.BCU1_SEC_lineno);
if (d.BCU1_PROTECT_lineno && d.BCU != BCU_bcu12)
die (_("line %d: not supported for this bcu type"),
d.BCU1_PROTECT_lineno);
if (d.AutoPLMA_lineno && d.BCU != BCU_bcu12)
die (_("line %d: not supported for this bcu type"), d.AutoPLMA_lineno);
if (d.BCU2_PROTECT_lineno && d.BCU == BCU_bcu12)
die (_("line %d: not supported for this bcu type"),
d.BCU2_PROTECT_lineno);
if (d.BCU2_WATCHDOG_lineno && d.BCU == BCU_bcu12)
die (_("line %d: not supported for this bcu type"),
d.BCU2_WATCHDOG_lineno);
if (d.PLM_FAST_lineno && d.BCU == BCU_bcu12)
die (_("line %d: not supported for this bcu type"), d.PLM_FAST_lineno);
if (d.RouteCount_lineno)
{
if (d.RouteCount < 0 || d.RouteCount > 7)
die (_("line %d: invalid value for RouteCount"), d.RouteCount_lineno);
}
else
d.RouteCount = 6;
if (d.BusyLimit_lineno)
{
if (d.BusyLimit < 0 || d.BusyLimit > 7)
die (_("line %d: invalid value for BusyLimit"), d.BusyLimit_lineno);
}
else
d.BusyLimit = 3;
if (d.INAKLimit_lineno)
{
if (d.INAKLimit < 0 || d.INAKLimit > 7)
die (_("line %d: invalid value for INAKLimit"), d.INAKLimit_lineno);
}
else
d.INAKLimit = 3;
if (d.RateLimit_lineno)
{
if (d.RateLimit < 1 || d.RateLimit > 127)
die (_("line %d: invalid value for RateLimit"), d.RateLimit_lineno);
}
if (!d.U_DELMSG_lineno)
d.U_DELMSG = 1;
if (!d.CPOL_lineno)
d.CPOL_lineno = 1;
if (!d.CPHA_lineno)
d.CPHA_lineno = 1;
if (!d.AutoPLMA_lineno)
d.AutoPLMA = 0;
if (!d.BCU1_SEC_lineno)
d.BCU1_SEC = 0;
if (!d.BCU1_PROTECT_lineno)
d.BCU1_PROTECT = 0;
if (!d.BCU2_PROTECT_lineno)
d.BCU2_PROTECT = 0;
if (!d.BCU2_WATCHDOG_lineno)
d.BCU2_WATCHDOG = 1;
if (!d.PLM_FAST_lineno)
d.PLM_FAST = 0;
if (!d.A_Event_lineno)
d.A_Event = 1;
#ifdef CHECK1
if (!d.Title ())
undefined ("Device", "Title", d.lineno);
#endif
#ifdef CHECK2
if (!d.PhysicalAddress_lineno)
undefined ("Device", "PhyiscalAddress", d.lineno);
#endif
if (d.BCU == BCU_bcu12 && d.Objects ())
die (_("BCU1 supports no objects"));
if (d.BCU == BCU_bcu12 && d.PollingMasters ())
die (_("BCU1 supports no polling"));
if (d.BCU == BCU_bcu12 && d.PollingSlaves ())
die (_("BCU1 supports no polling"));
if (d.BCU == BCU_bcu12 && d.InstallKey_lineno)
die (_("installkey not supported"));
if (d.BCU == BCU_bcu12 && d.Keys ())
die (_("BCU1 supports no access protection"));
if (d.BCU == BCU_bcu12 && UsePEI (d))
die (_("BCU1 supports no custom PEI handler"));
if (d.BCU != BCU_bcu12)
{
d.Key.resize (3);
for (i = 0; i < 3; i++)
d.Key[i] = 0xFFFFFFFF;
if (d.Keys ())
{
for (i = 0; i < d.Keys (); i++)
{
if (d.Keys[i].level < 0 || d.Keys[i].level > 2)
die (_("unsupported key level %d"), d.Keys[i].level);
for (int j = 0; j < i; j++)
if (d.Keys[i].level == d.Keys[j].level)
die (_("duplicate key level %d"), d.Keys[i].level);
d.Key[d.Keys[i].level] = d.Keys[i].key;
}
}
if (!d.InstallKey_lineno)
d.InstallKey = 0xFFFFFFFF;
if (d.PollingMasters ())
die (_("not yet supported"));
if (d.PollingSlaves ())
die (_("not yet supported"));
}
}
syntax highlighted by Code2HTML, v. 0.9.1