<commit_before>/*
 * Copyright 2021 Regents of the University of Michigan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define _GNU_SOURCE
#include "util.h"

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

#include "includes.h"
#include "xalloc.h"

#include <errno.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include <sys/types.h>
#include <pwd.h>

#include "../lib/logger.h"

#define MAX_SPLITS 128

int max_int(int a, int b)
{
	if (a >= b) {
		return a;
	}
	return b;
}

void enforce_range(const char *name, int v, int min, int max)
{
	if (check_range(v, min, max) == EXIT_FAILURE) {
		log_fatal("zmap", "argument `%s' must be between %d and %d\n",
			  name, min, max);
	}
}

void split_string(const char *in, int *len, const char ***results)
{
	const char **fields = xcalloc(MAX_SPLITS, sizeof(const char *));
	int retvlen = 0;
	const char *currloc = in;
	// parse csv into a set of strings
	while (1) {
		assert(retvlen < MAX_SPLITS);
		size_t len = strcspn(currloc, ", ");
		if (len == 0) {
			currloc++;
		} else {
			char *new = xmalloc(len + 1);
			strncpy(new, currloc, len);
			new[len] = '\0';
			fields[retvlen++] = new;
			assert(fields[retvlen - 1]);
		}
		if (len == strlen(currloc)) {
			break;
		}
		currloc += len;
	}
	*results = fields;
	*len = retvlen;
}

void fprintw(FILE *f, const char *s, size_t w)
{
	if (strlen(s) <= w) {
		fprintf(f, "%s", s);
		return;
	}
	// process each line individually in order to
	// respect existing line breaks in string.
	char *news = strdup(s);
	char *pch = strtok(news, "\n");
	while (pch) {
		if (strlen(pch) <= w) {
			printf("%s\n", pch);
			pch = strtok(NULL, "\n");
			continue;
		}
		char *t = pch;
		while (strlen(t)) {
			size_t numchars = 0; // number of chars to print
			char *tmp = t;
			while (1) {
				size_t new = strcspn(tmp, " ") + 1;
				if (new == strlen(tmp) || new > w) {
					// there are no spaces in the string,
					// so, just print the entire thing on
					// one line;
					numchars += new;
					break;
				} else if (numchars + new > w) {
					// if we added any more, we'd be over w
					// chars so time to print the line and
					// move on to the next.
					break;
				} else {
					tmp += (size_t) new;
					numchars += new;
				}
			}
			fprintf(f, "%.*s\n", (int)numchars, t);
			t += (size_t)numchars;
			if (t > pch + (size_t)strlen(pch)) {
				break;
			}
		}
		pch = strtok(NULL, "\n");
	}
	free(news);
}

uint32_t parse_max_hosts(char *max_targets)
{
	char *end;
	double v = strtod(max_targets, &end);
	if (end == max_targets || errno != 0) {
		log_fatal("argparse", "can't convert max-targets to a number");
	}
	if (end[0] == '%' && end[1] == '\0') {
		// treat as percentage
		v = v * ((unsigned long long int)1 << 32) / 100.;<commit_msg>stm: clear errno before calling strtod<commit_after>/*
 * Copyright 2021 Regents of the University of Michigan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define _GNU_SOURCE
#include "util.h"

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

#include "includes.h"
#include "xalloc.h"

#include <errno.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include <sys/types.h>
#include <pwd.h>

#include "../lib/logger.h"

#define MAX_SPLITS 128

int max_int(int a, int b)
{
	if (a >= b) {
		return a;
	}
	return b;
}

void enforce_range(const char *name, int v, int min, int max)
{
	if (check_range(v, min, max) == EXIT_FAILURE) {
		log_fatal("zmap", "argument `%s' must be between %d and %d\n",
			  name, min, max);
	}
}

void split_string(const char *in, int *len, const char ***results)
{
	const char **fields = xcalloc(MAX_SPLITS, sizeof(const char *));
	int retvlen = 0;
	const char *currloc = in;
	// parse csv into a set of strings
	while (1) {
		assert(retvlen < MAX_SPLITS);
		size_t len = strcspn(currloc, ", ");
		if (len == 0) {
			currloc++;
		} else {
			char *new = xmalloc(len + 1);
			strncpy(new, currloc, len);
			new[len] = '\0';
			fields[retvlen++] = new;
			assert(fields[retvlen - 1]);
		}
		if (len == strlen(currloc)) {
			break;
		}
		currloc += len;
	}
	*results = fields;
	*len = retvlen;
}

void fprintw(FILE *f, const char *s, size_t w)
{
	if (strlen(s) <= w) {
		fprintf(f, "%s", s);
		return;
	}
	// process each line individually in order to
	// respect existing line breaks in string.
	char *news = strdup(s);
	char *pch = strtok(news, "\n");
	while (pch) {
		if (strlen(pch) <= w) {
			printf("%s\n", pch);
			pch = strtok(NULL, "\n");
			continue;
		}
		char *t = pch;
		while (strlen(t)) {
			size_t numchars = 0; // number of chars to print
			char *tmp = t;
			while (1) {
				size_t new = strcspn(tmp, " ") + 1;
				if (new == strlen(tmp) || new > w) {
					// there are no spaces in the string,
					// so, just print the entire thing on
					// one line;
					numchars += new;
					break;
				} else if (numchars + new > w) {
					// if we added any more, we'd be over w
					// chars so time to print the line and
					// move on to the next.
					break;
				} else {
					tmp += (size_t) new;
					numchars += new;
				}
			}
			fprintf(f, "%.*s\n", (int)numchars, t);
			t += (size_t)numchars;
			if (t > pch + (size_t)strlen(pch)) {
				break;
			}
		}
		pch = strtok(NULL, "\n");
	}
	free(news);
}

uint32_t parse_max_hosts(char *max_targets)
{
	char *end;
	errno = 0;
	double v = strtod(max_targets, &end);
	if (end == max_targets || errno != 0) {
		log_fatal("argparse", "can't convert max-targets to a number");
	}
	if (end[0] == '%' && end[1] == '\0') {
		// treat as percentage
		v = v * ((unsigned long long int)1 << 32) / 100.;
{'fraction_non_alphanumeric': 0.15492111194590533, 'fraction_numerical': 0.009767092411720512, 'mean_word_length': 2.9904076738609113, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3888587', 'n_tokens_mistral': 2788, 'n_tokens_neox': 2493, 'n_words': 806}