xref: /csrg-svn/usr.bin/indent/io.c (revision 8803)
1*8803Smckusick static char sccsid[] = "@(#)io.c	4.1	(Berkeley)	10/21/82";
2*8803Smckusick 
3*8803Smckusick /*
4*8803Smckusick 
5*8803Smckusick 			  Copyright (C) 1976
6*8803Smckusick 				by the
7*8803Smckusick 			  Board of Trustees
8*8803Smckusick 				of the
9*8803Smckusick 			University of Illinois
10*8803Smckusick 
11*8803Smckusick 			 All rights reserved
12*8803Smckusick 
13*8803Smckusick 
14*8803Smckusick FILE NAME:
15*8803Smckusick 	io.c
16*8803Smckusick 
17*8803Smckusick PURPOSE:
18*8803Smckusick 	Contains routines to handle i/o related stuff for indent.
19*8803Smckusick 
20*8803Smckusick GLOBALS:
21*8803Smckusick 	None
22*8803Smckusick 
23*8803Smckusick FUNCTIONS:
24*8803Smckusick 	dump_line
25*8803Smckusick 	fill_buffer
26*8803Smckusick 	pad_output
27*8803Smckusick 	count_spaces
28*8803Smckusick 	eqin
29*8803Smckusick 	cmp
30*8803Smckusick 
31*8803Smckusick */
32*8803Smckusick /*
33*8803Smckusick 
34*8803Smckusick 			  Copyright (C) 1976
35*8803Smckusick 				by the
36*8803Smckusick 			  Board of Trustees
37*8803Smckusick 				of the
38*8803Smckusick 			University of Illinois
39*8803Smckusick 
40*8803Smckusick 			 All rights reserved
41*8803Smckusick 
42*8803Smckusick 
43*8803Smckusick NAME:
44*8803Smckusick 	dump_line
45*8803Smckusick 
46*8803Smckusick FUNCTION:
47*8803Smckusick 	Does the actual printing of the stored up line
48*8803Smckusick 
49*8803Smckusick ALGORITHM:
50*8803Smckusick 	For each of the label, code, and comment sections which are used on
51*8803Smckusick 	this line:
52*8803Smckusick 
53*8803Smckusick 	1) Use pad_output to get the section aligned properly.
54*8803Smckusick 	2) write the section
55*8803Smckusick 
56*8803Smckusick 	The indentation level used for the code is set by ind_level.  After
57*8803Smckusick 	printing, ind_level is set to i_l_follow.
58*8803Smckusick 
59*8803Smckusick 	An extra level of indentation is added if ind_stmt is 1.  After
60*8803Smckusick 	printing, ind_stmt is set to 1 iff the line just printed has an
61*8803Smckusick 	unterminated, non-declaration statement.
62*8803Smckusick 
63*8803Smckusick PARAMETERS:
64*8803Smckusick 	None
65*8803Smckusick 
66*8803Smckusick RETURNS:
67*8803Smckusick 	Nothing
68*8803Smckusick 
69*8803Smckusick GLOBALS:
70*8803Smckusick 	labbuf
71*8803Smckusick 	s_lab
72*8803Smckusick 	e_lab =		Reset to s_lab
73*8803Smckusick 
74*8803Smckusick 	codebuf
75*8803Smckusick 	s_code
76*8803Smckusick 	e_code =	Reset to s_code
77*8803Smckusick 
78*8803Smckusick 	combuf
79*8803Smckusick 	s_com
80*8803Smckusick 	e_com =		Reset to s_com
81*8803Smckusick 
82*8803Smckusick 	bl_line =	Set to true iff the line was blank
83*8803Smckusick 	case_ind
84*8803Smckusick 	code_lines =	Count lines with code
85*8803Smckusick 	com_col
86*8803Smckusick 	com_lines =	Keep track of lines with comments
87*8803Smckusick 	decl_on_line =	Set to in_decl after line is printed
88*8803Smckusick 	i_l_follow
89*8803Smckusick 	in_decl
90*8803Smckusick 	in_stmt
91*8803Smckusick 	ind_level =	Set to i_l_follow at completion
92*8803Smckusick 	ind_size
93*8803Smckusick 	ind_stmt =	Set to in_stmt at completion if not in declaration
94*8803Smckusick 	out_lines =	Count output lines
95*8803Smckusick 	p_l_follow
96*8803Smckusick 	paren_level =	Set to p_l_follow at completion
97*8803Smckusick 	pcase
98*8803Smckusick 	use_ff =	Reset to false
99*8803Smckusick 
100*8803Smckusick CALLS:
101*8803Smckusick 	pad_output
102*8803Smckusick 	printf (lib)
103*8803Smckusick 	write (lib)
104*8803Smckusick 
105*8803Smckusick CALLED BY:
106*8803Smckusick 	main
107*8803Smckusick 	pr_comment
108*8803Smckusick 
109*8803Smckusick HISTORY:
110*8803Smckusick 	initial coding 	November 1976	D A Willcox of CAC
111*8803Smckusick 
112*8803Smckusick */
113*8803Smckusick #include "indent_globs.h";
114*8803Smckusick 
115*8803Smckusick 
116*8803Smckusick 
117*8803Smckusick int     ff = 014;	       /* used to write a form feed */
118*8803Smckusick 
119*8803Smckusick 
120*8803Smckusick dump_line () {		       /* dump_line is the routine that actually
121*8803Smckusick 			          effects the printing of the new source.
122*8803Smckusick 			          It prints the label section, followed by
123*8803Smckusick 			          the code section with the appropriate
124*8803Smckusick 			          nesting level, followed by any comments
125*8803Smckusick 			       */
126*8803Smckusick     register int    cur_col,
127*8803Smckusick                     temp_col,
128*8803Smckusick                     target_col;
129*8803Smckusick 
130*8803Smckusick     bl_line = true;	       /* if we don't find otherwise, assume a
131*8803Smckusick 			          blank line */
132*8803Smckusick 
133*8803Smckusick     if (ind_level == 0)
134*8803Smckusick 	ind_stmt = 0;	       /* this is a class A kludge. don't do
135*8803Smckusick 			          additional statement indentation if we
136*8803Smckusick 			          are at bracket level 0 */
137*8803Smckusick 
138*8803Smckusick     if (e_lab != s_lab || e_code != s_code)
139*8803Smckusick 	++code_lines;	       /* keep count of lines with code */
140*8803Smckusick 
141*8803Smckusick     if (e_lab != s_lab) {      /* print lab, if any */
142*8803Smckusick 	if (pcase)	       /* if the label is really a case, we must
143*8803Smckusick 			          indent */
144*8803Smckusick 	    cur_col = pad_output (1, case_ind * ind_size + 1);
145*8803Smckusick 	else {
146*8803Smckusick 	    if (*s_lab == '#') /* check for #define, etc */
147*8803Smckusick 		cur_col = 1;
148*8803Smckusick 	    else
149*8803Smckusick 		cur_col = pad_output (1, ind_size * (ind_level - label_offset) + 1);
150*8803Smckusick 	}
151*8803Smckusick 
152*8803Smckusick 	write (output, s_lab, e_lab - s_lab);
153*8803Smckusick 	cur_col = count_spaces (cur_col, s_lab);
154*8803Smckusick     /* count_spaces gives number of characters, considering tabs */
155*8803Smckusick 	bl_line = false;       /* line not blank after all */
156*8803Smckusick     }
157*8803Smckusick     else
158*8803Smckusick 	cur_col = 1;	       /* there is no label section */
159*8803Smckusick 
160*8803Smckusick     pcase = false;
161*8803Smckusick 
162*8803Smckusick     if (s_code != e_code) {    /* print code section, if any */
163*8803Smckusick 	target_col = ind_size * (ind_level + paren_level + ind_stmt) + 1;
164*8803Smckusick 
165*8803Smckusick 	cur_col = pad_output (cur_col, target_col);
166*8803Smckusick     /* pad_output writes enough tabs and spaces to get the current char
167*8803Smckusick        position up to target_col */
168*8803Smckusick 	write (output, s_code, e_code - s_code);
169*8803Smckusick 	cur_col = count_spaces (cur_col, s_code);
170*8803Smckusick 	bl_line = false;       /* line not blank */
171*8803Smckusick     }
172*8803Smckusick 
173*8803Smckusick     if ((cur_col - 1) > max_col && output!=1)/* check for line too long */
174*8803Smckusick 	printf ("%d: Code has %d chars, max is %d\n", line_no, (cur_col - 1), max_col);
175*8803Smckusick 
176*8803Smckusick     if (s_com != e_com) {      /* print comment, if any */
177*8803Smckusick 	if (cur_col > com_col && count_spaces (cur_col, s_com) >= max_col) {
178*8803Smckusick 	/* if comment can't fit on this line, put it on next line */
179*8803Smckusick 	    write (output, "\n", 1);
180*8803Smckusick 	    cur_col = 1;
181*8803Smckusick 	    ++out_lines;
182*8803Smckusick 	}
183*8803Smckusick 	cur_col = pad_output (cur_col, com_col);
184*8803Smckusick 	write (output, s_com, e_com - s_com);
185*8803Smckusick 
186*8803Smckusick 	cur_col = count_spaces (cur_col, s_com);
187*8803Smckusick 	if ((cur_col - 1) > max_col && output!=1)/* check for too long comment */
188*8803Smckusick 	    printf ("%d: Comment goes to column %d.  Max is %d\n",
189*8803Smckusick 		line_no, (cur_col - 1), max_col);
190*8803Smckusick 
191*8803Smckusick 	bl_line = false;
192*8803Smckusick 	++com_lines;	       /* count lines with comments */
193*8803Smckusick     }
194*8803Smckusick 
195*8803Smckusick     if (use_ff)
196*8803Smckusick 	write (output, &ff, 1);/* end the output with a ff */
197*8803Smckusick     else
198*8803Smckusick 	write (output, "\n", 1); /* or a newline */
199*8803Smckusick     use_ff = false;
200*8803Smckusick     *(e_lab = s_lab) = '\0';   /* reset buffers */
201*8803Smckusick     *(e_code = s_code) = '\0';
202*8803Smckusick     *(e_com = s_com) = '\0';
203*8803Smckusick 
204*8803Smckusick     ind_level = i_l_follow;
205*8803Smckusick     paren_level = p_l_follow;
206*8803Smckusick     ++out_lines;
207*8803Smckusick     decl_on_line = in_decl;    /* if we are in the middle of a
208*8803Smckusick 			          declaration, remember that fact for
209*8803Smckusick 			          proper comment indentation */
210*8803Smckusick     ind_stmt = in_stmt & ~in_decl;
211*8803Smckusick  /* next line should be indented if we have not completed this stmt and if
212*8803Smckusick     we are not in the middle of a declaration */
213*8803Smckusick 
214*8803Smckusick     return;
215*8803Smckusick };
216*8803Smckusick /*
217*8803Smckusick 
218*8803Smckusick 			  Copyright (C) 1976
219*8803Smckusick 				by the
220*8803Smckusick 			  Board of Trustees
221*8803Smckusick 				of the
222*8803Smckusick 			University of Illinois
223*8803Smckusick 
224*8803Smckusick 			 All rights reserved
225*8803Smckusick 
226*8803Smckusick 
227*8803Smckusick NAME:
228*8803Smckusick 	fill_buffer
229*8803Smckusick 
230*8803Smckusick FUNCTION:
231*8803Smckusick 	Reads one block of input into input_buffer
232*8803Smckusick 
233*8803Smckusick ALGORITHM:
234*8803Smckusick 	Trivial
235*8803Smckusick 
236*8803Smckusick PARAMETERS:
237*8803Smckusick 	None
238*8803Smckusick 
239*8803Smckusick RETURNS:
240*8803Smckusick 	Nothing
241*8803Smckusick 
242*8803Smckusick GLOBALS:
243*8803Smckusick 	in_buffer =
244*8803Smckusick 	buf_end =	Set to 1 past last character read in
245*8803Smckusick 	buf_ptr =	Set to start of buffer
246*8803Smckusick 	be_save =	Set to zero if it was non-zero
247*8803Smckusick 	bp_save =	Set to zero
248*8803Smckusick 
249*8803Smckusick CALLS:
250*8803Smckusick 	read (lib)
251*8803Smckusick 
252*8803Smckusick CALLED BY:
253*8803Smckusick 	lexi
254*8803Smckusick 	main
255*8803Smckusick 	pr_comment
256*8803Smckusick 
257*8803Smckusick HISTORY:
258*8803Smckusick 	initial coding 	November 1976	D A Willcox of CAC
259*8803Smckusick 	1/7/77		D A Willcox of CAC	Added check for switch back to
260*8803Smckusick 						partly full input buffer from
261*8803Smckusick 						temporary buffer
262*8803Smckusick 
263*8803Smckusick */
264*8803Smckusick int     fill_buffer () { /* this routine reads stuff from the input */
265*8803Smckusick     int     count;
266*8803Smckusick     register int    i;
267*8803Smckusick 
268*8803Smckusick     if (bp_save != 0) {	       /* there is a partly filled input buffer
269*8803Smckusick 			          left */
270*8803Smckusick 	buf_ptr = bp_save;     /* don't read anything, just switch buffers
271*8803Smckusick 			       */
272*8803Smckusick 	buf_end = be_save;
273*8803Smckusick 	bp_save = be_save = 0;
274*8803Smckusick 	if (buf_ptr < buf_end)
275*8803Smckusick 	    return;	       /* only return if there is really something
276*8803Smckusick 			          in this buffer */
277*8803Smckusick     }
278*8803Smckusick 
279*8803Smckusick     count = read (input, in_buffer, inp_bufs);
280*8803Smckusick 
281*8803Smckusick     buf_end = in_buffer + count;
282*8803Smckusick     buf_ptr = in_buffer;
283*8803Smckusick 
284*8803Smckusick     if (count == 0) {	       /* count of zero means eof */
285*8803Smckusick 	had_eof = true;
286*8803Smckusick 	*buf_end++ = ' ';
287*8803Smckusick 	*buf_end++ = '\n';     /* insert extra newline.  it will
288*8803Smckusick 			          eventually get indent to stop */
289*8803Smckusick     }
290*8803Smckusick 
291*8803Smckusick     return;
292*8803Smckusick };
293*8803Smckusick /*
294*8803Smckusick 
295*8803Smckusick 			  Copyright (C) 1976
296*8803Smckusick 				by the
297*8803Smckusick 			  Board of Trustees
298*8803Smckusick 				of the
299*8803Smckusick 			University of Illinois
300*8803Smckusick 
301*8803Smckusick 			 All rights reserved
302*8803Smckusick 
303*8803Smckusick 
304*8803Smckusick NAME:
305*8803Smckusick 	pad_output
306*8803Smckusick 
307*8803Smckusick FUNCTION:
308*8803Smckusick 	Writes tabs and spaces to move the current column up to the
309*8803Smckusick 	desired position.
310*8803Smckusick 
311*8803Smckusick ALGORITHM:
312*8803Smckusick 	Put tabs and/or blanks into pobuf, then write pobuf.
313*8803Smckusick 
314*8803Smckusick PARAMETERS:
315*8803Smckusick 	current		integer		The current column
316*8803Smckusick 	target		integer		The desired column
317*8803Smckusick 
318*8803Smckusick RETURNS:
319*8803Smckusick 	Integer value of the new column.  (If current >= target,
320*8803Smckusick 	no action is taken, and current is returned.
321*8803Smckusick 
322*8803Smckusick GLOBALS:
323*8803Smckusick 	None
324*8803Smckusick 
325*8803Smckusick CALLS:
326*8803Smckusick 	write (sys)
327*8803Smckusick 
328*8803Smckusick CALLED BY:
329*8803Smckusick 	dump_line
330*8803Smckusick 
331*8803Smckusick HISTORY:
332*8803Smckusick 	initial coding 	November 1976	D A Willcox of CAC
333*8803Smckusick 
334*8803Smckusick */
335*8803Smckusick int     pad_output (current, target)/* writes tabs and blanks (if necessary) to
336*8803Smckusick 			          get the current output position up to
337*8803Smckusick 			          the target column */
338*8803Smckusick int     current;	       /* the current column value */
339*8803Smckusick int     target;		       /* position we want it at */
340*8803Smckusick {
341*8803Smckusick     register int    curr; /* internal column pointer */
342*8803Smckusick     register char  *p; /* pointer into buffer of characters to be written */
343*8803Smckusick     char    pobuf[256]; /* pad characters are stored here before writing */
344*8803Smckusick     register int tcur;
345*8803Smckusick 
346*8803Smckusick     if (current >= target)
347*8803Smckusick 	return (current);      /* line is already long enough */
348*8803Smckusick 
349*8803Smckusick     curr = current;
350*8803Smckusick     p = pobuf;
351*8803Smckusick     while (curr < target) {
352*8803Smckusick 	if ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target){
353*8803Smckusick 	    *p++ = '\t';       /* put a tab into buffer */
354*8803Smckusick 	    curr = tcur;
355*8803Smckusick 	}
356*8803Smckusick 	else {
357*8803Smckusick 	    while (curr++ < target)
358*8803Smckusick 		*p++ = ' ';    /* pad with final blanks */
359*8803Smckusick 	}
360*8803Smckusick     }
361*8803Smckusick 
362*8803Smckusick     write (output, pobuf, p - pobuf); /* write the characters we saved */
363*8803Smckusick     return (target);
364*8803Smckusick };
365*8803Smckusick /*
366*8803Smckusick 
367*8803Smckusick 			  Copyright (C) 1976
368*8803Smckusick 				by the
369*8803Smckusick 			  Board of Trustees
370*8803Smckusick 				of the
371*8803Smckusick 			University of Illinois
372*8803Smckusick 
373*8803Smckusick 			 All rights reserved
374*8803Smckusick 
375*8803Smckusick 
376*8803Smckusick NAME:
377*8803Smckusick 	count_spaces
378*8803Smckusick 
379*8803Smckusick FUNCTION:
380*8803Smckusick 	Find out where printing of a given string will leave the current
381*8803Smckusick 	character position on output.
382*8803Smckusick 
383*8803Smckusick ALGORITHM:
384*8803Smckusick 	Run thru input string and add appropriate values to current position.
385*8803Smckusick 
386*8803Smckusick PARAMETERS:
387*8803Smckusick 	current		integer		  The current line character position
388*8803Smckusick 	buffer		ptr to character  Pointer to input string
389*8803Smckusick 
390*8803Smckusick RETURNS:
391*8803Smckusick 	Integer value of position after printing "buffer" starting in
392*8803Smckusick 	column "current".
393*8803Smckusick 
394*8803Smckusick GLOBALS:
395*8803Smckusick 	None
396*8803Smckusick 
397*8803Smckusick CALLS:
398*8803Smckusick 	None
399*8803Smckusick 
400*8803Smckusick CALLED BY:
401*8803Smckusick 	pr_comment
402*8803Smckusick 
403*8803Smckusick HISTORY:
404*8803Smckusick 	initial coding 	November 1976	D A Willcox of CAC
405*8803Smckusick 
406*8803Smckusick */
407*8803Smckusick int     count_spaces (current, buffer)
408*8803Smckusick 			       /* this routine figures out where the
409*8803Smckusick 			          character position will be after
410*8803Smckusick 			          printing the text in buffer starting at
411*8803Smckusick 			          column "current" */
412*8803Smckusick int     current;
413*8803Smckusick char   *buffer;
414*8803Smckusick {
415*8803Smckusick     register char  *buf; /* used to look thru buffer */
416*8803Smckusick     register int    cur; /* current character counter */
417*8803Smckusick 
418*8803Smckusick     cur = current;
419*8803Smckusick 
420*8803Smckusick     for (buf = buffer; *buf != '\0'; ++buf) {
421*8803Smckusick 	switch (*buf) {
422*8803Smckusick 
423*8803Smckusick 	    case '\n':
424*8803Smckusick 	    case 014: 	       /* form feed */
425*8803Smckusick 		cur = 1;
426*8803Smckusick 		break;
427*8803Smckusick 
428*8803Smckusick 	    case '\t':
429*8803Smckusick 		cur = ((cur - 1) & tabmask) + tabsize + 1;
430*8803Smckusick 		break;
431*8803Smckusick 
432*8803Smckusick 	    case '': 	       /* this is a backspace */
433*8803Smckusick 		--cur;
434*8803Smckusick 		break;
435*8803Smckusick 
436*8803Smckusick 	    default:
437*8803Smckusick 		++cur;
438*8803Smckusick 		break;
439*8803Smckusick 	}		       /* end of switch */
440*8803Smckusick     }			       /* end of for loop */
441*8803Smckusick 
442*8803Smckusick     return (cur);
443*8803Smckusick };
444*8803Smckusick /*
445*8803Smckusick 
446*8803Smckusick 			  Copyright (C) 1976
447*8803Smckusick 				by the
448*8803Smckusick 			  Board of Trustees
449*8803Smckusick 				of the
450*8803Smckusick 			University of Illinois
451*8803Smckusick 
452*8803Smckusick 			 All rights reserved
453*8803Smckusick 
454*8803Smckusick 
455*8803Smckusick NAME:
456*8803Smckusick 	eqin
457*8803Smckusick 
458*8803Smckusick FUNCTION:
459*8803Smckusick 	Returns true if the first arg matches the beginning of the second arg.
460*8803Smckusick 
461*8803Smckusick ALGORITHM:
462*8803Smckusick 	Trivial
463*8803Smckusick 
464*8803Smckusick PARAMETERS:
465*8803Smckusick 	str1	pointer to character
466*8803Smckusick 	str2	pointer to character
467*8803Smckusick 
468*8803Smckusick RETURNS:
469*8803Smckusick 	1 if first string matches start of second string
470*8803Smckusick 	0 otherwise
471*8803Smckusick 
472*8803Smckusick GLOBALS:
473*8803Smckusick 	None
474*8803Smckusick 
475*8803Smckusick CALLS:
476*8803Smckusick 	None
477*8803Smckusick 
478*8803Smckusick CALLED BY:
479*8803Smckusick 	lexi
480*8803Smckusick 	main
481*8803Smckusick 
482*8803Smckusick HISTORY:
483*8803Smckusick 	initial coding November 1976 by D A Willcox of CAC
484*8803Smckusick 
485*8803Smckusick */
486*8803Smckusick eqin (str1, str2)
487*8803Smckusick char   *str1;
488*8803Smckusick char   *str2;
489*8803Smckusick {
490*8803Smckusick     register char  *s1; /* local pointer into first string */
491*8803Smckusick     register char  *s2; /* local pointer into second string */
492*8803Smckusick 
493*8803Smckusick     s1 = str1;
494*8803Smckusick     s2 = str2;
495*8803Smckusick     while (*s1) {	       /* compare no further than end of first
496*8803Smckusick 			          string */
497*8803Smckusick 	if (*s2 == 0)	       /* check that second string isn't too short
498*8803Smckusick 			       */
499*8803Smckusick 	    return (false);
500*8803Smckusick 	if (*s1++ != *s2++)
501*8803Smckusick 	    return (false);
502*8803Smckusick     }
503*8803Smckusick 
504*8803Smckusick     return (true);
505*8803Smckusick }
506*8803Smckusick /*
507*8803Smckusick 			  Copyright (C) 1976
508*8803Smckusick 				by the
509*8803Smckusick 			  Board of Trustees
510*8803Smckusick 				of the
511*8803Smckusick 			University of Illinois
512*8803Smckusick 
513*8803Smckusick 			 All rights reserved
514*8803Smckusick 
515*8803Smckusick NAME:
516*8803Smckusick 	cmp
517*8803Smckusick 
518*8803Smckusick FUNCTION:
519*8803Smckusick 	Compares two strings
520*8803Smckusick 
521*8803Smckusick ALGORITHM:
522*8803Smckusick 	Trivial
523*8803Smckusick 
524*8803Smckusick PARAMETERS:
525*8803Smckusick 	a	Pointer to char		First string to compare
526*8803Smckusick 	b	Pointer to char		Second string to compare
527*8803Smckusick 
528*8803Smckusick RETURNS:
529*8803Smckusick 	-1 if a < b
530*8803Smckusick 	 0 if a = b
531*8803Smckusick 	 1 if a > b
532*8803Smckusick 
533*8803Smckusick GLOBALS:
534*8803Smckusick 	None
535*8803Smckusick 
536*8803Smckusick CALLS:
537*8803Smckusick 	None
538*8803Smckusick 
539*8803Smckusick CALLED BY:
540*8803Smckusick 	main
541*8803Smckusick 
542*8803Smckusick HISTORY:
543*8803Smckusick 	1/7/77		D A Willcox of CAC	Initial Coding
544*8803Smckusick */
545*8803Smckusick int     cmp (a, b)
546*8803Smckusick char   *a;
547*8803Smckusick char   *b;
548*8803Smckusick {
549*8803Smckusick     register char  *ta,
550*8803Smckusick                    *tb;
551*8803Smckusick 
552*8803Smckusick     ta = a;
553*8803Smckusick     tb = b;
554*8803Smckusick 
555*8803Smckusick     while (*ta) {
556*8803Smckusick 	if (*ta > *tb)
557*8803Smckusick 	    return (1);
558*8803Smckusick 	if (*ta < *tb)
559*8803Smckusick 	    return (-1);
560*8803Smckusick 	++ta;
561*8803Smckusick 	++tb;
562*8803Smckusick     }
563*8803Smckusick     if (*tb)
564*8803Smckusick 	return (1);
565*8803Smckusick     else
566*8803Smckusick 	return (0);
567*8803Smckusick }
568