コード例 #1
0
ファイル: diag_vcdiff_contract.c プロジェクト: tabe/Diagonal
static void
contract_and_expand(const char *data, size_t s_window, uint32_t base, size_t s_pcodes)
{
	struct diag_vcdiff_script *script;
	struct diag_rollinghash32 *rh;
	size_t size, s;
	uint8_t *result;
	char *result0;

	size = strlen(data);
	rh = (struct diag_rollinghash32 *)diag_rollinghash32_new_rabin_karp((const uint8_t *)data, size, s_window, base);
	ASSERT_NOT_NULL(rh);
	script = diag_vcdiff_contract(rh);
	ASSERT_NOT_NULL(script);
	dump_pcodes(script);
	ASSERT_EQ_UINT(s_pcodes, script->s_pcodes);
	result = diag_vcdiff_expand(script, &s);
	ASSERT_EQ_UINT(size, s);
	result0 = diag_malloc(s + 1);
	(void)memcpy(result0, result, s);
	result0[s] = '\0';
	ASSERT_EQ_STRING(data, result0);
	diag_free(result0);
	diag_free(result);
	diag_vcdiff_script_destroy(script);
	diag_rollinghash32_destroy(rh);
}
コード例 #2
0
ファイル: diag_vcdiff_expand.c プロジェクト: tabe/Diagonal
int main(void)
{
	struct diag_vcdiff_pcode *pcodes;
	struct diag_vcdiff_script *script;
	uint8_t *result;
	size_t size, i;

	pcodes = diag_calloc(2, sizeof(struct diag_vcdiff_pcode));
	pcodes[0].inst = DIAG_VCD_RUN;
	pcodes[0].size = 1;
	pcodes[0].attr.byte = 'a';
	pcodes[1].inst = DIAG_VCD_COPY;
	pcodes[1].size = 20;
	pcodes[1].attr.addr = 0;
	script = diag_malloc(sizeof(struct diag_vcdiff_script));
	script->source = NULL;
	script->s_pcodes = 2;
	script->pcodes = pcodes;
	result = diag_vcdiff_expand(script, &size);
	ASSERT_NOT_NULL(result);
	ASSERT_EQ_UINT32(21, size);
	for (i = 0; i < size; i++) {
		ASSERT_EQ_UINT8('a', result[i]);
	}
	diag_free(result);
	diag_free(script);
	diag_free(pcodes);

	return EXIT_SUCCESS;
}
コード例 #3
0
ファイル: deque.c プロジェクト: tabe/Diagonal
void diag_deque_destroy(struct diag_deque *deque)
{
	if (deque) {
		struct diag_deque_elem *elem = deque->first;
		while (elem) {
			struct diag_deque_elem *tmp = elem;
			elem = tmp->next;
			diag_free(tmp);
		}
		diag_free(deque);
	}
}
コード例 #4
0
ファイル: hash.c プロジェクト: apiou/cogen
int
hash_table_remove(hash_table * hash_t, void *key, void **pdata)
{
	hash_node **node, *dest;

	node = hash_table_lookup_node(hash_t, key);
	if (*node)
	{
		if (pdata != NULL)
			*pdata = (*node)->value;
		dest = *node;
		*node = dest->next;
		if (pdata == NULL) {
			if (hash_t->hash_free)
				hash_t->hash_free(dest->value);
		}
		diag_free(dest);
		hash_t->nnodes--;
		hash_table_resize(hash_t);

		return 1;
	}

	return 0;
}
コード例 #5
0
ファイル: hash.c プロジェクト: apiou/cogen
hash_table *
hash_table_new(hash_func hash_f, hash_comp hash_c, hash_free hash_fr)
{
	hash_table *hash_t;

	hash_t = (struct _hash_table *) diag_malloc(sizeof(hash_table));
	if (hash_t == NULL)
		diag_fatal("Unable to allocate memory\n");

	hash_t->size = HASH_TABLE_MIN_SIZE;
	hash_t->nnodes = 0;
	if (hash_f)
		hash_t->hash_func = default_hash_func;
	else
		hash_t->hash_func = hash_f;
	if (hash_c)
		hash_t->hash_comp = default_compare_func;
	else
		hash_t->hash_comp = hash_c;
	hash_t->hash_free = hash_fr;
	hash_t->nodes = (hash_node **) diag_malloc(sizeof(hash_node *) * hash_t->size);
	if (hash_t->nodes == NULL)
	{
		diag_free(hash_t);
		diag_fatal("Unable to allocate memory\n");
	}
	memset(hash_t->nodes, 0, sizeof(hash_node *) * hash_t->size);

	return hash_t;
}
コード例 #6
0
ファイル: system.c プロジェクト: tabe/Diagonal
char *diag_get_command_line(char **argv)
{
	assert(argv);

	char *line = diag_malloc(32768);
	char *lp = line;
	int i;
	for (i = 0; argv[i]; i++) {
		const char *s = argv[i];
		int slen = (int)strlen(s);
		if (lp + slen >= line + 32768) {
			diag_free(line);
			return NULL;
		}
		if (i > 0) {
			*lp++ = ' ';
		}
		if (contains_space(s)) {
			*lp++ = '"';
			strcpy(lp, s);
			lp += slen;
			*lp++ = '"';
		} else {
			strcpy(lp, s);
			lp += slen;
		}
	}
	*lp = '\0';
	return line;
}
コード例 #7
0
ファイル: datum.c プロジェクト: tabe/Diagonal
void
diag_datum_destroy(struct diag_datum *datum)
{
	if (!datum) return;
	if (DIAG_DATUM_CUSTOMIZED_P(datum)) {
		struct diag_customized_datum *customized_datum;

		customized_datum = (struct diag_customized_datum *)datum;
		customized_datum->finalize(datum);
	}
	diag_free(datum);
}
コード例 #8
0
ファイル: hash.c プロジェクト: apiou/cogen
void
hash_table_destroy(hash_table * hash_t)
{
	long i;
	hash_node *next, *hash_n;

	for (i = 0; i < hash_t->size; i++)
	{
		hash_n = hash_t->nodes[i];

		while (hash_n)
		{
			next = hash_n->next;
			if (hash_t->hash_free)
				hash_t->hash_free(hash_n->value);
			diag_free(hash_n);
			hash_n = next;
		}
	}

	diag_free(hash_t->nodes);
	diag_free(hash_t);
}
コード例 #9
0
ファイル: system.c プロジェクト: tabe/Diagonal
void diag_command_destroy(struct diag_command *command)
{
	if (!command) return;
	int i;
	for (i = 0; command->argv[i]; i++) {
		diag_free(command->argv[i]);
	}
	diag_free(command->argv);
	diag_free(command->dir);
	diag_free(command->in);
	diag_free(command->out);
	diag_free(command->err);
	diag_free(command);
}
コード例 #10
0
ファイル: system.c プロジェクト: tabe/Diagonal
intptr_t diag_run_agent(char **argv)
{
	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	STARTUPINFO si;
	GetStartupInfo(&si);
	si.dwFlags |= STARTF_USESTDHANDLES;
	si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	char *line = diag_get_command_line(argv);

	BOOL b = CreateProcess(NULL,
			       line,
			       NULL,
			       NULL,
			       TRUE,
			       0,
			       NULL,
			       NULL,
			       &si,
			       &pi);
	if (!b) {
		diag_fatal("could not create process: %s: 0x%x",
			   line,
			   (unsigned int)GetLastError());
	}

	/* We do not want WaitForInputIdle() because there is no interaction
	   between the parent process and this child */

	diag_free(line);
	CloseHandle(pi.hThread);
	return (intptr_t)pi.hProcess;
}
コード例 #11
0
ファイル: hash.c プロジェクト: apiou/cogen
void
hash_table_removecurrval(hash_table_iter *iterator)
{
	if (iterator)
		if (iterator->hash_t && iterator->curr_item)
		{
			hash_node *dest, *removed = *(iterator->curr_item);

			if (removed)
			{
				hash_table *hash_t = iterator->hash_t;

				dest = removed;
				removed = dest->next;
				if (hash_t->hash_free)
					hash_t->hash_free(dest->value);
				diag_free(dest);
				hash_t->nnodes--;
			}
		}
}
コード例 #12
0
ファイル: hash.c プロジェクト: apiou/cogen
static void
hash_table_resize(hash_table * hash_t)
{
	hash_node **new_nodes;
	hash_node *node;
	hash_node *next;
	long hash_val;
	long new_size;
	long i;

	if ((hash_t->size >= 3 * hash_t->nnodes && hash_t->size > HASH_TABLE_MIN_SIZE)
	    || (3 * hash_t->size <= hash_t->nnodes && hash_t->size < HASH_TABLE_MAX_SIZE))
	{

		new_size = get_closest(hash_t->nnodes);

		new_nodes = (hash_node **) diag_malloc(sizeof(hash_node *) * new_size);
		if (new_nodes == NULL)
		{
			diag_msg("Unable to allocate memory\n");
			return;
		}
		memset(new_nodes, 0, sizeof(hash_node *) * new_size);

		for (i = 0; i < hash_t->size; i++)
			for (node = hash_t->nodes[i]; node; node = next)
			{
				next = node->next;

				hash_val = (*hash_t->hash_func) (node->key, new_size);

				node->next = new_nodes[hash_val];
				new_nodes[hash_val] = node;
			}

		diag_free(hash_t->nodes);
		hash_t->nodes = new_nodes;
		hash_t->size = new_size;
	}
}
コード例 #13
0
ファイル: cluster.c プロジェクト: tabe/Diagonal
void
diag_analysis_destroy(struct diag_analysis *analysis)
{
	diag_free(analysis);
}
コード例 #14
0
ファイル: system.c プロジェクト: tabe/Diagonal
void diag_process_destroy(struct diag_process *process)
{
	diag_free(process);
}
コード例 #15
0
ファイル: system.c プロジェクト: tabe/Diagonal
struct diag_process *diag_run_program(struct diag_command *command)
{
	assert(command);

