1 /* macstuff.c - macintosh interface routines for xlisp */
2 /* Written by Brian Kendig. */
3 /* This file contains the stuff that the other xlisp files call directly. */
4 
5 #include "cext.h"
6 #include <stdio.h>
7 #include <stdarg.h>
8 #include <QuickDraw.h>	/* for Random */
9 #include <Memory.h>		/* for DisposePtr */
10 #include <SegLoad.h>	/* for ExitToShell */
11 #include "xlisp.h"
12 #include <string.h>
13 #include "macint.h"
14 #include "MacCommandWin.h"
15 #define DELETE 0x08
16 
17 /* externals */
18 extern FILE *tfp;  /* transcript file pointer */
19 extern int cursorPos;
20 extern char *macgets (void);
21 
22 /* local variables */
23 int lposition;
24 static char *linebuf = NULL, *lineptr;
25 static int numChars;
26 
27 /* system-dependent variable definitions */
28 static const char os_pathchar = ':';
29 static const char os_sepchar = ',';
30 
31 
isascii(char c)32 int isascii (char c) { return 1; }  /* every char is an ascii char, isn't it? */
33 
osinit(char * banner)34 void osinit (char *banner) {
35 #ifdef SAFE_NYQUIST
36 SAFE_NYQUIST is not supported in macstuff.c
37 #endif
38     int i;
39     char version[] = "\nMacintosh interface by Brian Kendig, Erik A. Dahl, and Dominic Mazzoni.\n";
40     InitMac ();  /* initialize the mac interface routines */
41     lposition = 0;  /* initialize the line editor */
42     for (i = 0; banner[i] != '\0'; i++) macputc (banner[i]);
43     for (i = 0; version[i] != '\0'; i++) macputc (version[i]);
44 }
45 
osaopen(char * name,char * mode)46 FILE *osaopen (char *name, char *mode) {
47     return fopen (name, mode);
48 }
49 
osbopen(char * name,char * mode)50 FILE *osbopen (char *name, char *mode) {
51     FILE *f;
52     char nmode[4];
53     strcpy (nmode, mode); strcat (nmode, "b");
54     f = fopen(name, nmode);
55     return f;
56 }
57 
osclose(FILE * fp)58 int osclose (FILE *fp) { return (fclose (fp)); }
osaputc(int ch,FILE * fp)59 int osaputc (int ch, FILE *fp) { return (putc (ch, fp)); }
osbputc(int ch,FILE * fp)60 int osbputc (int ch, FILE *fp) { return (putc (ch, fp)); }
61 
62 /* osagetc - get a character from an ascii file */
osagetc(fp)63 int osagetc(fp)
64   FILE *fp;
65 {
66     return (getc(fp));
67 }
68 
ostgetc(void)69 int ostgetc (void) {
70     int i;
71 
72     if (numChars <= 0) {  /* get some more */
73         if (linebuf) DisposePtr (linebuf);
74         linebuf = macgets ();
75         i = 0;
76         while (linebuf[i] != '\0') i++;
77         numChars = i;
78         if (tfp) for (i = 0; i < numChars; i++) osaputc (linebuf[i], tfp);
79         lineptr = linebuf;
80     }
81     numChars--;
82     if (*lineptr == '\r') {
83         lineptr++;
84         return '\n';
85     } else return (*lineptr++);
86 }
87 
ostputc(int ch)88 void ostputc (int ch) {
89     macputc (ch);
90     if (tfp) osaputc (ch, tfp);
91 }
92 
osflush(void)93 void osflush (void) {
94     lineptr = linebuf;
95     numChars = 0;
96     lposition = 0;
97 }
98 
oscheck(void)99 void oscheck (void) { DoEvent (); }
100 
oserror(char * msg)101 void oserror (char *msg) {
102     char line[100], *p;
103     sprintf (line,"error: %s\n",msg);
104     for (p = line; *p != '\0'; ++p) ostputc (*p);
105 }
106 
osfinish(void)107 void osfinish(void) {
108     /* dispose of everything... */
109     if (linebuf) DisposePtr(linebuf);
110     portaudio_exit();
111     MacWrapUp ();
112     ExitToShell ();
113 }
114 
115 #define GPRINTF_MESSAGE_LEN 500
116 
117 /* nyquist_printf -- system independent version of printf */
118 /*
119  * this function prints to console like printf, but using GUI
120  * rather than stdio when appropriate.
121  *
122  */
nyquist_printf(char * format,...)123 void nyquist_printf(char *format, ...)
124 {
125     char temp[GPRINTF_MESSAGE_LEN];
126     va_list pvar;
127     char *p = temp;
128     va_start(pvar, format);
129     vsnprintf(temp, GPRINTF_MESSAGE_LEN, format, pvar);
130     va_end(pvar);
131     while (*p) ostputc(*p++);
132 }
133 
renamebackup(char * filename)134 int renamebackup (char *filename) { return 0; }
135 
136 static FSSpec prefsFSSpec;
137 static int need_preferences_file = false;
138 static char xlisp_path[1024]; /* cache for the path */
139 static int valid_xlisp_path = false;
140 
141 /* xsetupconsole -- used to configure window in Win32 version */
xsetupconsole()142 LVAL xsetupconsole() { return NIL; }
143 
144 
145 /* this should really be in a header for MacFileUtils.c */
146 void GetFullPath(FSSpec *theSpec, StringPtr theName);
147 
148 
get_xlisp_path(char * p,long p_max,int * prefs_found)149 void get_xlisp_path(char *p, long p_max, int *prefs_found)
150 {
151     Str63 fileName = "\pXLisp Preferences";
152     SInt16 foundPrefVRefNum = 0;
153     SInt32 foundPrefDirID = 0;
154     OSErr err = noErr;
155     *p = 0; /* initialize to empty string */
156     *prefs_found = false;
157     /* if we find path in the cache, copy and return */
158     if (valid_xlisp_path) {
159         *prefs_found = true;
160         strcpy(p, xlisp_path + 10); /* remember, path has XLISPPATH= at head */
161         return;
162     }
163     /* if we've been here before, do not try opening again */
164     if (need_preferences_file) return;
165     err = FindFolder(kOnSystemDisk, kPreferencesFolderType,
166                      kDontCreateFolder, &foundPrefVRefNum,
167                      &foundPrefDirID);
168     if (err == noErr) {
169         err = FSMakeFSSpec(foundPrefVRefNum, foundPrefDirID,
170                             fileName, &prefsFSSpec);
171         *prefs_found = (err == noErr);
172         need_preferences_file = !*prefs_found;
173     }
174     if (*prefs_found) {
175         FILE *pf;
176         GetFullPath(&prefsFSSpec, (StringPtr) xlisp_path);
177         P2CStr((StringPtr) xlisp_path);
178         pf = fopen(xlisp_path, "r");
179         if (!pf) {
180             return; /* problem opening the path */
181         }
182         while (fgets(xlisp_path, 1023, pf)) {
183             if (strncmp(xlisp_path, "XLISPPATH=", 10) == 0) {
184                 valid_xlisp_path = true;
185                 xlisp_path[strlen(xlisp_path) - 1] = 0; /* trim newline */
186                 strcpy(p, xlisp_path + 10);
187                 break;
188             }
189         }
190         fclose(pf);
191     }
192 }
193 
194 
195 /* this is called when we load a file -- if need_preference_file,
196  * we will build a preference file and insert the path of the file
197  * we just opened, assuming it will tell us where to find init.lsp
198  */
setup_preferences(char * filename)199 void setup_preferences(char *filename)
200 {
201     if (need_preferences_file) {
202         unsigned char prefname[256];
203         FILE *pf;
204         char *cp;
205         int len = 0;
206         GetFullPath(&prefsFSSpec, prefname);
207         need_preferences_file = false;
208         P2CStr(prefname);
209         /* we expect file-not-found error, path is valid */
210         pf = fopen((char *) prefname, "w");
211         if (pf == NULL) return;
212         cp = strrchr((char *) filename, ':');
213         if (cp == NULL) return;
214         cp[1] = 0;
215         /* now, filename is the path. If filename ends in runtime, this
216          * is probably the standard nyquist runtime folder. We should put
217          * the nyquist lib folder on the path too.
218          */
219         len = cp + 1 - filename;
220         if (len >= 9 &&
221             strcmp(filename + len - 9, ":runtime:") == 0) {
222             filename[len - 8] = 0;
223             fprintf(pf, "XLISPPATH=%sruntime:,%slib:\n", filename, filename);
224         } else {
225             fprintf(pf, "XLISPPATH=%s\n", filename);
226         }
227         fclose(pf);
228     }
229 }
230