First cut at fixing fc_sort.
This commit is contained in:
		
							parent
							
								
									2224ed3aa5
								
							
						
					
					
						commit
						6847e8295c
					
				| @ -1,5 +1,9 @@ | |||||||
|  | /* Copyright 2005, Tresys Technology */ | ||||||
|  | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
|  | typedef unsigned char bool_t; | ||||||
|  | 
 | ||||||
| /* file_context_node
 | /* file_context_node
 | ||||||
|  * A node used in a linked list of file contexts. |  * A node used in a linked list of file contexts. | ||||||
|  * Each node contains the regular expression, the type and  |  * Each node contains the regular expression, the type and  | ||||||
| @ -9,18 +13,22 @@ | |||||||
|  *  function after the regular expression has been loaded. |  *  function after the regular expression has been loaded. | ||||||
|  * next points to the next node in the linked list. |  * next points to the next node in the linked list. | ||||||
|  */ |  */ | ||||||
| struct file_context_node {  | typedef struct file_context_node { | ||||||
| 	char* regex; | 	char *regex; | ||||||
| 	char* type; | 	char *file_type; | ||||||
|         char* context; | 	char *context; | ||||||
|         int meta; | 	bool_t meta; | ||||||
|         int stem_len; | 	int stem_len; | ||||||
|         int str_len; | 	int str_len; | ||||||
| 
 | 	struct file_context_node *next; | ||||||
|         struct file_context_node* next; | } file_context_node_t; | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|  | void file_context_node_destroy(file_context_node_t *x) | ||||||
|  | { | ||||||
|  | 	free(x->regex); | ||||||
|  | 	free(x->file_type); | ||||||
|  | 	free(x->context); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| /* file_context_bucket
 | /* file_context_bucket
 | ||||||
|  * A node used in a linked list of buckets that contain |  * A node used in a linked list of buckets that contain | ||||||
| @ -30,11 +38,10 @@ struct file_context_node { | |||||||
|  *  content of this bucket. |  *  content of this bucket. | ||||||
|  * next points to the next bucket in the linked list. |  * next points to the next bucket in the linked list. | ||||||
|  */ |  */ | ||||||
| struct file_context_bucket { | typedef struct file_context_bucket { | ||||||
| 	struct file_context_node* data; | 	file_context_node_t *data; | ||||||
| 
 | 	struct file_context_bucket *next; | ||||||
| 	struct file_context_bucket* next; | } file_context_bucket_t; | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -44,60 +51,63 @@ struct file_context_bucket { | |||||||
|  * Pass two lists a and b, and after the completion of fc_merge, |  * Pass two lists a and b, and after the completion of fc_merge, | ||||||
|  *  the final list is contained in a, and b is empty. |  *  the final list is contained in a, and b is empty. | ||||||
|  */ |  */ | ||||||
| struct file_context_node* fc_merge( struct file_context_node* a, struct file_context_node* b ) | file_context_node_t *fc_merge(file_context_node_t *a, | ||||||
|  | 				   file_context_node_t *b) | ||||||
| { | { | ||||||
|         struct file_context_node* a_current; | 	file_context_node_t *a_current; | ||||||
|         struct file_context_node* b_current; | 	file_context_node_t *b_current; | ||||||
|         struct file_context_node* temp; | 	file_context_node_t *temp; | ||||||
|         struct file_context_node* jumpto; | 	file_context_node_t *jumpto; | ||||||
| 
 | 
 | ||||||
|         /* If a is a empty list, and b is not,
 | 	/* If a is a empty list, and b is not,
 | ||||||
|          *  set a as b and proceed to the end. */ | 	 *  set a as b and proceed to the end. */ | ||||||
|         if( !a && b ) | 	if (!a && b) | ||||||
|                 a = b; | 		a = b; | ||||||
|         /* If b is an empty list, leave a as it is. */ | 	/* If b is an empty list, leave a as it is. */ | ||||||
|         else if( !b ) { } | 	else if (!b) { | ||||||
|         else { | 	} else { | ||||||
|                 /* Make it so the list a has the lesser
 | 		/* Make it so the list a has the lesser
 | ||||||
|                  *  first element always. */ | 		 *  first element always. */ | ||||||
|                 if( fc_compare( a, b ) == 1 ) { | 		if (fc_compare(a, b) == 1) { | ||||||
|                         temp = a; | 			temp = a; | ||||||
|                         a = b; | 			a = b; | ||||||
|                         b = temp; | 			b = temp; | ||||||
|                 } | 		} | ||||||
|                 a_current = a; | 		a_current = a; | ||||||
|                 b_current = b; | 		b_current = b; | ||||||
| 
 | 
 | ||||||
|                 /* Merge by inserting b's nodes inbetween a's nodes. */ | 		/* Merge by inserting b's nodes inbetween a's nodes. */ | ||||||
|                 while( a_current->next && b_current ) { | 		while (a_current->next && b_current) { | ||||||
|                         jumpto = a_current->next; | 			jumpto = a_current->next; | ||||||
| 
 | 
 | ||||||
|                         /* Insert b's nodes inbetween the current a node
 | 			/* Insert b's nodes inbetween the current a node
 | ||||||
|                          *  and the next a node.*/ | 			 *  and the next a node.*/ | ||||||
|                         while( b_current && a_current->next && | 			while (b_current && a_current->next && | ||||||
|                                fc_compare( a_current->next, b_current) != -1 ) {                                temp = a_current->next; | 			       fc_compare(a_current->next, | ||||||
|                                 a_current->next = b_current; | 					  b_current) != -1) { | ||||||
|                                 b_current = b_current->next; | 				temp = a_current->next; | ||||||
|                                 a_current->next->next = temp; | 				a_current->next = b_current; | ||||||
|                                 a_current = a_current->next; | 				b_current = b_current->next; | ||||||
|                         } | 				a_current->next->next = temp; | ||||||
|  | 				a_current = a_current->next; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
|                         /* Skip all the inserted node from b to the
 | 			/* Skip all the inserted node from b to the
 | ||||||
|                          *  next node in the original a. */ | 			 *  next node in the original a. */ | ||||||
|                         a_current = jumpto; | 			a_current = jumpto; | ||||||
|                 } | 		} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|                 /* if there is anything left in b to be inserted,
 | 		/* if there is anything left in b to be inserted,
 | ||||||
|                    put it on the end */ | 		   put it on the end */ | ||||||
|                 if( b_current ) { | 		if (b_current) { | ||||||
|                         a_current->next = b_current; | 			a_current->next = b_current; | ||||||
|                 } | 		} | ||||||
|         } | 	} | ||||||
| 
 | 
 | ||||||
|         b = NULL; | 	b = NULL; | ||||||
| 
 | 
 | ||||||
|         return a; | 	return a; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -119,35 +129,37 @@ struct file_context_node* fc_merge( struct file_context_node* a, struct file_con | |||||||
|  *   until there is only  one bucket left, containing the list of |  *   until there is only  one bucket left, containing the list of | ||||||
|  *   file contexts, sorted. |  *   file contexts, sorted. | ||||||
|  */ |  */ | ||||||
| void fc_merge_sort( struct file_context_bucket* master ) | void fc_merge_sort(file_context_bucket_t *master) | ||||||
| { | { | ||||||
|         int i; | 	int i; | ||||||
| 
 | 
 | ||||||
|         struct file_context_bucket* current; | 	file_context_bucket_t *current; | ||||||
|         struct file_context_bucket* temp; | 	file_context_bucket_t *temp; | ||||||
| 
 | 
 | ||||||
|         struct file_context_node* ncurrent; | 	file_context_node_t *ncurrent; | ||||||
|         struct file_context_node* ntemp; | 	file_context_node_t *ntemp; | ||||||
| 
 | 
 | ||||||
| 	/* Loop until master is the only bucket left
 | 	/* Loop until master is the only bucket left
 | ||||||
|          * so that this will stop when master contains | 	 * so that this will stop when master contains | ||||||
| 	 * the sorted list. */ | 	 * the sorted list. */ | ||||||
|         while( master->next ) { | 	while (master->next) { | ||||||
|                 current = master; | 		current = master; | ||||||
| 
 | 
 | ||||||
| 		/* This loop merges buckets two-by-two. */ | 		/* This loop merges buckets two-by-two. */ | ||||||
| 		while( current ) { | 		while (current) { | ||||||
|                         if( current->next ) { | 			if (current->next) { | ||||||
| 				/* Merge the next one into the current one. */ | 				/* Merge the next one into the current one. */ | ||||||
|                                 current->data = fc_merge( current->data, current->next->data ); | 				current->data = | ||||||
|                         	/* remove the next bucket that is now empty. */ | 				    fc_merge(current->data, | ||||||
|  | 					     current->next->data); | ||||||
|  | 				/* remove the next bucket that is now empty. */ | ||||||
| 				temp = current->next; | 				temp = current->next; | ||||||
|                                 current->next = current->next->next; | 				current->next = current->next->next; | ||||||
|                                 free( temp ); | 				free(temp); | ||||||
|                         } | 			} | ||||||
|                         current = current->next; | 			current = current->next; | ||||||
|                 } | 		} | ||||||
|         } | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* fc_compare
 | /* fc_compare
 | ||||||
| @ -166,39 +178,39 @@ void fc_merge_sort( struct file_context_bucket* master ) | |||||||
|  *     If a does not have a specified type and b does not, |  *     If a does not have a specified type and b does not, | ||||||
|  *      -> a is less specific than b. |  *      -> a is less specific than b. | ||||||
|  */ |  */ | ||||||
| int fc_compare( struct file_context_node* a, struct file_context_node* b ) | int fc_compare(file_context_node_t *a, file_context_node_t *b) | ||||||
| { | { | ||||||
| 	/* Check to see if either a or b have meta characters
 | 	/* Check to see if either a or b have meta characters
 | ||||||
|          *  and the other doesn't. */ | 	 *  and the other doesn't. */ | ||||||
|         if( a->meta && !b->meta ) | 	if (a->meta && !b->meta) | ||||||
|                 return -1; | 		return -1; | ||||||
|         if( b->meta && !a->meta ) | 	if (b->meta && !a->meta) | ||||||
|                 return 1; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	/* Check to see if either a or b have a shorter stem
 | 	/* Check to see if either a or b have a shorter stem
 | ||||||
|          *  length than the other. */ | 	 *  length than the other. */ | ||||||
|         if( a->stem_len < b->stem_len ) | 	if (a->stem_len < b->stem_len) | ||||||
|                 return -1; | 		return -1; | ||||||
|         if( b->stem_len < a->stem_len ) | 	if (b->stem_len < a->stem_len) | ||||||
|                 return 1; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	/* Check to see if either a or b have a shorter string
 | 	/* Check to see if either a or b have a shorter string
 | ||||||
|          *  length than the other. */ | 	 *  length than the other. */ | ||||||
|         if( a->str_len < b->str_len ) | 	if (a->str_len < b->str_len) | ||||||
|                 return -1; | 		return -1; | ||||||
|         if( b->str_len < b->str_len ) | 	if (b->str_len < b->str_len) | ||||||
|                 return 1; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	/* Check to see if either a or b has a specified type
 | 	/* Check to see if either a or b has a specified type
 | ||||||
|          *  and the other doesn't. */ | 	 *  and the other doesn't. */ | ||||||
|         if( !a->type && b->type ) | 	if (!a->type && b->type) | ||||||
|                 return -1; | 		return -1; | ||||||
|         if( !b->type && a->type ) | 	if (!b->type && a->type) | ||||||
|                 return 1; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	/* If none of the above conditions were satisfied, 
 | 	/* If none of the above conditions were satisfied, 
 | ||||||
|          * then a and b are equally specific. */ | 	 * then a and b are equally specific. */ | ||||||
|         return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -216,49 +228,50 @@ int fc_compare( struct file_context_node* a, struct file_context_node* b ) | |||||||
|  *     fc_node->stem_len = 	The number of characters up until |  *     fc_node->stem_len = 	The number of characters up until | ||||||
|  *				 the first meta character. |  *				 the first meta character. | ||||||
|  */ |  */ | ||||||
| void fc_fill_data( struct file_context_node* fc_node ) | void fc_fill_data(file_context_node_t *fc_node) | ||||||
| { | { | ||||||
|         int c = 0; | 	int c = 0; | ||||||
| 
 | 
 | ||||||
|         fc_node->meta = 0; | 	fc_node->meta = 0; | ||||||
|         fc_node->stem_len = 0; | 	fc_node->stem_len = 0; | ||||||
|         fc_node->str_len = 0; | 	fc_node->str_len = 0; | ||||||
| 
 | 
 | ||||||
| 	/* Process until the string termination character
 | 	/* Process until the string termination character
 | ||||||
|          *  has been reached. | 	 *  has been reached. | ||||||
| 	 * Note: this while loop has been adapted from | 	 * Note: this while loop has been adapted from | ||||||
|          *  spec_hasMetaChars in matchpathcon.c from | 	 *  spec_hasMetaChars in matchpathcon.c from | ||||||
|          *  libselinux-1.22. */ | 	 *  libselinux-1.22. */ | ||||||
|         while( fc_node->regex[c] != 0 ) { | 	while (fc_node->regex[c] != 0) { | ||||||
|                 switch( fc_node->regex[c] ) { | 		switch (fc_node->regex[c]) { | ||||||
|                         case '.': | 		case '.': | ||||||
|                         case '^': | 		case '^': | ||||||
|                         case '$': | 		case '$': | ||||||
|                         case '?': | 		case '?': | ||||||
|                         case '*': | 		case '*': | ||||||
|                         case '+': | 		case '+': | ||||||
|                         case '|': | 		case '|': | ||||||
|                         case '[': | 		case '[': | ||||||
|                         case '(': | 		case '(': | ||||||
|                         case '{': | 		case '{': | ||||||
|             			/* If a meta character is found,
 | 			/* If a meta character is found,
 | ||||||
|                                  *  set meta to one */ | 			 *  set meta to one */ | ||||||
| 		                fc_node->meta = 1; | 			fc_node->meta = 1; | ||||||
|                                 break; | 			break; | ||||||
|                         case '\\': | 		case '\\': | ||||||
| 				/* If a escape character is found,
 | 			/* If a escape character is found,
 | ||||||
|                                  *  skip the next character. */ | 			 *  skip the next character. */ | ||||||
|                                 c++; | 			c++; | ||||||
|                         default: | 		default: | ||||||
| 				/* If no meta character has been found yet,
 | 			/* If no meta character has been found yet,
 | ||||||
| 				 *  add one to the stem length. */ | 			 *  add one to the stem length. */ | ||||||
|                                 if( !fc_node->meta ) fc_node->stem_len++; | 			if (!fc_node->meta) | ||||||
|                                 break; | 				fc_node->stem_len++; | ||||||
|                 } | 			break; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		fc_node->str_len++; | 		fc_node->str_len++; | ||||||
|                 c++; | 		c++; | ||||||
|         } | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* main
 | /* main
 | ||||||
| @ -267,143 +280,163 @@ void fc_fill_data( struct file_context_node* fc_node ) | |||||||
|  * Overall what is done in the main is read in the file and store each |  * Overall what is done in the main is read in the file and store each | ||||||
|  *  line of code, sort it, then output it to the output file. |  *  line of code, sort it, then output it to the output file. | ||||||
|  */ |  */ | ||||||
| int main( int argc, char *argv[]) | int main(int argc, char *argv[]) | ||||||
| { | { | ||||||
| 	int i, j, lines; | 	int lines; | ||||||
| 	int start, finish; | 	size_t start, finish, regex_len; | ||||||
| 	char* str; | 	size_t line_len, i, j; | ||||||
| 	struct file_context_node* temp; | 	char *str, *input_name, *output_name, *line_buf; | ||||||
| 	struct file_context_node* head; | 	 | ||||||
| 	struct file_context_node* current; | 	file_context_node_t *temp; | ||||||
| 	struct file_context_node* array;  | 	file_context_node_t *head; | ||||||
| 	struct file_context_bucket* master; | 	file_context_node_t *current; | ||||||
| 	struct file_context_bucket* bcurrent; | 	file_context_node_t *array; | ||||||
|  | 	file_context_bucket_t *master; | ||||||
|  | 	file_context_bucket_t *bcurrent; | ||||||
| 
 | 
 | ||||||
| 	FILE *path; | 	FILE *in_file, *out_file; | ||||||
| 	char line_buf[ 127 ]; |  | ||||||
| 
 | 
 | ||||||
| 	/* Check for the correct number of command line arguments. */ | 	/* Check for the correct number of command line arguments. */ | ||||||
| 	if( argc != 3 ) { | 	if (argc != 3) { | ||||||
| 		printf( "Error: invalid number of command line arguments.\n" ); | 		fprintf(stderr, "Error: invalid number of command line arguments.\n"); | ||||||
| 		return -1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
|  | 	input_name = argv[1]; | ||||||
|  | 	output_name = argv[2]; | ||||||
| 
 | 
 | ||||||
| 	i = j = lines = 0; | 	i = j = lines = 0; | ||||||
| 
 | 
 | ||||||
| 	/* Allocate the head of the file_context linked list. */ |  | ||||||
| 	if( !( current = head = (struct file_context_node*)malloc( sizeof( struct file_context_node ) ) ) ) { |  | ||||||
| 		printf( "Error: failure allocating memory.\n" ); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	/* Make sure to have a terminating character, always. */ | 	/* Make sure to have a terminating character, always. */ | ||||||
| 	line_buf[127] = 0; | 	line_buf[BUF_SIZE - 1] = '\0'; | ||||||
| 
 | 
 | ||||||
| 	/* Open the input file. */ | 	/* Open the input file. */ | ||||||
| 	if( !( path = fopen( argv[1], "r" ) ) ) { | 	if (!(in_file = fopen(input_name), "r")) { | ||||||
| 		printf( "Error: failure opening input file for read.\n" ); | 		fprintf(stderr, "Error: failure opening input file for read.\n"); | ||||||
| 		return -1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Parse the file into a file_context linked list. */ | 	/* Parse the file into a file_context linked list. */ | ||||||
| 	while( fgets( line_buf, 126, path ) != NULL ) { | 	buf = NULL; | ||||||
| 
 | 	while (getline(&line_buf, &line_len, in_file) { | ||||||
| 		/* Get rid of whitespace from the front of the line. */ | 		/* Get rid of whitespace from the front of the line. */ | ||||||
| 		i = 0; | 		for (i = 0; i < line_len; i++) { | ||||||
| 		while( line_buf[i] && line_buf[i] <= ' ' ) i++; | 			if (line_buf[i] != ' ' || line_buf[i] != '\t') | ||||||
| 
 | 				break; | ||||||
| 		/* Check if the line isn't empty and isn't a comment */ |  | ||||||
| 		if( line_buf[i] && line_buf[i] != '#' ) { |  | ||||||
| 			/* Allocate a new node. */ |  | ||||||
| 			temp = (struct file_context_node*)malloc( sizeof( struct file_context_node ) ); |  | ||||||
| 			if( !temp ) { |  | ||||||
| 				printf( "Error: failure allocating memory.\n" ); |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
| 			temp->next = NULL; |  | ||||||
| 
 |  | ||||||
| 			/* Parse out the regular expression from the line. */ |  | ||||||
| 			start = i; |  | ||||||
| 			while( line_buf[i] > ' ' )i++; |  | ||||||
| 			finish = i; |  | ||||||
| 
 |  | ||||||
| 			/* Allocate a character array to hold the regular
 |  | ||||||
|  			 *  expression. */ |  | ||||||
| 			temp->regex = (char*)malloc( sizeof( char ) * ( finish - start + 1) ); |  | ||||||
| 			if( !( temp->regex ) ) { |  | ||||||
| 				printf( "Error: failure allocating memory.\n" ); |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
| 			temp->regex[0] = 0; |  | ||||||
| 
 |  | ||||||
| 			/* Fill the regular expression array. */ |  | ||||||
| 			temp->regex[ ( finish - start ) ] = 0; |  | ||||||
| 			for( j = 0; j < finish - start; j++ ) { |  | ||||||
| 				temp->regex[j] = line_buf[j + start]; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			/* Get rid of whitespace after the regular
 |  | ||||||
|                          *  expression. */ |  | ||||||
| 			while( line_buf[i] <= ' ' ) i++; |  | ||||||
| 
 |  | ||||||
| 			/* Parse out the type from the line (if it 
 |  | ||||||
|                          *  is there). */ |  | ||||||
| 			if( line_buf[i] == '-' ) { |  | ||||||
| 				/* Allocate a character array to
 |  | ||||||
|                                  *  hold the type. */ |  | ||||||
| 				temp->type = (char*)malloc( sizeof( char ) * 3 ); |  | ||||||
| 				if( !( temp->type ) ) { |  | ||||||
| 					printf( "Error: failure allocating memory.\n" ); |  | ||||||
| 					return -1; |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				/* Fill the type into the array. */ |  | ||||||
| 				temp->type[0] = line_buf[i]; |  | ||||||
| 				temp->type[1] = line_buf[i + 1]; |  | ||||||
| 				i += 2; |  | ||||||
| 				temp->type[2] = 0; |  | ||||||
| 				 |  | ||||||
| 				/* Get rid of whitespace after the type. */ |  | ||||||
| 				while( line_buf[i] <= ' ' ) i++; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			/* Parse out the context from the line. */ |  | ||||||
|                         start = i; |  | ||||||
|                         while( line_buf[i] > ' ' ) i++; |  | ||||||
|                         finish = i; |  | ||||||
| 
 |  | ||||||
| 			/* Allocate a character array to hold the context. */ |  | ||||||
|                         temp->context = (char*)malloc( sizeof( char ) * ( finish - start + 1 ) ); |  | ||||||
| 			if( !( temp->context ) ) { |  | ||||||
| 				printf( "Error: failure allocating memory.\n" ); |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
| 			temp->context[0] = 0; |  | ||||||
| 
 |  | ||||||
| 			/* Fill the context array. */ |  | ||||||
|                         temp->context[ ( finish - start ) ] = 0; |  | ||||||
|                         for( j = 0; j < finish - start; j++ ) { |  | ||||||
|                                 temp->context[j] = line_buf[j + start]; |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
| 			/* Set all the data about the regular
 |  | ||||||
|                          *  expression. */ |  | ||||||
| 			fc_fill_data( temp ); |  | ||||||
| 
 |  | ||||||
| 			/* Link this line of code at the end of
 |  | ||||||
|                          *  the linked list. */ |  | ||||||
| 			current->next = temp; |  | ||||||
| 			current = current->next; |  | ||||||
| 			lines++; |  | ||||||
| 		} | 		} | ||||||
|  | 		 | ||||||
|  | 		if (i >= line_len) | ||||||
|  | 			continue; | ||||||
|  | 		/* Check if the line isn't empty and isn't a comment */ | ||||||
|  | 		if (line_buf[i] == '#') | ||||||
|  | 			continue; | ||||||
|  | 		 | ||||||
|  | 		/* We have a valid line - allocate a new node. */ | ||||||
|  | 		temp = (file_context_node_t *)malloc(sizeof(file_context_node_t)); | ||||||
|  | 		if (!temp) { | ||||||
|  | 			fprintf(stderr, "Error: failure allocating memory.\n"); | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
|  | 		memset(temp, 0, sizeof(file_context_node_t)); | ||||||
|  | 
 | ||||||
|  | 		/* Parse out the regular expression from the line. */ | ||||||
|  | 		start = i; | ||||||
|  | 		while (i < line_len && (line_buf[i] != ' ' || line_buf[i] != '\t')) | ||||||
|  | 			i++; | ||||||
|  | 		finish = i; | ||||||
|  | 		 | ||||||
|  | 		regex_len = start - finish; | ||||||
|  | 		 | ||||||
|  | 		if (regex_len == 0) { | ||||||
|  | 			file_context_node_destroy(temp); | ||||||
|  | 			free(temp); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		temp->path = strndup(&line_buf[start], regex_len); | ||||||
|  | 		if (!temp->path) { | ||||||
|  | 			file_context_node_destroy(temp); | ||||||
|  | 			free(temp); | ||||||
|  | 			fprintf(stderr, "Memory error\n"); | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Get rid of whitespace after the regular expression. */ | ||||||
|  | 		for (; i < line_len; i++) { | ||||||
|  | 			if (line_buf[i] != ' ' || line_buf[i] != '\t') | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		if (i == line_len) { | ||||||
|  | 			file_context_node_destroy(temp); | ||||||
|  | 			free(temp); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Parse out the type from the line (if it 
 | ||||||
|  | 			*  is there). */ | ||||||
|  | 		if (line_buf[i] == '-') { | ||||||
|  | 			 | ||||||
|  | 			temp->type = (char *)malloc(sizeof(char) * 3); | ||||||
|  | 			if (!(temp->type)) { | ||||||
|  | 				fprintf(stderr, "Error: failure allocating memory.\n"); | ||||||
|  | 				return 1; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			/* Fill the type into the array. */ | ||||||
|  | 			temp->type[0] = line_buf[i]; | ||||||
|  | 			temp->type[1] = line_buf[i + 1]; | ||||||
|  | 			i += 2; | ||||||
|  | 			temp->type[2] = 0; | ||||||
|  | 
 | ||||||
|  | 			/* Get rid of whitespace after the type. */ | ||||||
|  | 			while (line_buf[i] <= ' ') | ||||||
|  | 				i++; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Parse out the context from the line. */ | ||||||
|  | 		start = i; | ||||||
|  | 		while (line_buf[i] > ' ') | ||||||
|  | 			i++; | ||||||
|  | 		finish = i; | ||||||
|  | 
 | ||||||
|  | 		/* Allocate a character array to hold the context. */ | ||||||
|  | 		temp->context = | ||||||
|  | 			(char *) malloc(sizeof(char) * | ||||||
|  | 					(finish - start + 1)); | ||||||
|  | 		if (!(temp->context)) { | ||||||
|  | 			printf | ||||||
|  | 				("Error: failure allocating memory.\n"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		temp->context[0] = 0; | ||||||
|  | 
 | ||||||
|  | 		/* Fill the context array. */ | ||||||
|  | 		temp->context[(finish - start)] = 0; | ||||||
|  | 		for (j = 0; j < finish - start; j++) { | ||||||
|  | 			temp->context[j] = line_buf[j + start]; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Set all the data about the regular
 | ||||||
|  | 			*  expression. */ | ||||||
|  | 		fc_fill_data(temp); | ||||||
|  | 
 | ||||||
|  | 		/* Link this line of code at the end of
 | ||||||
|  | 			*  the linked list. */ | ||||||
|  | 		current->next = temp; | ||||||
|  | 		current = current->next; | ||||||
|  | 		lines++; | ||||||
| 	} | 	} | ||||||
| 	fclose( path ); | 	free(buf); | ||||||
|  | 	fclose(path); | ||||||
| 
 | 
 | ||||||
| 	/* Create the bucket linked list from the earlier linked list. */ | 	/* Create the bucket linked list from the earlier linked list. */ | ||||||
| 	current = head->next; | 	current = head->next; | ||||||
| 	bcurrent = master = (struct file_context_bucket*)malloc( sizeof( struct file_context_bucket ) ); | 	bcurrent = master = | ||||||
|  | 	    (file_context_bucket_t *) | ||||||
|  | 	    malloc(sizeof(file_context_bucket_t)); | ||||||
| 	/* Go until all the nodes have been put in individual buckets. */ | 	/* Go until all the nodes have been put in individual buckets. */ | ||||||
| 	while( current ) { | 	while (current) { | ||||||
| 		/* Copy over the file context line into the bucket. */ | 		/* Copy over the file context line into the bucket. */ | ||||||
| 		bcurrent->data = current; | 		bcurrent->data = current; | ||||||
| 		current = current->next; | 		current = current->next; | ||||||
| @ -412,15 +445,18 @@ int main( int argc, char *argv[]) | |||||||
| 		bcurrent->data->next = NULL; | 		bcurrent->data->next = NULL; | ||||||
| 
 | 
 | ||||||
| 		/* If there should be another bucket, put one at the end. */ | 		/* If there should be another bucket, put one at the end. */ | ||||||
| 		if( current ) { | 		if (current) { | ||||||
| 			bcurrent->next = (struct file_context_bucket*) malloc( sizeof( struct file_context_bucket ) ); | 			bcurrent->next = | ||||||
| 			if( !( bcurrent->next ) ) { | 			    (file_context_bucket_t *) | ||||||
| 				printf( "Error: failure allocating memory.\n" ); | 			    malloc(sizeof(file_context_bucket_t)); | ||||||
|  | 			if (!(bcurrent->next)) { | ||||||
|  | 				printf | ||||||
|  | 				    ("Error: failure allocating memory.\n"); | ||||||
| 				return -1; | 				return -1; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			/* Make sure the new bucket thinks it's the end of the
 | 			/* Make sure the new bucket thinks it's the end of the
 | ||||||
|                          *  list. */ | 			 *  list. */ | ||||||
| 			bcurrent->next->next = NULL; | 			bcurrent->next->next = NULL; | ||||||
| 
 | 
 | ||||||
| 			bcurrent = bcurrent->next; | 			bcurrent = bcurrent->next; | ||||||
| @ -428,57 +464,56 @@ int main( int argc, char *argv[]) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Sort the bucket list. */ | 	/* Sort the bucket list. */ | ||||||
| 	fc_merge_sort( master ); | 	fc_merge_sort(master); | ||||||
| 
 | 
 | ||||||
| 	/* Open the output file. */ | 	/* Open the output file. */ | ||||||
| 	if( !(path = fopen( argv[2], "w" ) ) ) { | 	if (!(path = fopen(argv[2], "w"))) { | ||||||
| 		printf( "Error: failure opening output file for write.\n" ); | 		printf("Error: failure opening output file for write.\n"); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Output the sorted file_context linked list to the output file. */ | 	/* Output the sorted file_context linked list to the output file. */ | ||||||
| 	current = master->data; | 	current = master->data; | ||||||
| 	while( current ) { | 	while (current) { | ||||||
| 		/* Output the regular expression. */ | 		/* Output the regular expression. */ | ||||||
| 		i = 0; | 		i = 0; | ||||||
| 		while( current->regex[i] != 0 ) { | 		while (current->regex[i] != 0) { | ||||||
| 			fprintf( path, "%c", current->regex[i] ); | 			fprintf(path, "%c", current->regex[i]); | ||||||
| 			i++; | 			i++; | ||||||
| 		} | 		} | ||||||
| 		fprintf( path, "\t" ); | 		fprintf(path, "\t"); | ||||||
| 		 | 
 | ||||||
| 		/* Output the type, if there is one. */ | 		/* Output the type, if there is one. */ | ||||||
| 		if( current->type ) { | 		if (current->type) { | ||||||
| 			i = 0; | 			i = 0; | ||||||
| 			while( current->type[i] != 0 ) { | 			while (current->type[i] != 0) { | ||||||
| 				fprintf( path, "%c", current->type[i] ); | 				fprintf(path, "%c", current->type[i]); | ||||||
| 				i++; | 				i++; | ||||||
| 			} | 			} | ||||||
| 			fprintf( path, "\t" ); 	 | 			fprintf(path, "\t"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/* Output the context. */ | 		/* Output the context. */ | ||||||
| 		i = 0; | 		i = 0; | ||||||
| 		while( current->context[i] != 0 ) { | 		while (current->context[i] != 0) { | ||||||
| 			fprintf( path, "%c", current->context[i] ); | 			fprintf(path, "%c", current->context[i]); | ||||||
| 			i++; | 			i++; | ||||||
| 		} | 		} | ||||||
| 		fprintf( path, "\n" ); | 		fprintf(path, "\n"); | ||||||
| 
 | 
 | ||||||
| 		/* Remove the node. */ | 		/* Remove the node. */ | ||||||
| 		temp = current; | 		temp = current; | ||||||
| 		current = current->next; | 		current = current->next; | ||||||
| 
 | 
 | ||||||
| 		free( temp->regex ); | 		free(temp->regex); | ||||||
| 		if( temp->type) | 		if (temp->type) | ||||||
| 			free( temp->type ); | 			free(temp->type); | ||||||
| 		free( temp->context );		 | 		free(temp->context); | ||||||
| 		free( temp ); | 		free(temp); | ||||||
| 	} | 	} | ||||||
| 	free( master ); | 	free(master); | ||||||
| 
 | 
 | ||||||
| 	fclose( path ); | 	fclose(path); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user