diff options
-rwxr-xr-x | .gitignore | 15 | ||||
-rw-r--r-- | bc_funcs/exit.bc | 3 | ||||
-rw-r--r-- | bc_funcs/init.bc | 3 | ||||
-rw-r--r-- | bc_funcs/lib.bc (renamed from bc_funcs/trig.bc) | 31 | ||||
-rw-r--r-- | bc_funcs/std.bc | 30 | ||||
-rwxr-xr-x | cogs/utils.py | 46 | ||||
-rw-r--r-- | utils/.clang-format | 59 | ||||
-rw-r--r-- | utils/Makefile | 30 | ||||
-rw-r--r-- | utils/math.c | 63 | ||||
-rw-r--r-- | utils/math.h | 29 |
10 files changed, 255 insertions, 54 deletions
@@ -1,9 +1,24 @@ +# Folders .vscode/ __pycache__/ downloads/ + +# Configuration files api_keys.json config.json blacklist.json runs_blacklist.json + +# Log files discord.log + +# GCC output +*.o +*.d + +# C binaries +math + +# Misc +bc_input.bc leaderboard.png diff --git a/bc_funcs/exit.bc b/bc_funcs/exit.bc new file mode 100644 index 0000000..1ac644c --- /dev/null +++ b/bc_funcs/exit.bc @@ -0,0 +1,3 @@ +# Any sort of code you want to run AFTER the users input is evaluated + +quit diff --git a/bc_funcs/init.bc b/bc_funcs/init.bc new file mode 100644 index 0000000..68785ff --- /dev/null +++ b/bc_funcs/init.bc @@ -0,0 +1,3 @@ +# Any sort of code you want to run BEFORE the users input is evaluated + +scale = 20 diff --git a/bc_funcs/trig.bc b/bc_funcs/lib.bc index 9a4fcb3..d413763 100644 --- a/bc_funcs/trig.bc +++ b/bc_funcs/lib.bc @@ -96,3 +96,34 @@ define atan(x) { ibase = b return ((m * a + r) / n) } + +define abs(x) { + if (x < 0) + x *= -1 + return x +} + +define fact(x) { + auto r, s + + if (x < 0) { + print "Error: Negative factorial\n" + return 0 + } + + /* x % 1 requires scale set to 0 */ + s = scale + scale = 0 + if (x % 1 != 0) { + print "Error: Non-integer factorial\n" + scale = s + return 0 + } + + r = 1 + for (i = 2; i <= x; i++) + r *= i + + scale = s + return r +} diff --git a/bc_funcs/std.bc b/bc_funcs/std.bc deleted file mode 100644 index e90231e..0000000 --- a/bc_funcs/std.bc +++ /dev/null @@ -1,30 +0,0 @@ -define abs(x) { - if (x < 0) - x *= -1 - return x -} - -define fact(x) { - auto r, s - - if (x < 0) { - print "Error: Negative factorial\n" - return 0 - } - - /* x % 1 requires scale set to 0 */ - s = scale - scale = 0 - if (x % 1 != 0) { - print "Error: Non-integer factorial\n" - scale = s - return 0 - } - - r = 1 - for (i = 2; i <= x; i++) - r *= i - - scale = s - return r -} diff --git a/cogs/utils.py b/cogs/utils.py index f27f14f..b1bb62f 100755 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -6,8 +6,6 @@ import os import subprocess from collections import namedtuple from datetime import timedelta -# forgot to import this and ended up looking mentally unstable -# troll literally pointed out atleast 4 things I did wrong in 3 lines of code from random import choice, randint import discord @@ -33,25 +31,6 @@ from pytz import exceptions, timezone # driver.set_window_size(*window_size) -async def bc_calc(ctx, eqn: str): - try: - # Allow for proper absolute value notation - pipes = eqn.count("|") - eqn = eqn.replace("|", "abs(", pipes // 2).replace("|", ")", pipes // 2) - - with open("temp.txt", "w") as f: - f.write(eqn) - result = subprocess.check_output( - f'echo "scale=20; $(cat temp.txt)" | bc bc_funcs/*', shell=True - ) - os.remove("temp.txt") - - await ctx.send(result.decode("utf-8").replace("\\\n", "").strip()) - except subprocess.CalledProcessError as err: - print(err) - await ctx.send("Something went wrong") - - async def reportStuff(self, ctx, message): channel = self.bot.get_channel( int(self.bot.config[str(ctx.message.guild.id)]["report_channel"]) @@ -272,7 +251,14 @@ class Utils(commands.Cog): badWords = ("fair", "ⓕⓐⓘⓡ") count = 0 year = datetime.date.today().year - CoolKids = namedtuple("CoolKid", ["name", "user", "bday",]) + CoolKids = namedtuple( + "CoolKid", + [ + "name", + "user", + "bday", + ], + ) coolKids = ( CoolKids( @@ -570,8 +556,20 @@ class Utils(commands.Cog): @commands.command(aliases=["calc"]) async def math(self, ctx, *, eqn: str): - # 10 second timeout - await asyncio.wait_for(bc_calc(ctx, eqn), 10) + try: + # Allow for proper absolute value notation + pipes = eqn.count("|") + eqn = eqn.replace("|", "abs(", pipes // 2).replace("|", ")", pipes // 2) + + with open("bc_input.bc", "w") as f: + f.write(eqn) + result = subprocess.check_output("utils/math", shell=True) + os.remove("bc_input.bc") + + await ctx.send(result.decode("utf-8").replace("\\\n", "").strip()) + except subprocess.CalledProcessError as err: + print(err) + await ctx.send("Something went wrong") @commands.command() async def retime(self, ctx, start_sec, end_sec, frames=0, framerate=30): diff --git a/utils/.clang-format b/utils/.clang-format new file mode 100644 index 0000000..0be45fa --- /dev/null +++ b/utils/.clang-format @@ -0,0 +1,59 @@ +Language: Cpp + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveBitFields: true +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: true +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: WebKit +BreakBeforeTernaryOperators: true +BreakStringLiterals: true +ColumnLimit: 80 +ContinuationIndentWidth: 4 +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat: false +IncludeBlocks: Preserve +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: Indent +IndentGotoLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 2 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseCRLF: false +UseTab: Never diff --git a/utils/Makefile b/utils/Makefile new file mode 100644 index 0000000..bfd55de --- /dev/null +++ b/utils/Makefile @@ -0,0 +1,30 @@ +target := math +objs := math.o + +CC := gcc +CFLAGS := -O3 -std=c99 -pedantic -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wno-unused-result + +all: $(target) + +### +# Automatic dependency tracking +# +deps := $(patsubst %.o,%.d,$(objs)) +-include $(deps) +DEPFLAGS = -MMD -MF $(@:.o=.d) + +### +# Compile the program +# +$(target): $(objs) + $(CC) $(CFLAGS) -o $@ $^ + +%.o: src/%.c + $(CC) $(CFLAGS) -c $< $(DEPFLAGS) + +### +# Phony targets +# +.PHONY: clean +clean: + rm -f $(target) $(objs) $(deps) diff --git a/utils/math.c b/utils/math.c new file mode 100644 index 0000000..25ae645 --- /dev/null +++ b/utils/math.c @@ -0,0 +1,63 @@ +/* + * This is a simple program that calls BC and terminates it if it takes longer + * than five seconds to complete. There is no real reason for this to be done + * in C instead of Python, however there are some key advantages: + * + * - Mango gets to play with C making him happy + * - C is compiled instead of interpreted so this is technically more efficient + * - Ok mayyyybe is slower because it uses a seperate process? + * - It makes us look smarter? + */ +#define _POSIX_SOURCE +#include <signal.h> +#include <stdbool.h> +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +#include "math.h" + +bool timeout = false, child_done = false; + +void timeout_hander(int UNUSED(sig)) +{ + timeout = true; +} + +void child_handler(int UNUSED(sig)) +{ + child_done = true; +} + +int main(void) +{ + pid_t pid = fork(); + switch (pid) { + case 0: + execl("/bin/bc", "", "-q", "bc_funcs/lib.bc", "bc_funcs/init.bc", + FILE_NAME, "bc_funcs/exit.bc", NULL); + fallthrough; + case -1: + perror("calc"); + return EXIT_FAILURE; + default: + /* Setup signal handlers after fork so the child doesnt inherit them */ + signal(SIGALRM, timeout_hander); + signal(SIGCHLD, child_handler); + alarm(TIMEOUT); + pause(); + + /* + * Wait for either the child process to terminate, or for 5 seconds to + * have passed + */ + if (timeout) { + puts("Error: 5 second timeout reached"); + kill(pid, 9); + } + + break; + } + + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/utils/math.h b/utils/math.h new file mode 100644 index 0000000..edfb9ee --- /dev/null +++ b/utils/math.h @@ -0,0 +1,29 @@ +#ifndef __MATH_H_ +#define __MATH_H_ + +/* Suppress unused parameter warnings */ +#ifdef __GNUC__ +# define UNUSED(x) UNUSED_##x __attribute__((__unused__)) +#else +# define UNUSED(x) UNUSED_##x +#endif + +/* Fallthrough pseudo-keyword macro */ +#if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +#else +# define fallthrough \ + do { \ + } while (0) /* fallthrough */ +#endif + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 +#define FILE_NAME "bc_input.bc" +#define TIMEOUT 5 + +/* Signal handlers */ +void timeout_hander(int sig); +void child_handler(int sig); + +#endif
\ No newline at end of file |