#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <regex.h>
#include <locale.h>
#include <langinfo.h>
#include <limits.h>
#include <errno.h>
#include "getresponse.h"
#define DEFAULT_YESSTR "yes"
#define DEFAULT_NOSTR "no"
#define DEFAULT_YESEXPR "^[yY]"
#define DEFAULT_NOEXPR "^[nN]"
#define FREE_MEM \
free(yesstr); \
free(nostr); \
free(yesexpr); \
free(noexpr)
#define SET_DEFAULT_STRS \
yesstr = DEFAULT_YESSTR; \
nostr = DEFAULT_NOSTR; \
yesexpr = DEFAULT_YESEXPR; \
noexpr = DEFAULT_NOEXPR;
char *yesstr = NULL;
char *nostr = NULL;
static regex_t preg_yes, preg_no;
int
init_yes(void)
{
int fallback = 0;
char *yesexpr;
char *noexpr;
yesstr = strdup(nl_langinfo(YESSTR));
nostr = strdup(nl_langinfo(NOSTR));
yesexpr = strdup(nl_langinfo(YESEXPR));
noexpr = strdup(nl_langinfo(NOEXPR));
if (yesstr == NULL || nostr == NULL ||
yesexpr == NULL || noexpr == NULL) {
FREE_MEM;
errno = ENOMEM;
return (-1);
}
if (*yesstr == '\0' || *nostr == '\0' ||
*yesexpr == '\0' || *noexpr == '\0') {
FREE_MEM;
SET_DEFAULT_STRS;
fallback = 1;
}
while (regcomp(&preg_yes, yesexpr, REG_EXTENDED | REG_NOSUB) != 0 ||
regcomp(&preg_no, noexpr, REG_EXTENDED | REG_NOSUB) != 0) {
if (fallback == 1) {
errno = EINVAL;
return (-1);
}
FREE_MEM;
SET_DEFAULT_STRS;
fallback = 1;
}
if (fallback == 0) {
free(yesexpr);
free(noexpr);
}
return (0);
}
void
fini_yes(void)
{
free(yesstr);
free(nostr);
yesstr = DEFAULT_YESSTR;
nostr = DEFAULT_NOSTR;
regfree(&preg_yes);
regfree(&preg_no);
}
static int
yes_no(int (*func)(char *))
{
int i, b;
char ans[LINE_MAX + 1];
i = 0;
for (;;) {
b = getchar();
if (b == '\n' || b == '\0' || b == EOF)
break;
if (i < LINE_MAX)
ans[i] = b;
i++;
}
if (i >= LINE_MAX)
ans[LINE_MAX] = '\0';
else
ans[i] = '\0';
return (func(ans));
}
static int
yes_no_check(char *ans, regex_t *reg1, regex_t *reg2)
{
if (regexec(reg1, ans, 0, NULL, 0) == 0) {
if (regexec(reg2, ans, 0, NULL, 0) == 0) {
return (0);
}
return (1);
}
return (0);
}
int
yes_check(char *ans)
{
return (yes_no_check(ans, &preg_yes, &preg_no));
}
int
no_check(char *ans)
{
return (yes_no_check(ans, &preg_no, &preg_yes));
}
int
yes(void)
{
return (yes_no(yes_check));
}
int
no(void)
{
return (yes_no(no_check));
}