aboutsummaryrefslogtreecommitdiff
path: root/src/io/input.c
blob: 507bd59e2ebdd71d4136454f011e4ff5c8a99c60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * ecgen, tool for generating Elliptic curve domain parameters
 * Copyright (C) 2017-2018 J08nY
 */
#define _POSIX_C_SOURCE 200809L

#include "input.h"
#include "output.h"

FILE *in;
int delim;

static GEN input_i(const char *prompt, unsigned long bits) {
	if (prompt && in == stdin) {
		fprintf(err, "%s ", prompt);
	}
	char *line = NULL;
	size_t n = 0;

	ssize_t len = getdelim(&line, &n, delim, in);
	if (len <= 0) {
		if (feof(in)) {
			fprintf(err, "Couldn't read an integer. Reached EOF!\n");
		} else if (ferror(in)) {
			perror("Couldn't read an integer.");
		} else {
			fprintf(err, "Couldn't read an integer.\n");
		}
		return gen_m2;
	}
	if (len == 1 && !feof(in)) {
		free(line);
		return gen_m1;
	}
	bool sign = line[0] == '-';

	pari_sp ltop = avma;
	GEN in = strtoi(line + sign);
	if (sign) {
		togglesign(in);
	}
	free(line);

	// check bitsize here
	GEN size = int2n(bits);
	if (cmpii(in, size) <= 0) {
		return gerepileupto(ltop, in);
	} else {
		fprintf(err, "Number too big(> %ld bits).\n", bits);
		return gen_m1;
	}
}

GEN input_prime(const char *prompt, unsigned long bits) {
	GEN read = input_i(prompt, bits);
	if (equalii(read, gen_m1) || equalii(read, gen_m2)) {
		return read;
	} else {
		if (isprime(read)) {
			return read;
		} else {
			fprintf(err, "Number is not prime. Prime required.\n");
			return gen_m1;
		}
	}
}

GEN input_int(const char *prompt, unsigned long bits) {
	return input_i(prompt, bits);
}

GEN input_short(const char *prompt) { return input_i(prompt, 16); }

GEN input_string(const char *prompt) {
	if (prompt && in == stdin) {
		fprintf(err, "%s ", prompt);
	}
	char *line = NULL;
	size_t n = 0;

	ssize_t len = getdelim(&line, &n, delim, in);
	if (len <= 0) {
		return strtoGENstr("");
	}
	if (len == 1) {
		free(line);
		return strtoGENstr("");
	}

	line[len - 1] = 0;
	GEN result = strtoGENstr(line);
	free(line);
	return result;
}

bool input_init() {
	if (cfg->input) {
		in = fopen(cfg->input, "r");
		delim = ',';
		if (!in) {
			perror("Failed to open input file.");
			return false;
		}
	} else {
		in = stdin;
		delim = '\n';
	}
	return true;
}

void input_quit(void) {
	if (in != NULL && in != stdin) {
		fclose(in);
	}
}