コード例 #1
0
ファイル: Node.c プロジェクト: fosinorm/HomeCANtrol
struct Node *FindNodeAdress (struct Node *Root,int Linie, int Knoten, int Port,struct Node *Except)
{
  struct Node *This,*That ;
  
  if (Root==NULL) return (NULL) ;

  // Knoten mit dem ersten Bezeichner finden
  for(This = Root ;This!=NULL;This=This->Next) {
    if ((This->Type==N_ADRESS)&&(This->Data.Adresse.Linie ==Linie)&&
	(This->Data.Adresse.Knoten==Knoten)&&(This->Data.Adresse.Port==Port)&&
	(This!=Except)) { 
      return (This->Parent) ;
    } ;
    That = FindNodeAdress(This->Child,Linie,Knoten,Port,Except) ;
    if (That!=NULL) return (That) ;
  } 
  return (NULL) ;
}
コード例 #2
0
ファイル: ParseXML.c プロジェクト: fosinorm/HomeCANtrol
void XMLCALL start(void *data, const char *el, const char **attr) 
{
  int i,Time;
  struct Node *This ;


  if (Current==NULL) {
    Current = CreateNode() ;
    Haus = Current ;
  } else {
    Current = NewChild (Current) ;
  } ;

  strncpy (Current->TypeDef,el,NAMELEN) ;
  Current->Type = FillType (Current->TypeDef) ;


  
  for (i = 0; attr[i]; i += 2) {
    if (strcmp(attr[i],"name")==0) {
      strncpy(Current->Name,attr[i+1],NAMELEN) ;
      continue; 
    } ;
    switch (Current->Type) {
    case N_ADRESS:
      if ((strcmp(attr[i],"linie")==0)||(strcmp(attr[i],"line")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Adresse.Linie)) ;
      } ;
      if ((strcmp(attr[i],"knoten")==0)||(strcmp(attr[i],"node")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Adresse.Knoten)) ;
      } ;
      if (strcmp(attr[i],"port")==0) {
	sscanf(attr[i+1],"%d",&(Current->Data.Adresse.Port)) ;
      } ;
      break ;
    case N_ACTION:
      if ((strcmp(attr[i],"kommando")==0)||(strcmp(attr[i],"command")==0)) {
	Current->Data.Aktion.Type = FillType(attr[i+1]) ;
      }
      if ((strcmp(attr[i],"objekt")==0)||(strcmp(attr[i],"object")==0)) {
	strncpy(Current->Data.Aktion.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      if ((strcmp(attr[i],"autonom")==0)||(strcmp(attr[i],"standalone")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Aktion.StandAlone)) ;
      } ;
      break ;
    case N_SENSOR:
      if ((strcmp(attr[i],"typ")==0)||(strcmp(attr[i],"type")==0)) {
	Current->Data.SensorTyp = FillType(attr[i+1]);
      } ;
      break ;
    case N_DELAY:
      if ((strcmp(attr[i],"zeit")==0)||(strcmp(attr[i],"time")==0)) {
	sscanf (attr[i+1],"%d",&Time) ;
	Current->Data.Time.tv_sec = Time/1000 ;
	Current->Data.Time.tv_usec = Time%1000 * 1000 ;
      } ;
      break ;
    case N_TIMER:
      if ((strcmp(attr[i],"zeit")==0)||(strcmp(attr[i],"time")==0)) {
	strncpy(Current->Data.Wert.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      break ;
    case N_CALL:
    case N_TASK:
      if ((strcmp(attr[i],"makro")==0)||(strcmp(attr[i],"macro")==0)) {
	strncpy(Current->Data.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      break ;
    case N_IF:
    case N_SET:
    case N_REPEAT:
      if ((strcmp(attr[i],"objekt")==0)||(strcmp(attr[i],"object")==0)) {
	strncpy(Current->Data.Wert.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      if ((strcmp(attr[i],"wert")==0)||(strcmp(attr[i],"value")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Wert.Wert)) ;
      } ;
      if ((strcmp(attr[i],"vergleich")==0)||(strcmp(attr[i],"comparison")==0)) {
	switch (attr[i+1][0]) {
	case '<':
	  Current->Data.Wert.Vergleich = -1 ;
	  break ;
	case '>':
	  Current->Data.Wert.Vergleich = 1 ;
	  break ;
	case '=':
	default:
	  Current->Data.Wert.Vergleich = 0 ;
	  break ;
	} ;
      } ;
      break ;
    case N_VAR:
      if ((strcmp(attr[i],"wert")==0)||(strcmp(attr[i],"value")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Value)) ;
      } ;
      break ;
    case N_LANGUAGE:
      if ((strcmp(attr[i],"ist")==0)||(strcmp(attr[i],"is")==0)) {
	switch (attr[i+1][0]) {
	case 'd':
	  setlocale(LC_TIME,"de_DE") ;
	  break ;
	default:
	  break ;
	} ;
      } ;
      break ;
    default:
      break ;
    } ;

  }
  // Ueberpruefen auf Semantik
  // Namensgleichheit
  for (This=Current->Prev;This!=NULL;This=This->Prev) {
    if ((strlen(Current->Name)>0)&&(strcmp(This->Name,Current->Name)==0)) {
      // Name wurde schon verwendet
      ParseError = 1 ;
      fprintf (stderr,"Name doppelt verwendet: ") ;
      for (This=Current;This!=NULL;This=This->Parent) fprintf (stderr,"%s ",This->Name) ;
      fprintf (stderr,"\n") ;
      break ;
    }
  } ;
  // Einzelelemente
  if (Current->Type==N_ADRESS) {
    if ((This=FindNodeAdress(Haus,Current->Data.Adresse.Linie,Current->Data.Adresse.Knoten,Current->Data.Adresse.Port,Current))!=NULL) {
      ParseError = 1 ;
      fprintf (stderr,"Adresse wurde doppelt verwendet: Linie %d, Knoten %d, Port %d\n",
	       Current->Data.Adresse.Linie,Current->Data.Adresse.Knoten,Current->Data.Adresse.Port) ;
      fprintf (stderr,"Erste Verwendung: ") ;
      for (;This!=NULL;This=This->Parent) fprintf (stderr,"%s ",This->Name) ;
      fprintf (stderr,"\nZweite Verwendung: ") ;
      for (This=Current;This!=NULL;This=This->Parent) fprintf (stderr,"%s ",This->Name) ;
      fprintf (stderr,"\n") ;
    } ;
  } ;

  // Element nachbearbeiten
  // Makros nummerieren 
  if (Current->Type==N_MACRO) {
    This = NewChild(Current) ;
    This->Type = N_ADRESS ;
    This->Data.Adresse.Linie = 0 ;
    This->Data.Adresse.Knoten = (MakroNummer>>8)+50 ;
    This->Data.Adresse.Port = (MakroNummer&0xFF) ;
    MakroNummer++ ;
  } ;
コード例 #3
0
ファイル: ParseXML.c プロジェクト: maveric00/HomeCANtrol
void XMLCALL start(void *data, const char *el, const char **attr) 
{
  int i,j,Time;
  char Val[5] ;
  struct Node *This ;
  struct NodeList *NL ;


  if (Current==NULL) {
    Current = CreateNode() ;
    Haus = Current ;
  } else {
    Current = NewChild (Current) ;
  } ;

  strncpy (Current->TypeDef,el,NAMELEN) ;
  Current->Type = FillType (Current->TypeDef) ;

  if (Current->Type==N_REACT) {
    // In die Liste der Reactions einhängen
    if (Reactions==NULL) {
      Reactions = malloc (sizeof (struct NodeList)) ;
      Reactions->Next = NULL ;
      Reactions->Node = Current ;
    } else {
      for (NL=Reactions;NL->Next!=NULL;NL=NL->Next) ;
      NL->Next = malloc (sizeof(struct NodeList)) ;
      NL = NL->Next ;
      NL->Next = NULL ;
      NL->Node = Current ;
    } ;
  } ;


  for (i = 0; attr[i]; i += 2) {
    if (strcmp(attr[i],"name")==0) {
      strncpy(Current->Name,attr[i+1],NAMELEN) ;
      continue; 
    } ;
    if ((strcmp(attr[i],"wert")==0)||(strcmp(attr[i],"value")==0)) {
      sscanf(attr[i+1],"%d",&(Current->Value)) ;
    } ;
    switch (Current->Type) {
    case N_STRUCTURE:
      if ((strcmp(attr[i],"default")==0)||(strcmp(attr[i],"default")==0)) {
	DefaultFloor = Current ;
      }  ;
      break ;
    case N_GROUP:
      if ((strcmp(attr[i],"nummer")==0)||(strcmp(attr[i],"number")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Group.Number)) ;
      } ;
    case N_ADRESS:
      if ((strcmp(attr[i],"linie")==0)||(strcmp(attr[i],"line")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Adresse.Linie)) ;
      } ;
      if ((strcmp(attr[i],"knoten")==0)||(strcmp(attr[i],"node")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Adresse.Knoten)) ;
      } ;
      if (strcmp(attr[i],"port")==0) {
	sscanf(attr[i+1],"%d",&(Current->Data.Adresse.Port)) ;
      } ;
      break ;
    case N_ACTION:
      if ((strcmp(attr[i],"kommando")==0)||(strcmp(attr[i],"command")==0)) {
	Current->Data.Aktion.Type = FillType(attr[i+1]) ;
      }
      if ((strcmp(attr[i],"objekt")==0)||(strcmp(attr[i],"object")==0)) {
	strncpy(Current->Data.Aktion.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      if ((strcmp(attr[i],"sequenz")==0)||(strcmp(attr[i],"sequence")==0)) {
	strncpy(Current->Data.Aktion.Sequence,attr[i+1],NAMELEN) ;
      } ;
      if ((strcmp(attr[i],"autonom")==0)||(strcmp(attr[i],"standalone")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Aktion.StandAlone)) ;
      } ;
      if ((strcmp(attr[i],"kurz")==0)||(strcmp(attr[i],"short")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Aktion.Short)) ;
      } ;
      if ((strcmp(attr[i],"R")==0)||(strcmp(attr[i],"H")==0)) {
	sscanf(attr[i+1],"%hhi",&(Current->Data.Aktion.R)) ;
      } ;
      if ((strcmp(attr[i],"G")==0)||(strcmp(attr[i],"S")==0)) {
	sscanf(attr[i+1],"%hhi",&(Current->Data.Aktion.G)) ;
      } ;
      if ((strcmp(attr[i],"B")==0)||(strcmp(attr[i],"V")==0)) {
	sscanf(attr[i+1],"%hhi",&(Current->Data.Aktion.B)) ;
      } ;
      if (strcmp(attr[i],"W")==0) {
	sscanf(attr[i+1],"%hhi",&(Current->Data.Aktion.W)) ;
      } ;
      if ((strcmp(attr[i],"dauer")==0)||(strcmp(attr[i],"time")==0)) {
	sscanf(attr[i+1],"%hhi",&(Current->Data.Aktion.Delay)) ;
      } ;
      if ((strcmp(attr[i],"schritt")==0)||(strcmp(attr[i],"step")==0)) {
	sscanf(attr[i+1],"%hhi",&(Current->Data.Aktion.Step)) ;
      } ;
      break ;
    case N_SENSOR:
    case N_SENS2:
    case N_LIGHT:
    case N_EXTENDED:
      if ((strcmp(attr[i],"typ")==0)||(strcmp(attr[i],"type")==0)) {
	Current->Data.Sensor.SensorTyp = FillType(attr[i+1]);
      } ;
      if ((strcmp(attr[i],"lang")==0)||(strcmp(attr[i],"long")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Lang)) ;
      } ;
      if ((strcmp(attr[i],"ende")==0)||(strcmp(attr[i],"end")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Ende)) ;
      } ;
      if (strcmp(attr[i],"reset")==0) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Reset)) ;
      } ;
      if ((strcmp(attr[i],"dauer")==0)||(strcmp(attr[i],"time")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Reset)) ;
      } ;
      if ((strcmp(attr[i],"intervall")==0)||(strcmp(attr[i],"interval")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Intervall)) ;
      } ;
      if ((strcmp(attr[i],"led")==0)||(strcmp(attr[i],"led")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.WSNum)) ;
      } ;
      if ((strcmp(attr[i],"virtled")==0)||(strcmp(attr[i],"virtled")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.VirtWSNum)) ;
      } ;
      if ((strcmp(attr[i],"power1")==0)||(strcmp(attr[i],"power1")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Power1)) ;
      } ;
      if ((strcmp(attr[i],"power2")==0)||(strcmp(attr[i],"power2")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Power2)) ;
      } ;
      break ;
    case N_BAD:
      if ((strcmp(attr[i],"dauer")==0)||(strcmp(attr[i],"duration")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Sensor.Lang)) ;
      } ;
      break ;
    case N_SHADE:
      if ((strcmp(attr[i],"lang")==0)||(strcmp(attr[i],"long")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Rollo.Lang)) ;
      } ;
      if ((strcmp(attr[i],"kurz")==0)||(strcmp(attr[i],"short")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Rollo.Kurz)) ;
      } ;
      if ((strcmp(attr[i],"vertauschen")==0)||(strcmp(attr[i],"swap")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Data.Rollo.Swap)) ;
      } ;
      break ;
    case N_DELAY:
      if ((strcmp(attr[i],"zeit")==0)||(strcmp(attr[i],"time")==0)) {
	sscanf (attr[i+1],"%d",&Time) ;
	Current->Data.Time.tv_sec = Time/1000 ;
	Current->Data.Time.tv_usec = Time%1000 * 1000 ;
      } ;
      break ;
    case N_TIMER:
      if ((strcmp(attr[i],"zeit")==0)||(strcmp(attr[i],"time")==0)) {
	strncpy(Current->Data.Wert.Wert,attr[i+1],NAMELEN*2) ;
      } ;
      if ((strcmp(attr[i],"relativ")==0)||(strcmp(attr[i],"relative")==0)) {
	if ((strcmp(attr[i+1],"vor aufgang")==0)||(strcmp(attr[i],"before sunrise")==0)) {
	  Current->Value = 1 ;
	} else if ((strcmp(attr[i+1],"nach aufgang")==0)||(strcmp(attr[i],"after sunrise")==0)) {
	  Current->Value = 2 ;
	} else 	if ((strcmp(attr[i+1],"vor untergang")==0)||(strcmp(attr[i],"before sunset")==0)) {
	  Current->Value = 3 ;
	} else 	if ((strcmp(attr[i+1],"nach untergang")==0)||(strcmp(attr[i],"after sunset")==0)) {
	  Current->Value = 4 ;
	} ;
      } ;
      break ;
    case N_CALL:
    case N_TASK:
      if ((strcmp(attr[i],"makro")==0)||(strcmp(attr[i],"macro")==0)) {
	strncpy(Current->Data.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      break ;
    case N_IF:
    case N_SET:
    case N_REPEAT:
    case N_WAITFOR:
    case N_ELEMENT:
      if ((strcmp(attr[i],"objekt")==0)||(strcmp(attr[i],"object")==0)) {
	strncpy(Current->Data.Wert.UnitName,attr[i+1],NAMELEN*4) ;
      } ;
      if ((strcmp(attr[i],"wert")==0)||(strcmp(attr[i],"value")==0)) {
	strncpy(Current->Data.Wert.Wert,attr[i+1],NAMELEN*2) ;
      } ;
      break ;
    case N_VAR:
      if ((strcmp(attr[i],"wert")==0)||(strcmp(attr[i],"value")==0)) {
	sscanf(attr[i+1],"%d",&(Current->Value)) ;
      } ;
      break ;
    case N_LANGUAGE:
      if ((strcmp(attr[i],"ist")==0)||(strcmp(attr[i],"is")==0)) {
	switch (attr[i+1][0]) {
	case 'd':
	  setlocale(LC_TIME,"de_DE") ;
	  break ;
	default:
	  break ;
	} ;
      } ;
    case N_PORT:
      if (strcmp(attr[i],"CAN")==0) {
	strncpy(CAN_PORT,attr[i+1],19) ;
	sscanf (CAN_PORT,"%d",&CAN_PORT_NUM) ;
      } ;
      if (strcmp(attr[i],"WS")==0) {
	strncpy(WS_PORT,attr[i+1],19) ;
	sscanf (WS_PORT,"%d",&WS_PORT_NUM) ;
      } ;
      if (strcmp(attr[i],"COM")==0) {
	strncpy(COM_PORT,attr[i+1],19) ;
	sscanf (COM_PORT,"%d",&COM_PORT_NUM) ;
      } ;
      if (strcmp(attr[i],"VOICE")==0) {
	strncpy(VOICE_PORT,attr[i+1],19) ;
	sscanf (VOICE_PORT,"%d",&VOICE_PORT_NUM) ;
      } ;
      if (strcmp(attr[i],"HTTP")==0) {
	strncpy(HTTP_PORT,attr[i+1],19) ;
	sscanf (HTTP_PORT,"%d",&HTTP_PORT_NUM) ;
      } ;
      break ;
    case N_BROADCAST:
      if (strcmp(attr[i],"IP")==0) {
	strncpy(CAN_BROADCAST,attr[i+1],NAMELEN-1) ;
      } ;
      break ;
    case N_FIRMWARE:
      if (strcmp(attr[i],"id")==0) {
	sscanf(attr[i+1],"%d",&(Current->Value)) ;
      } ;
      break ;
    case N_SEQUENCE:
      if ((strcmp(attr[i],"file")==0)||(strcmp(attr[i],"datei")==0)) {
	ReadSequence (Current->Name,(char*)attr[i+1]) ;
      } ;
      break ;
    case N_LOC:
      if (strcmp(attr[i],"west")==0) {
	sscanf (attr[i+1],"%lf",&West) ;
      } ;
      if ((strcmp(attr[i],"north")==0)||(strcmp(attr[i],"nord")==0)) {
	sscanf (attr[i+1],"%lf",&North) ;
      } ;
      break ;
    case N_PROGRAM:
      if (strcmp(attr[i],"port")==0) {
	sscanf(attr[i+1],"%hhd",&(Current->Data.Program.Port)) ;
      } ;
      if (strcmp(attr[i],"data")==0) {
	Val[0] = '0' ;
	Val[1] = 'x' ;
	Val[4] = '\0' ;
	for (j=0;j<50;j++) Current->Data.Program.Data[j]=0 ;
	for (j=0;attr[i+1][j]!='\0';j+=2) {
	  Val[2] = attr[i+1][j] ;
	  Val[3] = attr[i+1][j+1] ;
	  sscanf (Val,"%hhx",&(Current->Data.Program.Data[j/2])) ;
	} ;
      }; 
      break ;
    case N_REACT:
      if ((strcmp(attr[i],"von")==0)||(strcmp(attr[i],"from")==0)) {
	sscanf(attr[i+1],"%i.%i",&(Current->Data.Reaction.From.Linie),
	       &(Current->Data.Reaction.From.Knoten)) ;
      } ;
      if ((strcmp(attr[i],"von_maske")==0)||(strcmp(attr[i],"from_mask")==0)) {
	sscanf(attr[i+1],"%i.%i",&(Current->Data.Reaction.FromMask.Linie),
	       &(Current->Data.Reaction.FromMask.Knoten)) ;
      } ;
      if ((strcmp(attr[i],"nach")==0)||(strcmp(attr[i],"to")==0)) {
	sscanf(attr[i+1],"%i.%i",&(Current->Data.Reaction.To.Linie),
	       &(Current->Data.Reaction.To.Knoten)) ;
      } ;
      if ((strcmp(attr[i],"nach_maske")==0)||(strcmp(attr[i],"to_mask")==0)) {
	sscanf(attr[i+1],"%i.%i",&(Current->Data.Reaction.ToMask.Linie),
	       &(Current->Data.Reaction.ToMask.Knoten)) ;
      } ;
      if ((strcmp(attr[i],"daten")==0)||(strcmp(attr[i],"data")==0)) {
	for (j=0;j<8;j++) Current->Data.Reaction.Data[j] = 0  ;
	sscanf(attr[i+1],"%hhi %hhi %hhi %hhi %hhi %hhi %hhi %hhi",
	       &(Current->Data.Reaction.Data[0]),&(Current->Data.Reaction.Data[1]),
	       &(Current->Data.Reaction.Data[2]),&(Current->Data.Reaction.Data[3]),
	       &(Current->Data.Reaction.Data[4]),&(Current->Data.Reaction.Data[5]),
	       &(Current->Data.Reaction.Data[6]),&(Current->Data.Reaction.Data[7])) ;
      } ;	
      if ((strcmp(attr[i],"daten_maske")==0)||(strcmp(attr[i],"data_mask")==0)) {
	for (j=0;j<8;j++) Current->Data.Reaction.DataMask[j] = 0  ;
	sscanf(attr[i+1],"%hhi %hhi %hhi %hhi %hhi %hhi %hhi %hhi",
	       &(Current->Data.Reaction.DataMask[0]),&(Current->Data.Reaction.DataMask[1]),
	       &(Current->Data.Reaction.DataMask[2]),&(Current->Data.Reaction.DataMask[3]),
	       &(Current->Data.Reaction.DataMask[4]),&(Current->Data.Reaction.DataMask[5]),
	       &(Current->Data.Reaction.DataMask[6]),&(Current->Data.Reaction.DataMask[7])) ;
      } ;	
      break ;
    default:
      break ;
    } ;
  }
  // Ueberpruefen auf Semantik
  // Namensgleichheit
  for (This=Current->Prev;This!=NULL;This=This->Prev) {
    if ((strlen(Current->Name)>0)&&(strcmp(This->Name,Current->Name)==0)) {
      // Name wurde schon verwendet
      ParseError = 1 ;
      fprintf (stderr,"Name doppelt verwendet: ") ;
      for (This=Current;This!=NULL;This=This->Parent) fprintf (stderr,"%s ",This->Name) ;
      fprintf (stderr,"\n") ;
      break ;
    }
  } ;
  // Einzelelemente
  if (Current->Type==N_ADRESS) {
    if ((This=FindNodeAdress(Haus,Current->Data.Adresse.Linie,Current->Data.Adresse.Knoten,Current->Data.Adresse.Port,Current))!=NULL) {
      ParseError = 1 ;
      fprintf (stderr,"Adresse wurde doppelt verwendet: Linie %d, Knoten %d, Port %d\n",
	       Current->Data.Adresse.Linie,Current->Data.Adresse.Knoten,Current->Data.Adresse.Port) ;
      fprintf (stderr,"Erste Verwendung: ") ;
      for (;This!=NULL;This=This->Parent) fprintf (stderr,"%s ",This->Name) ;
      fprintf (stderr,"\nZweite Verwendung: ") ;
      for (This=Current;This!=NULL;This=This->Parent) fprintf (stderr,"%s ",This->Name) ;
      fprintf (stderr,"\n") ;
    } ;
    // Schauen, ob im Parent schon eine Adresse eingetragen ist; ggf diese ebenfalls
    // ueberschreiben (Ein Element sollte nur eine Adresse haben...)
    // Dient auch der Möglichkeit, Makros nachträglich mit einer Adresse zu versehen,
    // um die Konfiguration von Aktionen im Sensor nicht von der Reihenfolge der Makros
    // abhaengig zu haben.
    for (This=Current->Prev;This!=NULL;This=This->Prev)
      if (This->Type==N_ADRESS) {
	This->Data.Adresse.Linie = Current->Data.Adresse.Linie ;
	This->Data.Adresse.Knoten = Current->Data.Adresse.Knoten ;
	This->Data.Adresse.Port = Current->Data.Adresse.Port ;
      } ;
  } ;
  
  // Element nachbearbeiten
  // Makros nummerieren 
  if (Current->Type==N_MACRO) {
    This = NewChild(Current) ;
    This->Type = N_ADRESS ;
    This->Data.Adresse.Linie = 0 ;
    This->Data.Adresse.Knoten = (MakroNummer>>8)+50 ;
    This->Data.Adresse.Port = (MakroNummer&0xFF) ;
    MakroNummer++ ;
  } ;