| 1133 | } expansion_item; |
| 1134 | |
| 1135 | static LIST * expand( expansion_item * items, int const length ) |
| 1136 | { |
| 1137 | LIST * result = L0; |
| 1138 | string buf[ 1 ]; |
| 1139 | int size = 0; |
| 1140 | int i; |
| 1141 | |
| 1142 | assert( length > 0 ); |
| 1143 | for ( i = 0; i < length; ++i ) |
| 1144 | { |
| 1145 | LISTITER iter = list_begin( items[ i ].values ); |
| 1146 | LISTITER const end = list_end( items[ i ].values ); |
| 1147 | |
| 1148 | /* If any of the items has no values - the result is an empty list. */ |
| 1149 | if ( iter == end ) return L0; |
| 1150 | |
| 1151 | /* Set each item's 'current' to its first listed value. This indicates |
| 1152 | * each item's next value to be used when constructing the list of all |
| 1153 | * possible concatenated values. |
| 1154 | */ |
| 1155 | items[ i ].current = iter; |
| 1156 | |
| 1157 | /* Calculate the longest concatenated string length - to know how much |
| 1158 | * memory we need to allocate as a buffer for holding the concatenated |
| 1159 | * strings. |
| 1160 | */ |
| 1161 | { |
| 1162 | int max = 0; |
| 1163 | for ( ; iter != end; iter = list_next( iter ) ) |
| 1164 | { |
| 1165 | int const len = strlen( object_str( list_item( iter ) ) ); |
| 1166 | if ( len > max ) max = len; |
| 1167 | } |
| 1168 | size += max; |
| 1169 | } |
| 1170 | } |
| 1171 | |
| 1172 | string_new( buf ); |
| 1173 | string_reserve( buf, size ); |
| 1174 | |
| 1175 | i = 0; |
| 1176 | while ( i >= 0 ) |
| 1177 | { |
| 1178 | for ( ; i < length; ++i ) |
| 1179 | { |
| 1180 | items[ i ].size = buf->size; |
| 1181 | string_append( buf, object_str( list_item( items[ i ].current ) ) ); |
| 1182 | } |
| 1183 | result = list_push_back( result, object_new( buf->value ) ); |
| 1184 | while ( --i >= 0 ) |
| 1185 | { |
| 1186 | if ( list_next( items[ i ].current ) != list_end( items[ i ].values |
| 1187 | ) ) |
| 1188 | { |
| 1189 | items[ i ].current = list_next( items[ i ].current ); |
| 1190 | string_truncate( buf, items[ i ].size ); |
| 1191 | break; |
| 1192 | } |
no test coverage detected