Merge branch 'limits' of UBB/sort into master

This commit is contained in:
Chris Cromer 2018-11-17 11:40:14 -03:00 committed by Gitea
commit bc9a6573da

View File

@ -17,6 +17,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <limits.h>
#include "random.h" #include "random.h"
#include "timer.h" #include "timer.h"
#include "bubble_sort.h" #include "bubble_sort.h"
@ -27,9 +29,12 @@
#define SORT_VERSION "1.0.0" #define SORT_VERSION "1.0.0"
/** /**
* El array a ordenar * El array desordenado
*/ */
static int *unordered_array; static int *unordered_array;
/**
* El array a ordenar
*/
static int *work_array; static int *work_array;
/** /**
@ -72,30 +77,63 @@ void print_array(int *array, int n) {
* @return Retorna 1 si es exitosa ó 0 si falla * @return Retorna 1 si es exitosa ó 0 si falla
*/ */
int read_buffer(int *variable) { int read_buffer(int *variable) {
char buffer[12]; char buffer[32];
char *check;
while (1) { while (1) {
if (fgets(buffer, 12, stdin) != NULL) { if (fgets(buffer, 32, stdin) != NULL) {
if (buffer[strlen(buffer) - 1] == '\n') { if (buffer[strlen(buffer) - 1] == '\n') {
buffer[strlen(buffer) - 1] = '\0'; buffer[strlen(buffer) - 1] = '\0';
break; break;
} }
} }
} }
char **check = malloc(sizeof(char**)); errno = 0;
if (check == NULL) { long input = strtol(buffer, &check, 10);
fprintf(stderr, "Error: Out of heap space!\n"); if (buffer == check) {
exit(5); // Empty
return 0;
}
else if (errno == ERANGE && input == LONG_MIN) {
// Overflow
return 0;
}
else if (errno == ERANGE && input == LONG_MAX) {
// Underflow
return 0;
}
else if (errno == EINVAL) { /* not in all c99 implementations - gcc OK */
// Base contains unsupported value
// This check is not in all c99 implementations, but does exist in gcc
return 0;
}
else if (errno != 0 && input == 0) {
// Unspecified error
return 0;
}
else if (errno == 0 && !*check) {
// Valid number
if (input > INT_MAX || input < INT_MIN) {
fprintf(stderr, "Error: n tiene que ser menor de 2147483648 y mayor de -2147483649!\n");
return 0;
} }
long input = strtol(buffer, check, 10);
if (*check[0] == '\0') {
free(check);
*variable = (int) input; *variable = (int) input;
return 1; return 1;
} }
else { else if (errno == 0 && *check != 0) {
free(check); // Contains non number characters
return 0; return 0;
} }
else {
return 0;
}
}
/**
* Imprimir un mensaje y salir si n es invalido
*/
void print_invalid_n() {
fprintf(stderr, "Error: El valor de n es invalido!\n");
exit(7);
} }
/** /**
@ -112,7 +150,9 @@ void cleanup() {
* @return Retorna el codigo de error o 0 por exito * @return Retorna el codigo de error o 0 por exito
*/ */
int main (int argc, char **argv) { int main (int argc, char **argv) {
long long i; char *check = NULL;
long ninput = 0;
int i;
int n = 10; int n = 10;
int elegir = 0; int elegir = 0;
int imprimir = 0; int imprimir = 0;
@ -173,11 +213,45 @@ int main (int argc, char **argv) {
selection = 1; selection = 1;
break; break;
case 'n': case 'n':
n = atol(optarg); errno = 0;
ninput = strtol(optarg, &check, 10);
if (optarg == check) {
// Empty
print_invalid_n();
}
else if (errno == ERANGE && ninput == LONG_MIN) {
// Overflow
print_invalid_n();
}
else if (errno == ERANGE && ninput == LONG_MAX) {
// Underflow
print_invalid_n();
}
else if (errno == EINVAL) { /* not in all c99 implementations - gcc OK */
// Base contains unsupported value
// This check is not in all c99 implementations, but does exist in gcc
print_invalid_n();
}
else if (errno != 0 && ninput == 0) {
// Unspecified error
print_invalid_n();
}
else if (errno == 0 && optarg && !*check) {
// Valid number
if (ninput > INT_MAX || ninput < INT_MIN) {
fprintf(stderr, "Error: n tiene que ser menor de 2147483648!\n");
return 6;
}
n = (int) ninput;
if (n <= 1) { if (n <= 1) {
fprintf(stderr, "Error: n tiene que ser mayor de 1!\n"); fprintf(stderr, "Error: n tiene que ser mayor de 1!\n");
return 3; return 3;
} }
}
else if (errno == 0 && optarg && *check != 0) {
// Contains non number characters
print_invalid_n();
}
break; break;
case 'e': case 'e':
elegir = 1; elegir = 1;
@ -217,15 +291,15 @@ int main (int argc, char **argv) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (elegir) { if (elegir) {
opt = 0; opt = 0;
fprintf(stdout, "Elegir elemento %lli: ", i + 1); fprintf(stdout, "Elegir elemento %d: ", i + 1);
while (!read_buffer(&opt)) { while (!read_buffer(&opt)) {
fprintf(stdout, "Número invalido! Tiene que ser mayor de 1!\n"); fprintf(stdout, "Número invalido! Tiene que ser mayor de -2147483649 y menor de 2147483648!\n");
fprintf(stdout, "Elegir elemento %lli: ", i + 1); fprintf(stdout, "Elegir elemento %d: ", i + 1);
} }
unordered_array[i] = opt; unordered_array[i] = opt;
} }
else { else {
unordered_array[i] = gen_rand((n * 10) * -1, n * 10); unordered_array[i] = gen_rand(-100000000, 100000000);
} }
} }