--- freem/src/fma_gedit.c 2025/03/09 19:14:24 1.3
+++ freem/src/fma_gedit.c 2025/03/31 16:33:56 1.5
@@ -1,5 +1,5 @@
/*
- * $Id: fma_gedit.c,v 1.3 2025/03/09 19:14:24 snw Exp $
+ * $Id: fma_gedit.c,v 1.5 2025/03/31 16:33:56 snw Exp $
* FreeM global editor
*
*
@@ -24,6 +24,12 @@
* along with FreeM. If not, see .
*
* $Log: fma_gedit.c,v $
+ * Revision 1.5 2025/03/31 16:33:56 snw
+ * Work on fmadm edit global
+ *
+ * Revision 1.4 2025/03/30 01:36:58 snw
+ * Make it easier to bring back fma_gedit, fix double-free in global handler, limit $CHAR to 7-bit ASCII
+ *
* Revision 1.3 2025/03/09 19:14:24 snw
* First phase of REUSE compliance and header reformat
*
@@ -46,19 +52,33 @@
#include "fmadm.h"
#include "fma_globals.h"
-#if defined HAVE_NCURSESW_CURSES_H
-# include
-#elif defined HAVE_NCURSESW_H
-# include
-#elif defined HAVE_NCURSES_CURSES_H
-# include
-#elif defined HAVE_NCURSES_H
-# include
-#elif defined HAVE_CURSES_H
-# include
-#else
-# error "SysV or X/Open-compatible Curses header file required"
-#endif
+#ifdef HAVE_LIBREADLINE
+# if defined(HAVE_READLINE_READLINE_H)
+# include
+# elif defined(HAVE_READLINE_H)
+# include
+# else /* !defined(HAVE_READLINE_H) */
+extern char *readline ();
+# endif /* !defined(HAVE_READLINE_H) */
+/*char *cmdline = NULL;*/
+#else /* !defined(HAVE_READLINE_READLINE_H) */
+ /* no readline */
+#endif /* HAVE_LIBREADLINE */
+
+#ifdef HAVE_READLINE_HISTORY
+# if defined(HAVE_READLINE_HISTORY_H)
+# include
+# elif defined(HAVE_HISTORY_H)
+# include
+# else /* !defined(HAVE_HISTORY_H) */
+extern void add_history ();
+extern int write_history ();
+extern int read_history ();
+# endif /* defined(HAVE_READLINE_HISTORY_H) */
+ /* no history */
+#endif /* HAVE_READLINE_HISTORY */
+
+
#define GE_MXGBL 100
@@ -121,22 +141,6 @@ int ge_nextbuf;
int ge_rows;
int ge_columns;
-WINDOW *wge_key;
-WINDOW *wge_key_border;
-WINDOW *wge_node;
-WINDOW *wge_node_border;
-WINDOW *wge_msg_border;
-WINDOW *wge_msg;
-WINDOW *wge_block_border;
-WINDOW *wge_block;
-WINDOW *wge_global_border;
-WINDOW *wge_global;
-WINDOW *wge_command;
-
-WINDOW *wge_cur;
-
-void ge_set_wintitle(WINDOW *border_window, char *title);
-void ge_wininit(void);
void ge_update_gbl(void);
void ge_select_buffer(int buf);
short ge_select_block(int buf, long blocknum);
@@ -145,135 +149,141 @@ int ge_open_global(char *gblname);
void ge_init_buffers(void);
void ge_eventloop(void);
void ge_decode_key(const char *key, char *buf);
-void ge_win_next(void);
-void ge_win_previous(void);
+void ge_describe_block(void);
#define SPC ' '
+
+void ge_describe_gbl(void)
+{
+ printf ("global %s [#%d]\n", ge_buffers[ge_curbuf].name, ge_curbuf);
+ printf ("namespace %s\n", ge_buffers[ge_curbuf].namespace);
+ printf ("block size %d bytes\n", BLOCKLEN);
+ printf ("block count %d\n", ge_buffers[ge_curbuf].blockct);
+ printf ("file size %d bytes\n", ge_buffers[ge_curbuf].gblsize);
+}
+
+void ge_update_gbl(void)
+{
+ printf ("fmadm: selected global %s into buffer %d\n", ge_buffers[ge_curbuf].name, ge_curbuf);
+}
+
+
int fma_globals_edit(int optc, char **opts)
{
+ #define MODE_GBL 0
+ #define MODE_BLK 1
+#if defined(HAVE_LIBREADLINE) && !defined(_AIX)
int editbuf;
+ char fmge_prompt[256];
+ char *cmdt = (char *) malloc (65535 * sizeof (char));
+ char *fmarl_buf;
+ char **args;
+ int mode = MODE_GBL;
+ char *result = (char *) malloc (65535 * sizeof (char));;
+ int argc;
+ int tmpres;
+ register int i;
+
+ /* first dimension */
+ if ((args = (char **) malloc (FMA_MAXARGS * sizeof (char *))) == NULL) {
+ fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
+ return 1;
+ }
+
+ /* second dimension */
+ for (i = 0; i < FMA_MAXARGS; i++) {
+ if ((args[i] = (char *) malloc (STRLEN * sizeof (char *))) == NULL) {
+ fprintf (stderr, "fmadm [FATAL]: could not acquire memory\n");
+ return 1;
+ }
+ }
+
ge_curbuf = 0;
ge_nextbuf = 0;
-
- ge_init_buffers ();
- initscr ();
- ge_wininit ();
-
- wge_cur = wge_command;
-
- wprintw (wge_msg, "FreeM Global Editor\n");
- wprintw (wge_msg, " Copyright (C) 2023 Coherent Logic Development LLC\n\n");
-
- wattron (wge_msg, A_BOLD);
- wprintw (wge_msg, "Left and right arrow keys navigate blocks; 'q' to quit.\n\n");
- wattroff (wge_msg, A_BOLD);
- wrefresh (wge_msg);
+ ge_init_buffers ();
if (optc == 2) {
if ((editbuf = ge_open_global (opts[fma_base_opt])) == -1) {
- wprintw (wge_msg, "fmadm: cannot open global %s\n", opts[fma_base_opt]);
+ fprintf (stderr, "fmadm: cannot open global %s\n", opts[fma_base_opt]);
}
else {
ge_select_buffer (editbuf);
}
}
-
- ge_eventloop ();
-
- endwin ();
- return 0;
-}
-
-void ge_win_next(void)
-{
- /*
- switch (wge_cur) {
-
- case wge_key:
- wge_cur = wge_node;
- break;
-
- case wge_node:
- wge_cur = wge_global;
- break;
-
- case wge_global:
- wge_cur = wge_block;
- break;
-
- case wge_block:
- wge_cur = wge_command;
- break;
-
- case wge_command:
- wge_cur = wge_msg;
- break;
-
- case wge_msg:
- wge_cur = wge_key;
- break;
-
- }
- */
-
-}
-
-
-void ge_win_previous(void)
-{
-
-}
-
+ while(1) {
+ if (mode == MODE_GBL) {
+ sprintf (fmge_prompt, "global edit %s [buf %d/%d]> ",
+ ge_buffers[ge_curbuf].name,
+ ge_curbuf,
+ GE_MXGBL);
+ }
+ else {
+ sprintf (fmge_prompt, "block edit %s [blk %d/%d]> ",
+ ge_buffers[ge_curbuf].name,
+ ge_buffers[ge_curbuf].blocknum,
+ ge_buffers[ge_curbuf].blockct);
+ }
+
+ fmarl_buf = readline (fmge_prompt);
+ if (fmarl_buf == (char *) NULL) continue;
-void ge_eventloop(void)
-{
- int c;
- short quit_flag;
+ cmdt = strtok (fmarl_buf, " ");
+ if (cmdt == (char *) NULL) continue;
- quit_flag = FALSE;
+ i = 0;
+ while ((result = strtok (NULL, " ")) != NULL) {
+ strcpy (args[i++], result);
+ }
- while (!quit_flag) {
+ argc = i;
+
+ for (i = 0; i < strlen (cmdt); i++) cmdt[i] = cmdt[i] | 0140;
- noecho ();
- c = wgetch (wge_command);
- echo ();
-
- switch (c) {
-
- case 'q':
- case 'Q':
- quit_flag = TRUE;
- break;
-
- case KEY_LEFT:
- if (ge_buffers[ge_curbuf].blocknum != 0) {
- ge_select_block (ge_curbuf, ge_buffers[ge_curbuf].blocknum - 1);
- }
- else {
- ge_select_block (ge_curbuf, ge_buffers[ge_curbuf].blockct - 1);
- }
- break;
-
- case KEY_RIGHT:
- if (ge_buffers[ge_curbuf].blocknum + 1 < ge_buffers[ge_curbuf].blockct) {
- ge_select_block (ge_curbuf, ge_buffers[ge_curbuf].blocknum + 1);
- }
- else {
- ge_select_block (ge_curbuf, 0);
- }
- break;
-
+ if (strcmp (cmdt, "exit") == 0 || strcmp (cmdt, "quit") == 0) {
+ return 0;
}
-
+ else if (strcmp (cmdt, "block") == 0) {
+ mode = MODE_BLK;
+ }
+ else if (strcmp (cmdt, "global") == 0) {
+ mode = MODE_GBL;
+ }
+ else if (strcmp (cmdt, "describe") == 0) {
+ if (mode == MODE_GBL) {
+ ge_describe_gbl ();
+ }
+ else {
+ ge_describe_block ();
+ }
+ }
+ else if (strcmp (cmdt, "open") == 0) {
+ if (mode == MODE_GBL) {
+ printf ("TODO\n");
+ }
+ else {
+ long blknum;
+ blknum = atoi (args[0]);
+ ge_select_block (ge_curbuf, blknum);
+ }
+ }
+ else {
+ printf ("fmadm: command %s not recognized\n", cmdt);
+ }
+
+
}
+#endif
+
+ return 0;
}
+
void ge_init_buffers(void)
{
register int i;
@@ -296,87 +306,12 @@ void ge_init_buffers(void)
}
}
-void ge_wininit(void)
-{
- int half;
-
- getmaxyx (stdscr, ge_rows, ge_columns);
-
- half = ge_rows / 2;
-
- /* messages window */
- wge_msg_border = newwin (10, ge_columns - 41, ge_rows - 12, 0);
- wge_msg = newwin (8, ge_columns - 43, ge_rows - 11, 1);
- ge_set_wintitle (wge_msg_border, "Messages");
- wrefresh (wge_msg_border);
- wrefresh (wge_msg);
-
- /* global window */
- wge_global_border = newwin (half, 40, 0, ge_columns - 40);
- wge_global = newwin (half - 2, 38, 1, ge_columns - 39);
- ge_set_wintitle (wge_global_border, "No Global Selected");
- wrefresh (wge_global_border);
-
- /* block window */
- wge_block_border = newwin (half - 1, 40, half, ge_columns - 40);
- wge_block = newwin (half - 3, 37, half + 1, ge_columns - 38);
- ge_set_wintitle (wge_block_border, "Block");
- wrefresh (wge_block_border);
-
- /* command window */
- wge_command = newwin (1, ge_columns, ge_rows - 1, 0);
- wrefresh (wge_command);
-
- scrollok (wge_msg, TRUE);
- keypad (wge_command, TRUE);
- keypad (wge_msg, TRUE);
- keypad (wge_global, TRUE);
- keypad (wge_block, TRUE);
-
- curs_set (0);
-}
-
-void ge_update_gbl(void)
-{
- char wintit[4096];
-
- wclear (wge_global);
- snprintf (wintit, 4095, "%s [#%d]", ge_buffers[ge_curbuf].name, ge_curbuf);
- ge_set_wintitle (wge_global_border, wintit);
-
- wattron (wge_global, A_BOLD);
- wprintw (wge_global, "GLOBAL: ");
- wattroff (wge_global, A_BOLD);
- wprintw (wge_global, "%s\n", ge_buffers[ge_curbuf].name);
-
- wattron (wge_global, A_BOLD);
- wprintw (wge_global, "NAMESPACE: ");
- wattroff (wge_global, A_BOLD);
- wprintw (wge_global, "%s\n", ge_buffers[ge_curbuf].namespace);
-
- wattron (wge_global, A_BOLD);
- wprintw (wge_global, "BLOCK SIZE: ");
- wattroff (wge_global, A_BOLD);
- wprintw (wge_global, "%d bytes\n", BLOCKLEN);
-
- wattron (wge_global, A_BOLD);
- wprintw (wge_global, "BLOCK COUNT: ");
- wattroff (wge_global, A_BOLD);
- wprintw (wge_global, "%d\n", ge_buffers[ge_curbuf].blockct);
-
- wattron (wge_global, A_BOLD);
- wprintw (wge_global, "FILE SIZE: ");
- wattroff (wge_global, A_BOLD);
- wprintw (wge_global, "%d bytes\n", ge_buffers[ge_curbuf].gblsize);
- wrefresh (wge_global);
-}
void ge_select_buffer(int buf)
{
- wprintw (wge_msg, "Selected buffer %d\n", buf);
- wrefresh (wge_msg);
+ printf ("fmadm: selected buffer %d\n", buf);
ge_curbuf = buf;
@@ -387,15 +322,15 @@ short ge_select_block(int buf, long bloc
{
ge_blockinfo *b;
char *br;
- char key[256];
- char decoded[4096];
+ char key[2056];
+ char decoded[64096];
long i;
long j;
long k;
long length;
if ((blocknum < 0) || (blocknum > (ge_buffers[buf].blockct - 1))) {
- wprintw (wge_msg, "Block number for global %s must be between 0 and %d\n", ge_buffers[buf].name, ge_buffers[buf].blockct - 1);
+ printf ("block number for global %s must be between 0 and %d\n", ge_buffers[buf].name, ge_buffers[buf].blockct - 1);
return FALSE;
}
@@ -468,8 +403,8 @@ short ge_select_block(int buf, long bloc
key[k] = g_EOL;
ge_decode_key (key, decoded);
- decoded[stlen (decoded)] = '\0';
- wprintw (wge_msg, "found key %s\n", decoded);
+
+ printf ("found key %s\n", decoded);
b->keyct++;
}
@@ -548,48 +483,27 @@ void ge_decode_key(const char *key, char
}
-void ge_update_block(void)
+void ge_describe_block(void)
{
- char wintit[4096];
-
- wclear (wge_block);
- snprintf (wintit, 4095, "Block %d of %d", ge_buffers[ge_curbuf].blocknum, ge_buffers[ge_curbuf].blockct);
- ge_set_wintitle (wge_block_border, wintit);
-
- wattron (wge_block, A_BOLD);
- wprintw (wge_block, "TYPE: ");
- wattroff (wge_block, A_BOLD);
- wprintw (wge_block, "%s\n", ge_buffers[ge_curbuf].block.bt_desc);
+ printf ("type = %s\n", ge_buffers[ge_curbuf].block.bt_desc);
if (ge_buffers[ge_curbuf].blocknum != ROOT) {
- wattron (wge_block, A_BOLD);
- wprintw (wge_block, "LEFT LINK POINTER: ");
- wattroff (wge_block, A_BOLD);
- wprintw (wge_block, "%d\n", ge_buffers[ge_curbuf].block.llptr);
-
- wattron (wge_block, A_BOLD);
- wprintw (wge_block, "RIGHT LINK POINTER: ");
- wattroff (wge_block, A_BOLD);
- wprintw (wge_block, "%d\n", ge_buffers[ge_curbuf].block.rlptr);
+ printf ("llptr = %d\n", ge_buffers[ge_curbuf].block.llptr);
+ printf ("rlptr = %d\n", ge_buffers[ge_curbuf].block.rlptr);
}
else {
- wattron (wge_block, A_BOLD);
- wprintw (wge_block, "BLOCK COUNT: ");
- wattroff (wge_block, A_BOLD);
- wprintw (wge_block, "%d\n", ge_buffers[ge_curbuf].block.blockcount);
-
- wattron (wge_block, A_BOLD);
- wprintw (wge_block, "FREE OFFSET: ");
- wattroff (wge_block, A_BOLD);
- wprintw (wge_block, "%d\n", ge_buffers[ge_curbuf].block.free_offset);
- }
-
- wattron (wge_block, A_BOLD);
- wprintw (wge_block, "KEY COUNT: ");
- wattroff (wge_block, A_BOLD);
- wprintw (wge_block, "%d\n", ge_buffers[ge_curbuf].block.keyct);
-
- wrefresh (wge_block);
+ printf ("block count = %d\n", ge_buffers[ge_curbuf].block.blockcount);
+ printf ("offset to free space = %d\n", ge_buffers[ge_curbuf].block.free_offset);
+ }
+
+ printf ("key count = %d\n", ge_buffers[ge_curbuf].block.keyct);
+}
+
+void ge_update_block(void)
+{
+
+ printf ("fmadm: selected block %d of %d\n", ge_buffers[ge_curbuf].blocknum, ge_buffers[ge_curbuf].blockct);
+
}
int ge_open_global(char *gblname)
@@ -602,18 +516,14 @@ int ge_open_global(char *gblname)
snprintf (gpath, 4095, "%s/%s", fma_global_path, gblname);
- wprintw (wge_msg, "Opening global %s [path %s, namespace %s]... ", gblname, gpath, fma_namespace);
+ printf ("fmadm: opening global %s [path %s, namespace %s]... ", gblname, gpath, fma_namespace);
- wrefresh (wge_msg);
-
if ((ge_buffers[buf].fd = open (gpath, 0)) == -1) {
- wprintw (wge_msg, "[FAIL]\n");
- wrefresh (wge_msg);
+ printf ("[FAIL]\n");
return -1;
}
else {
- wprintw (wge_msg, "[OK]\n");
- wrefresh (wge_msg);
+ printf ("[OK]\n");
}
fstat (ge_buffers[buf].fd, &sb);
@@ -635,11 +545,3 @@ int ge_open_global(char *gblname)
return buf;
}
-void ge_set_wintitle(WINDOW *border_window, char *title)
-{
- box (border_window, 0, 0);
- wattron (border_window, A_BOLD);
- mvwprintw (border_window, 0, 3, title);
- wattroff (border_window, A_BOLD);
- wrefresh (border_window);
-}