/* John Pfeiffer, 20jul08 count the number of < > pairs there are in an .htm file
count-bracket.c.exe filename.htm
every part of the file can be considred an object, either a command object
or a data object: <command> data </command>
every object should carry it's own size (later on allows faster parsing of commands)
the <> symbol indicates the root of a list (doubly linked)
one list for commands, one list for data
limitations: buffer_counter is an int so MAX_OBJECT_SIZE cannot be larger than an int
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX_OBJECT_SIZE 128
typedef struct node tnode;
typedef struct node* nodeptr;
struct node
{ char object[MAX_OBJECT_SIZE];
int size; /* number of chars */
nodeptr next;
nodeptr prev;
};
nodeptr talloc(void)
{ return( (nodeptr)malloc( sizeof( struct node)) ); }
void zerobuffer(char object[MAX_OBJECT_SIZE])
{ int i;
for(i =0; i< MAX_OBJECT_SIZE; i++)
{ object[i] = 0; }
}/* end zerobuffer() */
void node_details(nodeptr current)
{ printf("size= %d, %s\n",current->size,current->object); }
nodeptr create_node( nodeptr parent )
{
nodeptr newnode = talloc(); /* allocate space for the node/object */
zerobuffer( newnode->object ); /* ensure that the array is empty */
newnode->size = 0; /* the object has 0 chars in it */
newnode->prev = parent; /* only root should have parent = NULL */
newnode->next = NULL; /* every new node is the "last" so next is NULL */
if( parent != NULL )
{ parent->next = newnode; } /* predecessor in list connects the chain EXCEPT root */
return( newnode ); /* returns a pointer to itself - careful, could leak! */
}/* end create_node() */
nodeptr find_end_of_list(nodeptr current)
{
while( current->next != NULL )
{ printf("FINDING END OF LIST %d\n",current->size); /* DEBUGGING: */
current = current->next; }
printf("FINDING END OF LIST %d\n",current->size);
return( current );
}/* end find_end_of_list() */
/* free list starts from the end of the list and works towards the root */
void free_list(nodeptr current)
{
nodeptr temp;
current = find_end_of_list(current);
printf("Freeing memory...\n");
while( current != NULL )
{ node_details( current ); /* DEBUGGING: list the details of what we're freeing */
temp = current;
current = current->prev; /* reverse listing */
free(temp); /* we've seen what's inside, now clean up */
}
}/* end free_list() */
/* function quits when finds close_symbol (char) from ifpbyref - puts them in current->object */
nodeptr get_until_close_symbol( char close_symbol, nodeptr current, FILE** ifpbyref)
{
int buffer_counter=0;
printf("\ngetting...\n");
while( (c != close_symbol) && (c != EOF) ) /* until close_symbol or EOF */
{
buffer_counter = 0;
printf("\nCreate node in list \n"); /* DEBUGGING */
current = create_node( current );
current->object[buffer_counter] = c;
while( (buffer_counter < MAX_OBJECT_SIZE-1) && (c != close_symbol) && (c != EOF) )
{
buffer_counter++;
c = getc( *ifpbyref );
current->object[buffer_counter] = c;
}
current->object[buffer_counter] = c;
current->size = buffer_counter + 1; /* for the > or EOF character */
}/* end while loop */
printf("\ndone getting...\n");
return( current );
}/* end get_until_close_symbol() */
/* **************MAIN******************************************************* */
int main(int argc, char* argv[])
{
char c;
FILE* ifp;
nodeptr current_commands; /* pointer to the current node in the list */
nodeptr current_data;
nodeptr root_commands;
nodeptr root_data;
root_commands = create_node( NULL ); /* predecesser of the new node */
root_commands->size = 2; /* size is 1 less because of 0 loc of array */
strcpy(root_commands->object,"<>");
/*root_data = create_node( NULL );
root_data->size = 2;
strcpy(root_data->object,"<>");
*/
current_commands = root_commands;
current_data = root_data;
ifp = fopen(argv[1],"r");
if( (ifp == NULL) )
{ printf("Error opening file(s)\nTry %s filename.htm",argv[0]);
exit(1);
}
printf("\nParsing %s...\n",argv[1]);
c=getc(ifp);
while( c != EOF )
{
if( c == '<')
{
current_commands = get_until_close_symbol( '>', current_commands, &ifp );
}/* end if c==< */
c = getc(ifp);
}/* end while loop */
fclose(ifp);
free_list( current_commands );
/* free_list( root_data ); */
return 0;
}/* end main */