<commit_before>/********************************
  copyright
 ********************************/
#include "reorder_main.h"
#include "reorder.h"

size_t n_swap = 0;

/* TODO: get rid of arbitrary limit on number of swaps */
int swap[32][3];

/** @brief copies ct into s, swapping fields in the process.
  * 
  * @param s destination buffer
  * @param ct source buffer
  * @param d delimiter
  */
void doswap( char *s, char *ct, const char *d );

/** @brief creates in s a new string delimited by d, containing the fields
  * from ct in the order specified by o.
  *
  * because a field may be included multiple times in the destination buffer,
  * it is entirely possible for the output to be larger than the input, so
  * this function may dynamically resize s as necessary.
  *
  * @param s address of destination buffer
  * @param ct source buffer
  * @param s_sz address of the size of destination buffer
  * @param d delimiter
  * @param o array of field numbers
  * @param n number of elements in o
  *
  * @return the length of s on success; < 0 on error
  */
int docut( char **s, const char *ct, size_t *s_sz, const char *d, const int *order, const size_t n );

int reorder ( struct cmdargs *args, int argc, char *argv[], int optind ){
	FILE *fp, *fpout;
	char *lbuf = NULL;	/* line buffer */
	size_t lbs = 0;		/* line buffer size */

	char *wbuf = NULL;	/* working buffer */
	size_t wbs = 0;		/* working buffer size */

	int *order = NULL;
	size_t order_sz = 0;
	size_t order_elems = 0;

	char default_delim[] = { 0xfe, 0x00 };

#ifdef DEBUG
	int i;
	for( i = 0; i < n_swap; i++ ) {
		if ( swap[i][2] == REORDER_TYPE_SWAP )
			printf("swap %d with %d\n", swap[i][0], swap[i][1]);
		else
			printf("move %d to %d\n", swap[i][0], swap[i][1]);
	}
#endif

	if ( ! args->delim ) {
		args->delim = default_delim;
	}

	/* may add output option later */
	fpout = stdout;

	if ( optind == argc )
		fp = stdin;
	else
		fp = nextfile ( argc, argv, &optind, "r" );

	if( fp == NULL )
		return EXIT_FILE_ERR;

	if ( args->fields ) {

		order_sz = fields_in_line(args->fields, ",");
		if ( (order = malloc(order_sz * sizeof(int))) == NULL )
			goto memerror;

		order_elems = splitnums(args->fields, &order, order_sz);

		if ( args->verbose ) {
			int i;
			fprintf(stderr, "there are %d fields: ", order_sz);
			for ( i = 0; i < order_elems; i++ ) {
				fprintf(stderr, " %d", order[i]);
			}
			fprintf(stderr, "\n");
		}
	}

	do {
		while( 1 ){

			if( getline(&lbuf, &lbs, fp) < 0 )
				break;

			/* make sure there's enough room in the working
			   buffer */
			if( wbuf == NULL ){
				if( (wbuf = malloc(lbs)) == NULL )
					goto memerror;
				wbs = lbs;
			} else if ( wbs < lbs ) {
				/* if realloc unsuccessful, we don't want
				 * wbuf to end up being NULL
				 */
				char *tmp_ptr;
				if( ( tmp_ptr = realloc(wbuf, lbs)) == NULL )
					goto memerror;
				wbuf = tmp_ptr;
				wbs = lbs;
			}

			if ( ! args->fields ) {
				doswap( wbuf, lbuf, args->delim );
			} else {
				if ( docut( &wbuf, lbuf, &wbs, args->delim, order, order_elems ) < 0 ) 
					goto memerror;
			}
			fprintf(fpout, "%s", wbuf);
			memset( lbuf, 0, lbs );
			memset( wbuf, 0, wbs );
			/* fputs(lbuf, fpout); */

		}

		fclose(fp);
		fp = NULL;

		optind++;

		if( optind >= argc )
			break;

		fp = nextfile ( argc, argv, &optind, "r" );

		if (fp == NULL)
			break;

	} while ( optind <= argc );

	fflush(fpout);
	fclose(fpout);

	if ( order )
		free(order);
	free(lbuf);
	free(wbuf);

	return EXIT_OKAY;

	/* cleanup stuff in case of an error with malloc or realloc */
memerror:<commit_msg>reorder: oversight in r691 - let nextfile() deal with incrementing optind. 	otherwise some input files are skipped<commit_after>/********************************
  copyright
 ********************************/
#include "reorder_main.h"
#include "reorder.h"

size_t n_swap = 0;

/* TODO: get rid of arbitrary limit on number of swaps */
int swap[32][3];

/** @brief copies ct into s, swapping fields in the process.
  * 
  * @param s destination buffer
  * @param ct source buffer
  * @param d delimiter
  */
void doswap( char *s, char *ct, const char *d );

/** @brief creates in s a new string delimited by d, containing the fields
  * from ct in the order specified by o.
  *
  * because a field may be included multiple times in the destination buffer,
  * it is entirely possible for the output to be larger than the input, so
  * this function may dynamically resize s as necessary.
  *
  * @param s address of destination buffer
  * @param ct source buffer
  * @param s_sz address of the size of destination buffer
  * @param d delimiter
  * @param o array of field numbers
  * @param n number of elements in o
  *
  * @return the length of s on success; < 0 on error
  */
int docut( char **s, const char *ct, size_t *s_sz, const char *d, const int *order, const size_t n );

int reorder ( struct cmdargs *args, int argc, char *argv[], int optind ){
	FILE *fp, *fpout;
	char *lbuf = NULL;	/* line buffer */
	size_t lbs = 0;		/* line buffer size */

	char *wbuf = NULL;	/* working buffer */
	size_t wbs = 0;		/* working buffer size */

	int *order = NULL;
	size_t order_sz = 0;
	size_t order_elems = 0;

	char default_delim[] = { 0xfe, 0x00 };

#ifdef DEBUG
	int i;
	for( i = 0; i < n_swap; i++ ) {
		if ( swap[i][2] == REORDER_TYPE_SWAP )
			printf("swap %d with %d\n", swap[i][0], swap[i][1]);
		else
			printf("move %d to %d\n", swap[i][0], swap[i][1]);
	}
#endif

	if ( ! args->delim ) {
		args->delim = default_delim;
	}

	/* may add output option later */
	fpout = stdout;

	if ( optind == argc )
		fp = stdin;
	else
		fp = nextfile ( argc, argv, &optind, "r" );

	if( fp == NULL )
		return EXIT_FILE_ERR;

	if ( args->fields ) {

		order_sz = fields_in_line(args->fields, ",");
		if ( (order = malloc(order_sz * sizeof(int))) == NULL )
			goto memerror;

		order_elems = splitnums(args->fields, &order, order_sz);

		if ( args->verbose ) {
			int i;
			fprintf(stderr, "there are %d fields: ", order_sz);
			for ( i = 0; i < order_elems; i++ ) {
				fprintf(stderr, " %d", order[i]);
			}
			fprintf(stderr, "\n");
		}
	}

	do {
		while( 1 ){

			if( getline(&lbuf, &lbs, fp) < 0 )
				break;

			/* make sure there's enough room in the working
			   buffer */
			if( wbuf == NULL ){
				if( (wbuf = malloc(lbs)) == NULL )
					goto memerror;
				wbs = lbs;
			} else if ( wbs < lbs ) {
				/* if realloc unsuccessful, we don't want
				 * wbuf to end up being NULL
				 */
				char *tmp_ptr;
				if( ( tmp_ptr = realloc(wbuf, lbs)) == NULL )
					goto memerror;
				wbuf = tmp_ptr;
				wbs = lbs;
			}

			if ( ! args->fields ) {
				doswap( wbuf, lbuf, args->delim );
			} else {
				if ( docut( &wbuf, lbuf, &wbs, args->delim, order, order_elems ) < 0 ) 
					goto memerror;
			}
			fprintf(fpout, "%s", wbuf);
			memset( lbuf, 0, lbs );
			memset( wbuf, 0, wbs );
			/* fputs(lbuf, fpout); */

		}

		fclose(fp);
		fp = NULL;

		fp = nextfile ( argc, argv, &optind, "r" );

		if (fp == NULL)
			break;

	} while ( optind <= argc );

	fflush(fpout);
	fclose(fpout);

	if ( order )
		free(order);
	free(lbuf);
	free(wbuf);

	return EXIT_OKAY;

	/* cleanup stuff in case of an error with malloc or realloc */
memerror:
{'fraction_non_alphanumeric': 0.15806272550652234, 'fraction_numerical': 0.007354981959478212, 'mean_word_length': 2.8664163090128754, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5974024', 'n_tokens_mistral': 2968, 'n_tokens_neox': 2600, 'n_words': 889}