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);
127 /* _O_doing_ul = 1; */ /* disabled by brg 13-April-2004 - this
128 makes the output unreadable */
142 (void) printf("%s",_O_endline);
155 _O_pchars(line,start,end)
161 for(cnt=start;cnt < end; cnt++)
166 (void) putchar('\b');
168 (void) putchar(line[cnt]);
174 ** convert a 0 origin token number to a 1 orgin token
175 ** number or 1 origin line number as appropriate
178 _O_con_line(numb,flags,filenum)
179 int numb, flags,filenum;
181 if (flags & U_TOKENS)
188 ** check to make sure that this is a real
189 ** line number. if not, then return 0
190 ** on rare occasions, (i.e. insertion/deletion
191 ** of the first token in a file) we'll get
192 ** line numbers of -1. the usual look-up technique
193 ** won't work since we have no lines before than 0.
198 ** look up the line number the token and then
199 ** add 1 to make line number 1 origin
201 return(L_tl2cl(filenum,numb)+1);
209 static char spacetext[Z_WORDLEN];
211 if (1 == strlen(ptr))
218 (void) strcpy(spacetext,"<NEWLINE>");
221 (void) strcpy(spacetext,"<TAB>");
224 (void) strcpy(spacetext,"<SPACE>");
233 _O_get_text(file,index,flags)
234 int file,index,flags;
236 static char buf[Z_LINELEN*2]; /* leave lots of room for both
237 the token text and the
238 chatter that preceeds it */
242 if (flags & U_TOKENS)
244 tmp = K_gettoken(file,index);
245 text = _O_convert(K_gettext(tmp));
246 (void) sprintf(buf,"%s -- line %d, character %d\n",
249 ** add 1 to make output start at line 1
250 ** and character numbers start at 1
252 L_tl2cl(file,K_getline(tmp))+1,
258 return(L_gettline(file,index));
267 _O_do_lines(start,end,file)
274 for (cnt=start;cnt <= end; cnt++)
276 nexttoken = K_get_token(file,cnt);
277 nextline = K_getline(nexttoken);
278 if (lastline != nextline)
280 int lastone,lastchar;
282 char linetext[Z_LINELEN+1]; /* leave room for
294 ** put loop here if you want to print
295 ** out any intervening lines that don't
296 ** have any tokens on them
300 ** following line is necessary because
301 ** L_gettline is a macro, and can't be passed
303 (void) strcpy(linetext,L_gettline(file,nextline));
304 _O_pchars(linetext,0,K_getpos(nexttoken));
307 ** look for last token on this line to be
310 for ( lastone=cnt,lasttok = K_get_token(file,lastone);
311 (lastone<=end)&&(nextline == K_getline(lasttok));
312 lastone++,lasttok = K_get_token(file,lastone))
316 lasttok = K_get_token(file,lastone);
317 lastchar = K_getpos(lasttok)
318 + strlen(K_gettext(lasttok));
319 _O_pchars(linetext,K_getpos(nexttoken),lastchar);
321 _O_pchars(linetext,lastchar,strlen(linetext));
329 O_output(start,flags)
333 int type = _O_TYPE_E; /* initialize to error state
334 ** this is to make sure that type is set
337 int t_beg1, t_beg2, t_end1, t_end2; /* token numbers */
338 int first1, last1, first2, last2;
340 E_edit ep, behind, ahead, a, b;
343 ** reverse the list of edits
347 while (ahead != E_NULL) {
349 ** set token numbers intentionally out of range
352 t_beg1 = t_beg2 = t_end1 = t_end2 = -1;
354 ** edit script is 1 origin, all of
355 ** our routines are zero origin
357 E_setl1(ahead,(E_getl1(ahead))-1);
358 E_setl2(ahead,(E_getl2(ahead))-1);
362 ahead = E_getnext(ahead);
363 E_setnext(ep,behind);
367 ** now run down the list and collect the following information
368 ** type of change (_O_APP, _O_DEL or _O_CHA)
369 ** start and length for each file
375 ** operation always start here
377 t_beg1 = E_getl1(ep);
379 ** any deletions will appear before any insertions,
380 ** so, if the first edit is an E_INSERT, then this
383 if (E_getop(ep) == E_INSERT)
387 ** run down the list looking for the edit
388 ** that is not part of the current deletion
393 } while ((b != E_NULL) &&
394 (E_getop(b) == E_DELETE) &&
395 ((E_getl1(b)) == ((E_getl1(a))+1)));
397 ** if we have an insertion at the same place
398 ** as the deletion we just scanned, then
402 ((E_getop(b)) == E_INSERT) &&
403 ((E_getl1(b))==(E_getl1(a))))
412 ** set up start and length information for
417 ** move pointer to beginning of insertion
421 ** if we are showing only a deletion,
422 ** then we're all done, so skip ahead
427 t_end2 = -1; /* dummy number, won't
433 t_beg2 = E_getl2(ep);
436 ** now run down the list lookingfor the
437 ** end of this insertion and keep count
438 ** of the number of times we step along
443 } while ((ep != E_NULL) && ((E_getop(ep)) == E_INSERT) &&
444 ((E_getl1(ep)) == (E_getl1(b))));
447 if (flags & U_TOKENS)
450 ** if we are dealing with tokens individually,
451 ** then just print then set printing so
461 ** we are printing differences in terms of lines
462 ** so find the beginning and ending lines of the
463 ** changes and print header in those terms
466 first1 = K_getline(K_get_token(0,t_beg1));
471 last1 = K_getline(K_get_token(0,t_end1));
476 first2 = K_getline(K_get_token(1,t_beg2));
481 last2 = K_getline(K_get_token(1,t_end2));
487 ** print the header for this difference
489 (void) printf("%d",_O_con_line(first1,flags,0));
493 (void) printf("a%d",_O_con_line(first2,flags,1));
496 (void) printf(",%d",_O_con_line(last2,flags,1));
503 (void) printf(",%d",_O_con_line(last1,flags,0));
505 (void) printf("d%d\n",_O_con_line(first2,flags,1));
510 (void) printf(",%d",_O_con_line(last1,flags,0));
512 (void) printf("c%d",_O_con_line(first2,flags,1));
515 (void) printf(",%d",_O_con_line(last2,flags,1));
520 Z_fatal("type in O_output wasn't set\n");
522 if (_O_DEL == type || _O_CHA == type)
524 if (flags & U_TOKENS)
527 for(cnt=first1;cnt <= last1; cnt++)
529 (void) printf("< %s",
530 _O_get_text(0,cnt,flags));
535 _O_do_lines(t_beg1,t_end1,0);
540 (void) printf("---\n");
542 if (_O_APP == type || _O_CHA == type)
544 if (flags & U_TOKENS)
547 for(cnt=first2;cnt <= last2; cnt++)
549 (void) printf("> %s",
550 _O_get_text(1,cnt,flags));
555 _O_do_lines(t_beg2,t_end2,1);