1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
Description: Accept a plain text file as user input.
The program is not robust at all and imposes a limit for the reply of
256 bytes, so even medium-sized files are likely to cause buffer
overflow. These do not cause crashes but are still unpleasant user
experience. The application logic should be fixed to automatically
grow the reply buffer.
Bug-Debian: https://bugs.debian.org/284416
Author: Yavor Doganov <yavor@gnu.org>
Forwarded: no
Last-Update: 2018-10-17
---
--- gniall.orig/gnome.c
+++ gniall/gnome.c
@@ -53,6 +53,7 @@
gboolean wordsSaved=TRUE;
char *fileName=NULL;
+static void sf_processFile(gchar *contents);
/********************************************************************************
* Callbacks from the File Requesters *
@@ -209,11 +210,58 @@
return(TRUE);
}
+/* Load a file and process it line by line as if it was user input
+ * from the GtkEntry. */
+static void load_input_file(gchar *file)
+{
+ GError *error = NULL;
+ gchar *contents;
+
+ g_file_get_contents(file, &contents, NULL, &error);
+ if (error)
+ {
+ Niall_Warning("Could not read input file %s: %s",
+ file, error->message);
+ g_error_free(error);
+ }
+ else if (g_utf8_validate(contents, -1, NULL))
+ sf_processFile(contents);
+ else
+ {
+ Niall_Warning("Input file %s is not valid UTF-8", file);
+ g_free(contents);
+ }
+}
/********************************************************************************
* Callbacks from the Main Window *
********************************************************************************/
+/* Load a plain text input file.
+*/
+static void input_open_cb(GtkMenuItem *item, gpointer data)
+{
+ gchar *file;
+
+ fileOpen = gtk_file_chooser_dialog_new(_("Choose Input File..."),
+ GTK_WINDOW(windowMain),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Cancel"),
+ GTK_RESPONSE_CANCEL,
+ _("_Open"),
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ if(gtk_dialog_run(GTK_DIALOG(fileOpen))==GTK_RESPONSE_ACCEPT)
+ {
+ file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileOpen));
+ load_input_file(file);
+ g_free(file);
+ }
+
+ gtk_widget_destroy(fileOpen);
+}
+
/* Clear the dictionary.
*/
static void file_new_cb(void)
@@ -380,7 +428,7 @@
/* Learn from a line of text, and then say something back.
*/
-static void sf_processLine(void)
+static void sf_processLine(GtkEntry *entry, gchar *data)
{
GtkTextBuffer *buf;
char *Buffer;
@@ -392,11 +440,11 @@
/* Allocate a buffer big enough for the text, but not less
** than BUFFER_SIZE so there is enough room for Niall to reply
*/
- buffer_size = strlen(gtk_entry_get_text(GTK_ENTRY(textEntry))) + 1;
+ buffer_size = strlen(entry ? gtk_entry_get_text(entry) : data) + 1;
buffer_size = buffer_size < BUFFER_SIZE ? BUFFER_SIZE : buffer_size;
if(!( Buffer = malloc( buffer_size ) )) Niall_Error( "Out of memory" );
- strncpy( Buffer, gtk_entry_get_text(GTK_ENTRY(textEntry)), buffer_size );
+ strncpy(Buffer, entry ? gtk_entry_get_text(entry) : data, buffer_size);
gtk_entry_set_text(GTK_ENTRY(textEntry),"");
printToTextArea("User: ",promptColour,NULL);
@@ -418,6 +466,21 @@
wordsSaved=FALSE;
}
+/* Split the contents of the input file into lines and process each
+ * line. Empty lines are skipped. */
+static void sf_processFile(gchar *contents)
+{
+ gchar **lines;
+ gint i;
+
+ lines = g_regex_split_simple("\\n", contents, 0, 0);
+ for (i = 0; i < g_strv_length(lines); i++)
+ if (strlen(lines[i]))
+ sf_processLine(NULL, lines[i]);
+
+ g_free(contents);
+ g_strfreev(lines);
+}
/********************************************************************************
* Initialise the user interface *
@@ -471,6 +534,11 @@
g_signal_connect(item, "activate", G_CALLBACK(file_new_cb), NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ item = gtk_menu_item_new_with_mnemonic(_("_Input..."));
+ gtk_widget_set_tooltip_text(item, _("Load a plain text file"));
+ g_signal_connect(item, "activate", G_CALLBACK(input_open_cb), NULL);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+
item = gtk_menu_item_new_with_mnemonic(_("_Open..."));
gtk_widget_set_tooltip_text(item, _("Open a file"));
gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_O,
@@ -628,12 +696,21 @@
int main(int argc, char *argv[])
{
+ GError *error = NULL;
+
Niall_Init();
- gtk_init(&argc, &argv);
+ gtk_init_with_args(&argc, &argv, _("[FILEā¦]"), NULL, NULL, &error);
+ if (error)
+ g_error("Could not initialize GUI: %s", error->message);
+
BuildGUI();
gtk_widget_show(windowMain);
gtk_widget_grab_focus(textEntry);
+
+ if (argv[1])
+ load_input_file(argv[1]);
+
gtk_main();
fprintf(stderr,"Error: Control should never reach here - main()!\n");
exit(EXIT_FAILURE);
--- gniall.orig/niall.c
+++ gniall/niall.c
@@ -63,11 +63,6 @@
WORD *WordList;
static GRegex *re = NULL;
-extern void Niall_Print( char *fmt, ... );
-extern void Niall_Warning( char *fmt, ... );
-extern void Niall_Error( char *fmt, ... );
-
-
/********************************************************************************
* Linked List Handlers *
********************************************************************************/
--- gniall.orig/niall.h
+++ gniall/niall.h
@@ -49,6 +49,10 @@
void Niall_LoadDictionary(char *file);
void Niall_CorrectSpelling(char *Original,char *Correct);
+void Niall_Print( char *fmt, ... );
+void Niall_Warning( char *fmt, ... );
+void Niall_Error( char *fmt, ... );
+
#endif
/*******************************************************************************/
|