Skip to content

Commit

Permalink
added EditLine.c
Browse files Browse the repository at this point in the history
  • Loading branch information
ColumPaget committed Feb 2, 2025
1 parent f70c8d9 commit c19b3e5
Show file tree
Hide file tree
Showing 15 changed files with 363 additions and 70 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
v5.34
v5.35
* Added LineEdit.c for full line editing with history
* Handle 'bigframes' in Websocket.c
* Add bech32 encoding

v5.34 (2025-01-23)
* Fixes for parsing unicode in 'UnQuoteStr'
* Handle NULL URL passed to 'STREAMOpen'
* Added function 'VarsFromNameValueList' to Vars.c
Expand Down
10 changes: 10 additions & 0 deletions Encodings.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ int EncodingParse(const char *Str)
else if (strcasecmp(Str,"b64")==0) Encode=ENCODE_BASE64;
else if (strcasecmp(Str,"base32")==0) Encode=ENCODE_BASE32;
else if (strcasecmp(Str,"b32")==0) Encode=ENCODE_BASE32;
else if (strcasecmp(Str,"bech32")==0) Encode=ENCODE_BECH32;
break;

case 'c':
Expand Down Expand Up @@ -336,6 +337,11 @@ char *EncodeBytes(char *Buffer, const char *Bytes, int len, int Encoding)
RetStr=base32encode(RetStr, Bytes, len, BASE32_WORDSAFE_CHARS, '=');
break;

case ENCODE_BECH32:
RetStr=base32encode(RetStr, Bytes, len, BASE32_BECH32_CHARS, '\0');
break;


case ENCODE_BASE64:
RetStr=SetStrLen(RetStr,len * 4);
to64frombits((unsigned char *) RetStr,(unsigned char *) Bytes,len);
Expand Down Expand Up @@ -473,6 +479,10 @@ int DecodeBytes(char **Return, const char *Text, int Encoding)
len=base32decode((unsigned char *) *Return, Text, BASE32_ZBASE32_CHARS);
break;

case ENCODE_BECH32:
len=base32decode((unsigned char *) *Return, Text, BASE32_BECH32_CHARS);
break;

case ENCODE_BASE64:
len=Radix64tobits(*Return,Text,BASE64_CHARS,'=');
break;
Expand Down
2 changes: 2 additions & 0 deletions Encodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ If you *KNOW* that your output of DecodeBytes is going to be null-terminated tex
#define ENCODE_WBASE32 35 //'word safe' base32
#define ENCODE_BASE32_WORDSAFE 35
#define ENCODE_ZBASE32 36
#define ENCODE_BECH32 37
#define ENCODE_BASE64 64
#define ENCODE_IBASE64 65
#define ENCODE_PBASE64 66
Expand Down Expand Up @@ -104,6 +105,7 @@ If you *KNOW* that your output of DecodeBytes is going to be null-terminated tex
#define BASE32_HEX_CHARS "0123456789ABCDEFGHIJKLMNOPQRSTUV"
#define BASE32_WORDSAFE_CHARS "23456789CFGHJMPQRVWXcfghjmpqrvwx"
#define BASE32_ZBASE32_CHARS "ybndrfg8ejkmcpqxot1uwisza345h769"
#define BASE32_BECH32_CHARS "qpzry9x8gf2tvdw0s3jn54khce6mua7l"


#ifdef __cplusplus
Expand Down
177 changes: 177 additions & 0 deletions LineEdit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#include "LineEdit.h"
#include "KeyCodes.h"

TLineEdit *LineEditCreate(int Flags)
{
TLineEdit *LE;

LE=(TLineEdit *) calloc(1, sizeof(TLineEdit));
LE->Flags = Flags;
if (Flags & LINE_EDIT_HISTORY) LE->History=ListCreate();
LE->MaxHistory=30;

return(LE);
}

void LineEditDestroy(TLineEdit *LE)
{
if (LE)
{
if (LE->History) ListDestroy(LE->History, Destroy);
Destroy(LE->Line);
free(LE);
}
}


void LineEditSetText(TLineEdit *LE, const char *Text)
{
LE->Line=CopyStr(LE->Line, Text);
LE->Len=StrLen(LE->Line);
LE->Cursor=LE->Len;
}


void LineEditClearHistory(TLineEdit *LE)
{
if (LE->History) ListClear(LE->History, Destroy);
}

