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