<commit_before>#include <nmem.h>

#include <npath.h> /* n_dirname() */
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>

#include <ndebug.h>

/*	ncp	the nmem cp replacement

A version of 'cp' showing zero-copy I/O using nmem.
This is usually faster for larger files.

(c)2017 Sirio; Balmelli Analog & Digital
*/


/*
	global option flags
*/
static int force = 0;
static int verbose = 0;


/*	print_usage()
*/
void print_usage(char *pgm_name)
{
	fprintf(stderr, "Usage: %1$s [OPTION]... SOURCE_FILE DEST_FILE\n\
  or:  %1$s [OPTION]... SOURCE_FILE... DEST_DIR/\n\
An analog of 'cp' using nmem(3) zero-copy I/O for speed.\n\
\n\
Options:\n\
\t-v, --verbose	:	list each file being copied\n\
\t-f, --force	:	overwrite destination file(s) if existing\n\
\t-h, --help	:	print usage and exit\n",
		pgm_name);
}


/*	cp()
Do copy operation
*/
int cp(const char *src_path, const char *dst_path)
{
	int err_cnt = 0;

	struct nmem src = { 0 };
	struct nmem dst = { 0 };
	char *dst_dir = NULL;

	/* open source */
	NB_die_if(
		nmem_file(src_path, &src)
		, "");
	/* open destination */
	dst_dir = n_dirname(dst_path);
	NB_die_if(
		nmem_alloc(src.len, dst_dir, &dst)
		, "");

	/* do copy */
	NB_die_if((
		nmem_cp(&src, 0, src.len, &dst, 0)
		) != src.len, "");

	/* Delete a possible existing file */
	if (force) {
		unlink(dst_path);
		errno = 0;
	}
	/* we're clean: close and deliver the file */
	nmem_free(&dst, dst_path);
	if (verbose)
		fprintf(stdout, "'%s' -> '%s'\n", src_path, dst_path);

die:
	nmem_free(&src, NULL);
	nmem_free(&dst, NULL);
	free(dst_dir);
	return err_cnt;
}


/*	main()
*/
int main(int argc, char **argv)
{
	int err_cnt = 0;

	char *src_path = NULL;
	char *dst_path = NULL;

	int opt = 0;
	static struct option long_options[] = {
		{ "verbose",	no_argument,	0,	'v'},
		{ "force",	no_argument,	0,	'f'},
		{ "help",	no_argument,	0,	'h'},
	};

	while ((opt = getopt_long(argc, argv, "vfh", long_options, NULL)) != -1) {
		switch(opt)
		{
			case 'v':
				verbose++;
				if (verbose >= 2)
					NB_inf("verbose");
				break;
			case 'f':
				force = 1;
				if (verbose >= 2)
					NB_inf("force");
				break;
			case 'h':
				print_usage(argv[0]);
				goto die;
			default:
				print_usage(argv[0]);
				NB_die("option '%c' invalid", opt);
		}
	}

	/* sanity check file arguments */
	int count = argc - optind;
	if (count < 2) {
		print_usage(argv[0]);
		NB_die("missing SOURCE_FILE or DEST_FILE");
	}

	/* SOURCE_FILE DEST_FILE */
	dst_path = argv[optind + 1];
	if (count == 2 && !n_is_dir(dst_path)) {
		src_path = argv[optind];
		cp(src_path, dst_path);

	/* SOURCE_FILE... DEST_DIR/ */
	} else {
		while (optind < argc -1) {
			src_path = argv[optind++];
			char *src_base = n_basename(src_path);
			dst_path = n_join(argv[argc-1], src_base);

			cp(src_path, dst_path);
			free(src_base);
			free(dst_path); dst_path = NULL;
		}
	}

die:
	return err_cnt;
}<commit_msg>clean up usage print for ncp<commit_after>#include <nmem.h>

#include <npath.h> /* n_dirname() */
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>

#include <ndebug.h>