	char *out = NULL;
	if (!command->out) {
		out = diag_malloc(PATH_LENGTH);
	}
	char *err = NULL;
	if (!command->err) {
		err = diag_malloc(PATH_LENGTH);
	}
	pid_t pid = fork();
	if (pid < 0) {
		perror(command->file);
		diag_free(out);
		diag_free(err);
		return NULL;
	}
	if (pid == 0) {
		pid = getpid();
		if (!command->out) {
			build_path(command->dir, pid, "out", out);
			command->out = out;
		}
		if (!command->err) {
			build_path(command->dir, pid, "err", err);
			command->err = err;
		}
		if (command->in) { /* redirect stdin only when specified */
			if (!freopen(command->in, "rb", stdin)) {
				perror(command->in);
				_Exit(EXIT_FAILURE);
			}
		}
		/* Both stdout and stderr should be always redirected */
		if (!freopen(command->out, "wb", stdout)) {
			perror(command->out);
			_Exit(EXIT_FAILURE);
		}
		if (!freopen(command->err, "wb", stderr)) {
			perror(command->err);
 			_Exit(EXIT_FAILURE);
		}
		if (execvp(command->file, command->argv) == -1) {
			perror(command->file);
			_Exit(EXIT_FAILURE);
		}
	}
	if (!command->out) {
		build_path(command->dir, pid, "out", out);
		command->out = out;
	}
	if (!command->err) {
		build_path(command->dir, pid, "err", err);
		command->err = err;
	}
	struct diag_process *p = diag_malloc(sizeof(*p));
	p->pid = (intptr_t)pid;
	p->status = 0;
	return p;
}
コード例 #16
0
ファイル: system.c プロジェクト: tabe/Diagonal
/*
 * References:
 *
 * How to spawn console processes with redirected standard handles
 * http://support.microsoft.com/kb/190351
 */
