3 #include <libchimara/glk.h>
4 #include <libchimara/glkstart.h>
5 #include "chimara-glk-private.h"
10 extern GPrivate *glk_data_key;
13 * glkunix_stream_open_pathname:
14 * @pathname: A path to a file, in the system filename encoding.
15 * @textmode: Bitfield with one or more of the <code>fileusage_</code> constants.
16 * @rock: The new stream's rock value.
18 * Opens an arbitrary file, in read-only mode. Note that this function is
19 * <emphasis>only</emphasis> available during glkunix_startup_code(). It is
20 * inherently non-portable; it should not and cannot be called from inside
23 * Returns: A new stream, or %NULL if the file operation failed.
26 glkunix_stream_open_pathname(char *pathname, glui32 textmode, glui32 rock)
28 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
30 if(!glk_data->in_startup)
31 ILLEGAL("glkunix_stream_open_pathname() may only be called from "
32 "glkunix_startup_code().");
34 g_return_val_if_fail(pathname, NULL);
35 g_return_val_if_fail(strlen(pathname) > 0, NULL);
37 frefid_t fileref = fileref_new(pathname, rock, textmode, filemode_Read);
38 return file_stream_new(fileref, filemode_Read, rock, FALSE);
42 * glkunix_set_base_file:
43 * @filename: A path to a file, in the system filename encoding.
45 * Sets the library's idea of the <quote>current directory</quote> for the
46 * executing program. The argument should be the name of a file (not a
47 * directory). When this is set, glk_fileref_create_by_name() will create files
48 * in the same directory as that file, and glk_fileref_create_by_prompt() will
49 * base default filenames off of the file. If this is not called, the library
50 * works in the Unix current working directory, and picks reasonable default
54 glkunix_set_base_file(char *filename)
56 g_return_if_fail(filename);
57 g_return_if_fail(strlen(filename) > 0);
59 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
61 gchar *dirname = g_path_get_dirname(filename);
62 if(!g_file_test(dirname, G_FILE_TEST_IS_DIR))
64 WARNING_S("Not a directory", dirname);
69 glk_data->current_dir = dirname;
72 /* Internal function: parse the command line, getting only the arguments
73 requested by the plugin in its glkunix_arguments structure. Algorithm copied
74 from CheapGlk by Andrew Plotkin. */
76 parse_command_line(glkunix_argumentlist_t glkunix_arguments[], int argc, char *argv[], glkunix_startup_t *data)
78 GSList *arglist = NULL, *iter;
81 /* Now some argument-parsing. This is probably going to hurt. */
82 for(arg = 1; arg < argc; arg++)
84 glkunix_argumentlist_t *argform;
87 for(argform = glkunix_arguments; argform->argtype != glkunix_arg_End; argform++)
89 if(argform->name[0] == '\0')
91 if(((argform->argtype == glkunix_arg_ValueFollows ||
92 argform->argtype == glkunix_arg_ValueCanFollow) &&
93 argv[arg][0] != '-') ||
94 (argform->argtype == glkunix_arg_NumberValue &&
95 (atoi(argv[arg]) != 0 || argv[arg][0] == '0')))
97 arglist = g_slist_prepend(arglist, argv[arg]);
103 else if((argform->argtype == glkunix_arg_NumberValue)
104 && !strncmp(argv[arg], argform->name, strlen(argform->name))
105 && (numptr = argv[arg] + strlen(argform->name))
106 && (atoi(numptr) != 0 || numptr[0] == '0'))
108 arglist = g_slist_prepend(arglist, argv[arg]);
111 else if(strcmp(argv[arg], argform->name) == 0)
113 if(argform->argtype == glkunix_arg_ValueFollows)
115 if(arg + 1 >= argc) {
116 g_slist_free(arglist);
117 return FALSE; /* No more arguments, and this one is invalid */
119 arglist = g_slist_prepend(arglist, argv[arg++]);
120 arglist = g_slist_prepend(arglist, argv[arg]);
123 else if(argform->argtype == glkunix_arg_NoValue)
124 arglist = g_slist_prepend(arglist, argv[arg]);
126 else if(argform->argtype == glkunix_arg_ValueCanFollow)
128 arglist = g_slist_prepend(arglist, argv[arg]);
129 if(arg + 1 < argc && argv[arg + 1][0] != '-')
130 arglist = g_slist_prepend(arglist, argv[++arg]);
133 else if(argform->argtype == glkunix_arg_NumberValue)
135 if(arg + 1 >= argc || (atoi(argv[arg + 1]) == 0 && argv[arg + 1][0] != '0'))
137 g_slist_free(arglist);
140 arglist = g_slist_prepend(arglist, argv[arg++]);
141 arglist = g_slist_prepend(arglist, argv[arg]);
145 g_slist_free(arglist);
152 data->argc = g_slist_length(arglist) + 1;
153 data->argv = g_new0(char *, data->argc);
154 arglist = g_slist_reverse(arglist);
155 for(iter = arglist, arg = 1; iter; iter = g_slist_next(iter), arg++)
156 data->argv[arg] = g_strdup(iter->data);
157 g_slist_free(arglist);