1*21969Sdist /* 2*21969Sdist * Copyright (c) 1980 Regents of the University of California. 3*21969Sdist * All rights reserved. The Berkeley software License Agreement 4*21969Sdist * specifies the terms and conditions for redistribution. 5*21969Sdist */ 68803Smckusick 7*21969Sdist #ifndef lint 8*21969Sdist static char sccsid[] = "@(#)io.c 5.1 (Berkeley) 06/04/85"; 9*21969Sdist #endif not lint 10*21969Sdist 118803Smckusick /* 128803Smckusick 138803Smckusick Copyright (C) 1976 148803Smckusick by the 158803Smckusick Board of Trustees 168803Smckusick of the 178803Smckusick University of Illinois 188803Smckusick 198803Smckusick All rights reserved 208803Smckusick 218803Smckusick 228803Smckusick FILE NAME: 238803Smckusick io.c 248803Smckusick 258803Smckusick PURPOSE: 268803Smckusick Contains routines to handle i/o related stuff for indent. 278803Smckusick 288803Smckusick GLOBALS: 298803Smckusick None 308803Smckusick 318803Smckusick FUNCTIONS: 328803Smckusick dump_line 338803Smckusick fill_buffer 348803Smckusick pad_output 358803Smckusick count_spaces 368803Smckusick eqin 378803Smckusick cmp 388803Smckusick 398803Smckusick */ 408803Smckusick /* 418803Smckusick 428803Smckusick Copyright (C) 1976 438803Smckusick by the 448803Smckusick Board of Trustees 458803Smckusick of the 468803Smckusick University of Illinois 478803Smckusick 488803Smckusick All rights reserved 498803Smckusick 508803Smckusick 518803Smckusick NAME: 528803Smckusick dump_line 538803Smckusick 548803Smckusick FUNCTION: 558803Smckusick Does the actual printing of the stored up line 568803Smckusick 578803Smckusick ALGORITHM: 588803Smckusick For each of the label, code, and comment sections which are used on 598803Smckusick this line: 608803Smckusick 618803Smckusick 1) Use pad_output to get the section aligned properly. 628803Smckusick 2) write the section 638803Smckusick 648803Smckusick The indentation level used for the code is set by ind_level. After 658803Smckusick printing, ind_level is set to i_l_follow. 668803Smckusick 678803Smckusick An extra level of indentation is added if ind_stmt is 1. After 688803Smckusick printing, ind_stmt is set to 1 iff the line just printed has an 698803Smckusick unterminated, non-declaration statement. 708803Smckusick 718803Smckusick PARAMETERS: 728803Smckusick None 738803Smckusick 748803Smckusick RETURNS: 758803Smckusick Nothing 768803Smckusick 778803Smckusick GLOBALS: 788803Smckusick labbuf 798803Smckusick s_lab 808803Smckusick e_lab = Reset to s_lab 818803Smckusick 828803Smckusick codebuf 838803Smckusick s_code 848803Smckusick e_code = Reset to s_code 858803Smckusick 868803Smckusick combuf 878803Smckusick s_com 888803Smckusick e_com = Reset to s_com 898803Smckusick 908803Smckusick bl_line = Set to true iff the line was blank 918803Smckusick case_ind 928803Smckusick code_lines = Count lines with code 938803Smckusick com_col 948803Smckusick com_lines = Keep track of lines with comments 958803Smckusick decl_on_line = Set to in_decl after line is printed 968803Smckusick i_l_follow 978803Smckusick in_decl 988803Smckusick in_stmt 998803Smckusick ind_level = Set to i_l_follow at completion 1008803Smckusick ind_size 1018803Smckusick ind_stmt = Set to in_stmt at completion if not in declaration 1028803Smckusick out_lines = Count output lines 1038803Smckusick p_l_follow 1048803Smckusick paren_level = Set to p_l_follow at completion 1058803Smckusick pcase 1068803Smckusick use_ff = Reset to false 1078803Smckusick 1088803Smckusick CALLS: 1098803Smckusick pad_output 1108803Smckusick printf (lib) 1118803Smckusick write (lib) 1128803Smckusick 1138803Smckusick CALLED BY: 1148803Smckusick main 1158803Smckusick pr_comment 1168803Smckusick 1178803Smckusick HISTORY: 1188803Smckusick initial coding November 1976 D A Willcox of CAC 1198803Smckusick 1208803Smckusick */ 1218803Smckusick #include "indent_globs.h"; 1228803Smckusick 1238803Smckusick 1248803Smckusick 1258803Smckusick int ff = 014; /* used to write a form feed */ 1268803Smckusick 1278803Smckusick 1288803Smckusick dump_line () { /* dump_line is the routine that actually 1298803Smckusick effects the printing of the new source. 1308803Smckusick It prints the label section, followed by 1318803Smckusick the code section with the appropriate 1328803Smckusick nesting level, followed by any comments 1338803Smckusick */ 1348803Smckusick register int cur_col, 1358803Smckusick temp_col, 1368803Smckusick target_col; 1378803Smckusick 1388803Smckusick bl_line = true; /* if we don't find otherwise, assume a 1398803Smckusick blank line */ 1408803Smckusick 1418803Smckusick if (ind_level == 0) 1428803Smckusick ind_stmt = 0; /* this is a class A kludge. don't do 1438803Smckusick additional statement indentation if we 1448803Smckusick are at bracket level 0 */ 1458803Smckusick 1468803Smckusick if (e_lab != s_lab || e_code != s_code) 1478803Smckusick ++code_lines; /* keep count of lines with code */ 1488803Smckusick 1498803Smckusick if (e_lab != s_lab) { /* print lab, if any */ 1508803Smckusick if (pcase) /* if the label is really a case, we must 1518803Smckusick indent */ 1528803Smckusick cur_col = pad_output (1, case_ind * ind_size + 1); 1538803Smckusick else { 1548803Smckusick if (*s_lab == '#') /* check for #define, etc */ 1558803Smckusick cur_col = 1; 1568803Smckusick else 1578803Smckusick cur_col = pad_output (1, ind_size * (ind_level - label_offset) + 1); 1588803Smckusick } 1598803Smckusick 1608803Smckusick write (output, s_lab, e_lab - s_lab); 1618803Smckusick cur_col = count_spaces (cur_col, s_lab); 1628803Smckusick /* count_spaces gives number of characters, considering tabs */ 1638803Smckusick bl_line = false; /* line not blank after all */ 1648803Smckusick } 1658803Smckusick else 1668803Smckusick cur_col = 1; /* there is no label section */ 1678803Smckusick 1688803Smckusick pcase = false; 1698803Smckusick 1708803Smckusick if (s_code != e_code) { /* print code section, if any */ 1718803Smckusick target_col = ind_size * (ind_level + paren_level + ind_stmt) + 1; 1728803Smckusick 1738803Smckusick cur_col = pad_output (cur_col, target_col); 1748803Smckusick /* pad_output writes enough tabs and spaces to get the current char 1758803Smckusick position up to target_col */ 1768803Smckusick write (output, s_code, e_code - s_code); 1778803Smckusick cur_col = count_spaces (cur_col, s_code); 1788803Smckusick bl_line = false; /* line not blank */ 1798803Smckusick } 1808803Smckusick 1818803Smckusick if ((cur_col - 1) > max_col && output!=1)/* check for line too long */ 1828803Smckusick printf ("%d: Code has %d chars, max is %d\n", line_no, (cur_col - 1), max_col); 1838803Smckusick 1848803Smckusick if (s_com != e_com) { /* print comment, if any */ 1858803Smckusick if (cur_col > com_col && count_spaces (cur_col, s_com) >= max_col) { 1868803Smckusick /* if comment can't fit on this line, put it on next line */ 1878803Smckusick write (output, "\n", 1); 1888803Smckusick cur_col = 1; 1898803Smckusick ++out_lines; 1908803Smckusick } 1918803Smckusick cur_col = pad_output (cur_col, com_col); 1928803Smckusick write (output, s_com, e_com - s_com); 1938803Smckusick 1948803Smckusick cur_col = count_spaces (cur_col, s_com); 1958803Smckusick if ((cur_col - 1) > max_col && output!=1)/* check for too long comment */ 1968803Smckusick printf ("%d: Comment goes to column %d. Max is %d\n", 1978803Smckusick line_no, (cur_col - 1), max_col); 1988803Smckusick 1998803Smckusick bl_line = false; 2008803Smckusick ++com_lines; /* count lines with comments */ 2018803Smckusick } 2028803Smckusick 2038803Smckusick if (use_ff) 2048803Smckusick write (output, &ff, 1);/* end the output with a ff */ 2058803Smckusick else 2068803Smckusick write (output, "\n", 1); /* or a newline */ 2078803Smckusick use_ff = false; 2088803Smckusick *(e_lab = s_lab) = '\0'; /* reset buffers */ 2098803Smckusick *(e_code = s_code) = '\0'; 2108803Smckusick *(e_com = s_com) = '\0'; 2118803Smckusick 2128803Smckusick ind_level = i_l_follow; 2138803Smckusick paren_level = p_l_follow; 2148803Smckusick ++out_lines; 2158803Smckusick decl_on_line = in_decl; /* if we are in the middle of a 2168803Smckusick declaration, remember that fact for 2178803Smckusick proper comment indentation */ 2188803Smckusick ind_stmt = in_stmt & ~in_decl; 2198803Smckusick /* next line should be indented if we have not completed this stmt and if 2208803Smckusick we are not in the middle of a declaration */ 2218803Smckusick 2228803Smckusick return; 2238803Smckusick }; 2248803Smckusick /* 2258803Smckusick 2268803Smckusick Copyright (C) 1976 2278803Smckusick by the 2288803Smckusick Board of Trustees 2298803Smckusick of the 2308803Smckusick University of Illinois 2318803Smckusick 2328803Smckusick All rights reserved 2338803Smckusick 2348803Smckusick 2358803Smckusick NAME: 2368803Smckusick fill_buffer 2378803Smckusick 2388803Smckusick FUNCTION: 2398803Smckusick Reads one block of input into input_buffer 2408803Smckusick 2418803Smckusick ALGORITHM: 2428803Smckusick Trivial 2438803Smckusick 2448803Smckusick PARAMETERS: 2458803Smckusick None 2468803Smckusick 2478803Smckusick RETURNS: 2488803Smckusick Nothing 2498803Smckusick 2508803Smckusick GLOBALS: 2518803Smckusick in_buffer = 2528803Smckusick buf_end = Set to 1 past last character read in 2538803Smckusick buf_ptr = Set to start of buffer 2548803Smckusick be_save = Set to zero if it was non-zero 2558803Smckusick bp_save = Set to zero 2568803Smckusick 2578803Smckusick CALLS: 2588803Smckusick read (lib) 2598803Smckusick 2608803Smckusick CALLED BY: 2618803Smckusick lexi 2628803Smckusick main 2638803Smckusick pr_comment 2648803Smckusick 2658803Smckusick HISTORY: 2668803Smckusick initial coding November 1976 D A Willcox of CAC 2678803Smckusick 1/7/77 D A Willcox of CAC Added check for switch back to 2688803Smckusick partly full input buffer from 2698803Smckusick temporary buffer 2708803Smckusick 2718803Smckusick */ 2728803Smckusick int fill_buffer () { /* this routine reads stuff from the input */ 2738803Smckusick int count; 2748803Smckusick register int i; 2758803Smckusick 2768803Smckusick if (bp_save != 0) { /* there is a partly filled input buffer 2778803Smckusick left */ 2788803Smckusick buf_ptr = bp_save; /* don't read anything, just switch buffers 2798803Smckusick */ 2808803Smckusick buf_end = be_save; 2818803Smckusick bp_save = be_save = 0; 2828803Smckusick if (buf_ptr < buf_end) 2838803Smckusick return; /* only return if there is really something 2848803Smckusick in this buffer */ 2858803Smckusick } 2868803Smckusick 2878803Smckusick count = read (input, in_buffer, inp_bufs); 2888803Smckusick 2898803Smckusick buf_end = in_buffer + count; 2908803Smckusick buf_ptr = in_buffer; 2918803Smckusick 2928803Smckusick if (count == 0) { /* count of zero means eof */ 2938803Smckusick had_eof = true; 2948803Smckusick *buf_end++ = ' '; 2958803Smckusick *buf_end++ = '\n'; /* insert extra newline. it will 2968803Smckusick eventually get indent to stop */ 2978803Smckusick } 2988803Smckusick 2998803Smckusick return; 3008803Smckusick }; 3018803Smckusick /* 3028803Smckusick 3038803Smckusick Copyright (C) 1976 3048803Smckusick by the 3058803Smckusick Board of Trustees 3068803Smckusick of the 3078803Smckusick University of Illinois 3088803Smckusick 3098803Smckusick All rights reserved 3108803Smckusick 3118803Smckusick 3128803Smckusick NAME: 3138803Smckusick pad_output 3148803Smckusick 3158803Smckusick FUNCTION: 3168803Smckusick Writes tabs and spaces to move the current column up to the 3178803Smckusick desired position. 3188803Smckusick 3198803Smckusick ALGORITHM: 3208803Smckusick Put tabs and/or blanks into pobuf, then write pobuf. 3218803Smckusick 3228803Smckusick PARAMETERS: 3238803Smckusick current integer The current column 3248803Smckusick target integer The desired column 3258803Smckusick 3268803Smckusick RETURNS: 3278803Smckusick Integer value of the new column. (If current >= target, 3288803Smckusick no action is taken, and current is returned. 3298803Smckusick 3308803Smckusick GLOBALS: 3318803Smckusick None 3328803Smckusick 3338803Smckusick CALLS: 3348803Smckusick write (sys) 3358803Smckusick 3368803Smckusick CALLED BY: 3378803Smckusick dump_line 3388803Smckusick 3398803Smckusick HISTORY: 3408803Smckusick initial coding November 1976 D A Willcox of CAC 3418803Smckusick 3428803Smckusick */ 3438803Smckusick int pad_output (current, target)/* writes tabs and blanks (if necessary) to 3448803Smckusick get the current output position up to 3458803Smckusick the target column */ 3468803Smckusick int current; /* the current column value */ 3478803Smckusick int target; /* position we want it at */ 3488803Smckusick { 3498803Smckusick register int curr; /* internal column pointer */ 3508803Smckusick register char *p; /* pointer into buffer of characters to be written */ 3518803Smckusick char pobuf[256]; /* pad characters are stored here before writing */ 3528803Smckusick register int tcur; 3538803Smckusick 3548803Smckusick if (current >= target) 3558803Smckusick return (current); /* line is already long enough */ 3568803Smckusick 3578803Smckusick curr = current; 3588803Smckusick p = pobuf; 3598803Smckusick while (curr < target) { 3608803Smckusick if ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target){ 3618803Smckusick *p++ = '\t'; /* put a tab into buffer */ 3628803Smckusick curr = tcur; 3638803Smckusick } 3648803Smckusick else { 3658803Smckusick while (curr++ < target) 3668803Smckusick *p++ = ' '; /* pad with final blanks */ 3678803Smckusick } 3688803Smckusick } 3698803Smckusick 3708803Smckusick write (output, pobuf, p - pobuf); /* write the characters we saved */ 3718803Smckusick return (target); 3728803Smckusick }; 3738803Smckusick /* 3748803Smckusick 3758803Smckusick Copyright (C) 1976 3768803Smckusick by the 3778803Smckusick Board of Trustees 3788803Smckusick of the 3798803Smckusick University of Illinois 3808803Smckusick 3818803Smckusick All rights reserved 3828803Smckusick 3838803Smckusick 3848803Smckusick NAME: 3858803Smckusick count_spaces 3868803Smckusick 3878803Smckusick FUNCTION: 3888803Smckusick Find out where printing of a given string will leave the current 3898803Smckusick character position on output. 3908803Smckusick 3918803Smckusick ALGORITHM: 3928803Smckusick Run thru input string and add appropriate values to current position. 3938803Smckusick 3948803Smckusick PARAMETERS: 3958803Smckusick current integer The current line character position 3968803Smckusick buffer ptr to character Pointer to input string 3978803Smckusick 3988803Smckusick RETURNS: 3998803Smckusick Integer value of position after printing "buffer" starting in 4008803Smckusick column "current". 4018803Smckusick 4028803Smckusick GLOBALS: 4038803Smckusick None 4048803Smckusick 4058803Smckusick CALLS: 4068803Smckusick None 4078803Smckusick 4088803Smckusick CALLED BY: 4098803Smckusick pr_comment 4108803Smckusick 4118803Smckusick HISTORY: 4128803Smckusick initial coding November 1976 D A Willcox of CAC 4138803Smckusick 4148803Smckusick */ 4158803Smckusick int count_spaces (current, buffer) 4168803Smckusick /* this routine figures out where the 4178803Smckusick character position will be after 4188803Smckusick printing the text in buffer starting at 4198803Smckusick column "current" */ 4208803Smckusick int current; 4218803Smckusick char *buffer; 4228803Smckusick { 4238803Smckusick register char *buf; /* used to look thru buffer */ 4248803Smckusick register int cur; /* current character counter */ 4258803Smckusick 4268803Smckusick cur = current; 4278803Smckusick 4288803Smckusick for (buf = buffer; *buf != '\0'; ++buf) { 4298803Smckusick switch (*buf) { 4308803Smckusick 4318803Smckusick case '\n': 4328803Smckusick case 014: /* form feed */ 4338803Smckusick cur = 1; 4348803Smckusick break; 4358803Smckusick 4368803Smckusick case '\t': 4378803Smckusick cur = ((cur - 1) & tabmask) + tabsize + 1; 4388803Smckusick break; 4398803Smckusick 4408803Smckusick case '': /* this is a backspace */ 4418803Smckusick --cur; 4428803Smckusick break; 4438803Smckusick 4448803Smckusick default: 4458803Smckusick ++cur; 4468803Smckusick break; 4478803Smckusick } /* end of switch */ 4488803Smckusick } /* end of for loop */ 4498803Smckusick 4508803Smckusick return (cur); 4518803Smckusick }; 4528803Smckusick /* 4538803Smckusick 4548803Smckusick Copyright (C) 1976 4558803Smckusick by the 4568803Smckusick Board of Trustees 4578803Smckusick of the 4588803Smckusick University of Illinois 4598803Smckusick 4608803Smckusick All rights reserved 4618803Smckusick 4628803Smckusick 4638803Smckusick NAME: 4648803Smckusick eqin 4658803Smckusick 4668803Smckusick FUNCTION: 4678803Smckusick Returns true if the first arg matches the beginning of the second arg. 4688803Smckusick 4698803Smckusick ALGORITHM: 4708803Smckusick Trivial 4718803Smckusick 4728803Smckusick PARAMETERS: 4738803Smckusick str1 pointer to character 4748803Smckusick str2 pointer to character 4758803Smckusick 4768803Smckusick RETURNS: 4778803Smckusick 1 if first string matches start of second string 4788803Smckusick 0 otherwise 4798803Smckusick 4808803Smckusick GLOBALS: 4818803Smckusick None 4828803Smckusick 4838803Smckusick CALLS: 4848803Smckusick None 4858803Smckusick 4868803Smckusick CALLED BY: 4878803Smckusick lexi 4888803Smckusick main 4898803Smckusick 4908803Smckusick HISTORY: 4918803Smckusick initial coding November 1976 by D A Willcox of CAC 4928803Smckusick 4938803Smckusick */ 4948803Smckusick eqin (str1, str2) 4958803Smckusick char *str1; 4968803Smckusick char *str2; 4978803Smckusick { 4988803Smckusick register char *s1; /* local pointer into first string */ 4998803Smckusick register char *s2; /* local pointer into second string */ 5008803Smckusick 5018803Smckusick s1 = str1; 5028803Smckusick s2 = str2; 5038803Smckusick while (*s1) { /* compare no further than end of first 5048803Smckusick string */ 5058803Smckusick if (*s2 == 0) /* check that second string isn't too short 5068803Smckusick */ 5078803Smckusick return (false); 5088803Smckusick if (*s1++ != *s2++) 5098803Smckusick return (false); 5108803Smckusick } 5118803Smckusick 5128803Smckusick return (true); 5138803Smckusick } 5148803Smckusick /* 5158803Smckusick Copyright (C) 1976 5168803Smckusick by the 5178803Smckusick Board of Trustees 5188803Smckusick of the 5198803Smckusick University of Illinois 5208803Smckusick 5218803Smckusick All rights reserved 5228803Smckusick 5238803Smckusick NAME: 5248803Smckusick cmp 5258803Smckusick 5268803Smckusick FUNCTION: 5278803Smckusick Compares two strings 5288803Smckusick 5298803Smckusick ALGORITHM: 5308803Smckusick Trivial 5318803Smckusick 5328803Smckusick PARAMETERS: 5338803Smckusick a Pointer to char First string to compare 5348803Smckusick b Pointer to char Second string to compare 5358803Smckusick 5368803Smckusick RETURNS: 5378803Smckusick -1 if a < b 5388803Smckusick 0 if a = b 5398803Smckusick 1 if a > b 5408803Smckusick 5418803Smckusick GLOBALS: 5428803Smckusick None 5438803Smckusick 5448803Smckusick CALLS: 5458803Smckusick None 5468803Smckusick 5478803Smckusick CALLED BY: 5488803Smckusick main 5498803Smckusick 5508803Smckusick HISTORY: 5518803Smckusick 1/7/77 D A Willcox of CAC Initial Coding 5528803Smckusick */ 5538803Smckusick int cmp (a, b) 5548803Smckusick char *a; 5558803Smckusick char *b; 5568803Smckusick { 5578803Smckusick register char *ta, 5588803Smckusick *tb; 5598803Smckusick 5608803Smckusick ta = a; 5618803Smckusick tb = b; 5628803Smckusick 5638803Smckusick while (*ta) { 5648803Smckusick if (*ta > *tb) 5658803Smckusick return (1); 5668803Smckusick if (*ta < *tb) 5678803Smckusick return (-1); 5688803Smckusick ++ta; 5698803Smckusick ++tb; 5708803Smckusick } 5718803Smckusick if (*tb) 5728803Smckusick return (1); 5738803Smckusick else 5748803Smckusick return (0); 5758803Smckusick } 576