mirror of
https://github.com/libretro/cpp-cheat.git
synced 2025-04-08 05:52:06 +00:00
184 lines
4.6 KiB
C
184 lines
4.6 KiB
C
#include "common.h"
|
|
|
|
/* Discard sdtin content up to first newline.
|
|
if there is no newline, waits for a newline to be input.*/
|
|
void flush_stdin_to_newline() {
|
|
|
|
char junk[16];
|
|
do {
|
|
if (fgets(junk, sizeof(junk), stdin) == NULL) {
|
|
/* TODO deal with error proprely */
|
|
}
|
|
} while (junk[strlen( junk ) -1 ] != '\n');
|
|
|
|
}
|
|
|
|
/*
|
|
* user get string until newline.
|
|
*
|
|
* fixed maximum size.
|
|
*
|
|
* no newline on output.
|
|
*
|
|
* prompt again until user inputs a string under maximun size.
|
|
*/
|
|
void ugstr(char* out, int max) {
|
|
bool done=false;
|
|
while(!done) {
|
|
if (fgets(out, max, stdin) == NULL) {
|
|
/* TODO deal with error proprely */
|
|
}
|
|
|
|
char *newline = strchr(out, '\n'); /* search for newline character */
|
|
if (newline == NULL) {
|
|
/* No newline. too much input. reask. */
|
|
flush_stdin_to_newline();
|
|
fprintf(stderr, "input too large. max %d chars. reenter and press <enter>:\n", max);
|
|
} else {
|
|
*newline = '\0'; /* overwrite trailing newline */
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* user prompt string until newline
|
|
*
|
|
* same as ugstr, but writes user prompt to stderr
|
|
*/
|
|
void upstr(char* out, int max) {
|
|
fprintf(stderr, "enter a string and press <enter> (max %d chars):\n", max-1);
|
|
fflush(stderr);
|
|
ugstr(out,max);
|
|
}
|
|
|
|
/*
|
|
This is not the canonical source for this function: it is somewhere else in this repo.
|
|
We just copy pasted it here because lazy for proprely sharing.
|
|
*/
|
|
typedef enum { S2NSUCCESS, S2NOVERFLOW, S2NUNDERFLOW, S2NINCONVERTIBLE } STR2NUM_ERROR;
|
|
STR2NUM_ERROR str2int(int *i, char *s, int base) {
|
|
if (isspace(s[0])) {
|
|
return S2NINCONVERTIBLE;
|
|
}
|
|
char *end;
|
|
errno = 0;
|
|
long l = strtol(s, &end, base);
|
|
if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX) {
|
|
return S2NOVERFLOW;
|
|
}
|
|
if ((errno == ERANGE && l == LONG_MIN) || l < INT_MIN) {
|
|
return S2NUNDERFLOW;
|
|
}
|
|
if (*s == '\0' || *end != '\0') {
|
|
return S2NINCONVERTIBLE;
|
|
}
|
|
*i = l;
|
|
return S2NSUCCESS;
|
|
}
|
|
|
|
/* Same as str2int, but prints errors to stderr. */
|
|
STR2NUM_ERROR str2int_stderr(int *i, char *s, int base) {
|
|
STR2NUM_ERROR out = str2int (i, s, base);
|
|
if (out == S2NINCONVERTIBLE) {
|
|
fprintf(stderr,"\"%s\" is not an int \n",s);
|
|
} else if (out == S2NOVERFLOW) {
|
|
fprintf(stderr,"\"%s\" is too large for an int. max value: %d\n",s,INT_MAX);
|
|
} else if (out == S2NUNDERFLOW) {
|
|
fprintf(stderr,"\"%s\" is too small for an int. min value: %d\n",s,INT_MIN);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
/* User prompt c int in base b <= 36. */
|
|
int upint(int base) {
|
|
int out;
|
|
STR2NUM_ERROR err;
|
|
const int max=64;
|
|
char in[max];
|
|
|
|
while (1) {
|
|
fprintf(stderr, "enter a integer and press <enter>:\n");
|
|
fflush(stderr);
|
|
ugstr (in,max);
|
|
err = str2int_stderr(&out, in, base);
|
|
if (err == S2NSUCCESS) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
STR2NUM_ERROR str2float(float *fout, char *s) {
|
|
/* strict checking: must be EXACTLY an int */
|
|
if(isspace(s[0])) {
|
|
return S2NINCONVERTIBLE;
|
|
}
|
|
|
|
char *end;
|
|
errno = 0;
|
|
float f = strtof(s, &end);
|
|
|
|
if ( errno == ERANGE && f == HUGE_VALF ) {
|
|
return S2NOVERFLOW;
|
|
}
|
|
if ( errno == ERANGE && f == -HUGE_VALF ) {
|
|
return S2NUNDERFLOW;
|
|
}
|
|
if (*s == '\0' || *end != '\0') {
|
|
return S2NINCONVERTIBLE;
|
|
}
|
|
*fout = f;
|
|
return S2NSUCCESS;
|
|
}
|
|
|
|
/*same as str2float, but prints errors to stderr*/
|
|
STR2NUM_ERROR str2float_stderr(float *f, char *s) {
|
|
STR2NUM_ERROR out = str2float (f, s);
|
|
if(out == S2NINCONVERTIBLE) {
|
|
fprintf(stderr,"\"%s\" is not a float \n",s);
|
|
} else if(out == S2NOVERFLOW) {
|
|
fprintf(stderr,"\"%s\" is too large for a float. max value: %f\n",s,FLT_MAX);
|
|
} else if(out == S2NUNDERFLOW) {
|
|
fprintf(stderr,"\"%s\" is too small for a float. min value: %f\n",s,FLT_MIN);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
|
|
float upfloat() {
|
|
float out;
|
|
STR2NUM_ERROR err;
|
|
const int max=64;
|
|
char in[max];
|
|
|
|
while (1) {
|
|
fprintf(stderr, "enter a float and press <enter>:\n");
|
|
fflush(stderr);
|
|
ugstr(in, max);
|
|
err = str2float_stderr (&out, in);
|
|
if (err == S2NSUCCESS) {
|
|
break;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
int main() {
|
|
const int l = 20;
|
|
int i;
|
|
float f;
|
|
if (0) {
|
|
char str[l];
|
|
upstr(str,l);
|
|
printf("user entered:\n%s\n",str);
|
|
|
|
i = upint(10);
|
|
printf("user entered:\n%d\n",i);
|
|
|
|
f = upfloat();
|
|
printf ("user entered:\n%f\n", f);
|
|
}
|
|
return 0;
|
|
}
|