Applied patches to Git interpreter from Gargoyle source code
[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 #ifdef USE_MMAP
12 #include <fcntl.h>
13 #include <sys/mman.h>
14 #include <sys/stat.h>
15 #include <errno.h>
16 #endif
17
18 // The only command-line argument is the filename.
19 glkunix_argumentlist_t glkunix_arguments[] =
20 {
21     { "", glkunix_arg_ValueFollows, "filename: The game file to load." },
22     { NULL, glkunix_arg_End, NULL }
23 };
24
25 #define CACHE_SIZE (256 * 1024L)
26 #define UNDO_SIZE (512 * 1024L)
27
28 int gHasInited = 0;
29
30 #ifdef CHIMARA_EXTENSIONS
31
32 void fatalError (const char * s)
33 {
34         winid_t win;
35         if (!gHasInited)
36         {
37                 win = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
38                 glk_set_window(win);
39         }
40         /* pray that this goes somewhere reasonable... */
41         glk_put_string("\n*** fatal error: ");
42         glk_put_string((char*)s);
43         glk_put_string(" ***\n");
44         glk_exit();
45 }
46
47 #else
48
49 void fatalError (const char * s)
50 {
51     fprintf (stderr, "*** fatal error: %s ***\n", s);
52     exit (1);
53 }
54
55 #endif /* CHIMARA_EXTENSIONS */
56
57 #ifdef USE_MMAP
58 // Fast loader that uses some fancy Unix features.
59
60 const char * gFilename = 0;
61 char * gStartupError = 0;
62
63 int glkunix_startup_code(glkunix_startup_t *data)
64 {
65     if (data->argc <= 1)
66     {
67         gStartupError = "No file given";
68         return 1;
69     }
70     gFilename = data->argv[1];
71     return 1;
72 }
73
74 void glk_main ()
75 {
76     int          file;
77     struct stat  info;
78     const char * ptr;
79
80         if (gStartupError)
81                 fatalError(gStartupError);
82
83     file = open (gFilename, O_RDONLY);
84     if (file < 0)
85         goto error;
86
87     if (fstat (file, &info) != 0)
88         goto error;
89     
90     if (info.st_size < 256)
91                 fatalError("This is too small to be a glulx file.");
92
93     ptr = mmap (NULL, info.st_size, PROT_READ, MAP_PRIVATE, file, 0);
94     if (ptr == MAP_FAILED)
95         goto error;
96
97         gHasInited = 1;
98         
99     git (ptr, info.st_size, CACHE_SIZE, UNDO_SIZE);
100     munmap ((void*) ptr, info.st_size);
101     return;
102     
103 error:
104         sprintf(errmsg, "git: %s", strerror(errno));
105     fatalError(errmsg);
106 }
107
108 #else
109 // Generic loader that should work anywhere.
110
111 strid_t gStream = 0;
112 char * gStartupError = 0;
113
114 int glkunix_startup_code(glkunix_startup_t *data)
115 {
116     if (data->argc <= 1)
117     {
118         gStartupError = "No file given";
119         return 1;
120     }
121     gStream = glkunix_stream_open_pathname ((char*) data->argv[1], 0, 0);
122     return 1;
123 }
124
125 void glk_main ()
126 {
127         if (gStartupError)
128                 fatalError(gStartupError);
129
130     if (gStream == NULL)
131         fatalError ("could not open game file");
132
133         gHasInited = 1;
134
135     gitWithStream (gStream, CACHE_SIZE, UNDO_SIZE);
136 }
137
138 #endif // USE_MMAP