Updated interpreters
[projects/chimara/chimara.git] / interpreters / git / git_unix.c
1 // $Id: git_unix.c,v 1.5 2004/01/25 18:44:51 iain Exp $
2
3 // unixstrt.c: Unix-specific code for Glulxe.
4 // Designed by Andrew Plotkin <erkyrath@eblong.com>
5 // http://www.eblong.com/zarf/glulx/index.html
6
7 #include "git.h"
8 #include <glk.h>
9 #include <glkstart.h> // This comes with the Glk library.
10
11 #include <string.h>
12
13 #ifdef USE_MMAP
14 #include <fcntl.h>
15 #include <sys/mman.h>
16 #include <sys/stat.h>
17 #include <errno.h>
18 #endif
19
20 // The only command-line argument is the filename.
21 glkunix_argumentlist_t glkunix_arguments[] =
22 {
23     { "", glkunix_arg_ValueFollows, "filename: The game file to load." },
24     { NULL, glkunix_arg_End, NULL }
25 };
26
27 #define CACHE_SIZE (256 * 1024L)
28 #define UNDO_SIZE (512 * 1024L)
29
30 int gHasInited = 0;
31
32 #ifdef GARGLK
33
34 void fatalError (const char * s)
35 {
36         winid_t win;
37         if (!gHasInited)
38         {
39                 win = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
40                 glk_set_window(win);
41         }
42         /* pray that this goes somewhere reasonable... */
43         glk_put_string("\n*** fatal error: ");
44         glk_put_string((char*)s);
45         glk_put_string(" ***\n");
46         glk_exit();
47 }
48
49 #else
50
51 void fatalError (const char * s)
52 {
53     fprintf (stderr, "*** fatal error: %s ***\n", s);
54     exit (1);
55 }
56
57 #endif /* GARGLK */
58
59 #ifdef USE_MMAP
60 // Fast loader that uses some fancy Unix features.
61
62 const char * gFilename = 0;
63 char * gStartupError = 0;
64
65 int glkunix_startup_code(glkunix_startup_t *data)
66 {
67 #ifdef GARGLK
68         {
69                 char buf[255];
70                 sprintf(buf, "Git %d.%d.%d", GIT_MAJOR, GIT_MINOR, GIT_PATCH);
71                 garglk_set_program_name(buf);
72                 sprintf(buf, "Git %d.%d.%d by Iain Merrick and David Kinder\n",
73                                 GIT_MAJOR, GIT_MINOR, GIT_PATCH);
74                 garglk_set_program_info(buf);
75         }
76 #endif /* GARGLK */
77
78     if (data->argc <= 1)
79     {
80         gStartupError = "No file given";
81         return 1;
82     }
83
84 #ifdef GARGLK
85         {
86                 char *s;
87                 s = strrchr(data->argv[1], '\\');
88                 if (s) garglk_set_story_name(s+1);
89                 s = strrchr(data->argv[1], '/');
90                 if (s) garglk_set_story_name(s+1);
91         }
92 #endif /* GARGLK */
93
94     gFilename = data->argv[1];
95     return 1;
96 }
97
98 void glk_main ()
99 {
100     int          file;
101     struct stat  info;
102     const char * ptr;
103
104         if (gStartupError)
105                 fatalError(gStartupError);
106
107     file = open (gFilename, O_RDONLY);
108     if (file < 0)
109         goto error;
110
111     if (fstat (file, &info) != 0)
112         goto error;
113     
114     if (info.st_size < 256)
115                 fatalError("This is too small to be a glulx file.");
116
117     ptr = mmap (NULL, info.st_size, PROT_READ, MAP_PRIVATE, file, 0);
118     if (ptr == MAP_FAILED)
119         goto error;
120
121         gHasInited = 1;
122         
123     git (ptr, info.st_size, CACHE_SIZE, UNDO_SIZE);
124     munmap ((void*) ptr, info.st_size);
125     return;
126     
127 error:
128         sprintf(errmsg, "git: %s", strerror(errno));
129     fatalError(errmsg);
130 }
131
132 #else
133 // Generic loader that should work anywhere.
134
135 strid_t gStream = 0;
136 char * gStartupError = 0;
137
138 int glkunix_startup_code(glkunix_startup_t *data)
139 {
140 #ifdef GARGLK
141         {
142                 char buf[255];
143                 sprintf(buf, "Git %d.%d.%d", GIT_MAJOR, GIT_MINOR, GIT_PATCH);
144                 garglk_set_program_name(buf);
145                 sprintf(buf, "Git %d.%d.%d by Iain Merrick and David Kinder\n",
146                                 GIT_MAJOR, GIT_MINOR, GIT_PATCH);
147                 garglk_set_program_info(buf);
148         }
149 #endif /* GARGLK */
150
151     if (data->argc <= 1)
152     {
153         gStartupError = "No file given";
154         return 1;
155     }
156
157 #ifdef GARGLK
158         {
159                 char *s;
160                 s = strrchr(data->argv[1], '\\');
161                 if (s) garglk_set_story_name(s+1);
162                 s = strrchr(data->argv[1], '/');
163                 if (s) garglk_set_story_name(s+1);
164         }
165 #endif /* GARGLK */
166
167     gStream = glkunix_stream_open_pathname ((char*) data->argv[1], 0, 0);
168     return 1;
169 }
170
171 void glk_main ()
172 {
173         if (gStartupError)
174                 fatalError(gStartupError);
175
176     if (gStream == NULL)
177         fatalError ("could not open game file");
178
179         gHasInited = 1;
180
181     gitWithStream (gStream, CACHE_SIZE, UNDO_SIZE);
182 }
183
184 #endif // USE_MMAP