6 Commits
v2.1 ... v3.1

Author SHA1 Message Date
529ac333ea make sure compile_commands.json doesn't end up in the repo 2025-02-27 12:45:48 -06:00
50aa5f157f typo :( 2025-02-27 12:45:40 -06:00
8f20a84ef7 bump version 2025-02-18 14:58:24 -06:00
09362e2c7c replace atoi with my own impl to make sure that no errors occour 2025-02-18 14:48:32 -06:00
6025b2d832 Add -e flag to explain what the previous smiley face means. This
requires us to also know what the previous return signal is, so
if XD is given a return code, it passes it through when finishing
execution.
2025-02-18 14:32:40 -06:00
6c099e3648 update man page to reflect passing in return codes 2024-12-22 13:01:45 -05:00
5 changed files with 144 additions and 12 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.o
XD
compile_commands.json

View File

@ -2,7 +2,7 @@ include config.mk
# flags and incs
PKGS = $(GITLIB)
CFLAGS = -DVERSION=\"$(VERSION)\" -Wall -pedantic -O3 $(GIT) $(ERR)
CFLAGS = -DVERSION=\"$(VERSION)\" -Wall -pedantic -O3 $(GIT) $(ERR) $(EXPLAIN)
LIBS = `$(PKG_CONFIG) --libs --cflags $(PKGS)`
all: XD

49
XD.1
View File

@ -1,4 +1,4 @@
.Dd December 19, 2024
.Dd Febuary 18, 2025
.Dt XD 1
.Sh NAME
.Nm XD
@ -7,10 +7,16 @@
.Sh SYNOPSIS
.Nm
.Op Fl v
.Op Fl e
.Op number
.Sh DESCRIPTION
.Nm
Displays information using a smiley face like so: :)
to interpret it refer to the following tables:
Displays information using a smiley face.
to interpret XD's output refer to the following tables (or
.Nm
\fB-e\fR):
.Ss Eyes
.TS
tab(;) allbox;
@ -40,3 +46,44 @@ c;l.
/;command not found
(;previous signal is failure
.TE
.Ss Exit Status:
.Nm
returns the number that was passed in to allow the user to re-run the program
and get the same results. If there's an internal error
.Nm
returns 1. If you wish to find out more infomation about the error enable ERR
in the config.mk.
.Sh OPTIONS
.Ss -v
Print version information to stdout and exit.
.Ss -e
Explain the output instead of putting a smiley face.
.Sh EXAMPLES
Running
.Nm
and passing in the previous return code ($?) results in a smiley face, if you
then follow that by \fBXD -e $?\fR then you will get an explination of what the
face is explaining.
$ \fBXD $?\fR
.br
:)
.br
$ \fBXD -e $?\fR
.br
Not in a git repository.
.br
Return code of 0, no errors.
$ \fBXD $?\fR
.br
;*O
.br
$ \fBXD -e $?\fR
.br
In a git repository.
.br
The're staged changes.
.br
Return code of 130, ctrl-c was pressed, or SIGTERM sent.

93
XD.c
View File

