OSDN Git Service

Fix no pic
[uclinux-h8/uClinux-dist.git] / user / a60 / xa60.c
1 /*
2  * Simple X11 edit-and-go frontend for the NASE A60 interpreter.
3  * Copyright (C) 1991,1992 Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
4  *
5  * This file is part of NASE A60.
6  * 
7  * NASE A60 is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * NASE A60 is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with NASE A60; see the file COPYING.  If not, write to the Free
19  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * xa60.c:                                              may 1991
22  *
23  * first steps to a simple X frontend for edit and go fun.
24  * (nothing serious - be warned)
25  */
26
27 #include <stdio.h>
28
29 #ifdef USG
30 #ifndef SYSV
31 /* commonly expected by X11R4: */
32 #define SYSV
33 #endif /* ! SYSV */
34 #endif /* USG */
35
36 #include <X11/Intrinsic.h>
37 #include <X11/StringDefs.h>
38 #include <X11/Xaw/Cardinals.h>
39 #include <X11/Xaw/AsciiText.h>
40 #include <X11/Xaw/Command.h>
41 #include <X11/Xaw/Paned.h>
42 #include <X11/Xaw/Box.h>
43
44 #define VERSION         "xa60  v0.11,  June 1991"
45
46 #define A60PATH         "a60"
47 #define A60FLAGS        "-X"
48
49 /*
50  * define as 1 to include a save button; this is not necessary,
51  * because the text is saved before every execution. (and upon exit) 
52  */
53 #define SAVE_BUTTEN     0
54
55
56 static String fallback_resources [] = { 
57     "*input:                    True",
58     "*showGrip:                 on",
59     "*paned.width:              560",
60
61     "*etext*height:             360", 
62     "*etext*editType:           edit",
63     "*etext*scrollVertical:     whenNeeded",
64     "*etext*autoFill:           on",
65
66     "*otext*height:             240", 
67     "*otext*editType:           append",
68     "*otext*scrollVertical:     whenNeeded",
69     "*otext*wrap:               line",
70     "*otext*displayCaret:       False",
71
72     "*bexit*label:              Exit",
73     "*bexit*shapeStyle:         oval",
74     "*bexit*borderWidth:        2",
75
76     "*clear*label:              Clear",
77     "*clear*shapeStyle:         oval",
78 #if SAVE_BUTTEN
79     "*save*label:               Save",
80     "*save*shapeStyle:          oval",
81 #endif
82     "*go*label:                 Go",
83     "*go*shapeStyle:            oval",
84
85     "*fnlab*borderWidth:        0",
86
87     NULL,
88 };
89
90
91 /* selected input file: */
92 static char *fname = (char *) 0;
93
94 /* temporary textbuffer (and its length): */
95 static char *txt_buf = (char *) 0;
96 static int txt_max = 0;
97 static int txt_len;
98
99 /* global ... */
100 static Widget etext, otext;
101
102 /* forward: */
103 static void have_a_run ();
104
105
106 /*
107  * create a temporary file; a simple name is enough.
108  * static storage is ok.
109  */
110
111 static char *
112 mk_fname ()
113 {
114         static char tmp [128];
115
116         sprintf (tmp, "/tmp/nase-%d", getpid () % 999);
117
118         return tmp;
119 }
120
121
122 static void
123 read_file ()
124 {
125         FILE *fp;
126         int ch;
127         
128         fp = fopen (fname, "r");
129
130         if (! fp) {
131                 fp = fopen (fname, "w");
132                 if (! fp) {
133                         fprintf (stderr, "cannot open `%s' for writing...\n",
134                                  fname);
135                         exit (1);
136                 }
137
138                 /*
139                  * insert some default text:
140                  */
141         
142                 fprintf (fp, "begin\n    vprint (\"Hi!\")\nend\n");
143                 fclose (fp);
144
145                 fp = fopen (fname, "r");
146         }
147
148         if (! fp) {
149                 fprintf (stderr, "cannot open `%s' for reading...\n",
150                          fname);
151                 exit (1);
152         }
153
154         txt_len = 0;
155
156         do {
157                 if (txt_len + 10 > txt_max) {
158                         txt_max += 1000;
159                         if (! txt_buf)
160                                 txt_buf = XtMalloc (txt_max);
161                         else
162                                 txt_buf = XtRealloc (txt_buf, txt_max);
163                 }
164                 
165                 ch = fgetc (fp);
166
167                 if (ch != EOF)
168                         txt_buf [txt_len++] = ch;
169         } while (ch != EOF);
170
171         fclose (fp);
172 }
173
174
175 static void
176 append_text (w, str)
177 Widget w;
178 char *str;
179 {
180         XawTextBlock tb;
181         int rc, point;
182         
183         tb.firstPos = 0;
184         tb.length = strlen (str);
185         tb.ptr = str;
186         tb.format = FMT8BIT;
187         
188         point = XawTextGetInsertionPoint (w);
189
190         rc = XawTextReplace (w, point, point, &tb);
191         
192         XawTextSetInsertionPoint (w, point + strlen (str));
193
194         if (rc == XawPositionError)
195                 printf ("** xa60 internal error: XawPositionError ...\n");
196         else if (rc == XawEditError)
197                 printf ("** xa60 internal error: XawEditError ...\n");
198 }
199
200
201 static void
202 set_caret (lno)
203 int lno;
204 {
205         Arg args[1];
206         String str;
207         int i, n;
208
209         XtSetArg(args[0], XtNstring, &str);
210         XtGetValues(etext, args, ONE);
211
212
213         /* look for character position of line lno : */
214
215         for (n = 0, i = 1; str [n] && i < lno; n++)
216                 i += str [n] == '\n';
217
218         XawTextSetInsertionPoint (etext, n);
219 }
220
221 /*
222  * saving the text means: print the string (which contains the
223  * complete text).
224  * If this fails - abort.
225  */
226
227 static void
228 save_file (txt)
229 char *txt;
230 {
231         FILE *fp;
232
233         fp = fopen (fname, "w");
234         if (! fp) {
235                 fprintf (stderr, "cannot open `%s' for writing...\n",
236                          fname);
237                 exit (1);
238         }
239
240         fprintf (fp, "%s\n", txt);
241         fclose (fp);
242 }
243
244
245 /*
246  * The callbacks for the Three buttons:  Exit, Clear, Save and Go:
247  */
248
249 /* ARGSUSED */
250 static void
251 cb_clear (w, text_ptr, call_data)
252 Widget w;
253 XtPointer text_ptr, call_data;
254 {
255         Widget text = (Widget) text_ptr;
256         Arg args[1];
257         
258         XtSetArg (args[0], XtNstring, "");
259         XtSetValues (text, args, ONE);
260 }
261
262
263 /* ARGSUSED */
264 static void
265 cb_save (w, text_ptr, call_data)
266 Widget w;
267 XtPointer text_ptr, call_data;
268 {
269         Widget text = (Widget) text_ptr;
270         Arg args[1];
271         String str;
272
273         XtSetArg(args[0], XtNstring, &str);
274         XtGetValues(text, args, ONE);
275
276         save_file (str);
277 }
278
279
280 /* ARGSUSED */
281 static void
282 cb_bexit (w, text_ptr, call_data)
283 Widget w;
284 XtPointer text_ptr, call_data;
285 {
286         cb_save (w, text_ptr, call_data);
287         
288         exit (0);
289 }
290
291
292 /* ARGSUSED */
293 static void
294 cb_go (w, text_ptr, call_data)
295 Widget w;
296 XtPointer text_ptr, call_data;
297 {
298         cb_save (w, text_ptr, call_data);
299
300         have_a_run ();
301 }
302
303
304 /*
305  * Try to get a linenumber from this line: error lines are looking like:
306  * nase.a60: 12: parse error
307  * return the linenumber or return a 0.
308  */
309
310 static int
311 is_error_line (s)
312 char *s;
313 {
314         int lno = 0;
315
316         int len = strlen (fname);
317
318         if (! strncmp (fname, s, len) && s [len] == ':')
319                 lno = atoi (s + len + 1);
320
321         return lno;
322 }
323
324
325 /*
326  * read the lines from fp look about an error message (to set the
327  * caret [cursor]) and append the line to the output.
328  */
329
330 static void
331 process_a60 (fp)
332 FILE *fp;
333 {
334         char buf [1024];                        /* fixed length :-( */
335         int cursor_set = 0, lno;
336
337         while (buf == fgets (buf, 1024, fp)) {
338                 append_text (otext, buf);
339
340                 if (! cursor_set) {
341                         lno = is_error_line (buf);
342                         if (lno) {
343                                 set_caret (lno);
344                                 cursor_set = 1;
345                         }
346                 }
347         }
348 }
349
350
351 /*
352  * process the buffer through a60. a single directional pipe is enough
353  * and i'll use popen.
354  * (may be a fork providing a stdin from this process would be nice)
355  */
356
357 static void
358 have_a_run ()
359 {
360         FILE *fp;
361         char cmd [100];
362         char tmp [100];
363
364         sprintf (cmd, "%s %s %s", A60PATH, A60FLAGS, fname);
365         fp = popen (cmd, "r");
366
367         if (! fp) {
368                 sprintf (tmp, "cannot execute `%s'.\n", cmd);
369                 append_text (otext, tmp);
370         }
371         else {
372                 sprintf (tmp, "*** a60 starting:\n");
373                 append_text (otext, tmp);
374                 process_a60 (fp);
375                 pclose (fp);
376                 append_text (otext, "*** a60 done.\n\n");
377         }
378 }
379
380
381
382 static void 
383 usage ()
384 {
385         fprintf (stderr, "Use:  xa60  [ -V ] | [ <source file> ]\n");
386         
387         exit (1);
388 }
389
390
391 /*
392  * M A I N
393  */
394
395 int
396 main (argc, argv)
397 int argc;
398 char *argv[];
399 {
400         XtAppContext app_con;
401         Widget toplevel, paned, box, clear, bexit, go;
402         Arg args[1];
403         char *fn_str;
404 #if SAVE_BUTTEN
405         Widget save;
406 #endif
407
408         toplevel = XtAppInitialize (&app_con, "XA60", NULL, ZERO,
409                            &argc, argv, fallback_resources, NULL, ZERO);
410
411         /*
412          * Check to see that all arguments were processed, and if not then
413          * report an error and exit.
414          */
415         
416         if (argc > 2)
417                 usage ();
418
419         if (argc == 2) 
420         {
421                 if (! strcmp (argv [1], "-V")) 
422                 {
423                         printf ("Version:  %s.\n", VERSION);
424                         exit (0);
425                 }
426                 else if (! strcmp (argv [1], "-h")) 
427                 {
428                         usage ();
429                 }
430                 else {
431                         fname = argv [1];
432                 }
433         }
434         else {
435                 fname = mk_fname ();
436         }
437
438         fn_str = XtMalloc (strlen (fname) + 20);
439         sprintf (fn_str, " File: %s", fname);
440
441         read_file ();
442         
443         paned = XtCreateManagedWidget ("paned", panedWidgetClass, toplevel, 
444                                        NULL, ZERO);
445         
446         box = XtCreateManagedWidget ("box", boxWidgetClass, paned, 
447                                      NULL, ZERO);
448         
449         bexit = XtCreateManagedWidget ("bexit", commandWidgetClass, box, 
450                                        NULL, ZERO);
451         
452         clear = XtCreateManagedWidget ("clear", commandWidgetClass, box, 
453                                        NULL, ZERO);
454 #if SAVE_BUTTEN
455         save = XtCreateManagedWidget ("save", commandWidgetClass, box, 
456                                       NULL, ZERO);
457 #endif
458         go = XtCreateManagedWidget ("go", commandWidgetClass, box, 
459                                     NULL, ZERO);
460
461         XtSetArg (args[0], XtNlabel, fn_str);
462         XtCreateManagedWidget ("fnlab", labelWidgetClass, box, args, ONE);
463
464         XtSetArg (args[0], XtNstring, txt_buf);
465         etext = XtCreateManagedWidget ("etext", asciiTextWidgetClass, paned, 
466                                      args, ONE);
467
468         XtSetArg (args[0], XtNstring, "See:\n");
469         otext = XtCreateManagedWidget ("otext", asciiTextWidgetClass, paned, 
470                                       args, ONE);
471
472         XtAddCallback (bexit, XtNcallback, cb_bexit, (XtPointer) etext);
473         XtAddCallback (clear, XtNcallback, cb_clear, (XtPointer) etext);
474 #if SAVE_BUTTEN
475         XtAddCallback (save, XtNcallback, cb_save, (XtPointer) etext);
476 #endif
477         XtAddCallback (go, XtNcallback, cb_go, (XtPointer) etext);
478
479         XtRealizeWidget (toplevel);
480         XtAppMainLoop (app_con);
481
482         /* not reached */
483         return 0;
484 }
485
486 /* end of xa60.c */
487