void LineEditAddToHistory(TLineEdit *LE, const char *Text)
{
ListNode *Node;

if (StrValid(Text))
{
if (! LE->History) LE->History=ListCreate();

if (ListSize(LE->History) > LE->MaxHistory)
{
Node=ListGetNext(LE->History);
ListDeleteNode(Node);
}

Node=ListGetLast(LE->History);

if (Node && Node->Tag)
{
if (strcmp(Node->Tag, Text) !=0) ListAddNamedItem(LE->History, Text, NULL);
}
else ListAddNamedItem(LE->History, Text, NULL);
}

}

int LineEditHandleChar(TLineEdit *LE, int Char)
{
char *Tempstr=NULL;
char *ptr;

switch (Char)
{
//seems like control-c sends this
case STREAM_NODATA:
case ESCAPE:
return(LINE_EDIT_CANCEL);
break;

case STREAM_TIMEOUT:
break;

case TKEY_UP:
if (LE->History)
{
if (LE->History->Side)
{
if (LE->History->Side != ListGetNext(LE->History)) LE->History->Side=ListGetPrev(LE->History->Side);
}
else LE->History->Side=ListGetLast(LE->History);

if (LE->History->Side) LineEditSetText(LE, LE->History->Side->Tag);
}
break;

case TKEY_DOWN:
if (LE->History)
{
if (LE->History->Side)
{
LE->History->Side=ListGetNext(LE->History->Side);
if (LE->History->Side) LineEditSetText(LE, LE->History->Side->Tag);
}
}
break;

case TKEY_LEFT:
if ((! (LE->Flags & LINE_EDIT_NOMOVE)) && (LE->Cursor > 0)) LE->Cursor--;
break;

case TKEY_RIGHT:
if ((! (LE->Flags & LINE_EDIT_NOMOVE)) && (LE->Cursor < LE->Len)) LE->Cursor++;
break;

case TKEY_HOME:
if ((! (LE->Flags & LINE_EDIT_NOMOVE)) && (LE->Cursor < LE->Len)) LE->Cursor=0;
break;

case TKEY_END:
if ((! (LE->Flags & LINE_EDIT_NOMOVE)) && (LE->Cursor < LE->Len)) LE->Cursor=LE->Len;
break;

//'backspace' key on keyboard will send the 'del' character in some cases!
case 0x7f: //this is 'del'
if (LE->Cursor < LE->Len)
{
ptr=LE->Line + LE->Cursor;
if (LE->Cursor < LE->Len) memmove(ptr, ptr +1, LE->Len - LE->Cursor);
LE->Len--;
StrTrunc(LE->Line, LE->Len);
}
break;

case TKEY_BACKSPACE:
if (LE->Cursor > 0)
{
LE->Cursor--;
ptr=LE->Line + LE->Cursor;
if (LE->Cursor < LE->Len) memmove(ptr, ptr +1, LE->Len - LE->Cursor);
LE->Len--;
StrTrunc(LE->Line, LE->Len);
}
break;

case TKEY_ENTER:
if (LE->History) LE->History->Side=NULL;
return(LINE_EDIT_ENTER);
break;

default:
if (LE->Cursor == LE->Len) LE->Line=AddCharToBuffer(LE->Line, LE->Cursor, Char);
else
{
Tempstr=CopyStrLen(Tempstr, LE->Line, LE->Cursor);
Tempstr=AddCharToBuffer(Tempstr, LE->Cursor, Char);
Tempstr=CatStr(Tempstr, LE->Line + LE->Cursor);
LE->Line=CopyStr(LE->Line, Tempstr);
}
LE->Cursor++;
LE->Len++;
break;
}

Destroy(Tempstr);

return(LE->Cursor);
}


char *LineEditDone(char *RetStr, TLineEdit *LE)
{
RetStr=CopyStr(RetStr, LE->Line);
if (LE->Flags & LINE_EDIT_HISTORY) LineEditAddToHistory(LE, LE->Line);
LE->Line=CopyStr(LE->Line, "");
LE->Len=0;
LE->Cursor=0;

return(RetStr);
}
69 changes: 69 additions & 0 deletions LineEdit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#ifndef LIBUSEFUL_LINEEDIT_H
#define LIBUSEFUL_LINEEDIT_H

