Mercurial > noffle
comparison src/itemlist.c @ 72:78e2ae741240 noffle
[svn] Fix stupid bug in Itl_next
| author | bears |
|---|---|
| date | Sat, 13 May 2000 16:34:15 +0100 |
| parents | 125d79c9e586 |
| children | 24d4cd032da5 |
comparison
equal
deleted
inserted
replaced
| 71:6aa3a8eff5a9 | 72:78e2ae741240 |
|---|---|
| 1 /* | 1 /* |
| 2 itemlist.c | 2 itemlist.c |
| 3 | 3 |
| 4 $Id: itemlist.c 60 2000-05-09 22:28:38Z uh1763 $ | 4 $Id: itemlist.c 78 2000-05-13 15:34:15Z bears $ |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #if HAVE_CONFIG_H | 7 #if HAVE_CONFIG_H |
| 8 #include <config.h> | 8 #include <config.h> |
| 9 #endif | 9 #endif |
| 14 #include <stdlib.h> | 14 #include <stdlib.h> |
| 15 #include "common.h" | 15 #include "common.h" |
| 16 #include "log.h" | 16 #include "log.h" |
| 17 #include "portable.h" | 17 #include "portable.h" |
| 18 | 18 |
| 19 #if defined(ITEMLIST_TEST) | |
| 20 #define Log_err printf | |
| 21 #endif | |
| 22 | |
| 23 #define SEP_CHAR '\1' /* Replace all separators with this */ | |
| 24 | |
| 19 struct ItemList | 25 struct ItemList |
| 20 { | 26 { |
| 21 char *list; | 27 char *list; |
| 22 char *separators; | |
| 23 char *next; | 28 char *next; |
| 24 size_t count; | 29 size_t count; |
| 25 }; | 30 }; |
| 26 | 31 |
| 27 /* Make a new item list. */ | 32 /* Make a new item list. */ |
| 45 Log_err( "Malloc of ItemList.list failed." ); | 50 Log_err( "Malloc of ItemList.list failed." ); |
| 46 exit( EXIT_FAILURE ); | 51 exit( EXIT_FAILURE ); |
| 47 } | 52 } |
| 48 strcpy( res->list, list ); | 53 strcpy( res->list, list ); |
| 49 | 54 |
| 50 if ( ( res->separators = strdup( separators ) ) == NULL ) | |
| 51 { | |
| 52 Log_err( "Malloc of ItemList.separators failed." ); | |
| 53 exit( EXIT_FAILURE ); | |
| 54 } | |
| 55 | |
| 56 res->count = 0; | 55 res->count = 0; |
| 57 res->next = res->list; | 56 res->next = res->list; |
| 58 | 57 |
| 59 /* Separate items into strings and have final zero-length string. */ | 58 /* Separate items into strings and have final zero-length string. */ |
| 60 for( p = res->list, inItem = FALSE; *p != '\0'; p++ ) | 59 for( p = res->list, inItem = FALSE; *p != '\0'; p++ ) |
| 70 res->count++; | 69 res->count++; |
| 71 } | 70 } |
| 72 } | 71 } |
| 73 else | 72 else |
| 74 { | 73 { |
| 75 if ( ! isSep ) | 74 if ( isSep ) |
| 75 p[ 0 ] = SEP_CHAR; | |
| 76 else | |
| 76 inItem = TRUE; | 77 inItem = TRUE; |
| 77 } | 78 } |
| 78 } | 79 } |
| 79 if ( inItem ) | 80 if ( inItem ) |
| 80 res->count++; | 81 res->count++; |
| 87 del_Itl( ItemList *self ) | 88 del_Itl( ItemList *self ) |
| 88 { | 89 { |
| 89 if ( self == NULL ) | 90 if ( self == NULL ) |
| 90 return; | 91 return; |
| 91 free( self->list ); | 92 free( self->list ); |
| 92 free( self->separators ); | |
| 93 free( self ); | 93 free( self ); |
| 94 } | 94 } |
| 95 | 95 |
| 96 /* Get first item. */ | 96 /* Get first item. */ |
| 97 const char * | 97 const char * |
| 103 | 103 |
| 104 /* Get next item or NULL. */ | 104 /* Get next item or NULL. */ |
| 105 const char * | 105 const char * |
| 106 Itl_next( ItemList *self ) | 106 Itl_next( ItemList *self ) |
| 107 { | 107 { |
| 108 const char *res = self->next; | 108 char *res = self->next; |
| 109 | 109 |
| 110 if ( res[ 0 ] == '\0' ) | 110 if ( res[ 0 ] == '\0' ) |
| 111 return NULL; | 111 return NULL; |
| 112 | 112 |
| 113 while ( strchr( self->separators, res[ 0 ] ) != NULL ) | 113 while ( res[ 0 ] == SEP_CHAR ) |
| 114 res++; | 114 res++; |
| 115 | 115 |
| 116 if ( res[ 0 ] == '\0' && res[ 1 ] == '\0' ) | 116 if ( res[ 0 ] == '\0' && res[ 1 ] == '\0' ) |
| 117 return NULL; | 117 return NULL; |
| 118 | 118 |
| 119 self->next += strlen( res ) + 1; | 119 self->next = res + strlen( res ) + 1; |
| 120 return res; | 120 return res; |
| 121 } | 121 } |
| 122 | 122 |
| 123 /* Get count of items in list. */ | 123 /* Get count of items in list. */ |
| 124 size_t | 124 size_t |
| 125 Itl_count( const ItemList *self ) | 125 Itl_count( const ItemList *self ) |
| 126 { | 126 { |
| 127 return self->count; | 127 return self->count; |
| 128 } | 128 } |
| 129 | |
| 130 #if defined(ITEMLIST_TEST) | |
| 131 | |
| 132 /* Test code borrowed from wildmat.c. Yep, still uses gets(). */ | |
| 133 extern char *gets(); | |
| 134 | |
| 135 int | |
| 136 main() | |
| 137 { | |
| 138 Str line; | |
| 139 Str seps; | |
| 140 ItemList * itl; | |
| 141 int count; | |
| 142 const char *item; | |
| 143 | |
| 144 printf( "Itemlist tester. Enter seperators, then strings to test.\n" ); | |
| 145 printf( "A blank line gets prompts for new seperators; blank separators\n" ); | |
| 146 printf( "exits the program.\n" ); | |
| 147 | |
| 148 for ( ; ; ) | |
| 149 { | |
| 150 printf( "\nEnter seperators: " ); | |
| 151 (void) fflush( stdout ); | |
| 152 if ( gets( seps ) == NULL || seps[0] == '\0' ) | |
| 153 break; | |
| 154 for ( ; ; ) | |
| 155 { | |
| 156 printf( "Enter line: " ); | |
| 157 (void) fflush( stdout ); | |
| 158 if ( gets( line ) == NULL ) | |
| 159 exit( 0 ); | |
| 160 if ( line[0] == '\0' ) | |
| 161 break; | |
| 162 itl = new_Itl( line, seps ); | |
| 163 printf( "%d items on list\n", Itl_count( itl ) ); | |
| 164 count = 0; | |
| 165 for ( item = Itl_first( itl ); | |
| 166 item != NULL; | |
| 167 item = Itl_next( itl ) ) | |
| 168 printf( " Item %d is '%s'\n", ++count, item ); | |
| 169 if ( count != Itl_count( itl ) ) | |
| 170 printf( "*** Warning - counts don't match ***\n" ); | |
| 171 del_Itl( itl ); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 exit(0); | |
| 176 /* NOTREACHED */ | |
| 177 } | |
| 178 #endif /* defined(TEST) */ |
