3 #include <libchimara/glk.h>
4 #include <libchimara/glkstart.h>
5 #include "chimara-glk-private.h"
10 extern ChimaraGlkPrivate *glk_data;
13 * glkunix_stream_open_pathname:
14 * @pathname: A path to a file, in the system filename encoding.
15 * @usage: 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 usage, glui32 rock)
28 if(!glk_data->in_startup)
29 ILLEGAL("glkunix_stream_open_pathname() may only be called from "
30 "glkunix_startup_code().");
32 g_return_val_if_fail(pathname, NULL);
33 g_return_val_if_fail(strlen(pathname) > 0, NULL);
35 frefid_t fileref = fileref_new(pathname, rock, usage, filemode_Read);
36 return file_stream_new(fileref, filemode_Read, rock, FALSE);
40 * glkunix_set_base_file:
41 * @filename: A path to a file, in the system filename encoding.
43 * Sets the library's idea of the <quote>current directory</quote> for the
44 * executing program. The argument should be the name of a file (not a
45 * directory). When this is set, glk_fileref_create_by_name() will create files
46 * in the same directory as that file, and glk_fileref_create_by_prompt() will
47 * base default filenames off of the file. If this is not called, the library
48 * works in the Unix current working directory, and picks reasonable default
52 glkunix_set_base_file(char *filename)
54 g_return_if_fail(filename);
55 g_return_if_fail(strlen(filename) > 0);
57 gchar *dirname = g_path_get_dirname(filename);
58 if(!g_file_test(dirname, G_FILE_TEST_IS_DIR))
60 WARNING_S("Not a directory", dirname);
65 glk_data->current_dir = dirname;
68 /* Internal function: parse the command line, getting only the arguments
69 requested by the plugin in its glkunix_arguments structure. Algorithm copied
70 from CheapGlk by Andrew Plotkin. */
72 parse_command_line(glkunix_argumentlist_t glkunix_arguments[], int argc, char *argv[], glkunix_startup_t *data)
74 GSList *arglist = NULL, *iter;
77 /* Now some argument-parsing. This is probably going to hurt. */
78 for(arg = 1; arg < argc; arg++)
80 glkunix_argumentlist_t *argform;
83 for(argform = glkunix_arguments; argform->argtype != glkunix_arg_End; argform++)
85 if(argform->name[0] == '\0')
87 if(((argform->argtype == glkunix_arg_ValueFollows ||
88 argform->argtype == glkunix_arg_ValueCanFollow) &&
89 argv[arg][0] != '-') ||
90 (argform->argtype == glkunix_arg_NumberValue &&
91 (atoi(argv[arg]) != 0 || argv[arg][0] == '0')))
93 arglist = g_slist_prepend(arglist, argv[arg]);
99 else if((argform->argtype == glkunix_arg_NumberValue)
100 && !strncmp(argv[arg], argform->name, strlen(argform->name))
101 && (numptr = argv[arg] + strlen(argform->name))
102 && (atoi(numptr) != 0 || numptr[0] == '0'))
104 arglist = g_slist_prepend(arglist, argv[arg]);
107 else if(strcmp(argv[arg], argform->name) == 0)
109 if(argform->argtype == glkunix_arg_ValueFollows)
111 if(arg + 1 >= argc) {
112 g_slist_free(arglist);
113 return FALSE; /* No more arguments, and this one is invalid */
115 arglist = g_slist_prepend(arglist, argv[arg++]);
116 arglist = g_slist_prepend(arglist, argv[arg]);
119 else if(argform->argtype == glkunix_arg_NoValue)
120 arglist = g_slist_prepend(arglist, argv[arg]);
122 else if(argform->argtype == glkunix_arg_ValueCanFollow)
124 arglist = g_slist_prepend(arglist, argv[arg]);
125 if(arg + 1 < argc && argv[arg + 1][0] != '-')
126 arglist = g_slist_prepend(arglist, argv[++arg]);
129 else if(argform->argtype == glkunix_arg_NumberValue)
131 if(arg + 1 >= argc || (atoi(argv[arg + 1]) == 0 && argv[arg + 1][0] != '0'))
133 g_slist_free(arglist);
136 arglist = g_slist_prepend(arglist, argv[arg++]);
137 arglist = g_slist_prepend(arglist, argv[arg]);
141 g_slist_free(arglist);
148 data->argc = g_slist_length(arglist) + 1;
149 data->argv = g_new0(char *, data->argc);
150 arglist = g_slist_reverse(arglist);
151 for(iter = arglist, arg = 1; iter; iter = g_slist_next(iter), arg++)
152 data->argv[arg] = g_strdup(iter->data);
153 g_slist_free(arglist);