Allow for arbitrary prompts and options in confirm
* Rewrite confirm in c * Add str_dupe and str_toupper to util.c/util.h
This commit is contained in:
parent
9d2ff81c61
commit
b3791d5d4d
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Dylan Lom <djl@dylanlom.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
const char *argv0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display msg, and prompt user for choice from opts.
|
||||||
|
* Returns index of chosen opt.
|
||||||
|
*
|
||||||
|
* First option (opts[0]) is default if nothing else matches
|
||||||
|
* Comparison is case insensitive
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
confirm(const char *msg, const char **opts, int opts_count)
|
||||||
|
{
|
||||||
|
if (opts_count < 2) return 0;
|
||||||
|
|
||||||
|
char *opt0 = str_dupe(opts[0], sizeof(opts[0]));
|
||||||
|
printf("%s [%s", msg, str_toupper(opt0, strlen(opt0)));
|
||||||
|
free(opt0);
|
||||||
|
for (int i = 1; i < opts_count; i++) {
|
||||||
|
printf("/%s", opts[i]);
|
||||||
|
}
|
||||||
|
printf("]: ");
|
||||||
|
|
||||||
|
char *resp = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
getline(&resp, &n, stdin);
|
||||||
|
str_trimr(resp, '\n', 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < opts_count; i++) {
|
||||||
|
if (strncasecmp(opts[i], resp, n) == 0) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get user confirmation
|
||||||
|
* Examples:
|
||||||
|
* $ confirm
|
||||||
|
* $ confirm "Exit?"
|
||||||
|
* $ confirm "Download file?" n y
|
||||||
|
* $ confirm "What color?" red yellow blue
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
main(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
SET_ARGV0();
|
||||||
|
|
||||||
|
// Options provided as args
|
||||||
|
if (argc > 1) return confirm(argv[0], argv+1, argc-1);
|
||||||
|
|
||||||
|
const char **opts = STR_EALLOC(2);
|
||||||
|
opts[0] = "y";
|
||||||
|
opts[1] = "n";
|
||||||
|
return confirm(argc == 1 ? argv[0] : "Are you sure?", opts, 2);
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
#
|
|
||||||
# confirm: get user confirmation
|
|
||||||
# author: Dylan Lom <djl@dylanlom.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2021 Dylan Lom <djl@dylanlom.com>
|
|
||||||
#
|
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
||||||
# with or without fee is hereby granted.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
||||||
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
||||||
# THIS SOFTWARE.
|
|
||||||
#
|
|
||||||
|
|
||||||
truthy "$1" \
|
|
||||||
&& msg="$1" \
|
|
||||||
|| msg="Are you sure you want to do that?"
|
|
||||||
printf "%s [Y/n]: " "$msg"
|
|
||||||
read resp
|
|
||||||
test ! "$resp" = 'N' -a ! "$resp" = 'n'
|
|
||||||
|
|
18
src/util.c
18
src/util.c
|
@ -13,6 +13,7 @@
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -51,6 +52,14 @@ ecalloc(size_t nmemb, size_t size)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
str_dupe(const char *s, size_t n)
|
||||||
|
{
|
||||||
|
char *r = STR_EALLOC(n);
|
||||||
|
strncpy(r, s, n);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
str_pushc(char *s, char c, size_t s_size, size_t realloc_amount)
|
str_pushc(char *s, char c, size_t s_size, size_t realloc_amount)
|
||||||
{
|
{
|
||||||
|
@ -105,3 +114,12 @@ str_concat(int count, ...)
|
||||||
|
|
||||||
return new_str;
|
return new_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
str_toupper(char *s, size_t n)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
if islower(s[i]) s[i] = toupper(s[i]);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
|
@ -9,8 +9,10 @@ void edie(const char *fmt, ...);
|
||||||
|
|
||||||
void *ecalloc(size_t nmemb, size_t size);
|
void *ecalloc(size_t nmemb, size_t size);
|
||||||
|
|
||||||
|
char *str_dupe(const char *s, size_t n);
|
||||||
size_t str_pushc(char *s, char c, size_t size, size_t realloc_amount);
|
size_t str_pushc(char *s, char c, size_t size, size_t realloc_amount);
|
||||||
int str_trimr(char *s, char c, int max_num);
|
int str_trimr(char *s, char c, int max_num);
|
||||||
char *str_concat(int count, ...);
|
char *str_concat(int count, ...);
|
||||||
|
char *str_toupper(char *s, size_t n);
|
||||||
#define STR_EALLOC(s) ecalloc((s), sizeof(char))
|
#define STR_EALLOC(s) ecalloc((s), sizeof(char))
|
||||||
#define STR_MALLOC(s) calloc((s), sizeof(char))
|
#define STR_MALLOC(s) calloc((s), sizeof(char))
|
||||||
|
|
Loading…
Reference in New Issue