Add input and error modules for getting input and reporting errors
modified: Makefile new file: src/error.c new file: src/error.h new file: src/input.c new file: src/input.h modified: src/nms.c modified: src/nmseffect.c modified: src/nmseffect.h
This commit is contained in:
parent
86181d9b52
commit
d921892576
2
Makefile
2
Makefile
@ -17,7 +17,7 @@ CFLAGS ?= -Wextra -Wall -O2
|
|||||||
|
|
||||||
.PHONY: all install uninstall clean
|
.PHONY: all install uninstall clean
|
||||||
|
|
||||||
nms: $(OBJ)/nmscharset.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/nms.o | $(BIN)
|
nms: $(OBJ)/input.o $(OBJ)/error.o $(OBJ)/nmscharset.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/nms.o | $(BIN)
|
||||||
$(CC) $(CFLAGS) -o $(BIN)/$@ $^
|
$(CC) $(CFLAGS) -o $(BIN)/$@ $^
|
||||||
|
|
||||||
sneakers: $(OBJ)/nmscharset.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/sneakers.o | $(BIN)
|
sneakers: $(OBJ)/nmscharset.o $(OBJ)/nmstermio.o $(OBJ)/nmseffect.o $(OBJ)/sneakers.o | $(BIN)
|
||||||
|
56
src/error.c
Normal file
56
src/error.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Brian Barto
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GPL License. See LICENSE for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define ERROR_LIST_MAX 20
|
||||||
|
#define ERROR_LENGTH_MAX 100
|
||||||
|
|
||||||
|
static char error_stack[ERROR_LIST_MAX][ERROR_LENGTH_MAX];
|
||||||
|
static int N = 0;
|
||||||
|
|
||||||
|
void error_log(char *error, ...)
|
||||||
|
{
|
||||||
|
va_list argList;
|
||||||
|
|
||||||
|
if (N < ERROR_LIST_MAX)
|
||||||
|
{
|
||||||
|
va_start(argList, error);
|
||||||
|
vsnprintf(error_stack[N++], ERROR_LENGTH_MAX - 1, error, argList);
|
||||||
|
va_end(argList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void error_print(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = N-1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s ", error_stack[i]);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *error_get(void)
|
||||||
|
{
|
||||||
|
if (N > 0)
|
||||||
|
{
|
||||||
|
return error_stack[--N];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void error_clear(void)
|
||||||
|
{
|
||||||
|
N = 0;
|
||||||
|
}
|
16
src/error.h
Normal file
16
src/error.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Brian Barto
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GPL License. See LICENSE for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ERROR_H
|
||||||
|
#define ERROR_H 1
|
||||||
|
|
||||||
|
void error_log(char *, ...);
|
||||||
|
void error_print(void);
|
||||||
|
char *error_get(void);
|
||||||
|
void error_clear(void);
|
||||||
|
|
||||||
|
#endif
|
166
src/input.c
Normal file
166
src/input.c
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Brian Barto
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GPL License. See LICENSE for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "input.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
int input_get(unsigned char** dest, char *prompt)
|
||||||
|
{
|
||||||
|
int r, input_len;
|
||||||
|
fd_set input_stream;
|
||||||
|
struct timeval timeout;
|
||||||
|
void *timeout_p;
|
||||||
|
|
||||||
|
FD_ZERO(&input_stream);
|
||||||
|
input_len = 0;
|
||||||
|
|
||||||
|
timeout.tv_sec = 10;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
if (isatty(STDIN_FILENO))
|
||||||
|
{
|
||||||
|
timeout_p = NULL;
|
||||||
|
if (prompt != NULL)
|
||||||
|
{
|
||||||
|
printf("%s", prompt);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeout_p = &timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_SET(STDIN_FILENO, &input_stream);
|
||||||
|
r = select(FD_SETSIZE, &input_stream, NULL, NULL, timeout_p);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
error_log("Error while waiting for input data. Errno: %i", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (r > 0)
|
||||||
|
{
|
||||||
|
r = ioctl(STDIN_FILENO, FIONREAD, &input_len);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
error_log("Could not determine length of input. Errno: %i", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (input_len > 0)
|
||||||
|
{
|
||||||
|
*dest = malloc(input_len);
|
||||||
|
if (*dest == NULL)
|
||||||
|
{
|
||||||
|
error_log("Memory allocation error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
r = read(STDIN_FILENO, *dest, input_len);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
error_log("Input read error. Errno: %i", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_CLR(STDIN_FILENO, &input_stream);
|
||||||
|
|
||||||
|
return input_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_get_str(char** dest, char *prompt)
|
||||||
|
{
|
||||||
|
int r, i, input_len;
|
||||||
|
unsigned char *input;
|
||||||
|
|
||||||
|
r = input_get(&input, prompt);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
error_log("Could not get input.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r > 0)
|
||||||
|
{
|
||||||
|
if (input[r - 1] == '\n')
|
||||||
|
{
|
||||||
|
--r;
|
||||||
|
if (r > 0 && input[r - 1] == '\r')
|
||||||
|
{
|
||||||
|
--r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == 0)
|
||||||
|
{
|
||||||
|
error_log("No input provided.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_len = r;
|
||||||
|
|
||||||
|
*dest = malloc(input_len + 1);
|
||||||
|
if (*dest == NULL)
|
||||||
|
{
|
||||||
|
error_log("Memory allocation error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(*dest, 0, input_len + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < input_len; ++i)
|
||||||
|
{
|
||||||
|
if (isascii(input[i]))
|
||||||
|
{
|
||||||
|
(*dest)[i] = input[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_log("Input contains non-ascii characters.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
|
||||||
|
return input_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_get_from_pipe(unsigned char** dest)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (isatty(STDIN_FILENO))
|
||||||
|
{
|
||||||
|
error_log("Input data from a piped or redirected source is required.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = input_get(dest, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
error_log("Could not get input.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (r == 0)
|
||||||
|
{
|
||||||
|
error_log("No input provided.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
15
src/input.h
Normal file
15
src/input.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Brian Barto
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GPL License. See LICENSE for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INPUT_H
|
||||||
|
#define INPUT_H 1
|
||||||
|
|
||||||
|
int input_get(unsigned char** dest, char *prompt);
|
||||||
|
int input_get_str(char** dest, char *prompt);
|
||||||
|
int input_get_from_pipe(unsigned char** dest);
|
||||||
|
|
||||||
|
#endif
|
49
src/nms.c
49
src/nms.c
@ -10,16 +10,17 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "nmseffect.h"
|
#include "nmseffect.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#define VERSION "0.3.3"
|
#define VERSION "0.3.3"
|
||||||
#define INITIAL_CAPACITY 50
|
|
||||||
#define INPUT_GROWTH_FACTOR 2
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int c, o, i, inCapacity = INITIAL_CAPACITY;
|
int r, o;
|
||||||
char *input = NULL;
|
unsigned char *input;
|
||||||
|
|
||||||
|
input = NULL;
|
||||||
|
|
||||||
// Processing command arguments
|
|
||||||
while ((o = getopt(argc, argv, "f:ascv")) != -1) {
|
while ((o = getopt(argc, argv, "f:ascv")) != -1) {
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -45,32 +46,24 @@ int main(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory for our input buffer
|
r = input_get(&input, "Enter input: ");
|
||||||
if ((input = malloc(inCapacity + 1)) == NULL) {
|
if (r < 0)
|
||||||
fprintf (stderr, "Memory Allocation Error! Quitting...\n");
|
{
|
||||||
return 1;
|
error_log("Could not get input.");
|
||||||
|
error_print();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
else if (r == 0)
|
||||||
|
{
|
||||||
|
error_log("Input is empty.");
|
||||||
|
error_print();
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Geting input
|
r = nmseffect_exec(input, r);
|
||||||
for (i = 0; (c = getchar()) != EOF; ++i) {
|
|
||||||
if (i >= inCapacity) {
|
|
||||||
inCapacity *= INPUT_GROWTH_FACTOR;
|
|
||||||
input = realloc(input, inCapacity + 1);
|
|
||||||
if (input == NULL) {
|
|
||||||
fprintf (stderr, "Memory Allocation Error! Quitting...\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input[i] = c;
|
|
||||||
input[i+1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute effect
|
|
||||||
c = nmseffect_exec(input);
|
|
||||||
|
|
||||||
// Free allocated memory (not necessary here, but good practice)
|
|
||||||
free(input);
|
free(input);
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -58,19 +58,13 @@ static void nmseffect_sleep(int);
|
|||||||
* string that is provided as an argument. It returns the last character
|
* string that is provided as an argument. It returns the last character
|
||||||
* pressed by the user.
|
* pressed by the user.
|
||||||
*/
|
*/
|
||||||
char nmseffect_exec(char *string) {
|
char nmseffect_exec(unsigned char *string, int string_len) {
|
||||||
struct charAttr *list_pointer = NULL;
|
struct charAttr *list_pointer = NULL;
|
||||||
struct charAttr *list_head = NULL;
|
struct charAttr *list_head = NULL;
|
||||||
struct charAttr *list_temp = NULL;
|
struct charAttr *list_temp = NULL;
|
||||||
int i, revealed = 0;
|
int i, l, revealed = 0;
|
||||||
int maxRows, maxCols, curRow, curCol, origRow = 0, origCol = 0;
|
int maxRows, maxCols, curRow, curCol, origRow = 0, origCol = 0;
|
||||||
char ret = 0;
|
char ret = 0;
|
||||||
|
|
||||||
// Error if we have an empty string.
|
|
||||||
if (string == NULL || string[0] == '\0') {
|
|
||||||
fprintf(stderr, "Error. Empty string.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reassociate STDIN to the terminal if needed
|
// Reassociate STDIN to the terminal if needed
|
||||||
if (!isatty(STDIN_FILENO) && !freopen ("/dev/tty", "r", stdin)) {
|
if (!isatty(STDIN_FILENO) && !freopen ("/dev/tty", "r", stdin)) {
|
||||||
@ -108,8 +102,8 @@ char nmseffect_exec(char *string) {
|
|||||||
curCol = origCol;
|
curCol = origCol;
|
||||||
|
|
||||||
// Processing input
|
// Processing input
|
||||||
for (i = 0; string[i] != '\0'; ++i) {
|
for (i = 0; i < string_len; ++i) {
|
||||||
|
|
||||||
// Don't go beyond maxRows
|
// Don't go beyond maxRows
|
||||||
if (curRow - origRow >= maxRows - 1) {
|
if (curRow - origRow >= maxRows - 1) {
|
||||||
break;
|
break;
|
||||||
@ -125,11 +119,12 @@ char nmseffect_exec(char *string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get character's byte-length and store character.
|
// Get character's byte-length and store character.
|
||||||
if (mblen(&string[i], 4) > 0) {
|
l = mblen((char *)&string[i], 4);
|
||||||
list_pointer->source = malloc(mblen(&string[i], 4) + 1);
|
if (l > 0) {
|
||||||
strncpy(list_pointer->source, &string[i], mblen(&string[i], 4));
|
list_pointer->source = malloc(l + 1);
|
||||||
list_pointer->source[mblen(&string[i], 4)] = '\0';
|
memcpy(list_pointer->source, &string[i], l);
|
||||||
i += (mblen(&string[i], 4) - 1);
|
list_pointer->source[l] = '\0';
|
||||||
|
i += (l - 1);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown character encountered. Quitting.\n");
|
fprintf(stderr, "Unknown character encountered. Quitting.\n");
|
||||||
nmstermio_restore_terminal();
|
nmstermio_restore_terminal();
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define NMSEFFECT_H 1
|
#define NMSEFFECT_H 1
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
char nmseffect_exec(char *);
|
char nmseffect_exec(unsigned char *, int string_len);
|
||||||
void nmseffect_set_foregroundcolor(char *);
|
void nmseffect_set_foregroundcolor(char *);
|
||||||
void nmseffect_set_returnopts(char *);
|
void nmseffect_set_returnopts(char *);
|
||||||
void nmseffect_set_autodecrypt(int);
|
void nmseffect_set_autodecrypt(int);
|
||||||
|
Loading…
Reference in New Issue
Block a user