@@ -178,64 +178,60 @@ bool is_default_measure(SEXP vec) {
178178// maybe unlist, then unique, then set_diff.
179179SEXP uniq_diff (SEXP int_or_list , int ncol , bool is_measure ) {
180180 SEXP int_vec = PROTECT (isNewList (int_or_list ) ? unlist_ (int_or_list ) : int_or_list );
181-
182181 SEXP is_duplicated = PROTECT (duplicated (int_vec , FALSE));
183-
184182 int n_unique_cols = 0 ;
185-
186183 SEXP invalid_columns = PROTECT (allocVector (INTSXP , length (int_vec )));
187184 int * invalid_col_ptr = INTEGER (invalid_columns );
188185 int invalid_count = 0 ;
189-
186+
190187 for (int i = 0 ; i < length (int_vec ); ++ i ) {
191188 int col_number = INTEGER (int_vec )[i ];
192-
193189 bool good_number = 0 < col_number && col_number <= ncol ;
194-
195190 if (is_measure ) good_number |= (col_number == NA_INTEGER );
196-
197191 if (!good_number || col_number == 0 ) {
198192 invalid_col_ptr [invalid_count ++ ] = col_number ;
199193 } else if (!LOGICAL (is_duplicated )[i ]) {
200194 n_unique_cols ++ ;
201195 }
202196 }
203-
197+
204198 if (invalid_count > 0 ) {
205- char buffer [4096 ] = "" ;
199+ int buffer_size = 256 ;
200+ char * error_message = (char * ) malloc (buffer_size * sizeof (char ));
201+ snprintf (error_message , buffer_size ,
202+ "One or more values in '%s' are invalid; please fix by removing: " ,
203+ is_measure ? "measure.vars" : "id.vars" );
206204 for (int i = 0 ; i < invalid_count ; ++ i ) {
207- char temp [32 ];
208- snprintf (temp , 32 , "[%d]" , invalid_col_ptr [i ]);
209-
210- if (i > 0 ) {
211- strncat (buffer , ", " , sizeof (buffer ) - strlen (buffer ) - 1 );
205+ if (strlen (error_message ) + 10 >= buffer_size ) {
206+ buffer_size *= 2 ;
207+ error_message = (char * ) realloc (error_message , buffer_size * sizeof (char ));
212208 }
213- strncat (buffer , temp , sizeof (buffer ) - strlen (buffer ) - 1 );
214- }
215-
216- error (_ ("One or more values in '%s' are invalid; please fix by removing: %s" ),
217- is_measure ? "measure.vars" : "id.vars" , buffer );
209+ snprintf (error_message + strlen (error_message ),
210+ buffer_size - strlen (error_message ),
211+ "[%d]%s" ,
212+ invalid_col_ptr [i ],
213+ (i < invalid_count - 1 ) ? ", " : "" );
214+ }
215+ error (_ ("%s" ), error_message );
216+ free (error_message );
218217 }
219-
218+
220219 SEXP unique_col_numbers = PROTECT (allocVector (INTSXP , n_unique_cols ));
221220 int unique_i = 0 ;
222-
221+
223222 for (int i = 0 ; i < length (is_duplicated ); ++ i ) {
224223 if (!LOGICAL (is_duplicated )[i ]) {
225224 INTEGER (unique_col_numbers )[unique_i ++ ] = INTEGER (int_vec )[i ];
226225 }
227226 }
228-
227+
229228 SEXP out = set_diff (unique_col_numbers , ncol );
230-
231229 UNPROTECT (4 );
232-
233230 return out ;
234231}
235232
236233
237234
238-
239235SEXP cols_to_int_or_list (SEXP cols , SEXP dtnames , bool is_measure ) {
240236 switch (TYPEOF (cols )) {
241237 case STRSXP : return chmatch (cols , dtnames , 0 );
0 commit comments