<commit_before>/*
 * Copyright 2008-2017 <NAME>
 *
 * See LICENCE for the full copyright terms.
 */

#define _POSIX_C_SOURCE 200112L

#include <unistd.h>

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include <fsm/fsm.h>
#include <fsm/bool.h>
#include <fsm/pred.h>
#include <fsm/walk.h>
#include <fsm/print.h>
#include <fsm/options.h>

#include <adt/stateset.h> /* XXX */

#include "libfsm/internal.h" /* XXX */

#include "parser.h"
#include "wordgen.h"

#if defined(__APPLE__) && defined(__MACH__) && defined(MACOS_HAS_NO_CLOCK_GETITME)
#include <mach/clock.h>
#include <mach/mach.h>

/* we're running Darwin/macOS, so we don't necessarily have clock_gettime,
 * so we do it the ugly way...
 */

#define CLOCK_MONOTONIC 0
static int clock_gettime(int clk_id, struct timespec *ts)
{
	clock_serv_t cclock;
	mach_timespec_t mts;

	(void)clk_id;

	host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
	clock_get_time(cclock, &mts);
	mach_port_deallocate(mach_task_self(), cclock);

	ts->tv_sec = mts.tv_sec;
	ts->tv_nsec = mts.tv_nsec;

	return 0;
}
#endif /* defined(__APPLE__) && defined(__MACH__) && !defined(MACOS_HAS_CLOCK_GETITME) */

extern int optind;
extern char *optarg;

static struct fsm_options opt;

#define OP_ARITY 0x1

enum op {
	/* unary */
	OP_IDENTITY    = ( 0 << 1) | 1,
	OP_COMPLETE    = ( 1 << 1) | 1,
	OP_COMPLEMENT  = ( 2 << 1) | 1,
	OP_REVERSE     = ( 3 << 1) | 1,
	OP_DETERMINISE = ( 4 << 1) | 1,
	OP_MINIMISE    = ( 5 << 1) | 1,
	OP_TRIM        = ( 6 << 1) | 1,
	OP_GLUSHKOVISE = (12 << 1) | 1,

	/* binary */
	OP_CONCAT      = ( 7 << 1) | 0,
	OP_UNION       = ( 8 << 1) | 0,
	OP_INTERSECT   = ( 9 << 1) | 0,
	OP_SUBTRACT    = (10 << 1) | 0,
	OP_EQUAL       = (11 << 1) | 0
};

static int
query_countstates(const struct fsm *fsm, fsm_state_t state)
{
	(void) fsm;
	(void) state;

	/* never called */
	abort();
}

static int
query_epsilonclosure(const struct fsm *fsm, fsm_state_t state)
{
	(void) fsm;
	(void) state;

	/* never called */
	abort();
}

static void
usage(void)
{
	printf("usage: fsm [-x] {<text> ...}\n");
	printf("       fsm {-p} [-l <language>] [-acwX] [-k <io>] [-e <prefix>]\n");
	printf("       fsm {-dmr | -t <transformation>} [-i <iterations>] [<file.fsm> | <file-a> <file-b>]\n");
	printf("       fsm {-q <query>} [<file>]\n");
	printf("       fsm {-W <maxlen>} <file.fsm>\n");
	printf("       fsm -h\n");
}

static enum fsm_io
io(const char *name)
{
	size_t i;

	struct {
		const char *name;
		enum fsm_io io;
	} a[] = {
		{ "getc", FSM_IO_GETC },
		{ "str",  FSM_IO_STR  },
		{ "pair", FSM_IO_PAIR }
	};

	assert(name != NULL);

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		if (0 == strcmp(a[i].name, name)) {
			return a[i].io;
		}
	}

	fprintf(stderr, "unrecognised IO API; valid IO APIs are: ");

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		fprintf(stderr, "%s%s",
			a[i].name,
			i + 1 < sizeof a / sizeof *a ? ", " : "\n");
	}

	exit(EXIT_FAILURE);
}

static fsm_print *
print_name(const char *name)
{
	size_t i;

	struct {
		const char *name;
		fsm_print *f;
	} a[] = {
		{ "api",  fsm_print_api  },
		{ "c",    fsm_print_c    },
		{ "dot",  fsm_print_dot  },
		{ "fsm",  fsm_print_fsm  },
		{ "ir",   fsm_print_ir   },
		{ "json", fsm_print_json },
		{ "vmc",  fsm_print_vmc  }
	};

	assert(name != NULL);

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		if (0 == strcmp(a[i].name, name)) {
			return a[i].f;
		}
	}

	fprintf(stderr, "unrecognised output language; valid languages are: ");

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		fprintf(stderr, "%s%s",
			a[i].name,
			i + 1 < sizeof a / sizeof *a ? ", " : "\n");
	}

	exit(EXIT_FAILURE);
}

