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_gen:
14 * @pathname: A path to a file, in the system filename encoding.
15 * @writemode: 0 for read-only mode, 1 for write mode.
16 * @textmode: 0 for binary mode, 1 for text mode.
17 * @rock: The new stream's rock value.
19 * Opens an arbitrary file for reading or writing. (You cannot open a file for
20 * appending using this call.) Note that this function is
21 * <emphasis>only</emphasis> available during glkunix_startup_code(). It is
22 * inherently non-portable; it should not and cannot be called from inside
25 * Returns: A new stream, or %NULL if the file operation failed.
28 glkunix_stream_open_pathname_gen(char *pathname, glui32 writemode, glui32 textmode, glui32 rock)
30 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
32 if(!glk_data->in_startup)
33 ILLEGAL("glkunix_stream_open_pathname_gen() may only be called from "
34 "glkunix_startup_code().");
36 g_return_val_if_fail(pathname, NULL);
37 g_return_val_if_fail(strlen(pathname) > 0, NULL);
39 frefid_t fileref = fileref_new(pathname, rock,
40 textmode? fileusage_TextMode : fileusage_BinaryMode,
41 writemode? filemode_Write : filemode_Read);
42 return file_stream_new(fileref, writemode? filemode_Write : filemode_Read, rock, FALSE);
46 * glkunix_stream_open_pathname:
47 * @pathname: A path to a file, in the system filename encoding.
48 * @textmode: 0 for binary mode, 1 for text mode.
49 * @rock: The new stream's rock value.
51 * This opens a file for reading. It is a less-general form of
52 * glkunix_stream_open_pathname_gen(), preserved for backwards compatibility.
54 * This should be used only by glkunix_startup_code().
56 * Returns: A new stream, or %NULL if the file operation failed.
59 glkunix_stream_open_pathname(char *pathname, glui32 textmode, glui32 rock)
61 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
63 if(!glk_data->in_startup)
64 ILLEGAL("glkunix_stream_open_pathname() may only be called from "
65 "glkunix_startup_code().");
67 g_return_val_if_fail(pathname, NULL);
68 g_return_val_if_fail(strlen(pathname) > 0, NULL);
70 frefid_t fileref = fileref_new(pathname, rock, textmode? fileusage_TextMode : fileusage_BinaryMode, filemode_Read);
71 return file_stream_new(fileref, filemode_Read, rock, FALSE);
75 * glkunix_set_base_file:
76 * @filename: A path to a file, in the system filename encoding.
78 * Sets the library's idea of the <quote>current directory</quote> for the
79 * executing program. The argument should be the name of a file (not a
80 * directory). When this is set, glk_fileref_create_by_name() will create files
81 * in the same directory as that file, and glk_fileref_create_by_prompt() will
82 * base default filenames off of the file. If this is not called, the library
83 * works in the Unix current working directory, and picks reasonable default
87 glkunix_set_base_file(char *filename)
89 g_return_if_fail(filename);
90 g_return_if_fail(strlen(filename) > 0);
92 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
94 gchar *dirname = g_path_get_dirname(filename);
95 if(!g_file_test(dirname, G_FILE_TEST_IS_DIR))
97 WARNING_S("Not a directory", dirname);
102 glk_data->current_dir = dirname;
105 /* Internal function: parse the command line, getting only the arguments
106 requested by the plugin in its glkunix_arguments structure. Algorithm copied
107 from CheapGlk by Andrew Plotkin. */
109 parse_command_line(glkunix_argumentlist_t glkunix_arguments[], int argc, char *argv[], glkunix_startup_t *data)
111 GSList *arglist = NULL, *iter;
114 /* Now some argument-parsing. This is probably going to hurt. */
115 for(arg = 1; arg < argc; arg++)
117 glkunix_argumentlist_t *argform;
120 for(argform = glkunix_arguments; argform->argtype != glkunix_arg_End; argform++)
122 if(argform->name[0] == '\0')
124 if(((argform->argtype == glkunix_arg_ValueFollows ||
125 argform->argtype == glkunix_arg_ValueCanFollow) &&
126 argv[arg][0] != '-') ||
127 (argform->argtype == glkunix_arg_NumberValue &&
128 (atoi(argv[arg]) != 0 || argv[arg][0] == '0')))
130 arglist = g_slist_prepend(arglist, argv[arg]);
136 else if((argform->argtype == glkunix_arg_NumberValue)
137 && !strncmp(argv[arg], argform->name, strlen(argform->name))
138 && (numptr = argv[arg] + strlen(argform->name))
139 && (atoi(numptr) != 0 || numptr[0] == '0'))
141 arglist = g_slist_prepend(arglist, argv[arg]);
144 else if(strcmp(argv[arg], argform->name) == 0)
146 if(argform->argtype == glkunix_arg_ValueFollows)
148 if(arg + 1 >= argc) {
149 g_slist_free(arglist);
150 return FALSE; /* No more arguments, and this one is invalid */
152 arglist = g_slist_prepend(arglist, argv[arg++]);
153 arglist = g_slist_prepend(arglist, argv[arg]);
156 else if(argform->argtype == glkunix_arg_NoValue)
157 arglist = g_slist_prepend(arglist, argv[arg]);
159 else if(argform->argtype == glkunix_arg_ValueCanFollow)
161 arglist = g_slist_prepend(arglist, argv[arg]);
162 if(arg + 1 < argc && argv[arg + 1][0] != '-')
163 arglist = g_slist_prepend(arglist, argv[++arg]);
166 else if(argform->argtype == glkunix_arg_NumberValue)
168 if(arg + 1 >= argc || (atoi(argv[arg + 1]) == 0 && argv[arg + 1][0] != '0'))
170 g_slist_free(arglist);
173 arglist = g_slist_prepend(arglist, argv[arg++]);
174 arglist = g_slist_prepend(arglist, argv[arg]);
178 g_slist_free(arglist);
185 data->argc = g_slist_length(arglist) + 1;
186 data->argv = g_new0(char *, data->argc);
187 arglist = g_slist_reverse(arglist);
188 for(iter = arglist, arg = 1; iter; iter = g_slist_next(iter), arg++)
189 data->argv[arg] = g_strdup(iter->data);
190 g_slist_free(arglist);