/*
This module supplies a line-editor with a history.
Example code using this can be found in Terminal.h in 'TerminalReadText' or in examples/EditLine.c
The 'LineEditCreate' command can be passed the flags:
LINE_EDIT_HISTORY - provide an recallable history of entered lines
LINE_EDIT_NOMOVE - don't allow use of left/right to move back into the text
this is used for password entry text that is invisible and
thus we cannot allow the user to use full editing, as they
can become 'lost'.
The 'EditLineHandleChar' function does most of the work, it expects to receive
the following characters (defined in KeyCodes.h)
TKEY_LEFT - move cursor left within text
TKEY_RIGHT - move cursor right within text
TKEY_UP - if history mode is active, recall previous entry
TKEY_DOWN - if moving through history goto next entry
TKEY_HOME - move cursor to start of text
TKEY_END - move cursor to end of text
TKEY_BACKSPACE - backspace delete previous character
TKEY_ERASE - erase curr character
TKEY_ENTER - return/enter line
TKEY_ESCAPE - cancel line editing
The 'EditLineHandleChar' function returns the cursor position within the edited line, or if 'enter' is pressed it will return the value LINE_EDIT_ENTER, if 'escape' is pressed then it will return LINE_EDIT_CANCEL.
When LINE_EDIT_ENTER is called 'LineEditDone' should be used to collect the typed line, as it will reset the LineEdit for a new line to be typed in, and if history mode is active, it will add the typed line to the history.
*/


#include "includes.h"
#include "List.h"


#define LINE_EDIT_ENTER -1
#define LINE_EDIT_CANCEL -2

#define LINE_EDIT_HISTORY 1
#define LINE_EDIT_NOMOVE 2

typedef struct
{
char *Line;
int Flags;
int Len;
int MaxHistory;
int Cursor;
ListNode *History;
} TLineEdit;


#define LineEditSetMaxHistory(LE, Max) ((LE)->MaxHistory = (Max))

TLineEdit *LineEditCreate(int Flags);
void LineEditSetText(TLineEdit *LE, const char *Text);
void LineEditDestroy(TLineEdit *LE);
int LineEditHandleChar(TLineEdit *LE, int Char);
char *LineEditDone(char *RetStr, TLineEdit *LE);
void LineEditClearHistory(TLineEdit *LE);
void LineEditAddToHistory(TLineEdit *LE, const char *Text);

