fmpzio.c (3022B)
1 #include "fmpzio.h" 2 3 #define BASE_ALLOC 1024 4 #define LINE_SIZE_MAX 8192 5 6 int 7 read_next_fmpz(fmpz_t res) 8 { 9 char buffer[LINE_SIZE_MAX]; 10 size_t i; 11 12 int next_char = getchar(); 13 while (next_char == '\n' || next_char == ' ') 14 next_char = getchar(); 15 16 if (next_char == EOF) 17 return -1; 18 19 buffer[0] = next_char; 20 i = 1; 21 while (i < LINE_SIZE_MAX - 1) { 22 next_char = getchar(); 23 if (next_char == EOF || next_char == '\n' || next_char == ' ') 24 break; 25 26 buffer[i] = (char)next_char; 27 28 i++; 29 } 30 buffer[i] = '\0'; 31 32 return fmpz_set_str(res, buffer, 10); 33 } 34 35 int 36 read_next_hex_fmpz(fmpz_t res) 37 { 38 char buffer[LINE_SIZE_MAX]; 39 size_t i; 40 41 int next_char = getchar(); 42 while (next_char == '\n' || next_char == ' ') 43 next_char = getchar(); 44 45 if (next_char == EOF) 46 return -1; 47 48 buffer[0] = next_char; 49 i = 1; 50 while (i < LINE_SIZE_MAX - 1) { 51 next_char = getchar(); 52 if (next_char == EOF || next_char == '\n' || next_char == ' ') 53 break; 54 55 buffer[i] = (char)next_char; 56 57 i++; 58 } 59 buffer[i] = '\0'; 60 61 return fmpz_set_str(res, buffer, 16); 62 } 63 64 static char * 65 read_all_stdin(const size_t base_alloc) 66 { 67 size_t rsize, cread = 0, current_size = base_alloc; 68 char *buffer = malloc(base_alloc * sizeof(*buffer)); 69 70 if (buffer == NULL) 71 return NULL; 72 73 rsize = fread(buffer, sizeof(*buffer), base_alloc, stdin); 74 75 while (rsize + cread == current_size) { 76 cread = current_size; 77 current_size <<= 1; 78 buffer = realloc(buffer, current_size * sizeof(*buffer)); 79 80 if (buffer == NULL) 81 return NULL; 82 83 rsize = fread(&buffer[cread], sizeof(*buffer), cread, stdin); 84 } 85 86 buffer[rsize + cread] = '\0'; 87 88 return buffer; 89 } 90 91 static inline char * 92 whitespace_sep(char **s) 93 { 94 char *orig = *s; 95 96 if (**s == '\0') { 97 return NULL; 98 } 99 100 while (**s != '\0') { 101 if (**s == ' ' || **s == '\t' || **s == '\n') { 102 **s = '\0'; 103 (*s)++; 104 break; 105 } 106 (*s)++; 107 } 108 109 return orig; 110 } 111 112 slong 113 read_hex_lines(fmpz **v) 114 { 115 assert(v != NULL); 116 117 slong i; 118 char *r = read_all_stdin(BASE_ALLOC); 119 120 if (r == NULL) { 121 err(EXIT_FAILURE, "reading entire stdin failed"); 122 } 123 124 char *s = r; 125 slong ntokens = 0, tokens_alloc = BASE_ALLOC; 126 char **tokens = malloc(tokens_alloc * sizeof(*tokens)); 127 128 while ((tokens[ntokens] = whitespace_sep(&s)) != NULL) { 129 ntokens++; 130 131 if (ntokens == tokens_alloc) { 132 tokens_alloc <<= 1; 133 tokens = realloc(tokens, tokens_alloc * sizeof(*tokens)); 134 135 if (tokens == NULL) { 136 err(EXIT_FAILURE, "reallocating tokens failed"); 137 } 138 } 139 } 140 141 if (ntokens == 0) { 142 err(EXIT_FAILURE, "nothing to read for read_hex_lines"); 143 } 144 145 *v = _fmpz_vec_init(ntokens); 146 147 if (*v == NULL) { 148 err(EXIT_FAILURE, "creating vector in read_hex_lines failed"); 149 } 150 151 for (i = 0; i < ntokens; i++) { 152 if (fmpz_set_str(&(*v)[i], tokens[i], 16) != 0) { 153 errx(EXIT_FAILURE, "could not interpret \"%s\" as hex integer", 154 tokens[i]); 155 } 156 } 157 158 free(r); 159 free(tokens); 160 161 return ntokens; 162 }