Vollständiger Quelltext: XML

Anleitung

Zu kompilieren mit

gcc html.c

Download

Ansicht

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct Parameter
{
  struct Parameter * Next;
 
  char * Name;
  char * Value;
};
 
void parameter_delete( struct Parameter * toDelete )
{
  if( toDelete )
  {
    printf( "-Parameter: %s\n", toDelete->Name );
 
    free( toDelete->Name );
    free( toDelete->Value );
    free( toDelete );
  }
}
 
struct Parameter * parameter_newWithLength( char const * name, 
                                            unsigned int nameLength, 
                                            char const * value, 
                                            unsigned int valueLength )
{
  struct Parameter * result = malloc( sizeof( struct Parameter ) );
  printf( "+Parameter: %*s\n", nameLength, name );
 
  if( result )
  {
    result->Next  = NULL;
 
    result->Name  = malloc( 1 +  nameLength );
    result->Value = malloc( 1 + valueLength );
 
    if( result->Name && result->Value )
    {
      memcpy( result->Name,   name,  nameLength );
      result->Name[nameLength] = '\0';
      memcpy( result->Value, value, valueLength );
      result->Value[valueLength] = '\0';
 
      return result;
    }
 
    /* Parameter konnte nicht angelegt werden */
 
    parameter_delete( result );
  }
 
  return NULL;
}
 
struct Parameter * parameter_new( char const * name, 
                                  char const * value )
{
  return parameter_newWithLength( name, strlen( name ), value, strlen( value ) );
}
 
struct Node
{
  struct Node      * Next;
 
  char             * Text;         // Falls es ein Textknoten, wie "proggen.org" ist.
 
  char             * Name;         // Name des Knotens
  struct Parameter * Parameter;    // Parameter wie bei <body ...>
  struct Node      * SubNodes;     // H1 ist der erste Subknoten von body.
};
 
void node_delete( struct Node * toDelete )
{
  if( toDelete )
  {
    struct Parameter *tempP, *p = toDelete->Parameter;
    struct Node      *tempN, *n = toDelete->SubNodes;
 
    printf( "-%s: \"%s\"\n", ( toDelete->Name ) ? "Node" : "Text", 
                             ( toDelete->Name ) ? toDelete->Name : toDelete->Text );
 
    free( toDelete->Name );  // Falls Name vorhanden, dann löschen
    free( toDelete->Text );  // Falls Text vorhanden, dann löschen
 
    // Parameter löschen
    while( p )
    {
      tempP = p->Next;
      parameter_delete( p );
      p = tempP;
    }
 
    // Unterknoten löschen
    while( n )
    {
      tempN = n->Next;
      node_delete( n );     // Rekursiver Aufruf
      n = tempN;
    }
 
    // Diese Node löschen
    free( toDelete );
  }
}
 
struct Node * node_newWithLength( char const * name, unsigned int nameLength )
{
  struct Node * result = malloc( sizeof( struct Node ) );
 
  printf( "+Node: %*s\n", nameLength, name );
 
  if( result )
  {
    result->Name = malloc( 1 + nameLength );
    if( result )
    {
      memcpy( result->Name, name, nameLength );
      result->Name[nameLength] = '\0';
 
      result->Next      = NULL;
      result->Text      = NULL;
      result->Parameter = NULL;
      result->SubNodes  = NULL;
 
      return result;
    }
 
    node_delete( result );
  }
 
  return NULL;
}
 
struct Node * node_new( char const * name )
{
  return node_newWithLength( name, strlen( name ) );
}
 
struct Node * node_textWithLength( char const * text, unsigned int textLength )
{
  struct Node * result = malloc( sizeof( struct Node ) );
  printf( "+Text: %*s\n", textLength, text );
 
  if( result )
  {
    result->Text = malloc( 1 + textLength );
    if( result )
    {
      memcpy( result->Text, text, textLength );
      result->Text[textLength] = '\0';
 
      result->Next      = NULL;
      result->Name      = NULL;
      result->Parameter = NULL;
      result->SubNodes  = NULL;
 
      return result;
    }
 
    node_delete( result );
  }
 
  return NULL;
}
 
struct Node * node_text( char const * text )
{
  return node_textWithLength( text, strlen( text ) );
}
 
void node_addParameter( struct Node * node, struct Parameter * parameter )
{
  if( node )
  {
    struct Parameter ** parameterPtr = &node->Parameter;
 
    /* Letzten Parameter finden */
    while( *parameterPtr )
      parameterPtr = &(*parameterPtr)->Next;
 
    *parameterPtr = parameter;
  }
}
 
void node_addSubNode( struct Node * node, struct Node * subnode )
{
  if( node )
  {
    struct Node ** nodePtr = &node->SubNodes;
 
    /* Letzte Node finden */
    while( *nodePtr )
      nodePtr = &(*nodePtr)->Next;
 
    *nodePtr = subnode;
  }
}
 
int main( void )
{
  /* Variablendeklarationen */
 
  struct Node      * html;
  struct Node      * body;
  struct Parameter * par;
  struct Node      * text;
  struct Node      * headline;
 
  /* Programmteil */
 
  html     = node_new( "html" );
  body     = node_new( "body" );
 
  node_addSubNode( html, body );
 
  par      = parameter_new( "background", "white" );
 
  node_addParameter( body, par );
 
  text     = node_text( "proggen.org" );
  headline = node_new( "h1" );
 
  node_addSubNode( headline, text );
  node_addSubNode( body, headline );
 
  text = node_text( "C-Tutorial" );
  node_addSubNode( body, text );
 
  /* Datenstruktur fertig */
 
  node_delete( html );
 
  return 0;
}