struct diag_process *diag_run_program(struct diag_command *command)
{
	assert(command);

	if (!command->out) {
		command->out = diag_malloc(PATH_LENGTH);
		build_path(command->dir, local_pid, "out", command->out);
	}
	if (!command->err) {
		command->err = diag_malloc(PATH_LENGTH);
		build_path(command->dir, local_pid, "err", command->err);
	}
	local_pid++;

	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	HANDLE ih = NULL;
	if (command->in) {
		ih = CreateFile(command->in,
				GENERIC_READ,
				FILE_SHARE_READ,
				&sa,
				OPEN_EXISTING,
				0,
				NULL);
		if (ih == INVALID_HANDLE_VALUE) {
			diag_error("failed to open file: %s: 0x%x",
				   command->in,
				   (unsigned int)GetLastError());
			return NULL;
		}
	}

	HANDLE oh = CreateFile(command->out,
			       GENERIC_WRITE,
			       FILE_SHARE_WRITE|FILE_SHARE_DELETE,
			       &sa,
			       CREATE_NEW,
			       FILE_ATTRIBUTE_NORMAL,
			       NULL);
	if (oh == INVALID_HANDLE_VALUE) {
		diag_error("failed to open file: %s: 0x%x",
			   command->out,
			   (unsigned int)GetLastError());
		return NULL;
	}

	HANDLE eh = CreateFile(command->err,
			       GENERIC_WRITE,
			       FILE_SHARE_WRITE|FILE_SHARE_DELETE,
			       &sa,
			       CREATE_NEW,
			       FILE_ATTRIBUTE_NORMAL,
			       NULL);
	if (eh == INVALID_HANDLE_VALUE) {
		diag_error("failed to open file: %s: 0x%x",
			   command->err,
			   (unsigned int)GetLastError());
		return NULL;
	}