static int
(*query_name(const char *name,
	int (**walk)(const struct fsm *,<commit_msg>Add sh output for fsm(1).<commit_after>/*
 * Copyright 2008-2017 <NAME>
 *
 * See LICENCE for the full copyright terms.
 */

#define _POSIX_C_SOURCE 200112L

#include <unistd.h>

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include <fsm/fsm.h>
#include <fsm/bool.h>
#include <fsm/pred.h>
#include <fsm/walk.h>
#include <fsm/print.h>
#include <fsm/options.h>

#include <adt/stateset.h> /* XXX */

#include "libfsm/internal.h" /* XXX */

#include "parser.h"
#include "wordgen.h"

#if defined(__APPLE__) && defined(__MACH__) && defined(MACOS_HAS_NO_CLOCK_GETITME)
#include <mach/clock.h>
#include <mach/mach.h>

/* we're running Darwin/macOS, so we don't necessarily have clock_gettime,
 * so we do it the ugly way...
 */

#define CLOCK_MONOTONIC 0
static int clock_gettime(int clk_id, struct timespec *ts)
{
	clock_serv_t cclock;
	mach_timespec_t mts;

	(void)clk_id;

	host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
	clock_get_time(cclock, &mts);
	mach_port_deallocate(mach_task_self(), cclock);

	ts->tv_sec = mts.tv_sec;
	ts->tv_nsec = mts.tv_nsec;

	return 0;
}
#endif /* defined(__APPLE__) && defined(__MACH__) && !defined(MACOS_HAS_CLOCK_GETITME) */

extern int optind;
extern char *optarg;

static struct fsm_options opt;

#define OP_ARITY 0x1

enum op {
	/* unary */
	OP_IDENTITY    = ( 0 << 1) | 1,
	OP_COMPLETE    = ( 1 << 1) | 1,
	OP_COMPLEMENT  = ( 2 << 1) | 1,
	OP_REVERSE     = ( 3 << 1) | 1,
	OP_DETERMINISE = ( 4 << 1) | 1,
	OP_MINIMISE    = ( 5 << 1) | 1,
	OP_TRIM        = ( 6 << 1) | 1,
	OP_GLUSHKOVISE = (12 << 1) | 1,

	/* binary */
	OP_CONCAT      = ( 7 << 1) | 0,
	OP_UNION       = ( 8 << 1) | 0,
	OP_INTERSECT   = ( 9 << 1) | 0,
	OP_SUBTRACT    = (10 << 1) | 0,
	OP_EQUAL       = (11 << 1) | 0
};

static int
query_countstates(const struct fsm *fsm, fsm_state_t state)
{
	(void) fsm;
	(void) state;

	/* never called */
	abort();
}

static int
query_epsilonclosure(const struct fsm *fsm, fsm_state_t state)
{
	(void) fsm;
	(void) state;

	/* never called */
	abort();
}

static void
usage(void)
{
	printf("usage: fsm [-x] {<text> ...}\n");
	printf("       fsm {-p} [-l <language>] [-acwX] [-k <io>] [-e <prefix>]\n");
	printf("       fsm {-dmr | -t <transformation>} [-i <iterations>] [<file.fsm> | <file-a> <file-b>]\n");
	printf("       fsm {-q <query>} [<file>]\n");
	printf("       fsm {-W <maxlen>} <file.fsm>\n");
	printf("       fsm -h\n");
}

static enum fsm_io
io(const char *name)
{
	size_t i;

	struct {
		const char *name;
		enum fsm_io io;
	} a[] = {
		{ "getc", FSM_IO_GETC },
		{ "str",  FSM_IO_STR  },
		{ "pair", FSM_IO_PAIR }
	};

	assert(name != NULL);

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		if (0 == strcmp(a[i].name, name)) {
			return a[i].io;
		}
	}

	fprintf(stderr, "unrecognised IO API; valid IO APIs are: ");

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		fprintf(stderr, "%s%s",
			a[i].name,
			i + 1 < sizeof a / sizeof *a ? ", " : "\n");
	}

	exit(EXIT_FAILURE);
}

static fsm_print *
print_name(const char *name)
{
	size_t i;

	struct {
		const char *name;
		fsm_print *f;
	} a[] = {
		{ "api",  fsm_print_api  },
		{ "c",    fsm_print_c    },
		{ "dot",  fsm_print_dot  },
		{ "fsm",  fsm_print_fsm  },
		{ "ir",   fsm_print_ir   },
		{ "json", fsm_print_json },
		{ "vmc",  fsm_print_vmc  },
		{ "sh",   fsm_print_sh   }
	};

	assert(name != NULL);

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		if (0 == strcmp(a[i].name, name)) {
			return a[i].f;
		}
	}

	fprintf(stderr, "unrecognised output language; valid languages are: ");

	for (i = 0; i < sizeof a / sizeof *a; i++) {
		fprintf(stderr, "%s%s",
			a[i].name,
			i + 1 < sizeof a / sizeof *a ? ", " : "\n");
	}

	exit(EXIT_FAILURE);
}

static int
(*query_name(const char *name,
	int (**walk)(const struct fsm *,
{'fraction_non_alphanumeric': 0.1893700787401575, 'fraction_numerical': 0.017979002624671916, 'mean_word_length': 3.132863340563991, 'pattern_counts': {'":': 0, '<': 127, '<?xml version=': 0, '>': 67, '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': '177148', 'n_tokens_mistral': 3571, 'n_tokens_neox': 3319, 'n_words': 794}