#endif
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CC = gcc
AR = ar
VERSION = 5.34
VERSION = 5.35
MAJOR=5
LIBFILE=libUseful.so.$(VERSION)
SONAME=libUseful.so.$(MAJOR)
Expand All @@ -9,8 +9,8 @@ LDFLAGS=
LIBS = -lc -lz -lssl -lcrypto -lc -lc -lc -lc
prefix=/usr/local
sysconfdir=${prefix}/etc
FLAGS=$(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -fPIC -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DHAVE_LIBC=1 -DHAVE_GET_CURR_DIR=1 -DHAVE_PTSNAME_R=1 -DHAVE_CLEARENV=1 -DHAVE_SETRESUID=1 -DHAVE_INITGROUPS=1 -DHAVE_POLL=1 -DHAVE_MLOCK=1 -DHAVE_MLOCKALL=1 -DHAVE_MUNLOCKALL=1 -DHAVE_MADVISE=1 -DHAVE_MKOSTEMP=1 -DHAVE_MOUNT=1 -DHAVE_UMOUNT=1 -DHAVE_UMOUNT2=1 -DHAVE_GETENTROPY=1 -DHAVE_PRCTL=1 -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_SENDFILE=1 -DUSE_INET6=1 -DHAVE_LIBC=1 -DHAVE_XATTR=1 -DHAVE_LIBC=1 -DHAVE_UNSHARE=1 -DHAVE_LIBC=1 -DHAVE_SETNS=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBSSL=1 -DHAVE_EVP_MD_CTX_NEW=1 -DHAVE_EVP_MD_CTX_FREE=1 -DHAVE_X509_CHECK_HOST=1 -DHAVE_EVP_CIPHER_FETCH=1 -DHAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS=1 -DHAVE_OPENSSL_ADD_ALL_ALGORITHMS=1 -DHAVE_DECL_SSL_SET_TLSEXT_HOST_NAME=1 -DHAVE_SSL_SET_TLSEXT_HOST_NAME=1 -DHAVE_LIBZ=1 -DHAVE_LIBC=1 -DUSE_SECCOMP=1 -DVERSION=\"$(VERSION)\" -DSYSCONFDIR=\"$(sysconfdir)\"
OBJ=StrLenCache.o String.o Array.o List.o IPAddress.o Socket.o Server.o UnixSocket.o Stream.o StreamAuth.o Errors.o Unicode.o TerminalKeys.o Terminal.o TerminalWidget.o TerminalMenu.o TerminalChoice.o TerminalBar.o TerminalProgress.o TerminalCalendar.o TerminalTheme.o FileSystem.o GeneralFunctions.o DataProcessing.o Pty.o Log.o HttpUtil.o HttpChunkedTransfer.o Http.o Gemini.o Smtp.o Inet.o Expect.o base32.o base64.o crc32.o md5c.o sha1.o sha2.o whirlpool.o jh_ref.o HashCRC32.o HashMD5.o HashSHA.o HashJH.o HashWhirlpool.o HashOpenSSL.o Hash.o HMAC.o Ssh.o Compression.o Encryption.o OAuth.o LibSettings.o Vars.o Time.o Markup.o SpawnPrograms.o Tokenizer.o StringList.o PatternMatch.o URL.o DataParser.o ConnectionChain.o OpenSSL.o Seccomp.o Process.o Container.o Encodings.o RawData.o SecureMem.o CommandLineParser.o SysInfo.o Entropy.o Users.o UnitsOfMeasure.o HttpServer.o WebSocket.o ContentType.o PasswordFile.o OTP.o CGI.o
FLAGS=$(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -fPIC -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -D_FILE_OFFSET_BITS=64 -DHAVE_LIBC=1 -DHAVE_GET_CURR_DIR=1 -DHAVE_PTSNAME_R=1 -DHAVE_CLEARENV=1 -DHAVE_SETRESUID=1 -DHAVE_INITGROUPS=1 -DHAVE_POLL=1 -DHAVE_MLOCK=1 -DHAVE_MLOCKALL=1 -DHAVE_MUNLOCKALL=1 -DHAVE_MADVISE=1 -DHAVE_MKOSTEMP=1 -DHAVE_MOUNT=1 -DHAVE_UMOUNT=1 -DHAVE_UMOUNT2=1 -DHAVE_GETENTROPY=1 -DHAVE_PRCTL=1 -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_SENDFILE=1 -DUSE_INET6=1 -DHAVE_LIBC=1 -DHAVE_XATTR=1 -DHAVE_LIBC=1 -DHAVE_UNSHARE=1 -DHAVE_LIBC=1 -DHAVE_SETNS=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBSSL=1 -DHAVE_EVP_MD_CTX_CREATE=1 -DHAVE_EVP_MD_CTX_NEW=1 -DHAVE_EVP_MD_CTX_DESTROY=1 -DHAVE_EVP_MD_CTX_FREE=1 -DHAVE_X509_CHECK_HOST=1 -DHAVE_SSL_SET_MIN_PROTO_VERSION=1 -DHAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS=1 -DHAVE_OPENSSL_ADD_ALL_ALGORITHMS=1 -DHAVE_DECL_SSL_SET_TLSEXT_HOST_NAME=1 -DHAVE_SSL_SET_TLSEXT_HOST_NAME=1 -DHAVE_LIBZ=1 -DHAVE_LIBC=1 -DUSE_SECCOMP=1 -DVERSION=\"$(VERSION)\" -DSYSCONFDIR=\"$(sysconfdir)\"
OBJ=StrLenCache.o String.o Array.o List.o IPAddress.o Socket.o Server.o UnixSocket.o Stream.o StreamAuth.o Errors.o Unicode.o TerminalKeys.o Terminal.o TerminalWidget.o TerminalMenu.o TerminalChoice.o TerminalBar.o TerminalProgress.o TerminalCalendar.o TerminalTheme.o FileSystem.o GeneralFunctions.o DataProcessing.o Pty.o Log.o HttpUtil.o HttpChunkedTransfer.o Http.o Gemini.o Smtp.o Inet.o Expect.o base32.o base64.o crc32.o md5c.o sha1.o sha2.o whirlpool.o jh_ref.o HashCRC32.o HashMD5.o HashSHA.o HashJH.o HashWhirlpool.o HashOpenSSL.o Hash.o HMAC.o Ssh.o Compression.o Encryption.o OAuth.o LibSettings.o Vars.o Time.o Markup.o SpawnPrograms.o Tokenizer.o StringList.o PatternMatch.o URL.o DataParser.o ConnectionChain.o OpenSSL.o Seccomp.o Process.o Container.o Encodings.o RawData.o SecureMem.o CommandLineParser.o SysInfo.o Entropy.o Users.o UnitsOfMeasure.o HttpServer.o WebSocket.o ContentType.o PasswordFile.o OTP.o CGI.o LineEdit.o


all: $(OBJ)
Expand Down Expand Up @@ -268,6 +268,9 @@ OTP.o: OTP.c OTP.h
CGI.o: CGI.c CGI.h
$(CC) $(FLAGS) -c CGI.c

LineEdit.o: LineEdit.c LineEdit.h
$(CC) $(FLAGS) -c LineEdit.c



#No dependancies, must always be compiled
Expand Down
7 changes: 5 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CC = @CC@
AR = @AR@
VERSION = 5.34
VERSION = 5.35
MAJOR=5
LIBFILE=libUseful.so.$(VERSION)
SONAME=libUseful.so.$(MAJOR)
Expand All @@ -10,7 +10,7 @@ LIBS = @LIBS@
prefix=@prefix@
sysconfdir=@sysconfdir@
FLAGS=$(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -fPIC @DEFS@ -DVERSION=\"$(VERSION)\" -DSYSCONFDIR=\"$(sysconfdir)\"
OBJ=StrLenCache.o String.o Array.o List.o IPAddress.o Socket.o Server.o UnixSocket.o Stream.o StreamAuth.o Errors.o Unicode.o TerminalKeys.o Terminal.o TerminalWidget.o TerminalMenu.o TerminalChoice.o TerminalBar.o TerminalProgress.o TerminalCalendar.o TerminalTheme.o FileSystem.o GeneralFunctions.o DataProcessing.o Pty.o Log.o HttpUtil.o HttpChunkedTransfer.o Http.o Gemini.o Smtp.o Inet.o Expect.o base32.o base64.o crc32.o md5c.o sha1.o sha2.o whirlpool.o jh_ref.o HashCRC32.o HashMD5.o HashSHA.o HashJH.o HashWhirlpool.o HashOpenSSL.o Hash.o HMAC.o Ssh.o Compression.o Encryption.o OAuth.o LibSettings.o Vars.o Time.o Markup.o SpawnPrograms.o Tokenizer.o StringList.o PatternMatch.o URL.o DataParser.o ConnectionChain.o OpenSSL.o Seccomp.o Process.o Container.o Encodings.o RawData.o SecureMem.o CommandLineParser.o SysInfo.o Entropy.o Users.o UnitsOfMeasure.o HttpServer.o WebSocket.o ContentType.o PasswordFile.o OTP.o CGI.o
OBJ=StrLenCache.o String.o Array.o List.o IPAddress.o Socket.o Server.o UnixSocket.o Stream.o StreamAuth.o Errors.o Unicode.o TerminalKeys.o Terminal.o TerminalWidget.o TerminalMenu.o TerminalChoice.o TerminalBar.o TerminalProgress.o TerminalCalendar.o TerminalTheme.o FileSystem.o GeneralFunctions.o DataProcessing.o Pty.o Log.o HttpUtil.o HttpChunkedTransfer.o Http.o Gemini.o Smtp.o Inet.o Expect.o base32.o base64.o crc32.o md5c.o sha1.o sha2.o whirlpool.o jh_ref.o HashCRC32.o HashMD5.o HashSHA.o HashJH.o HashWhirlpool.o HashOpenSSL.o Hash.o HMAC.o Ssh.o Compression.o Encryption.o OAuth.o LibSettings.o Vars.o Time.o Markup.o SpawnPrograms.o Tokenizer.o StringList.o PatternMatch.o URL.o DataParser.o ConnectionChain.o OpenSSL.o Seccomp.o Process.o Container.o Encodings.o RawData.o SecureMem.o CommandLineParser.o SysInfo.o Entropy.o Users.o UnitsOfMeasure.o HttpServer.o WebSocket.o ContentType.o PasswordFile.o OTP.o CGI.o LineEdit.o


all: $(OBJ)
Expand Down Expand Up @@ -268,6 +268,9 @@ OTP.o: OTP.c OTP.h
CGI.o: CGI.c CGI.h
$(CC) $(FLAGS) -c CGI.c

LineEdit.o: LineEdit.c LineEdit.h
$(CC) $(FLAGS) -c LineEdit.c



#No dependancies, must always be compiled
Expand Down
Loading

0 comments on commit c19b3e5

Please sign in to comment.