<commit_before>#include "system.h"
#include "sccs.h"

private int included(char *, char *);
private int excluded(char *, char *);
private int export_patch(char *, char *, char *, char *, int, int);

int
export_main(int ac,  char **av)
{
	int	c, count;
	int	vflag = 0, hflag = 0, kflag = 0, tflag = 0, wflag = 0;
	char	*rev = NULL, *diff_style = NULL;
	char	file_rev[MAXPATH];
	char	buf[MAXLINE], buf1[MAXPATH];
	char	include[MAXLINE] = "";
	char	exclude[MAXLINE];
	char	*src, *dst;
	char	*p, *q;
	char	src_path[MAXPATH], dst_path[MAXPATH];
	sccs	*s;
	delta	*d;
	FILE	*f, *f1;
	char	*type = 0;

	if (ac == 2 && streq("--help", av[1])) {
		system("bk help export");
		return (1);
	}

	sprintf(exclude, "*%cBitKeeper/*%c*", BK_FS, BK_FS);

	while ((c = getopt(ac, av, "d:hkt:Twvi|x|r:")) != -1) {
		switch (c) {
		    case 'v':	vflag = 1; break;		/* doc 2.0 */
		    case 'q':					/* undoc 2.0 */
				break; /* no op; for interface consistency */
		    case 'd':	diff_style = optarg; break;	/* doc 2.0 */
		    case 'h':					/* doc 2.0 */
			hflag = 1; break; /*disbale patch header*/
		    case 'k':	kflag = 1; break;		/* doc 2.0 */
		    case 'r':	rev = optarg; break;		/* doc 2.0 */
		    case 't':	if (type) goto usage;		/* doc 2.0 */
				type = optarg; 
				if (!streq(type, "patch") &&
				    !streq(type, "plain")) {
					goto usage;
				}
				break;
		    case 'T':	tflag = 1; break;		/* doc 2.0 */
		    case 'w':	wflag = 1; break;		/* doc 2.0 */
		    case 'i':	if (optarg && *optarg) {	/* doc 2.0 */
					strcpy(include, optarg);
				} else {
					include[0] = 0;
				}
				break;
		    case 'x':	if (optarg && *optarg) {	/* doc 2.0 */
					strcpy(exclude, optarg);
				} else {
					exclude[0] = 0;
				}
				break;
		    default :
usage:			system("bk help -s export");
			exit(1);
		}
	}

	unless (type) type = "plain";
	if (streq(type, "patch")) {
		if (sccs_cd2root(0, 0) == -1) {
			fprintf(stderr, "export: can not find package root.\n");
			exit(1);
		}
		return (export_patch(diff_style,
		    rev, include, exclude, hflag, tflag));
	}

	count =  ac - optind;
	switch (count) {
	    case 1: src = "."; dst = av[optind]; break;
	    case 2: src = av[optind++]; dst = av[optind]; break;
	    default: goto usage;
	}

	if (mkdirp(dst) != 0) {
		fprintf(stderr, "cannot mkdir %s\n", dst);
		exit(1);
	}
	strcpy(dst_path, fullname(dst, 0));
	chdir(src);
	if (sccs_cd2root(0, 0) == -1) {
		fprintf(stderr, "Cannot find package root.\n");
		exit(1);
	}
	strcpy(src_path, fullname(".", 0));

	sprintf(file_rev, "%s/bk_file_rev%d", TMP_PATH, getpid());
	if (rev) {
		sprintf(buf, "bk rset -hl%s > %s", rev, file_rev);
	} else {
		sprintf(buf, "bk rset -hl+ > %s", file_rev);
	}
	system(buf);

	f = fopen(file_rev, "rt");
	assert(f);
	while (fgets(buf, sizeof(buf), f)) {
		char	*t, output[MAXPATH];
		int	flags = 0;
		struct	stat sb;

		chop(buf);
		if (!included(buf, include)) continue;
		if (excluded(buf, exclude)) continue;
		p = strchr(buf, BK_FS);
		assert(p);
		*p++ = '\0';
		if (streq(buf, "ChangeSet")) continue;
		sprintf(buf1, "%s/%s", src_path, buf);
		t = name2sccs(buf1);
		s = sccs_init(t, SILENT, 0);
		free(t);
		assert(s && s->tree);
		q = strchr(p, BK_FS); 
		assert(q);
		*q++ = '\0';
		d = findrev(s, q);
		assert(d);
		sprintf(output, "%s/%s", dst_path, p);
		unless (vflag) flags |= SILENT;
		unless (kflag) flags |= GET_EXPAND;
		if (tflag) flags |= GET_DTIME;
		mkdirf(output);
		/*
		 * This is stolen from the get -G code
		 * XXX - why do we have output then?
		 */
		free(s->gfile);
		s->gfile = strdup(output);
		if (sccs_get(s, q, 0, 0, 0, flags, "-")) {
			fprintf(stderr, "cannot export to %s\n", output);
		}
		sccs_free(s);
		if (wflag) {
			if (stat(output, &sb)) {
				perror(output);
			} else {
				chmod(output, sb.st_mode | S_IWUSR);
			}
		}
	}
	fclose(f);
	unlink(file_rev);
	return (0);
}
<commit_msg>add "bk export -p<num>" option, this allows user to trim off the top <num> components of the export path. (i.e. a/b/c/d ==> c/d) (This feature is requested by Logitech)<commit_after>#include "system.h"
#include "sccs.h"

private int included(char *, char *);
private int excluded(char *, char *);
private int export_patch(char *, char *, char *, char *, int, int);