	STARTUPINFO si;
	GetStartupInfo(&si);
	si.dwFlags |= STARTF_USESTDHANDLES;
	si.hStdInput = ih;
	si.hStdOutput = oh;
	si.hStdError = eh;

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	char *line = diag_get_command_line(command->argv);

	BOOL b = CreateProcess(NULL,
			       line,
			       NULL,
			       NULL,
			       TRUE,
			       0,
			       NULL,
			       NULL,
			       &si,
			       &pi);
	if (!b) {
		diag_error("could not create process: %s: 0x%x",
			   line,
			   (unsigned int)GetLastError());
		// should follow GetLastError()
		diag_free(line);
		if (ih) CloseHandle(ih);
		CloseHandle(oh);
		CloseHandle(eh);
		return NULL;
	}

	/* We do not want WaitForInputIdle() because there is no interaction
	   between the parent process and this child */

	diag_free(line);
	if (ih) CloseHandle(ih);
	CloseHandle(oh);
	CloseHandle(eh);

	CloseHandle(pi.hThread);

	struct diag_process *p = diag_malloc(sizeof(*p));
	p->pid = (intptr_t)pi.hProcess;
	return p;
}
コード例 #17
0
ファイル: hash.c プロジェクト: apiou/cogen
void
hash_str_free(void *str)
{
	if (str != NULL)
		diag_free(str);
}
コード例 #18
0
ファイル: qselect.c プロジェクト: tabe/Diagonal
void *diag_qselect(void *base, size_t nmemb, size_t size,
		   int (*cmp)(const void *, const void *),
		   size_t k)
{
	assert(base);
	assert(nmemb > 0);
	assert(size > 0);

	if (nmemb <= k) return NULL;
	if (nmemb == 1) return base;

	int *rv = diag_calloc(nmemb, sizeof(int));
	size_t i;
	size_t n_lt;
	size_t n_gt;
	size_t n_eq;
	char *p;

 partition:
	assert(k < nmemb);
	if (nmemb == 1) goto done;

	n_lt = 0;
	n_gt = 0;
	p = (char *)base;
	for (i = 1; i < nmemb; i++) {
		int r = cmp(p, p + size * i);
		if (r < 0) n_lt++;
		if (0 < r) n_gt++;
		rv[i] = r;
	}
	n_eq = nmemb - n_lt - n_gt;
	if (k < n_lt) {
		size_t j = n_lt + 1;
		for (i = 1; i <= n_lt; i++) {
			if (rv[i] >= 0) {
				while (j < nmemb && rv[j] >= 0) {
					j++;
				}
				assert(j < nmemb);
				memcpy(p + size * i, p + size * j++, size);
			}
		}
		base = p + size;
		nmemb = n_lt;
		/* k is unchanged */
		goto partition;
	}
	if (k >= n_lt + n_eq) {
		size_t j = n_gt + 1;
		for (i = 1; i <= n_gt; i++) {
			if (rv[i] <= 0) {
				while (j < nmemb && rv[j] <= 0) {
					j++;
				}
				assert(j < nmemb);
				memcpy(p + size * i, p + size * j++, size);
			}
		}
		base = p + size;
		nmemb = n_gt;
		k -= n_lt + n_eq;
		goto partition;
	}

 done:
	diag_free(rv);
	return base;
}
コード例 #19
0
ファイル: diag_deque_append.c プロジェクト: tabe/Diagonal
int main(void)
{
	struct diag_deque *head, *tail;
	struct diag_deque_elem *elem;
	intptr_t i;
	size_t len;

	head = diag_deque_new();
	tail = diag_deque_new();

	/* both are empty */
	len = diag_deque_append(head, tail);
	ASSERT_EQ_UINT(0, len);
	ASSERT_EQ_UINT(0, head->length);
	ASSERT_EQ_UINT(0, tail->length);

	/* head is trivial */
	i = 0;
	while (i < 29) {
		diag_deque_push(tail, i++);
	}
	len = diag_deque_append(head, tail);
	ASSERT_EQ_UINT(29, head->length);
	ASSERT_EQ_UINT(0, tail->length);
	i = 0;
	while ( (elem = diag_deque_shift(head)) ) {
		ASSERT_EQ_UINTPTR(i++, elem->attr);
		diag_free(elem);
	}
	ASSERT_EQ_UINTPTR(29, i);

	/* tail is trivial */
	i = 0;
	while (i < 31) {
		diag_deque_push(head, i++);
	}
	len = diag_deque_append(head, tail);
	ASSERT_EQ_UINT(31, head->length);
	ASSERT_EQ_UINT(0, tail->length);
	i = 0;
	while ( (elem = diag_deque_shift(head)) ) {
		ASSERT_EQ_UINTPTR(i++, elem->attr);
		diag_free(elem);
	}
	ASSERT_EQ_UINTPTR(31, i);

	/* general */
	i = 0;
	while (i < 100) {
		diag_deque_push(head, i++);
	}
	while (i < 300) {
		diag_deque_push(tail, i++);
	}
	len = diag_deque_append(head, tail);
	ASSERT_EQ_UINT(300, len);
	ASSERT_EQ_UINT(300, head->length);
	ASSERT_EQ_UINT(0, tail->length);
	i = 0;
	while ( (elem = diag_deque_shift(head)) ) {
		ASSERT_EQ_UINTPTR(i++, elem->attr);
		diag_free(elem);
	}
	ASSERT_EQ_UINTPTR(300, i);

	diag_deque_destroy(head);
	diag_deque_destroy(tail);
	return EXIT_SUCCESS;
}
コード例 #20
0
ファイル: cluster.c プロジェクト: tabe/Diagonal
void
diag_delta_destroy(struct diag_delta *delta)
{
	diag_free(delta);
}
コード例 #21
0
ファイル: cluster.c プロジェクト: tabe/Diagonal
void
diag_code_destroy(struct diag_code *datum)
{
	diag_free(datum);
}
コード例 #22
0
ファイル: diag-times.c プロジェクト: tabe/Diagonal
int main(int argc, char *argv[])
{
	int c;
	int n = 0;
	int r = EXIT_FAILURE;
	char *in = NULL;

	diag_init();

	while ( (c = getopt(argc, argv, "+Vhi:n:")) >=0) {
		switch (c) {
		case 'V':
			diag_print_version();
			exit(EXIT_SUCCESS);
			break;
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
			break;
		case 'i':
			in = optarg;
			break;
		case 'n':
			n = atoi(optarg);
			if (n < 0) {
				diag_fatal("non-negative integer expected, but %d", n);
			} else if (n == 0) {
				exit(EXIT_SUCCESS);
			}
			break;
		case ':':
		case '?':
			usage();
			exit(EXIT_FAILURE);
			break;
		}
	}
	if (!argv[optind]) {
		usage();
		exit(EXIT_FAILURE);
	}
	if (n == 0) {
		diag_fatal("please specify the number with the -n option");
	}

	char *tfin = NULL;
	if (!in) {
		struct diag_temporary_file *tf = diag_temporary_file_new();
		if (!tf) {
			return EXIT_FAILURE;
		}
		tfin = diag_strdup(tf->path);
		struct diag_port *ip = diag_port_new_stdin();
		assert(ip);
		ssize_t s = diag_port_copy(ip, tf->port);
		diag_port_destroy(ip);
		diag_temporary_file_destroy(tf);
		if (s < 0) {
			assert(tfin);
			diag_remove(tfin);
			diag_free(tfin);
			return EXIT_FAILURE;
		}
	}

	int i = 0;
	char *file = in ? in : tfin;
	struct diag_command *cmd;
 run:
	cmd = diag_command_new(argv + optind, NULL, file, NULL, NULL);
	if (!cmd) {
		goto done;
	}
	struct diag_process *p = diag_run_program(cmd);
	if (!p) {
		goto done;
	}
	diag_process_wait(p);
	int status = p->status;
	diag_process_destroy(p);
	if (status != 0) {
		r = status;
		goto done;
	}

	assert(cmd->err);
	diag_remove(cmd->err);

	if (i) {
		diag_remove(file);
		diag_free(file);
	} else if (tfin) {
		diag_remove(tfin);
		diag_free(tfin);
		tfin = NULL;
	}

	if (++i < n) {
		file = diag_strdup(cmd->out);
		diag_command_destroy(cmd);
		goto run;
	}

	struct diag_port *ip = diag_port_new_path(cmd->out, "rb");
	if (!ip) {
		goto done;
	}
	struct diag_port *op = diag_port_new_stdout();
	assert(op);
	ssize_t s = diag_port_copy(ip, op);
	diag_port_destroy(op);
	diag_port_destroy(ip);
	if (s < 0) {
		goto done;
	}

	diag_remove(cmd->out);
	r = EXIT_SUCCESS;

 done:
	diag_command_destroy(cmd);
	if (tfin) {
		diag_remove(tfin);
		diag_free(tfin);
	}
	return r;
}
コード例 #23
0
ファイル: cluster.c プロジェクト: tabe/Diagonal
void
diag_cluster_destroy(struct diag_cluster *cluster)
{
	diag_free(cluster);
}