|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */
4:
5: #include "gedit.h"
6:
7: #ifndef lint
8: static char *rcsid_gedit_c = "$Header: gedit.c,v 10.6 86/02/01 16:18:53 tony Rel $";
9: #endif lint
10:
11: char *malloc(), *gentry(), *strcpy(), *strcat();
12:
13: struct state cur_state = { /* everything about what we are doing */
14: NULL, 1, 4, 0, 0, 0, 0, 0, 0, 16, 0, NULL, 0, 0, 0
15: };
16:
17: /*extern char Aborted;*/
18:
19: struct prototype *directory;
20:
21: short incol; /* current text prompt column */
22: char *prompt; /* what the current user prompt is */
23: char typein[100]; /* user input buffer */
24:
25: char ocomp[8][8] = /* orientation composition matrix */
26: { NORTH, EAST, SOUTH, WEST, RNORTH, REAST, RSOUTH, RWEST,
27: EAST, SOUTH, WEST, NORTH, RWEST, RNORTH, REAST, RSOUTH,
28: SOUTH, WEST, NORTH, EAST, RSOUTH, RWEST, RNORTH, REAST,
29: WEST, NORTH, EAST, SOUTH, REAST, RSOUTH, RWEST, RNORTH,
30: RNORTH, REAST, RSOUTH, RWEST, NORTH, EAST, SOUTH, WEST,
31: REAST, RSOUTH, RWEST, RNORTH, WEST, NORTH, EAST, SOUTH,
32: RSOUTH, RWEST, RNORTH, REAST, SOUTH, WEST, NORTH, EAST,
33: RWEST, RNORTH, REAST, RSOUTH, EAST, SOUTH, WEST, NORTH
34: };
35:
36: char lcomp[8][9] = /* orient & label composition matrix */
37: { CC, TC, BC, CL, TL, BL, CR, TR, BR, /* north */
38: CC, CR, CL, TC, TR, TL, BC, BR, BL, /* east */
39: CC, BC, TC, CR, BR, TR, CL, BL, TL, /* south */
40: CC, CL, CR, BC, BL, BR, TC, TL, TR, /* west */
41: CC, TC, BC, CR, TR, BR, CL, TL, BL, /* rnorth */
42: CC, CL, CR, TC, TL, TR, BC, BL, BR, /* reast */
43: CC, BC, TC, CL, BL, TL, CR, BR, TR, /* rsouth */
44: CC, CR, CL, BC, BR, BL, TC, TR, TL /* rwest */
45: };
46:
47: char *lorient[] = { "cc", "tc", "bc", "cl", "tl", "bl", "cr", "tr", "br" };
48: char *oorient[] = { "n", "e", "s", "w", "rn", "re", "rs", "rw" };
49:
50: /* read a coordinate from the input file */
51: short read_coord(f)
52: FILE *f;
53: { register int ch;
54: register short coord = 0;
55: char sign = 0;
56:
57: /* skip over leading blanks */
58: while ((ch = getc(f))<=' ' && ch!=EOF);
59:
60: /* look for negative coord */
61: if (ch == '~') { sign = 1; ch = getc(f); }
62:
63: /* read in the number itself */
64: while (ch>='0' && ch<='9') {
65: coord *= 10;
66: coord += ch - '0';
67: ch = getc(f);
68: }
69:
70: return(sign ? -coord : coord);
71: }
72:
73: /* read a token from the input file */
74: read_token(f,t)
75: FILE *f;
76: register char *t;
77: { register int ch;
78:
79: /* skip over leading blanks */
80: while ((ch = getc(f))<=' ' && ch!=EOF);
81:
82: /* read in the number itself */
83: while (ch > ' ' && ch!=EOF) {
84: if (ch == '~') *t++ = ' '; /* embedded blank */
85: else *t++ = ch;
86: ch = getc(f);
87: }
88: *t = 0;
89: }
90:
91: /* read a .def file and return pointer to linked list of objects. For now,
92: * not much error checking is done...
93: */
94: struct prototype *read_def(name)
95: char *name;
96: { register int ch;
97: register gptr p;
98: struct prototype *d;
99: FILE *in;
100: char token[200],iname[100],buf[100];
101: short x1,y1,x2,y2;
102:
103: /* see if we've already got a copy in core */
104: for (d = directory; d != NULL; d = d->next)
105: if (strcmp(name,d->name) == 0) return(d);
106:
107: /* new widget, set up directory entry */
108: d = (struct prototype *)malloc(sizeof(struct prototype));
109:
110: d->recent = cur_state; /* Copy current parameters. */
111: d->recent.curobj = d;
112: d->recent.editee = NULL;
113: d->recent.curx = d->recent.cury = 0;
114: d->recent.oldx = d->recent.oldy = 0;
115: d->recent.lxoff = d->recent.lyoff = 0;
116: new_window(&d->recent,0,0);
117:
118: d->next = directory;
119: directory = d;
120: d->name = malloc((unsigned) (strlen(name) + 1));
121: strcpy(d->name,name);
122: d->body = NULL;
123: d->modified = 0;
124:
125: strcpy(iname,name);
126: strcat(iname,".def");
127: if ((in = fopen(iname,"r")) == NULL) return(d);
128: sprintf(buf,"reading in %s",iname);
129: msg(buf);
130:
131: /* read through file processing commands */
132: while ((ch = getc(in)) != EOF) switch (ch) {
133: case ' ':
134: case '\n':
135: case '\r':
136: case '\t': continue;
137:
138: case '|': while ((ch = getc(in))!='\n' && ch!=EOF);
139: continue;
140:
141: case 'd': read_token(in,token);
142: continue;
143:
144: case 'e': goto done;
145:
146: case 'm': x1 = read_coord(in);
147: y1 = read_coord(in);
148: continue;
149:
150: case 'A':
151: case 'l': x2 = read_coord(in);
152: y2 = read_coord(in);
153: if (ch == 'A') read_token(in,token); /* angle */
154: if ((p = (gptr)malloc(sizeof(struct segment))) == NULL) {
155: msg("out of room!");
156: continue;
157: }
158: p->s.type = SEGMENT;
159: p->s.selink = NULL;
160: p->s.next = d->body;
161: d->body = p;
162: p->s.parent = d;
163: p->s.x1 = x1;
164: p->s.y1 = y1;
165: p->s.x2 = x2;
166: p->s.y2 = y2;
167: if (ch == 'A') p->s.angle = atoi(token);
168: else p->s.angle = 0;
169: p->s.cache = NULL;
170: newalist(&p->s,p->s.x1,p->s.y1,p->s.x2,p->s.y2);
171: x1 = x2;
172: y1 = y2;
173: continue;
174:
175: case 'c': read_token(in,token); /* label orientation */
176: x2 = token[0];
177: y2 = token[1];
178: read_token(in,token); /* the label itself */
179: if ((p = (gptr)malloc(sizeof(struct label))) == NULL) {
180: msg("out of room!");
181: continue;
182: }
183: p->l.type = LABEL;
184: p->l.selink = NULL;
185: p->l.next = d->body;
186: d->body = p;
187: p->l.parent = d;
188: p->l.x = x1;
189: p->l.y = y1;
190: switch (x2) {
191: default:
192: case 'c': x2 = CC; break;
193: case 't': x2 = TC; break;
194: case 'b': x2 = BC; break;
195: }
196: switch (y2) {
197: default:
198: case 'c': p->l.orient = CC + x2; break;
199: case 'l': p->l.orient = CL + x2; break;
200: case 'r': p->l.orient = CR + x2; break;
201: }
202: if ((p->l.string = malloc((unsigned) (strlen(token)+1))) == NULL) {
203: msg("out of room!");
204: continue;
205: }
206: strcpy(p->l.string,token);
207: continue;
208:
209: case 'i': read_token(in,iname); /* name of file */
210:
211: /* next is "___" or scale factor */
212: read_token(in,token);
213: if (token[0]>='0' && token[0]<='9')
214: sscanf(token,"%hd:%hd",&x2,&y2);
215: else x2 = y2 = 1;
216:
217: read_token(in,token); /* orientation */
218: if ((p = (gptr)malloc(sizeof(struct object))) == NULL) {
219: msg("out of room!");
220: continue;
221: }
222: p->o.type = OBJECT;
223: p->o.selink = NULL;
224: p->o.next = d->body;
225: d->body = p;
226: p->o.parent = d;
227: p->o.x = x1;
228: p->o.y = y1;
229: if (token[0] == 'r') {
230: p->o.orient = RNORTH;
231: token[0] = token[1];
232: } else p->o.orient = NORTH;
233: switch (token[0]) {
234: default:
235: case 'n': ch = NORTH; break;
236: case 'e': ch = EAST; break;
237: case 's': ch = SOUTH; break;
238: case 'w': ch = WEST; break;
239: }
240: p->o.orient = ocomp[p->o.orient][ch];
241: p->o.proto = read_def(iname);
242: p->o.mscale = x2;
243: p->o.dscale = y2;
244: continue;
245:
246: default: sprintf(buf,"%s: unrecognized .def command: 0%o, ESC continues...",d->name,ch);
247: userinput("",buf);
248: continue;
249: }
250:
251: done: fclose(in);
252: clearprompt();
253: return(d);
254: }
255:
256: /* print .def file coordinate */
257: pcoord(f,n)
258: FILE *f;
259: { if (n < 0) fprintf(f," ~%d",-n);
260: else fprintf(f," %d",n);
261: }
262:
263: /* write out a object list */
264: write_defn(p)
265: register struct prototype *p;
266: { register gptr o;
267: char *s,temp[100],buf[100];
268: FILE *out;
269:
270: strcpy(temp,p->name);
271: strcat(temp,".def");
272: if ((out = fopen(temp,"w")) == NULL) {
273: sprintf(buf,"cannot open %s for output, ESC continues...",temp);
274: userinput("",buf);
275: return(1);
276: }
277:
278: sprintf(buf,"writing out %s",temp);
279: msg(buf);
280: fprintf(out,"d main\n");
281:
282: for (o = p->body; o != NULL; o = o->s.next) {
283: putc('m',out);
284: pcoord(out,o->s.x1);
285: pcoord(out,o->s.y1);
286: putc(' ',out);
287: switch (o->s.type) {
288: case SEGMENT:
289: if (o->s.angle == 0) {
290: putc('l',out);
291: pcoord(out,o->s.x2);
292: pcoord(out,o->s.y2);
293: } else {
294: putc('A',out);
295: pcoord(out,o->s.x2);
296: pcoord(out,o->s.y2);
297: fprintf(out," %d",o->s.angle);
298: }
299: break;
300:
301: case LABEL:
302: fprintf(out,"c %s ",lorient[o->l.orient]);
303: for (s = o->l.string; *s; s += 1)
304: putc(*s==' ' ? '~' : *s,out);
305: break;
306:
307: case OBJECT:
308: fprintf(out,"i %s %d:%d %s",
309: o->o.proto->name,
310: o->o.mscale,o->o.dscale,
311: oorient[o->o.orient]);
312: break;
313: }
314: putc('\n',out);
315: }
316:
317: fprintf(out,"e\n");
318: fclose(out);
319: clearprompt();
320: p->modified = 0; /* we've saved away changes */
321: return(0);
322: }
323:
324: /* remove an object from its prototype and reclaim its storage */
325: rmalist(q)
326: register gptr q;
327: { register gptr r;
328:
329: for (; q != NULL; q = r) {
330: r = q->s.next;
331: free((char *)q);
332: }
333: }
334:
335: remove(p)
336: register gptr p;
337: { register gptr q;
338:
339: p->s.parent->modified = 1;
340:
341: if ((q = p->s.parent->body) == p) p->s.parent->body = p->s.next;
342: else {
343: while (q->s.next!=p && q!=NULL) q = q->s.next;
344: if (q != NULL) q->s.next = p->s.next;
345: }
346:
347: if (p->s.type == LABEL) free(p->l.string);
348: else if (p->s.type == SEGMENT) rmalist(p->s.cache);
349: free((char *)p);
350: }
351:
352: main(argc,argv)
353: char **argv;
354: { register struct prototype *d;
355: char *fname;
356: char buf[100];
357:
358: fname = gentry(argc,argv); /* initialize display and keyboard */
359:
360: prompt = NULL; /* not reading anything from user */
361: typein[0] = 0;
362: directory = NULL;
363:
364: cur_state.mscale = 1; /* initial state settings */
365: cur_state.dscale = 4;
366: cur_state.csize = 16;
367: cur_state.grid = 0;
368:
369: redisplay(); /* start with a fresh slate */
370:
371: if (fname == NULL) {
372: again: do if(userinput("","name of definition to edit: ")) goto done;
373: while (typein[0] == 0);
374: d = read_def(typein);
375: } else d = read_def(fname);
376:
377: cur_state = d->recent; /* Restore state at last edit */
378: redisplay();
379:
380: while (1) {
381: extern char mousechanged;
382: if (mousechanged || UserReady()) {
383: if (command()) break;
384: } else {
385: DpyUp(0); }
386: }
387: d->recent = cur_state;
388:
389: /* check to see if we should write anything out */
390: for (d = directory; d != NULL; d = d->next)
391: if (d->modified) {
392: sprintf(buf,"%s has not been written out, should it be? (y,n) ",d->name);
393: if (userinput("",buf))
394: goto again;
395: if (typein[0] == 'y')
396: if (write_defn(d)) goto again;
397: }
398:
399: /* return to system */
400: done: gexit();
401: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.