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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -51,6 +52,14 @@ ecalloc(size_t nmemb, size_t size)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
str_dupe(const char *s, size_t n)
|
||||
{
|
||||
char *r = STR_EALLOC(n);
|
||||
strncpy(r, s, n);
|
||||
return r;
|
||||
}
|
||||
|
||||
size_t
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
char *str_dupe(const char *s, size_t n);
|
||||
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);
|
||||
char *str_concat(int count, ...);
|
||||
char *str_toupper(char *s, size_t n);
|
||||
#define STR_EALLOC(s) ecalloc((s), sizeof(char))
|
||||
#define STR_MALLOC(s) calloc((s), sizeof(char))
|
||||
|
|
Loading…
Reference in New Issue