int
export_main(int ac,  char **av)
{
	int	i, c, count, trim = 0;
	int	vflag = 0, hflag = 0, kflag = 0, tflag = 0, wflag = 0;
	char	*rev = NULL, *diff_style = NULL;
	char	file_rev[MAXPATH];
	char	buf[MAXLINE], buf1[MAXPATH];
	char	include[MAXLINE] = "";
	char	exclude[MAXLINE];
	char	*src, *dst;
	char	*p, *q, *p_sav;
	char	src_path[MAXPATH], dst_path[MAXPATH];
	sccs	*s;
	delta	*d;
	FILE	*f, *f1;
	char	*type = 0;

	if (ac == 2 && streq("--help", av[1])) {
		system("bk help export");
		return (1);
	}

	sprintf(exclude, "*%cBitKeeper/*%c*", BK_FS, BK_FS);

	while ((c = getopt(ac, av, "d:hkp:t:Twvi|x|r:")) != -1) {
		switch (c) {
		    case 'v':	vflag = 1; break;		/* doc 2.0 */
		    case 'q':					/* undoc 2.0 */
				break; /* no op; for interface consistency */
		    case 'd':	diff_style = optarg; break;	/* doc 2.0 */
		    case 'h':					/* doc 2.0 */
			hflag = 1; break; /*disable patch header*/
		    case 'k':	kflag = 1; break;		/* doc 2.0 */
		    case 'p':	trim = atoi(optarg); break;
		    case 'r':	rev = optarg; break;		/* doc 2.0 */
		    case 't':	if (type) goto usage;		/* doc 2.0 */
				type = optarg; 
				if (!streq(type, "patch") &&
				    !streq(type, "plain")) {
					goto usage;
				}
				break;
		    case 'T':	tflag = 1; break;		/* doc 2.0 */
		    case 'w':	wflag = 1; break;		/* doc 2.0 */
		    case 'i':	if (optarg && *optarg) {	/* doc 2.0 */
					strcpy(include, optarg);
				} else {
					include[0] = 0;
				}
				break;
		    case 'x':	if (optarg && *optarg) {	/* doc 2.0 */
					strcpy(exclude, optarg);
				} else {
					exclude[0] = 0;
				}
				break;
		    default :
usage:			system("bk help -s export");
			exit(1);
		}
	}

	unless (type) type = "plain";
	if (streq(type, "patch")) {
		if (sccs_cd2root(0, 0) == -1) {
			fprintf(stderr, "export: can not find package root.\n");
			exit(1);
		}
		return (export_patch(diff_style,
		    rev, include, exclude, hflag, tflag));
	}

	count =  ac - optind;
	switch (count) {
	    case 1: src = "."; dst = av[optind]; break;
	    case 2: src = av[optind++]; dst = av[optind]; break;
	    default: goto usage;
	}

	if (mkdirp(dst) != 0) {
		fprintf(stderr, "cannot mkdir %s\n", dst);
		exit(1);
	}
	strcpy(dst_path, fullname(dst, 0));
	chdir(src);
	if (sccs_cd2root(0, 0) == -1) {
		fprintf(stderr, "Cannot find package root.\n");
		exit(1);
	}
	strcpy(src_path, fullname(".", 0));

	sprintf(file_rev, "%s/bk_file_rev%d", TMP_PATH, getpid());
	if (rev) {
		sprintf(buf, "bk rset -hl%s > %s", rev, file_rev);
	} else {
		sprintf(buf, "bk rset -hl+ > %s", file_rev);
	}
	system(buf);

	f = fopen(file_rev, "rt");
	assert(f);
	while (fgets(buf, sizeof(buf), f)) {
		char	*t, output[MAXPATH];
		int	flags = 0;
		struct	stat sb;

		chop(buf);
		if (!included(buf, include)) continue;
		if (excluded(buf, exclude)) continue;
		p = strchr(buf, BK_FS);
		assert(p);
		*p++ = '\0';
		if (streq(buf, "ChangeSet")) continue;
		sprintf(buf1, "%s/%s", src_path, buf);
		t = name2sccs(buf1);
		s = sccs_init(t, SILENT, 0);
		free(t);
		assert(s && s->tree);
		q = strchr(p, BK_FS); 
		assert(q);
		*q++ = '\0';
		d = findrev(s, q);
		assert(d);
		p_sav = p;
		for (i = 0; i < trim; i++) {
			p = strchr(p, '/');
			unless (p) {
				fprintf(stderr,
				    "%s: Cannot trim path; path too short. "
				    "File skipped.\n",
				    p_sav);
				goto next;
			}
			p++;
		}
		sprintf(output, "%s/%s", dst_path, p);
		unless (vflag) flags |= SILENT;
		unless (kflag) flags |= GET_EXPAND;
		if (tflag) flags |= GET_DTIME;
		mkdirf(output);
		/*
		 * This is stolen from the get -G code
		 * XXX - why do we have output then?
		 */
		free(s->gfile);
		s->gfile = strdup(output);
		if (sccs_get(s, q, 0, 0, 0, flags, "-")) {
			fprintf(stderr, "cannot export to %s\n", output);
		}
		sccs_free(s);
		if (wflag) {
			if (stat(output, &sb)) {
				perror(output);
			} else {
				chmod(output, sb.st_mode | S_IWUSR);
			}
		}
next:		;
	}
	fclose(f);
	unlink(file_rev);
	return (0);
}

{'fraction_non_alphanumeric': 0.1994368266405485, 'fraction_numerical': 0.01762977473065622, 'mean_word_length': 2.7766990291262137, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 16, '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': '858854', 'n_tokens_mistral': 3962, 'n_tokens_neox': 3474, 'n_words': 916}