1 /* Copyright (c) 1988 Bellcore
3 ** Permission is granted to copy or use this program, EXCEPT that it
4 ** may not be sold for profit, the copyright notice must be reproduced
5 ** on copies, and credit should be given to Bellcore where it is due.
6 ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
11 static char rcsid[]= "$Header$";
35 static int _O_need_init = 1;
36 static int _O_st_ok = 0;
37 static int _O_doing_ul = 0;
38 static char *_O_st_tmp;
40 static char _O_startline[Z_WORDLEN];
41 static char _O_endline[Z_WORDLEN];
47 char termn[Z_WORDLEN];
49 static char entry[1024];
53 ** see if standard out is a terminal
62 if (NULL == (_O_st_tmp = (char*) getenv("TERM")))
64 Z_complain("can't find TERM entry in environment\n");
69 (void) strcpy(termn,_O_st_tmp);
72 if (1 != tgetent(entry,termn))
74 Z_complain("can't get TERMCAP info for terminal\n");
80 _O_st_tmp = _O_startline;
81 _O_startline[0] = '\0';
82 tgetstr("so",&_O_st_tmp);
84 _O_st_tmp = _O_endline;
86 tgetstr("se",&_O_st_tmp);
88 _O_st_ok = (strlen(_O_startline) > 0) && (strlen(_O_endline) > 0);
92 setupterm(termn,1,&_O_st_ok);
101 ** this probably isn't necessary, but in the
102 ** name of compeleteness.
119 (void) printf("%s",_O_startline);
141 (void) printf("%s",_O_endline);
154 _O_pchars(line,start,end)
160 for(cnt=start;cnt < end; cnt++)
165 (void) putchar('\b');
167 (void) putchar(line[cnt]);
173 ** convert a 0 origin token number to a 1 orgin token
174 ** number or 1 origin line number as appropriate
177 _O_con_line(numb,flags,filenum)
178 int numb, flags,filenum;
180 if (flags & U_TOKENS)
187 ** check to make sure that this is a real
188 ** line number. if not, then return 0
189 ** on rare occasions, (i.e. insertion/deletion
190 ** of the first token in a file) we'll get
191 ** line numbers of -1. the usual look-up technique
192 ** won't work since we have no lines before than 0.
197 ** look up the line number the token and then
198 ** add 1 to make line number 1 origin
200 return(L_tl2cl(filenum,numb)+1);
208 static char spacetext[Z_WORDLEN];
210 if (1 == strlen(ptr))
217 (void) strcpy(spacetext,"<NEWLINE>");
220 (void) strcpy(spacetext,"<TAB>");
223 (void) strcpy(spacetext,"<SPACE>");
232 _O_get_text(file,index,flags)
233 int file,index,flags;
235 static char buf[Z_LINELEN*2]; /* leave lots of room for both
236 the token text and the
237 chatter that preceeds it */
241 if (flags & U_TOKENS)
243 tmp = K_gettoken(file,index);
244 text = _O_convert(K_gettext(tmp));
245 (void) sprintf(buf,"%s -- line %d, character %d\n",
248 ** add 1 to make output start at line 1
249 ** and character numbers start at 1
251 L_tl2cl(file,K_getline(tmp))+1,
257 return(L_gettline(file,index));
266 _O_do_lines(start,end,file)
273 for (cnt=start;cnt <= end; cnt++)
275 nexttoken = K_get_token(file,cnt);
276 nextline = K_getline(nexttoken);
277 if (lastline != nextline)
279 int lastone,lastchar;
281 char linetext[Z_LINELEN+1]; /* leave room for
293 ** put loop here if you want to print
294 ** out any intervening lines that don't
295 ** have any tokens on them
299 ** following line is necessary because
300 ** L_gettline is a macro, and can't be passed
302 (void) strcpy(linetext,L_gettline(file,nextline));
303 _O_pchars(linetext,0,K_getpos(nexttoken));
306 ** look for last token on this line to be
309 for ( lastone=cnt,lasttok = K_get_token(file,lastone);
310 (lastone<=end)&&(nextline == K_getline(lasttok));
311 lastone++,lasttok = K_get_token(file,lastone))
315 lasttok = K_get_token(file,lastone);
316 lastchar = K_getpos(lasttok)
317 + strlen(K_gettext(lasttok));
318 _O_pchars(linetext,K_getpos(nexttoken),lastchar);
320 _O_pchars(linetext,lastchar,strlen(linetext));
328 O_output(start,flags)
332 int type = _O_TYPE_E; /* initialize to error state
333 ** this is to make sure that type is set
336 int t_beg1, t_beg2, t_end1, t_end2; /* token numbers */
337 int first1, last1, first2, last2;
339 E_edit ep, behind, ahead, a, b;
342 ** reverse the list of edits
346 while (ahead != E_NULL) {
348 ** set token numbers intentionally out of range
351 t_beg1 = t_beg2 = t_end1 = t_end2 = -1;
353 ** edit script is 1 origin, all of
354 ** our routines are zero origin
356 E_setl1(ahead,(E_getl1(ahead))-1);
357 E_setl2(ahead,(E_getl2(ahead))-1);
361 ahead = E_getnext(ahead);
362 E_setnext(ep,behind);
366 ** now run down the list and collect the following information
367 ** type of change (_O_APP, _O_DEL or _O_CHA)
368 ** start and length for each file
374 ** operation always start here
376 t_beg1 = E_getl1(ep);
378 ** any deletions will appear before any insertions,
379 ** so, if the first edit is an E_INSERT, then this
382 if (E_getop(ep) == E_INSERT)
386 ** run down the list looking for the edit
387 ** that is not part of the current deletion
392 } while ((b != E_NULL) &&
393 (E_getop(b) == E_DELETE) &&
394 ((E_getl1(b)) == ((E_getl1(a))+1)));
396 ** if we have an insertion at the same place
397 ** as the deletion we just scanned, then
401 ((E_getop(b)) == E_INSERT) &&
402 ((E_getl1(b))==(E_getl1(a))))
411 ** set up start and length information for
416 ** move pointer to beginning of insertion
420 ** if we are showing only a deletion,
421 ** then we're all done, so skip ahead
426 t_end2 = -1; /* dummy number, won't
432 t_beg2 = E_getl2(ep);
435 ** now run down the list lookingfor the
436 ** end of this insertion and keep count
437 ** of the number of times we step along
442 } while ((ep != E_NULL) && ((E_getop(ep)) == E_INSERT) &&
443 ((E_getl1(ep)) == (E_getl1(b))));
446 if (flags & U_TOKENS)
449 ** if we are dealing with tokens individually,
450 ** then just print then set printing so
460 ** we are printing differences in terms of lines
461 ** so find the beginning and ending lines of the
462 ** changes and print header in those terms
465 first1 = K_getline(K_get_token(0,t_beg1));
470 last1 = K_getline(K_get_token(0,t_end1));
475 first2 = K_getline(K_get_token(1,t_beg2));
480 last2 = K_getline(K_get_token(1,t_end2));
486 ** print the header for this difference
488 (void) printf("%d",_O_con_line(first1,flags,0));
492 (void) printf("a%d",_O_con_line(first2,flags,1));
495 (void) printf(",%d",_O_con_line(last2,flags,1));
502 (void) printf(",%d",_O_con_line(last1,flags,0));
504 (void) printf("d%d\n",_O_con_line(first2,flags,1));
509 (void) printf(",%d",_O_con_line(last1,flags,0));
511 (void) printf("c%d",_O_con_line(first2,flags,1));
514 (void) printf(",%d",_O_con_line(last2,flags,1));
519 Z_fatal("type in O_output wasn't set\n");
521 if (_O_DEL == type || _O_CHA == type)
523 if (flags & U_TOKENS)
526 for(cnt=first1;cnt <= last1; cnt++)
528 (void) printf("< %s",
529 _O_get_text(0,cnt,flags));
534 _O_do_lines(t_beg1,t_end1,0);
539 (void) printf("---\n");
541 if (_O_APP == type || _O_CHA == type)
543 if (flags & U_TOKENS)
546 for(cnt=first2;cnt <= last2; cnt++)
548 (void) printf("> %s",
549 _O_get_text(1,cnt,flags));
554 _O_do_lines(t_beg2,t_end2,1);