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