From 62c15ab976d69a71c2081f0eb06153276b574c38 Mon Sep 17 00:00:00 2001 From: Stephen Toth Date: Sat, 30 Sep 2023 12:26:00 -0400 Subject: [PATCH] Regex works now added branding in a seperate file and a config.h replace_rules count in branding does not work as of now way better replace functions that actually work --- .gitignore | 3 +- .vscode/c_cpp_properties.json | 3 +- .vscode/launch.json | 34 ----- .vscode/tasks.json | 17 +-- Makefile | 9 +- build/.gitkeep | 1 - include/branding.h | 11 ++ include/config.h | 40 ++++++ include/debug.h | 14 +- include/linework.h | 12 ++ include/notmine.h | 2 + include/structdef.h | 11 ++ make/genbuildno.sh | 3 + src/branding.c | 60 ++++++++ src/linework.c | 161 ++++++++++++++++++++++ src/main.c | 253 +++++++++++++++++----------------- src/notmine.c | 53 ++++++- testing/alpineA | 0 18 files changed, 505 insertions(+), 182 deletions(-) delete mode 100644 .vscode/launch.json create mode 100644 include/branding.h create mode 100644 include/config.h create mode 100644 include/linework.h create mode 100755 make/genbuildno.sh create mode 100644 src/branding.c create mode 100644 src/linework.c create mode 100644 testing/alpineA diff --git a/.gitignore b/.gitignore index ff87054..6f3ba1d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,8 @@ bin/* # Ignore temp editor files *.swp +*.tmp -.vscode +.vscode/* !.gitkeep \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 771b8a4..86310d8 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,8 +3,7 @@ { "name": "Linux", "includePath": [ - "${workspaceFolder}/**", - "${workspaceFolder}/include" + "${workspaceFolder}/**" ], "defines": [], "compilerPath": "/bin/gcc", diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index ccd4bcc..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "(gdb) Attach", - "type": "cppdbg", - "request": "attach", - "program": "${workspaceFolder}/bin/cterm", - "MIMode": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - }, - { - "description": "Set Disassembly Flavor to Intel", - "text": "-gdb-set disassembly-flavor intel", - "ignoreFailures": true - } - ] - }, - { - "name": "colorwrap", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/bin/cterm", - "args": ["/bin/sh"], - "cwd": "${workspaceFolder}/" - }] -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 63b0ad0..d915286 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,20 +1,5 @@ { "tasks": [ - { - "type": "cppbuild", - "label": "Make Build", - "command": "make", - "args": [ - "--directory=${workspaceFolder}" - ], - "options": { - "cwd": "${workspaceFolder}" - }, - "group": { - "kind": "build", - "isDefault": true - } - }, { "type": "cppbuild", "label": "C/C++: gcc build active file", @@ -34,7 +19,7 @@ ], "group": { "kind": "build", - "isDefault": false + "isDefault": true }, "detail": "Task generated by Debugger." } diff --git a/Makefile b/Makefile index aac47d2..4fc6a34 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,10 @@ CFLAGS := -lreadline LIB := -L lib -lutil -lreadline INC := -I include + $(TARGET): $(OBJECTS) + @echo " Incrementing Build #"; make/genbuildno.sh + @echo "Build number: $(shell grep BUILD include/config.h | cut -d' ' -f 3)" @echo " Linking..." @echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB) -O3 @echo " Done!" @@ -23,9 +26,11 @@ $(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT) clean: @echo " Cleaning..."; @echo " cat /dev/null > $(TESTDIR)/trace.lp"; cat /dev/null > $(TESTDIR)/trace.lp; - @echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET) + @echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR)/* $(TARGET); -debug: CFLAGS += -ggdb -O0 -Wall -Wextra -pedantic -D"DEBUG=1" +#debug: clean +debug: CFLAGS += -ggdb -O0 -Wall -Wextra -pedantic -Wno-unused-variable -Wno-unused-parameter +debug: CFLAGS += -D"DEBUG=1" -DGITBRANCH=\"$(shell git branch --show-current)\" debug: $(TARGET) test: diff --git a/build/.gitkeep b/build/.gitkeep index 9c558e3..e69de29 100644 --- a/build/.gitkeep +++ b/build/.gitkeep @@ -1 +0,0 @@ -. diff --git a/include/branding.h b/include/branding.h new file mode 100644 index 0000000..b48ce52 --- /dev/null +++ b/include/branding.h @@ -0,0 +1,11 @@ +#ifndef _BRANDING_H +#define _BRANDING_H + +#if !defined(GITBRANCH) + #define GITBRANCH "" +#endif + +void printbranding(); + + +#endif \ No newline at end of file diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..a196aad --- /dev/null +++ b/include/config.h @@ -0,0 +1,40 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +// Project global information +#define PROJECT_NAME "cterm" +#define VERSION_MAJOR 0 +#define VERSION_MINOR 2 +#define VERSION_HOTFIX 0 +#define VERSION_BUILD 350 + +//#define DEFAULT_CMD "/bin/sh" +#define CONF_DO_CMD_ACK 1 + +#define DEBG_DO_EOL_MARK 1 + //EOLMARK defined in parsebuffer() + + +// Color codes +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" +#define KGRN "\x1B[32m" +#define KYEL "\x1B[33m" +#define KBLU "\x1B[34m" +#define KMAG "\x1B[35m" +#define KCYN "\x1B[36m" +#define KWHT "\x1B[37m" +#define BKRED "\x1B[41m" +#define BKGRN "\x1B[42m" +#define BKYEL "\x1B[43m" +#define BKBLU "\x1B[44m" +#define BKMAG "\x1B[45m" +#define BKCYN "\x1B[46m" +#define BKWHT "\x1B[47m" + +//child stdout read buffer size +#define BUFCHUNKSIZE 4096 +#define BUFSAFEPAD 8 //shut it, ik its useless + + +#endif \ No newline at end of file diff --git a/include/debug.h b/include/debug.h index fef4c9a..0564f41 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,8 +1,17 @@ #ifndef _DEBUG_H #define _DEBUG_H +#include + + #if defined(DEBUG) && DEBUG > 0 - #define DEBUG_PRINT(fmt, ...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \ + #define _DEBUG_H_DRED "\x1B[31m" + #define _DEBUG_H_DNRM "\x1B[0m" + #define DEBUG_PRINT(fmt, ...) fprintf(stderr, "[-] %s:%d:%s(): " fmt, \ + __FILE__, __LINE__, __func__, ##__VA_ARGS__) + #define DDEBUG_PRINT(fmt, ...) fprintf(stderr, "[_] %s:%d:%s(): " fmt, \ + __FILE__, __LINE__, __func__, ##__VA_ARGS__) + #define DEBUG_ERROR(fmt, ...) fprintf(stderr, "\n"_DEBUG_H_DRED"[!]"_DEBUG_H_DNRM" %s:%d:%s(): E.%d " fmt, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define COLORTEST() fprintf(stderr, "Color Palate:\n" \ KRED"KRED"KGRN"KGRN"KYEL"KYEL"KBLU"KBLU"KMAG"KMAG"KCYN"KCYN"KWHT"KWHT"KNRM"\n" \ @@ -11,7 +20,10 @@ BKRED"KRED"BKGRN"KGRN"BKYEL"KYEL"BKBLU"KBLU"BKMAG"KMAG"BKCYN"KCYN"BKWHT"KWHT"KNRM"\n" ) #else #define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */ + #define DDEBUG_PRINT(fmt, args...) + #define DEBUG_ERROR(fmt, args...) #define COLORTEST() #endif + #endif \ No newline at end of file diff --git a/include/linework.h b/include/linework.h new file mode 100644 index 0000000..75e9874 --- /dev/null +++ b/include/linework.h @@ -0,0 +1,12 @@ +#ifndef _LINEWORK_H +#define _LINEWORK_H + +#include +#include + + +int line_regex_replace(ct_line *line, regex_t *regex, int replace_group, char *with, int max_instances); + +int line_regex_wrap_match(ct_line *line, regex_t *regex, int target_capture_group, char *left, char *right, int max_instances); + +#endif \ No newline at end of file diff --git a/include/notmine.h b/include/notmine.h index 41b25c5..d70666e 100644 --- a/include/notmine.h +++ b/include/notmine.h @@ -4,5 +4,7 @@ // You must free the result if result is non-NULL. char *str_replace(char *orig, char *rep, char *with); +//char *str_index_replace(char *orig, int rep_s, int rep_e, char *with); + #endif \ No newline at end of file diff --git a/include/structdef.h b/include/structdef.h index ccd7494..4ee5d8e 100644 --- a/include/structdef.h +++ b/include/structdef.h @@ -1,5 +1,16 @@ #ifndef _STRUCTDEF_H #define _STRUCTDEF_H +typedef struct { + char* match_regex; + int match_cflags; + int replace_group; //if no regex groups (()), should be 0 + char* replace_with; +} ct_match; + +typedef struct { + char* line_str; //pointer to first char in string + int need_free; //tracks if buffer is on the stack or in heap +} ct_line; #endif \ No newline at end of file diff --git a/make/genbuildno.sh b/make/genbuildno.sh new file mode 100755 index 0000000..adbb6a9 --- /dev/null +++ b/make/genbuildno.sh @@ -0,0 +1,3 @@ +#!/bin/sh +sed -i "s/BUILD .*/BUILD $(($(grep BUILD include/config.h | cut -d' ' -f3) + 1 ))/g" include/config.h + diff --git a/src/branding.c b/src/branding.c new file mode 100644 index 0000000..b140ea2 --- /dev/null +++ b/src/branding.c @@ -0,0 +1,60 @@ +#include +#include +#include + +#include +#include + +// c macros to clean up lines later +#define b_lenofarr(axx) (sizeof(axx)/sizeof(axx[0])) +#define b_roundup(x) ((x)+1) & ~1 + +void printbranding(){ + //compile change config + int min_content_padding = 4; + char *box_pad_char = "----------"; // this is repeated to be in the horrror later; printf ugh; + int box_top_width = 3; // --- text --- + int box_side_width = 2; // -- text -- + + + char pre_print_lines[10][100] = {0}; //these are not end-user affectable so 100 chars should be fine for now. + + sprintf(pre_print_lines[0], "%s v%d.%d.%d" , PROJECT_NAME, VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); + //sprintf(pre_print_lines[0], "%s v%d.%d.%d.%d" , PROJECT_NAME, VERSION_MAJOR, VERSION_MINOR, VERSION_HOTFIX, VERSION_BUILD); + sprintf(pre_print_lines[1], "(c) never"); + sprintf(pre_print_lines[2], "%d rules loaded", 9); //TODO: actually use the number of rules loaded + if (GITBRANCH) sprintf(pre_print_lines[3], "%s", GITBRANCH); + + + + int max_used_line_length = 0; + int used_lines = 0; //the number of lines actually used above + for (int i = b_lenofarr(pre_print_lines)-1; i >= 0; i-- ){ //reverse loop from 9->0 + if (pre_print_lines[i][0] == 0) continue; //not set, dont care + used_lines++; + int line_length = strlen(pre_print_lines[i]); + if (line_length > max_used_line_length) max_used_line_length = b_roundup(line_length); + + if (line_length % 2 != 0) { //also going to use this (convienent) loop to pad the end of odd number length strings + pre_print_lines[i][line_length]=' '; + pre_print_lines[i][line_length+1]='\0'; //bad for user defined strings, but not in this case since its not + } + } + //DDEBUG_PRINT("max_used_line_length=%d; used_lines=%d\n", max_used_line_length, used_lines); + + int output_line_length = b_roundup(max_used_line_length+min_content_padding*2+box_top_width); + //DDEBUG_PRINT("output_line_length=%d\n", output_line_length); + + for (int i = 0; i +#include +#include + +#include +#include +#include + + +char *str_index_replace(const char *orig, const char *with, const int start_index, const int end_index){ + //no error checking on the args + //will always call malloc + char *result; + char *tmp; //temporary pointer for replace process later + int len_with = strlen(with); //doesnt change with loop repetitions + int len_replace = end_index - start_index; + int len_delta = len_with - len_replace; //how many chars are we changing the buffer by? + + result = tmp = malloc(strlen(orig) + len_delta + 1); + if (!result) return NULL; + + int len_front = start_index; + tmp = strncpy(tmp, orig, len_front) + len_front; //fill front end of buffer with already processed stuff + tmp = strcpy(tmp, with) + len_with; + strcpy(tmp, (orig + len_front + len_replace)); //writes the nice good \0 at the end + /* reference: 0___1___2______4 + * fL...B + * result: 0___1-----2_______4 + * fL.....B + */ + return result; +} + + + + + +/// @brief +/// You could probably break this function if you really wanted to. fortunately, the regex is done at start time, not dynamically; yet :'( +/// @param line mutates +/// @param regex compiled regex +/// @param target_capture_group int of the capture group to replace. 0=everything +/// @param with +/// @param max_instances 0=all instances +/// @return 0 if no match; 1 if match and replace; -1 for error +int line_regex_replace(ct_line *line, regex_t *regex, int target_capture_group, char *with, int max_instances){ + //TODO: logic for max_instances being 0 + + if (target_capture_group > (int)regex->re_nsub){ + DEBUG_ERROR("[target_capture_group bigger than number of subexpressions in regex]\n", 26); + return -1; + } + //TODO: more failure conditions + + /* References: + * https://www.gnu.org/software/libc/manual/html_node/Matching-POSIX-Regexps.html + * https://www.ibm.com/docs/en/i/7.2?topic=functions-regexec-execute-compiled-regular-expression + */ + int num_instances = 0; + size_t nmatch = target_capture_group+1; //number of capture groups we care about + regmatch_t pmatch[nmatch+1]; //0=everything, else is capture groups +1 for "safety" + char *search_start_point = line->line_str; + + int match_result = regexec(regex, search_start_point, nmatch, pmatch, 0); + if (match_result==REG_NOMATCH) return 0; + //DEBUG_PRINT("fresh:%s\n", line->line_str); + + do { + num_instances++; + if (pmatch[target_capture_group].rm_so == -1) { DEBUG_ERROR("[Subexpression did not participate in an otherwise successful match]\n", 40); continue; } + if (pmatch[target_capture_group].rm_eo < pmatch[target_capture_group].rm_so) { DEBUG_ERROR("[End offset < Start Offset] wtf???? now how did you manage that?\n", 41); continue; } + + int front_delta = (search_start_point - line->line_str); //how far are we into the string? + int start_index = pmatch[target_capture_group].rm_so + front_delta; //normalize indicies to be from real start + int end_index = pmatch[target_capture_group].rm_eo + front_delta; + //with + + + //do the replace + char *result = str_index_replace(line->line_str, with, start_index, end_index); //nice good pointer to the new and improved string + if (!result) { + DEBUG_ERROR("[replace error] idk\n", 85); + return -1; + } + + + //clean up previous line memory and sub in the new pointer + if(line->need_free) free(line->line_str); + line->line_str = result; + line->need_free = 1; + + search_start_point = line->line_str + start_index + strlen(with); //its *back but recalculated for the new string + //DEBUG_PRINT("new set:%s\n", line->line_str); + //DEBUG_PRINT("new search space:%s\n", search_start_point); + match_result = regexec(regex, search_start_point, nmatch, pmatch, REG_NOTBOL); + } while(match_result==0 && num_instances<=max_instances); + + return 1; +} + + + + +int line_regex_wrap_match(ct_line *line, regex_t *regex, int target_capture_group, char *left, char *right, int max_instances){ + //TODO: logic for max_instances being 0 + if (target_capture_group > (int)regex->re_nsub){ + DEBUG_ERROR("[target_capture_group bigger than number of subexpressions in regex] MAYBE: fallback?\n", 26); + return -1; + } + //TODO: more failure conditions + + /* References: + * https://www.gnu.org/software/libc/manual/html_node/Matching-POSIX-Regexps.html + * https://www.ibm.com/docs/en/i/7.2?topic=functions-regexec-execute-compiled-regular-expression + */ + int num_instances = 0; + size_t nmatch = target_capture_group+1; //number of capture groups we care about + regmatch_t pmatch[nmatch+1]; //0=everything, else is capture groups +1 for "safety" + char *search_start_point = line->line_str; + + int match_result = regexec(regex, search_start_point, nmatch, pmatch, 0); + if (match_result==REG_NOMATCH) return 0; + + do { + num_instances++; + if (pmatch[target_capture_group].rm_so == -1) { DEBUG_ERROR("[Subexpression did not participate in an otherwise successful match]\n", 40); continue; } + if (pmatch[target_capture_group].rm_eo < pmatch[target_capture_group].rm_so) { DEBUG_ERROR("[End offset < Start Offset] wtf???? now how did you manage that?\n", 41); continue; } + + char *match_start = search_start_point + pmatch[target_capture_group].rm_so; + int len_match = pmatch[target_capture_group].rm_eo - pmatch[target_capture_group].rm_so; + int len_wrap = strlen(left) + strlen(right); + char with[len_match + len_wrap + 1]; + strcpy(with, left); + strncat(with, match_start, len_match); + strcat(with, right); + + int front_delta = (search_start_point - line->line_str); //how far are we into the string? + int start_index = pmatch[target_capture_group].rm_so + front_delta; //normalize indicies to be from real start + int end_index = pmatch[target_capture_group].rm_eo + front_delta; + + //do the replace + char *result = str_index_replace(line->line_str, with, start_index, end_index); //nice good pointer to the new and improved string + if (!result) { + DEBUG_ERROR("[replace error] idk\n", 85); + return -1; + } + + + //clean up previous line memory and sub in the new pointer + if(line->need_free) free(line->line_str); + line->line_str = result; + line->need_free = 1; + + search_start_point = line->line_str + start_index + strlen(with); //its *back but recalculated for the new string + //DEBUG_PRINT("new set:%s\n", line->line_str); + //DEBUG_PRINT("new search space:%s\n", search_start_point); + match_result = regexec(regex, search_start_point, nmatch, pmatch, REG_NOTBOL); + } while(match_result==0 && num_instances<=max_instances); + + return 1; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7aeb3ea..310a28a 100644 --- a/src/main.c +++ b/src/main.c @@ -10,158 +10,165 @@ #include #include //#include +//regex branch init +#include + // Custom debug include for some debug macros and functions +#include #include +#include +#include +#include #include -#define VERSIONSTRING "0.2" -#define BUFCHUNKSIZE 4096 -#define BUFSAFEPAD 8 -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KYEL "\x1B[33m" -#define KBLU "\x1B[34m" -#define KMAG "\x1B[35m" -#define KCYN "\x1B[36m" -#define KWHT "\x1B[37m" -#define BKRED "\x1B[41m" -#define BKGRN "\x1B[42m" -#define BKYEL "\x1B[43m" -#define BKBLU "\x1B[44m" -#define BKMAG "\x1B[45m" -#define BKCYN "\x1B[46m" -#define BKWHT "\x1B[47m" - //temporary -char *replace_rules[][2] = { - { "r--", KGRN"r--"KNRM }, - { "rw-", KRED"rw-"KNRM }, - { "alpine", KMAG"alpine"KNRM }, - { " ..$", KBLU" .."KNRM"$" }, - { " .$", KBLU" ."KNRM"$" }, - { "^d", "^"KMAG"d"KNRM }, - { "z9Da0Da1", KRED"z9Da0Da1"KNRM }, +ct_match replace_rules[]= { + { "alpine", 0, 0, KMAG"alpine"KNRM }, + { "r--", 0, 0, KGRN"r--"KNRM }, + { "rw-", 0, 0, KRED"rw-"KNRM }, + { " ..$", 0, 0, KBLU" .."KNRM }, + { " .$", 0, 0, KBLU" ."KNRM }, + { "^d", 0, 0, KMAG"d"KNRM }, + { "z9Da0Da1", 0, 0, KRED"z9Da0Da1"KNRM }, }; char ps1[] = KGRN"~>"KNRM; char ps1_ack[] = KBLU"1~"KNRM; + + +ct_line processline(ct_line current_line){ + + int rules_length = (sizeof(replace_rules)/sizeof(replace_rules[0])); + + for (int i=0; i 0) { + parsebuffer(child_out_roll_buffer, read_size, read_loop_no); + read_loop_no++; + continue; + } + if (read_size == -1 && errno == EAGAIN) break; //read would block (no more data and buffer contents are already processed) + //fallthrough read_size == 0 + DEBUG_PRINT("read_size=0: EOF\n"); + printf("Reached EOF. child exit? exiting...\n"); + exit(0); + } + //read stdin + //send to child + memset(parent_in_buffer, 0, BUFCHUNKSIZE); + strncpy(parent_in_buffer, readline(ps1), BUFCHUNKSIZE-1); + write(master_fd, parent_in_buffer, strlen(parent_in_buffer)); + write(master_fd, "\n", 1); + + usleep(100*1000); + } + + free(child_out_roll_buffer); + free(parent_in_buffer); +} + + + + void child_process(char *argv[]){ execl(argv[1], argv[1], NULL); } -void processline(const char *line, int first_line){ - size_t line_length = strlen(line); - char copyline[line_length+3]; - copyline[0] = '^'; - strncpy(©line[1], line, line_length); //yes, I know this is "jank" its fine tho. (see next) - // 1. line *should* always be NULL terminated - // 2. line is ALWAYS < 4097 - copyline[line_length+1] = '$'; - copyline[line_length+2] = '\0'; - //strncat(copyline, "$", 2); - char *newline = (char *)©line; - char endstring[] = KNRM"\n"; - //if (first_line) newline = str_replace(newline, "^", "^User Input: "); - if (first_line) write(STDOUT_FILENO, ps1_ack, strlen(ps1_ack)); - for(unsigned int i = 0; i<(sizeof(replace_rules)/sizeof(replace_rules[0])); i++){ - newline = str_replace(newline, replace_rules[i][0], replace_rules[i][1]); - //write(STDOUT_FILENO, debugstring, strlen(debugstring)); - if (newline == NULL) { - newline = copyline; - } - } - write(STDOUT_FILENO, newline+1, strlen(newline)-2); - if (newline != NULL) free(newline); - write(STDOUT_FILENO, endstring, strlen(endstring)); -} - - -void processbuffer(char *roll_buffer, size_t read_length, int first_read) { - //this is where some optimization could come in with using malloc and then freeing subset of memory; dog garn dynamic memory allocation - //int found_index; - char *found_char = strtok(roll_buffer, "\r\n"); - int first_line = 1; - while(found_char != NULL){ - processline(found_char, first_line&&first_read); - first_line = 0; - found_char = strtok(NULL, "\r\n"); - } - //no more instances -} int main(int argc, char *argv[]) { - printf(" --- cterm v%s ---\n" , VERSIONSTRING); - printf(" -- %d replace rules loaded --\n", (int *)(sizeof(replace_rules)/sizeof(replace_rules[0]))); - printf(" --- ---\n"); - printf("\n"); - COLORTEST(); - int master; - pid_t child_pid; - //struct winsize win = { - // .ws_col = 80, .ws_row = 24, - // .ws_xpixel = 480, .ws_ypixel = 192, - //}; + printbranding(); + COLORTEST(); //macro for testing + // sanity checking if (argc < 2) { printf("Usage: %s cmd [args...]\n", argv[0]); exit(EX_USAGE); } - child_pid = forkpty(&master, NULL, NULL, NULL); - if (child_pid == -1) { + + + int master_fd; + pid_t child_pid; + //if the pty window size is to be assigned. shoudnt be a concern since only used by tui programs + /*struct winsize win = { + .ws_col = 80, .ws_row = 24, + .ws_xpixel = 480, .ws_ypixel = 192, + };*/ + + + child_pid = forkpty(&master_fd, NULL, NULL, NULL); + //TODO: Better error checking + if (child_pid == -3) { perror("forkpty failed"); exit(EX_OSERR); } + if (child_pid == 0) { child_process(argv); exit(0); } - //remainder is main is the parent process for processing input and shit - fcntl(master, F_SETFL, O_NONBLOCK); - char *child_out_roll_buffer = (char*) malloc(sizeof(char) * (BUFCHUNKSIZE+BUFSAFEPAD+1)); - char *parent_in_buffer = (char*) malloc(sizeof(char) * (BUFCHUNKSIZE+BUFSAFEPAD+1)); - - usleep(300*1000); //wait for child shell to init; bad practice, but it works for now - while(1){ - // ideally I would want to read from the pipe and buffer the output, rewriting the line on change - // whenever it sees a newline, it should send it to the processor and print to stdout, with that newline - //CHILD OUTPUT HANDLING - // treating the buffer as kind of a FIFO stack thing - // strip lines from top and then move leftover to top, - // then start reading where we left off - // Later on: it kinda has that behavior, I cant confirm rn, but it "works" - int first_read = 1; - while(1){ - memset(child_out_roll_buffer, 0, BUFCHUNKSIZE+BUFSAFEPAD); - ssize_t read_count = read(master, &child_out_roll_buffer[0], BUFCHUNKSIZE - 0); - if (read_count == 0 ) { - DEBUG_PRINT("EOF\n"); - exit(0); - } - if (read_count == -1){ - if(errno == EAGAIN){ //errored because read would block io - break; - } else { - DEBUG_PRINT("I/O \"Error\" (Child Exited?) %d\n", errno); - exit(0); - } - } - //process da block then write it - processbuffer(child_out_roll_buffer, read_count, first_read); - first_read = 0; - } - - //INPUT HANDLING - memset(parent_in_buffer, 0, BUFCHUNKSIZE); - strncpy(parent_in_buffer, readline(ps1), BUFCHUNKSIZE-1); - write(master, parent_in_buffer, strlen(parent_in_buffer)); - write(master, "\n", 1); - - usleep(100*1000); - } -} \ No newline at end of file + supervise(master_fd, child_pid); + exit(0); +} diff --git a/src/notmine.c b/src/notmine.c index 8c9408f..a4941f2 100644 --- a/src/notmine.c +++ b/src/notmine.c @@ -2,6 +2,9 @@ #include #include +#include +#include + //https://stackoverflow.com/a/779960/8229149 char *str_replace(char *orig, char *rep, char *with) { char *result; // the return string @@ -24,7 +27,7 @@ char *str_replace(char *orig, char *rep, char *with) { // count the number of replacements needed ins = orig; - for (count = 0; tmp = strstr(ins, rep); ++count) { + for (count = 0; (tmp = strstr(ins, rep)); ++count) { ins = tmp + len_rep; } @@ -47,4 +50,50 @@ char *str_replace(char *orig, char *rep, char *with) { } strcpy(tmp, orig); return result; -} \ No newline at end of file +} + + + +/* char *str_index_replace(char *orig, int rep_s, int rep_e, char *with) { + // Ugh, Re-worked the preceding str_replace function to work with indexes + char *result; // the return string + char *ins; // the next insert point + char *tmp; // varies + int len_rep; // length of rep (the string to remove) + int len_with; // length of with (the string to replace rep with) + int len_front; // distance between rep and end of last rep + + // sanity checks and initialization + if (!orig || !rep_e){ + DEBUG_ERROR("[orig or rep_e is false] *orig=%p; rep_s=%d, rep_e=%d\n", 67, orig, rep_s, rep_e); + return NULL; + } + len_rep = rep_e - rep_s; + if (len_rep == 0){ + DEBUG_ERROR("[rep empty]\n", 72); + return NULL; // empty rep causes infinite loop during count + } + if (!with) + with = ""; + len_with = strlen(with); + + tmp = result = malloc(strlen(orig) + (len_with - len_rep) + 1); + + if (!result) { + DEBUG_ERROR("[bad malloc]", 83); + return NULL; + } + + // first time through the loop, all the variable are set correctly + // from here on, + // tmp points to the end of the result string + // ins points to the next occurrence of rep in orig + // orig points to the remainder of orig after "end of rep" + ins = orig + rep_s; + len_front = ins - orig; + tmp = strncpy(tmp, orig, len_front) + len_front; + tmp = strcpy(tmp, with) + len_with; + orig += len_front + len_rep; // move to next "end of rep" + strcpy(tmp, orig); + return result; +} */ \ No newline at end of file diff --git a/testing/alpineA b/testing/alpineA new file mode 100644 index 0000000..e69de29