@ -1,7 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef ERR
#include <ctype.h>
#if defined(ERR) || defined(EXPLAIN)
#include <stdarg.h>
#endif
@ -13,7 +15,7 @@
#define P(X) fwrite(X, 1, 1, stdout)
#ifdef ERR
#if defined(ERR) || defined(EXPLAIN)
void
l(const char *fmt, ...)
{
@ -30,11 +32,23 @@ l(const char *fmt, ...)
fputc('\n', stderr);
}
}
#endif
#ifdef ERR
#define L(...) l(__VA_ARGS__)
#else
#define L(...)
#endif
#ifdef EXPLAIN
static int explain = 0;
#define E(...) if (explain) { \
l(__VA_ARGS__); \
} else
#else
#define E(...)
#endif
#ifdef GIT
/**
* @brief search all parent directories for a git repo
@ -216,6 +230,34 @@ has_staged(git_repository *repo)
}
#endif
inline unsigned
numcat(unsigned x, unsigned y)
{
unsigned pow = 10;
while(y >= pow) {
pow *= 10;
}
return (x * pow) + y;
}
int
str_to_int(char *str)
{
int res = -1;
char *c;
for (c = str; (*c != '\0') && isdigit(*c); c++) {
if (res == -1) {
res = *c - '0';
} else {
res = numcat(res, *c - '0');
}
}
return res;
}
int
main(int argc, char *argv[])
{
@ -225,6 +267,10 @@ main(int argc, char *argv[])
if (argc > 1 && strcmp(argv[1], "-v") == 0) {
printf("XD [number] v%s\n", VERSION);
return 0;
#ifdef EXPLAIN
} else if (argc > 1 && strcmp(argv[1], "-e") == 0) {
explain = 1;
#endif
}
#ifdef GIT
@ -233,19 +279,25 @@ main(int argc, char *argv[])
if ((repo = init_git())) {
/* change the eyes depending on the current git repo's status */
if (has_stashes(repo)) {
E("The current git repo has stashed changes.")
P("8"); /* goggle eyes if we have some stashed changes */
} else if (git_repository_is_empty(repo)) {
E("This is a new git repo.")
P("B"); /* sunglasses if we're in a new repo with no HEAD */
} else {
E("In a git repository.")
P(";"); /* wink when we're in a git repo */
}
/* change the nose depending on the current git repo's status */
if (has_staged(repo)) {
E("They're staged changes.")
P("*"); /* change to broken nose for staged changes */
} else if (has_untracked(repo)) {
E("There are untracked changes in the repository.")
P("^"); /* add a little nose when there are untracked changes in the repo */
} else if (git_repository_head_detached(repo)) {
E("The HEAD is detached.")
P("-"); /* add a minus nose when the HEAD is detached */
}
git_repository_free(repo);
@ -253,24 +305,47 @@ main(int argc, char *argv[])
} else
#endif
if (1) {
E("Not in a git repository.")
P(":");
}
/* get exit code from user args */
if (argv[1]) {
code = atoi(argv[1]);
if (argc > 1 && argv[argc - 1]) {
code = str_to_int(argv[argc - 1]);
if (code < 0) {
L("Return code, %d, not valid", code);
exit(1);
}
}
/* change mouth based on exit code */
if (code >= 0) {
switch (code) {
case 0: P(")"); break; /* all good */
case 130: P("O"); break; /* Ctrl-c pressed (SIGTERM) */
case 126: P("P"); break; /* permission denied */
case 127: P("/"); break; /* command not found */
default: P("("); break; /* all other codes (usually the program saying it has failed) */
case 0: /* all good */
E("Return code of %d, no errors.", code)
P(")");
break;
case 130: /* Ctrl-c pressed (SIGTERM) */
E("Return code of %d, ctrl-c was pressed, or SIGTERM sent.", code)
P("O");
break;
case 126: /* permission denied */
E("Return code of %d, permission denied.", code)
P("P");
break;
case 127: /* command not found */
E("Return code of %d, command not found.", code)
P("/");
break;
default: /* all other codes (usually the program saying it has failed) */
E("Return code of %d, probably an error with the program.", code)
P("(");
break;
}
} else {
E("No code information passed in.")
P("|"); /* no code info */
}
return code;
}

View File

@ -1,4 +1,4 @@
VERSION = 2.0
VERSION = 3.0
PKG_CONFIG = pkg-config
@ -16,6 +16,10 @@ ERR =
# uncomment to enable errors
# ERR = -DERR
EXPLAIN =
# comment to disable explinations
EXPLAIN = -DEXPLAIN
# add compilation details to VERSION variable
ifneq ($(GIT),)
VERSION := $(VERSION)"\\nlibgit2 "`$(PKG_CONFIG) --modversion $(GITLIB)`
@ -25,5 +29,10 @@ ifeq ($(ERR),)
else
VERSION := $(VERSION)"\\nerrors enabled"
endif
ifeq ($(EXPLAIN),)
VERSION := $(VERSION)"\\nexplinations disabled"
else
VERSION := $(VERSION)"\\nexplinations enabled"
endif
CC = cc