/*	ncp	the nmem cp replacement

A version of 'cp' showing zero-copy I/O using nmem.
This is usually faster for larger files.

(c)2017 Sirio; Balmelli Analog & Digital
*/


/*
	global option flags
*/
static int force = 0;
static int verbose = 0;


/* Use as a printf prototype.
 * Expects 'program_name' as a string variable.
 */
static const char *usage =
"Usage:\n"
"\t%1$s [OPTION]... SOURCE_FILE DEST_FILE\n"
"or:\t%1$s [OPTION]... SOURCE_FILE... DEST_DIR/\n"
"\n"
"An analog of 'cp' using nmem(3) zero-copy I/O for speed.\n"
"\n"
"Options:\n"
"\t-v, --verbose	:	list each file being copied\n"
"\t-f, --force	:	overwrite destination file(s) if existing\n"
"\t-h, --help	:	print usage and exit\n";


/*	cp()
Do copy operation
*/
int cp(const char *src_path, const char *dst_path)
{
	int err_cnt = 0;

	struct nmem src = { 0 };
	struct nmem dst = { 0 };
	char *dst_dir = NULL;

	/* open source */
	NB_die_if(
		nmem_file(src_path, &src)
		, "");
	/* open destination */
	dst_dir = n_dirname(dst_path);
	NB_die_if(
		nmem_alloc(src.len, dst_dir, &dst)
		, "");

	/* do copy */
	NB_die_if((
		nmem_cp(&src, 0, src.len, &dst, 0)
		) != src.len, "");

	/* Delete a possible existing file */
	if (force) {
		unlink(dst_path);
		errno = 0;
	}
	/* we're clean: close and deliver the file */
	nmem_free(&dst, dst_path);
	if (verbose)
		fprintf(stdout, "'%s' -> '%s'\n", src_path, dst_path);

die:
	nmem_free(&src, NULL);
	nmem_free(&dst, NULL);
	free(dst_dir);
	return err_cnt;
}


/*	main()
*/
int main(int argc, char **argv)
{
	int err_cnt = 0;

	char *src_path = NULL;
	char *dst_path = NULL;

	int opt = 0;
	static struct option long_options[] = {
		{ "verbose",	no_argument,	0,	'v'},
		{ "force",	no_argument,	0,	'f'},
		{ "help",	no_argument,	0,	'h'},
	};

	while ((opt = getopt_long(argc, argv, "vfh", long_options, NULL)) != -1) {
		switch(opt)
		{
			case 'v':
				verbose++;
				if (verbose >= 2)
					NB_inf("verbose");
				break;
			case 'f':
				force = 1;
				if (verbose >= 2)
					NB_inf("force");
				break;
			case 'h':
				fprintf(stderr, usage, argv[0]);
				goto die;
			default:
				NB_die(""); /* libc will alreadyc complain about invalid option */
		}
	}

	/* sanity check file arguments */
	int count = argc - optind;
	if (count < 2)
		NB_die("missing SOURCE_FILE or DEST_FILE");

	/* SOURCE_FILE DEST_FILE */
	dst_path = argv[optind + 1];
	if (count == 2 && !n_is_dir(dst_path)) {
		src_path = argv[optind];
		cp(src_path, dst_path);

	/* SOURCE_FILE... DEST_DIR/ */
	} else {
		while (optind < argc -1) {
			src_path = argv[optind++];
			char *src_base = n_basename(src_path);
			dst_path = n_join(argv[argc-1], src_base);

			cp(src_path, dst_path);
			free(src_base);
			free(dst_path); dst_path = NULL;
		}
	}

die:
	if (err_cnt)
		fprintf(stderr, usage, argv[0]);
	return err_cnt;
}
{'fraction_non_alphanumeric': 0.1761006289308176, 'fraction_numerical': 0.010708822029576747, 'mean_word_length': 3.2239770279971287, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, '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': '2422903', 'n_tokens_mistral': 2656, 'n_tokens_neox': 2425, 'n_words': 629}