Annotation of 42BSD/ucb/indent/indent.c, revision 1.1.1.1

1.1       root        1: static char sccsid[] = "@(#)indent.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: NAME:
                     15:        indent main program
                     16: 
                     17: FUNCTION:
                     18:        This is the main program of the indent program.  Indent will take a C
                     19:        program source and reformat it into a semi-reasonable form.
                     20: 
                     21: ALGORITHM:
                     22:        The routine lexi scans tokens and passes them back one at a time to the
                     23:        main routine.  The subroutine parse takes care of much of the work of
                     24:        figuring indentation level.  
                     25: 
                     26:        1) Call lexi
                     27:        2) Enter a monster switch statement on the code returned by lexi.  If 
                     28:           the indentation level for the line yet to be printed should be 
                     29:           changed, set the variable ind_level.  If the indentation level for
                     30:           the following line should be changed, set the variable i_l_follow.
                     31: 
                     32: PARAMETERS:
                     33:        None
                     34: 
                     35: RETURNS:
                     36:        Nothing
                     37: 
                     38: GLOBALS:
                     39:        be_save =
                     40:        break_comma
                     41:        bp_save =
                     42:        btype_2 =
                     43:        code_lines
                     44:        com_ind =
                     45:        com_lines
                     46:        dec_nest =
                     47:        decl_com_ind =
                     48:        decl_on_line =
                     49:        i_l_follow =
                     50:        in_decl =
                     51:        ind_level =
                     52:        ind_size =
                     53:        ind_stmt =
                     54:        last_u_d =
                     55:        leave_comma =
                     56:        line_no =
                     57:        ljust_decl =
                     58:        max_col =
                     59:        out_coms
                     60:        out_lines
                     61:        p_l_follow =
                     62:        paren_level =
                     63:        pcase =
                     64:        sc_end =
                     65:        unindent_displace =
                     66:        use_ff =
                     67:        verbose =
                     68: 
                     69: CALLS:
                     70:        atoi (lib)
                     71:        cmp
                     72:        creat (lib)
                     73:        dump_line
                     74:        eqin
                     75:        fill_buffer
                     76:        lexi
                     77:        open (lib)
                     78:        parse
                     79:        pr_comment
                     80:        printf (lib)
                     81:        seek (lib)
                     82:        time (lib)
                     83: 
                     84: CALLED BY:
                     85:        No one (main routine)
                     86: 
                     87: HISTORY:
                     88:        November 1976   D A Willcox of CAC      Initial coding
                     89:        12/9/76         D A Willcox of CAC      Fixed defaults for decl_com_ind
                     90:                                                to be 8 less than com_ind if 
                     91:                                                left justifying declarations
                     92:        12/9/76         D A Willcox of CAC      Fixed processing of nested
                     93:                                                <c>?<s>:<s> constructs
                     94:        1/7/77          D A Willcox of CAC      Added check for overwrite of
                     95:                                                input file
                     96:                                                Added code to handle -br and -bl
                     97:                                                parameters
                     98: */
                     99: #include "indent_globs.h";
                    100: #include "indent_codes.h";
                    101: 
                    102: /* #define dolog 1     /* if this define is removed, then the code to
                    103:                           produce a log file will be removed */
                    104: 
                    105: struct templ {                /* this is a template for the list of
                    106:                                  command line args */
                    107:     char   *str;              /* pointer to string which is a valid
                    108:                                  command line arg */
                    109:     int     code;             /* code to be used in switch for processing
                    110:                                  this arg */
                    111: };
                    112: 
                    113: 
                    114: struct templ    options[] =
                    115: {                             /* warning - because of the way that this
                    116:                                  table is scanned, if one entry is an
                    117:                                  initial substring of another, then the
                    118:                                  longer entry should occur first */
                    119:     "-cd", 4,
                    120:     "-c", 2,
                    121:     "-l", 1,
                    122:     "-i", 3,
                    123:     "-v", 5,
                    124:     "-nv", 6,
                    125:     "-dj", 7,
                    126:     "-d", 13,                 /* unindented comment placement */
                    127:     "-ndj", 8,
                    128:     "-bc", 10,                /* break after command in decl */
                    129:     "-nbc", 9,                /* don't break after comma */
                    130:     "-br", 14,                /* put brace on right of stmt */
                    131:     "-bl", 15,                /* put brace on left by itself */
                    132:     "-st", 16,                /* use the standard input and output
                    133:                                  files */
                    134:     0, 0
                    135: };
                    136: 
                    137: 
                    138: char   *in_name = "Standard Input";
                    139:                               /* will always point to name of input file 
                    140:                               */
                    141: char   *out_name = "Standard Output";
                    142:                               /* will always point to name of output file
                    143:                                  */
                    144: char    bakfile[32] = "";
                    145: 
                    146: main (argc, argv)
                    147: int     argc;
                    148: char  **argv;
                    149: {
                    150: 
                    151:     int     dec_ind;          /* current indentation for declarations */
                    152:     int     di_stack[20];      /* a stack of structure indentation levels 
                    153:                               */
                    154:     int     flushed_nl;               /* used when buffering up comments to
                    155:                                  remember that a newline was passed over 
                    156:                               */
                    157:     int     force_nl;         /* when true, code must be broken */
                    158:     int     hd_type;          /* used to store type of stmt for if (...),
                    159:                                  for (...), etc */
                    160:     register int    i;        /* local loop counter */
                    161:     int     in_or_st;         /* Will be true iff there has been a
                    162:                                  declarator (e.g. int or char) and no
                    163:                                  left paren since the last semicolon.
                    164:                                  When true, a { is starting a structure
                    165:                                  definition or an initialization list */
                    166:     register int    j;        /* local loop counter */
                    167:     int     scase;            /* set to true when we see a case, so we
                    168:                                  will know what to do with the following
                    169:                                  colon */
                    170:     int     sp_sw;            /* when true, we are in the expressin of
                    171:                                  if(...), while(...), etc. */
                    172:     int     squest;           /* when this is positive, we have seen a ?
                    173:                                  without the matching : in a <c>?<s>:<s>
                    174:                                  construct */
                    175:     register char  *t_ptr;     /* used for copying tokens */
                    176:     int     type_code;        /* the type of token, returned by lexi */
                    177:     int     want_blank;               /* set to true when the following token
                    178:                                  should be prefixed by a blank. (Said
                    179:                                  prefixing is ignored in some cases.) */
                    180: 
                    181: #ifdef dolog                  /* include declarations needed for log */
                    182:     int     log_fid;          /* fid of log file */
                    183: 
                    184:     struct logtmpl {          /* structure of a log entry */
                    185:        int     tvec[2];       /* time of execution */
                    186:        char    inp;           /* input fid */
                    187:        char    outp;          /* output fid */
                    188:        int     nout;          /* # output lines */
                    189:        int     ncom;          /* # comments */
                    190:        int     wcom;          /* # lines w/ comments */
                    191:        int     wcode;         /* # lines w/code */
                    192:        char    mc;            /* max line size */
                    193:        char    ci;            /* comment indentation */
                    194:        char    inds;          /* indent size */
                    195:        char    dci;           /* decl comment indentation */
                    196:        char    verb;          /* verbose */
                    197:        char    ljus;          /* left just */
                    198:        char    lvcom;         /* leave commas */
                    199:        char    unin;          /* unindented comment indentation */
                    200:        char    uid;           /* the user id */
                    201:        char    bropt;         /* btype_2 */
                    202:        int     reserved[2];
                    203:     };
                    204: 
                    205:     struct logtmpl  logent;
                    206: #endif
                    207: 
                    208: /*-----------------------------------------------*\
                    209: |    INITIALIZATION
                    210: \*-----------------------------------------------*/
                    211: 
                    212: 
                    213:     combuf[0] = codebuf[0] = labbuf[0] = ' ';
                    214:  /* set up code, label, and comment buffers */
                    215:     combuf[1] = codebuf[1] = labbuf[1] = '\0';
                    216:     s_lab = e_lab = labbuf + 1;
                    217:     s_code = e_code = codebuf + 1;
                    218:     s_com = e_com = combuf + 1;
                    219: 
                    220:     buf_ptr = buf_end = in_buffer;
                    221:     line_no = 1;
                    222:     had_eof = in_decl = decl_on_line = break_comma = false;
                    223:     sp_sw = force_nl = false;
                    224:     in_or_st = false;
                    225:     bl_line = true;
                    226:     dec_ind = 0;
                    227:     di_stack[dec_nest = 0] = 0;
                    228:     want_blank = in_stmt = ind_stmt = false;
                    229: 
                    230: 
                    231:     scase = pcase = false;
                    232:     squest = 0;
                    233:     sc_end = 0;
                    234:     bp_save = 0;
                    235:     be_save = 0;
                    236: 
                    237:     input = -1;
                    238:     output = -1;
                    239:     ljust_decl = d_ljust;
                    240: 
                    241: 
                    242: 
                    243: /*--------------------------------------------------*\
                    244: |   COMMAND LINE SCAN
                    245: \*--------------------------------------------------*/
                    246: 
                    247:     max_col = d_max_col;       /* set up some default values */
                    248:     com_ind = d_com_ind;
                    249:     ind_size = d_ind_size;
                    250:     verbose = d_verbose;
                    251:     decl_com_ind = 0;         /* if this is not set to some positive
                    252:                                  value by an arg, we will set this equal
                    253:                                  to com_ind */
                    254:     btype_2 = d_btype_2;
                    255:     unindent_displace = d_unindent;
                    256:     leave_comma = d_leave_comma;
                    257: 
                    258:     set_profile ();
                    259: 
                    260:     for (i = 1; i < argc; ++i) {
                    261:     /* look thru args (if any) for changes to defaults */
                    262:        if (argv[i][0] != '-') {/* no flag on parameter */
                    263:            if (input < 0) {   /* we must have the input file */
                    264:                in_name = argv[i];      /* remember name of input
                    265:                                           file */
                    266:                input = open (in_name, 0);
                    267:                if (input < 0) {        /* check for open error */
                    268:                    printf ("Can't open %s\n", argv[i]);
                    269:                    exit ();
                    270:                }
                    271:                continue;
                    272:            }
                    273:            else
                    274:                if (output < 0) {       /* we have the output file */
                    275:                    out_name = argv[i]; /* remember name of output file */
                    276:                    if (cmp (in_name, out_name) == 0) {  /* attempt to
                    277:                                           overwright the file */
                    278:                        printf ("Input and output files must be different\n");
                    279:                        exit ();
                    280:                    }
                    281:                    output = creat (out_name, 0644);
                    282:                    if (output < 0) {   /* check for create error */
                    283:                        printf ("Can't create %s\n", argv[i]);
                    284:                        exit ();
                    285:                    }
                    286:                    continue;
                    287:                }
                    288: 
                    289:            printf ("Unknown parameter: %s\n", argv[i]);
                    290:            exit ();
                    291:        }
                    292:        else
                    293:            set_option (argv[i]);
                    294: 
                    295:     }                         /* end of for */
                    296: 
                    297:     if (input < 0) {
                    298:        printf ("Usage: indent file [ outfile ] [ options ]\n");
                    299:        exit ();
                    300:     }
                    301:     if (output < 0) {
                    302:        out_name = in_name;
                    303:        bakcopy ();
                    304:     }
                    305: 
                    306:     if (com_ind <= 1)
                    307:        com_ind = 2;           /* don't put normal comments before column
                    308:                                  2 */
                    309: 
                    310:     if (decl_com_ind <= 0)     /* if not specified by user, set this */
                    311:        decl_com_ind = ljust_decl ? (com_ind <= 10 ? 2 : com_ind - 8) : com_ind;
                    312: 
                    313:     fill_buffer ();           /* get first batch of stuff into input
                    314:                                  buffer */
                    315: 
                    316:     parse (semicolon);
                    317: /*-----------------------------------------------------
                    318: |   START OF MAIN LOOP
                    319: \*----------------------------------------------------*/
                    320: 
                    321:     while (1) {                       /* this is the main loop.  it will go until
                    322:                                  we reach eof */
                    323:        type_code = lexi ();   /* lexi reads one token.  The actual
                    324:                                  characters read are stored in "token".
                    325:                                  lexi returns a code indicating the type
                    326:                                  of token */
                    327: 
                    328:     /* 
                    329:      * The following code moves everything following an if (), while (),
                    330:      * else, etc. up to the start of the following stmt to a buffer.  This
                    331:      * allows proper handling of both kinds of brace placement.
                    332:      */
                    333: 
                    334:        flushed_nl = false;
                    335:        while (search_brace) { /* if we scanned an if(), while(), etc., we
                    336:                                  might need to copy stuff into a buffer 
                    337:        *//* we must loop, copying stuff into save_com, until we find the
                    338:           start of the stmt which follows the if, or whatever */
                    339:            switch (type_code) {
                    340:                case newline: 
                    341:                    ++line_no;
                    342:                    flushed_nl = true;
                    343:                case form_feed: 
                    344:                    break;     /* form feeds and newlines found here will
                    345:                                  be ignored */
                    346: 
                    347:                case lbrace:   /* this is a brace that starts the compound
                    348:                                  stmt */
                    349:                    if (sc_end == 0) {
                    350:                    /* ignore buffering if a comment wasn't stored up */
                    351:                        search_brace = false;
                    352:                        goto check_type;
                    353:                    }
                    354: 
                    355:                    if (btype_2) {
                    356:                        save_com[0] = '{';
                    357:                    /* we either want to put the brace right after the if 
                    358:                    */
                    359:                        goto sw_buffer;
                    360:                    /* go to common code to get out of this loop */
                    361:                    }
                    362: 
                    363:                default:       /* it is the start of a normal statment */
                    364:                    if (flushed_nl)
                    365:                               /* if we flushed a newline, make sure it is
                    366:                                  put back */
                    367:                        force_nl = true;
                    368: 
                    369:                    if (sc_end == 0) {
                    370:                    /* ignore buffering if comment wasn't saved up */
                    371:                        search_brace = false;
                    372:                        goto check_type;
                    373:                    }
                    374: 
                    375:                    if (force_nl) {
                    376:                    /* if we should insert a nl here, put it into the
                    377:                       buffer */
                    378:                        force_nl = false;
                    379:                        --line_no;
                    380:                    /* this will be re-increased when the nl is read from
                    381:                       the buffer */
                    382:                        *sc_end++ = '\n';
                    383:                        *sc_end++ = ' ';
                    384:                        if (verbose && !flushed_nl)
                    385:                               /* print error msg if the line was not
                    386:                                  already broken */
                    387:                            printf ("%d: Line broken\n", line_no);
                    388:                        flushed_nl = false;
                    389:                    }
                    390: 
                    391:                    for (t_ptr = token; *t_ptr; ++t_ptr)
                    392:                        *sc_end++ = *t_ptr;
                    393:                /* copy token into temp buffer */
                    394: 
                    395:            sw_buffer: 
                    396:                    search_brace = false;
                    397:                /* stop looking for start of stmt */
                    398:                    bp_save = buf_ptr;
                    399:                /* save current input buffer */
                    400:                    be_save = buf_end;
                    401:                    buf_ptr = save_com;
                    402:                /* fix so that subsequent calls to lexi will take tokens
                    403:                   out of save_com */
                    404:                    *sc_end++ = ' ';
                    405:                /* add trailing blank, just in case */
                    406:                    buf_end = sc_end;
                    407:                    sc_end = 0;
                    408:                    break;
                    409: 
                    410:                case comment:  /* we have a comment, so we must copy it
                    411:                                  into the buffer */
                    412:                    if (sc_end == 0) {
                    413:                    /* if this is the first comment, we must set up the
                    414:                       buffer */
                    415:                        save_com[0] = save_com[1] = ' ';
                    416:                        sc_end = &(save_com[2]);
                    417:                    }
                    418:                    else {
                    419:                        *sc_end++ = '\n';
                    420:                    /* add newline between comments */
                    421:                        *sc_end++ = ' ';
                    422:                        --line_no;
                    423:                    }
                    424: 
                    425:                    *sc_end++ = '/';
                    426:                /* copy in start of comment */
                    427:                    *sc_end++ = '*';
                    428: 
                    429:                    for (;;) { /* loop until we get to the end of the
                    430:                                  comment */
                    431:                        *sc_end = *buf_ptr++;
                    432:                        if (buf_ptr >= buf_end)
                    433:                            fill_buffer ();
                    434: 
                    435:                        if (*sc_end++ == '*' && *buf_ptr == '/')
                    436:                            break;
                    437:                    /* we are at end of comment */
                    438: 
                    439:                        if (sc_end >= &(save_com[sc_size])) {
                    440:                        /* check for temp buffer overflow */
                    441:                            printf ("%d: Internal buffer overflow.\n",
                    442:                                    line_no);
                    443:                            printf ("Move big comment from right after if,\
                    444:  while, or whatever.\n");
                    445:                            exit ();
                    446:                        }
                    447:                    }
                    448: 
                    449:                    *sc_end++ = '/';
                    450:                /* add ending slash */
                    451:                    if (++buf_ptr >= buf_end)/* get past / in buffer */
                    452:                        fill_buffer ();
                    453:                    break;
                    454:            }                  /* end of switch */
                    455: 
                    456:            if (type_code != 0)/* we must make this check, just in case
                    457:                                  there was an unexpected EOF */
                    458:                type_code = lexi ();
                    459:        /* read another token */
                    460:        }                      /* end of while (serach_brace) */
                    461: check_type: 
                    462: 
                    463:        if (type_code == 0) {  /* we got eof */
                    464:            if (s_lab != e_lab || s_code != e_code
                    465:                    || s_com != e_com)/* must dump end of line */
                    466:                dump_line ();
                    467:            if (i_l_follow != 0)/* check for balanced braces */
                    468:                printf ("%d too few }'s\n", i_l_follow);
                    469: 
                    470: #ifdef dolog                  /* only include this stuff if we want to
                    471:                                  keep a log */
                    472:            log_fid = open ("/mnt/net/willcox/indent/indent_log", 1);
                    473:        /* open the log file */
                    474:            if (log_fid >= 0) {
                    475:                seek (log_fid, 0, 2);
                    476:            /* point to end of log */
                    477:                time (logent.tvec);
                    478:            /* get current time */
                    479:                logent.inp = input;
                    480:            /* set up the log entry */
                    481:                logent.outp = output;
                    482:                logent.nout = out_lines;
                    483:                logent.ncom = out_coms;
                    484:                logent.wcom = com_lines;
                    485:                logent.wcode = code_lines;
                    486:                logent.mc = max_col;
                    487:                logent.ci = com_ind;
                    488:                logent.inds = ind_size;
                    489:                logent.dci = decl_com_ind;
                    490:                logent.verb = verbose;
                    491:                logent.ljus = ljust_decl;
                    492:                logent.lvcom = leave_comma;
                    493:                logent.unin = unindent_displace;
                    494:                logent.uid = getuid ();
                    495:                logent.bropt = btype_2;
                    496:                write (log_fid, &logent, sizeof logent);
                    497:            }
                    498: #endif
                    499:            if (verbose) {
                    500:                printf ("There were %d output lines and %d comments\n",
                    501:                        out_lines, out_coms);
                    502:                printf ("(Lines with comments)/(Lines with code): %6.3f\n",
                    503:                        (1.0 * com_lines) / code_lines);
                    504:            }
                    505: 
                    506:            exit ();
                    507:        }
                    508: 
                    509:        if (
                    510:                (type_code != comment) &&
                    511:                (type_code != newline) &&
                    512:                (type_code != preesc) &&
                    513:                (type_code != form_feed)) {
                    514:            if (
                    515:                    force_nl
                    516:                    &&
                    517:                    (type_code != semicolon) &&
                    518:                    (
                    519:                        type_code != lbrace
                    520:                        ||
                    521:                        !btype_2
                    522:                    )) {       /* we should force a broken line here */
                    523:                if (verbose && !flushed_nl)
                    524:                    printf ("%d: Line broken\n", line_no);
                    525:                flushed_nl = false;
                    526:                dump_line ();
                    527:                want_blank = false;
                    528:            /* don't insert blank at line start */
                    529:                force_nl = false;
                    530:            }
                    531: 
                    532:            in_stmt = true;    /* turn on flag which causes an extra level
                    533:                                  of indentation. this is turned off by a
                    534:                                  ; or } */
                    535:            if (s_com != e_com) {
                    536:            /* the turkey has embedded a comment in a line. fix it */
                    537:                *e_code++ = ' ';
                    538:                for (t_ptr = s_com; *t_ptr; ++t_ptr)
                    539:                    *e_code++ = *t_ptr;
                    540:                *e_code++ = ' ';
                    541:                *e_code = '\0';/* null terminate code sect */
                    542:                want_blank = false;
                    543:                e_com = s_com;
                    544:            }
                    545:        }
                    546:        else
                    547:            if (type_code != comment)
                    548:                               /* preserve force_nl thru a comment */
                    549:                force_nl = false;
                    550:     /* cancel forced newline after newline, form feed, etc */
                    551: 
                    552: 
                    553: 
                    554:     /*----------------------------------------------------*\
                    555:     |   do switch on type of token scanned
                    556:     \*----------------------------------------------------*/
                    557:        switch (type_code) {   /* now, decide what to do with the token */
                    558: 
                    559:            case form_feed:    /* found a form feed in line */
                    560:                use_ff = true; /* a form feed is treated much like a
                    561:                                  newline */
                    562:                dump_line ();
                    563:                want_blank = false;
                    564:                break;
                    565: 
                    566:            case newline: 
                    567:                dump_line ();
                    568:                ++line_no;     /* keep track of input line number */
                    569:                want_blank = false;
                    570:                break;
                    571: 
                    572:            case lparen:       /* got a ( or [ */
                    573:                ++p_l_follow;  /* count parens to make Healy happy */
                    574:                if (want_blank && *token != '[')
                    575:                               /* don't put space in front of square
                    576:                                  bracket */
                    577:                    *e_code++ = ' ';
                    578: 
                    579:                if (in_decl)
                    580:                    while ((e_code - s_code) < dec_ind)
                    581:                        *e_code++ = ' ';
                    582: 
                    583:                *e_code++ = token[0];
                    584:                want_blank = false;
                    585:                if (in_or_st && *token == '(') {
                    586:                /* this is a kluge to make sure that declarations will be
                    587:                   aaigned right if proc decl has an explicit type on it,
                    588:                   i.e. "int a(x) {..." */
                    589:                    parse (semicolon);
                    590:                /* I said this was a kluge... */
                    591:                    in_or_st = false;
                    592:                /* turn off flag for structure decl or initialization */
                    593:                }
                    594: 
                    595:                break;
                    596: 
                    597:            case rparen:       /* got a ) or ] */
                    598:                if (--p_l_follow < 0) {
                    599:                    p_l_follow = 0;
                    600:                    printf ("%d: Extra %c\n", line_no, *token);
                    601:                }
                    602: 
                    603:                if (e_code == s_code)/* if the paren starts the line */
                    604:                    paren_level = p_l_follow;
                    605:            /*    then indent it */
                    606: 
                    607:                *e_code++ = token[0];
                    608:                want_blank = true;
                    609: 
                    610:                if (sp_sw && (p_l_follow == 0)) {
                    611:                /* check for end of if (...), or some such */
                    612:                    sp_sw = false;
                    613:                    force_nl = true;
                    614:                /* must force newline after if */
                    615:                    last_u_d = true;
                    616:                /* inform lexi that a following operator is unary */
                    617:                    in_stmt = false;
                    618:                /* don't use stmt continuation indentation */
                    619: 
                    620:                    parse (hd_type);
                    621:                /* let parser worry about if, or whatever */
                    622:                }
                    623: 
                    624:                search_brace = btype_2;
                    625:            /* this should insure that constructs such as main(){... and
                    626:               int[]{... have their braces put in the right place */
                    627:                break;
                    628: 
                    629:            case unary_op:     /* this could be any unary operation */
                    630:                if (want_blank)
                    631:                    *e_code++ = ' ';
                    632: 
                    633:                if (in_decl) { /* if this is a unary op in a *//*
                    634:                                  declaration, we should indent this token
                    635:                                  */
                    636:                    for (i = 0; token[i]; ++i);
                    637:                /* find length of token */
                    638:                    while ((e_code - s_code) < (dec_ind - i))
                    639:                        *e_code++ = ' ';
                    640:                /* pad it */
                    641:                }
                    642: 
                    643:                for (t_ptr = token; *t_ptr; ++t_ptr)
                    644:                    *e_code++ = *t_ptr;
                    645:            /* move the token to buffer */
                    646:                want_blank = false;
                    647:                break;
                    648: 
                    649:            case binary_op:    /* any binary operation */
                    650:        do_binary: 
                    651:                if (want_blank)
                    652:                    *e_code++ = ' ';
                    653:                for (t_ptr = token; *t_ptr; ++t_ptr)
                    654:                    *e_code++ = *t_ptr;
                    655:            /* move the operator */
                    656:                want_blank = true;
                    657:                break;
                    658: 
                    659:            case postop:       /* got a trailing ++ or -- */
                    660:                *e_code++ = token[0];
                    661:                *e_code++ = token[1];
                    662:                want_blank = true;
                    663:                break;
                    664: 
                    665:            case question:     /* got a ? */
                    666:                squest++;      /* this will be used when a later colon
                    667:                                  appears so we can distinguish the
                    668:                                  <c>?<n>:<n> construct */
                    669:                if (want_blank)
                    670:                    *e_code++ = ' ';
                    671:                *e_code++ = '?';
                    672:                want_blank = true;
                    673:                break;
                    674: 
                    675:            case casestmt:     /* got word 'case' or 'default' */
                    676:                scase = true;  /* so we can process the later colon
                    677:                                  properly */
                    678:                if (want_blank)
                    679:                    *e_code++ = ' ';
                    680:                for (t_ptr = token; *t_ptr; ++t_ptr)
                    681:                    *e_code++ = *t_ptr;
                    682:                want_blank = true;
                    683:                break;
                    684: 
                    685:            case colon:        /* got a ':' */
                    686:                if (squest > 0) {
                    687:                /* it is part of the <c>?<n>: <n> construct */
                    688:                    --squest;
                    689:                    if (want_blank)
                    690:                        *e_code++ = ' ';
                    691:                    *e_code++ = ':';
                    692:                    want_blank = true;
                    693:                    break;
                    694:                }
                    695: 
                    696:                in_stmt = false;
                    697:            /* seeing a label does not imply we are in a stmt */
                    698:                for (t_ptr = s_code; *t_ptr; ++t_ptr)
                    699:                    *e_lab++ = *t_ptr;
                    700:            /* turn everything so far into a label */
                    701:                e_code = s_code;
                    702:                *e_lab++ = ':';
                    703:                *e_lab++ = ' ';
                    704:                *e_lab = '\0';
                    705: 
                    706:                force_nl = pcase = scase;
                    707:            /* pcase will be used by dump_line to decide how to indent the
                    708:               label. force_nl will force a case n: to be on a line by
                    709:               itself */
                    710:                scase = false;
                    711:                want_blank = false;
                    712:                break;
                    713: 
                    714:            case semicolon:    /* got a ';' */
                    715:                in_or_st = false;
                    716:            /* we are not in an initialization or structure declaration */
                    717:                scase = false; /* these will only need resetting in a
                    718:                                  error */
                    719:                squest = 0;
                    720: 
                    721:                if (in_decl && s_code == e_code)
                    722:                               /* align this in a declaration */
                    723:                    while ((e_code - s_code) < (dec_ind - 1))
                    724:                        *e_code++ = ' ';
                    725: 
                    726:                in_decl = (dec_nest > 0);
                    727:            /* if we were in a first level structure declaration, we
                    728:               aren't any more */
                    729: 
                    730:                if ((!sp_sw || hd_type != forstmt) && p_l_follow > 0) {
                    731:                /* This should be true iff there were unbalanced parens in
                    732:                   the stmt.  It is a bit complicated, because the
                    733:                   semicolon might be in a for stmt */
                    734:                    printf ("%d: Unbalanced parens\n", line_no);
                    735:                    p_l_follow = 0;
                    736:                    if (sp_sw) {
                    737:                    /* this is a check for a if, while, etc. with
                    738:                       unbalanced parens */
                    739:                        sp_sw = false;
                    740:                        parse (hd_type);
                    741:                    /* don't lose the if, or whatever */
                    742:                    }
                    743:                }
                    744: 
                    745:                *e_code++ = ';';
                    746:                want_blank = true;
                    747:                in_stmt = (p_l_follow > 0);
                    748:            /* we are no longer in the middle of a stmt */
                    749: 
                    750:                if (!sp_sw) {  /* if not if for (;;) */
                    751:                    parse (semicolon);
                    752:                /* let parser know about end of stmt */
                    753:                    force_nl = true;
                    754:                /* force newline after a end of stmt */
                    755:                }
                    756: 
                    757:                break;
                    758: 
                    759:            case lbrace:       /* got a { */
                    760:                in_stmt = false;
                    761:            /* don't indent the { */
                    762:                force_nl = true;
                    763:            /* force other stuff on same line as { onto new line */
                    764: 
                    765:                if (s_code != e_code && !btype_2) {
                    766:                /* bracket is not alone on line */
                    767:                    if (verbose)
                    768:                        printf ("%d: Line broken\n", line_no);
                    769:                    dump_line ();
                    770:                    want_blank = false;
                    771:                }
                    772: 
                    773:                if (p_l_follow > 0) {
                    774:                /* check for preceeding unbalanced parens */
                    775:                    printf ("%d: Unbalanced parens\n", line_no);
                    776:                    p_l_follow = 0;
                    777:                    if (sp_sw) {
                    778:                    /* check for unclosed if, for, etc. */
                    779:                        sp_sw = false;
                    780:                        parse (hd_type);
                    781:                        ind_level = i_l_follow;
                    782:                    }
                    783:                }
                    784: 
                    785:                if (s_code == e_code)
                    786:                    ind_stmt = false;
                    787:            /* don't put extra indentation on line with '{' */
                    788:                if (in_decl && in_or_st) {
                    789:                /* this is either a structure declaration or an init */
                    790:                    di_stack[dec_nest++] = dec_ind;
                    791:                    dec_ind = 0;
                    792:                }
                    793:                else
                    794:                    decl_on_line = false;
                    795:            /* we can't be in the middle of a declaration, so don't do
                    796:               special indentation of comments */
                    797: 
                    798:                parse (lbrace);/* let parser know about this */
                    799:                if (want_blank)/* put a blank before { if { is not at
                    800:                                  start of line */
                    801:                    *e_code++ = ' ';
                    802:                want_blank = false;
                    803:                *e_code++ = '{';
                    804:                break;
                    805: 
                    806:            case rbrace:       /* got a } */
                    807:                if (p_l_follow) {
                    808:                /* check for unclosed if, for, else. */
                    809:                    printf ("%d: Unbalanced parens\n", line_no);
                    810:                    p_l_follow = 0;
                    811:                    sp_sw = false;
                    812:                }
                    813: 
                    814:                if (s_code != e_code) {
                    815:                /* } must be first on line */
                    816:                    if (verbose)
                    817:                        printf ("%d: Line broken\n", line_no);
                    818:                    dump_line ();
                    819:                }
                    820: 
                    821:                *e_code++ = '}';
                    822:                want_blank = true;
                    823:                in_stmt = ind_stmt = false;
                    824: 
                    825:                if (dec_nest > 0) {
                    826:                /* we are in multi-level structure declaration */
                    827:                    dec_ind = di_stack[--dec_nest];
                    828:                    in_decl = true;
                    829:                }
                    830: 
                    831:                parse (rbrace);/*   let parser know about this */
                    832:                break;
                    833: 
                    834:            case swstmt:       /* got keyword "switch" */
                    835:                sp_sw = true;
                    836:                hd_type = swstmt;
                    837:            /* keep this for when we have seen the expression */
                    838:                goto copy_id;  /* go move the token into buffer */
                    839: 
                    840:            case sp_paren:     /* token is if, while, for */
                    841:                sp_sw = true;  /* the interesting stuff is done after the
                    842:                                  expression is scanned */
                    843:                hd_type = (*token == 'i' ? ifstmt :
                    844:                        (*token == 'w' ? whilestmt : forstmt));
                    845:            /* remember the type of header for later use by parser */
                    846:                goto copy_id;  /* copy the token into line */
                    847: 
                    848:            case sp_nparen:    /* got else, do */
                    849:                in_stmt = false;
                    850:                if (e_code != s_code) {
                    851:                /* make sure this starts a line */
                    852:                    if (verbose)
                    853:                        printf ("%d: Line broken\n", line_no);
                    854:                    dump_line ();
                    855:                    want_blank = false;
                    856:                }
                    857: 
                    858:                force_nl = true;
                    859:            /* also, following stuff must go onto new line */
                    860:                parse (*token == 'e' ? elselit : dolit);
                    861:            /* pass token on to parser */
                    862:                goto copy_id;  /* move the token into line */
                    863: 
                    864:            case decl:         /* we have a declaration type (int,
                    865:                                  register, etc.) */
                    866:                parse (decl);  /* let parser worry about indentation */
                    867:                in_or_st = true;
                    868:            /* this might be a structure or initialization declaration */
                    869:                in_decl = decl_on_line = true;
                    870:                for (i = 0; token[i++];);
                    871:            /* get length of token */
                    872: 
                    873:                if (i <= 3)
                    874:                    i = 4;
                    875: 
                    876:                dec_ind = ((e_code - s_code + i) / ind_size + 1) * ind_size;
                    877:            /* this will tell us how far to indent subsequent identifiers 
                    878:            */
                    879:                goto copy_id;
                    880: 
                    881:            case ident:        /* got an identifier or constant */
                    882:                if (in_decl) { /* if we are in a declaration, we must
                    883:                                  indent identifier */
                    884:                    if (want_blank)
                    885:                        *e_code++ = ' ';
                    886:                    want_blank = false;
                    887: 
                    888:                    while ((e_code - s_code) < dec_ind)
                    889:                        *e_code++ = ' ';
                    890:                }
                    891:                else
                    892:                    if (sp_sw && p_l_follow == 0) {
                    893:                    /* check for if expr w/o parens *//* this will make
                    894:                       JRM's obsurd "for ever" statements work */
                    895:                        sp_sw = false;
                    896:                        force_nl = true;
                    897:                        last_u_d = true;
                    898:                        in_stmt = false;
                    899:                        parse (hd_type);
                    900:                    }
                    901: 
                    902:        copy_id: 
                    903:                if (want_blank)
                    904:                    *e_code++ = ' ';
                    905:                for (t_ptr = token; *t_ptr; ++t_ptr)
                    906:                    *e_code++ = *t_ptr;
                    907:                want_blank = true;
                    908:                break;
                    909: 
                    910:            case period:       /* treat a period kind of like a binary
                    911:                                  operation */
                    912:                *e_code++ = '.';
                    913:            /* move the period into line */
                    914:                want_blank = false;
                    915:            /* don't put a blank after a period */
                    916:                break;
                    917: 
                    918:            case comma: 
                    919:                want_blank = (s_code != e_code);
                    920:            /* only put blank after comma if comma does not start the line
                    921:               */
                    922:                if (in_decl)   /* align these in a declaration */
                    923:                    while ((e_code - s_code) < (dec_ind - 1))
                    924:                        *e_code++ = ' ';
                    925: 
                    926:                *e_code++ = ',';
                    927: 
                    928:                if (break_comma && p_l_follow == 0 && !leave_comma)
                    929:                    force_nl = true;
                    930: 
                    931:                break;
                    932: 
                    933:            case preesc:       /* got the character '#' */
                    934:                if (
                    935:                        (s_com != e_com) ||
                    936:                        (s_lab != e_lab) ||
                    937:                        (s_code != e_code)) {
                    938:                /* true iff the '#' was not at start of the line */
                    939:                    printf ("%d: What is this # doing here?\n", line_no);
                    940:                    goto do_binary;
                    941:                /* treat it as a binary operator */
                    942:                }
                    943: 
                    944:                *e_lab++ = '#';/* move whole line to 'label' buffer */
                    945:                while (*buf_ptr != '\n') {
                    946:                    *e_lab = *buf_ptr++;
                    947:                    if (buf_ptr >= buf_end)
                    948:                        fill_buffer ();
                    949: 
                    950:                    if (*e_lab++ == '/' && *buf_ptr == '*') {
                    951:                    /* check for comment on preprocessor line */
                    952:                        e_lab - = 2;
                    953:                    /* skip back over slash */
                    954:                        while (*e_lab == '\t' || *e_lab == ' ')
                    955:                            --e_lab;
                    956:                    /* strip off trailing blanks and tabs */
                    957:                        *(++e_lab) = '\0';
                    958:                    /* null terminate the line */
                    959:                        if (++buf_ptr >= buf_end)
                    960:                               /* space past start of comment */
                    961:                            fill_buffer ();
                    962:                        col_1 = false;
                    963:                    /* don't let pr_comment think that this comment starts
                    964:                       in column 1 */
                    965:                        decl_on_line = true;
                    966:                    /* treat this as a declaration for comment placement
                    967:                       purposes */
                    968:                        goto proc_comment;
                    969:                    /* go process the comment */
                    970:                    }
                    971:                }
                    972: 
                    973:                *e_lab = '\0'; /* null terminate line */
                    974:                pcase = false;
                    975:                break;         /* subsequent processing of the newline
                    976:                                  character will cause the line to be
                    977:                                  printed */
                    978: 
                    979:            case comment:      /* we have gotten a /*  this is a biggie */
                    980:        proc_comment: 
                    981:                pr_comment ();
                    982:                break;
                    983:        }                      /* end of big switch stmt */
                    984: 
                    985:        *e_code = '\0';        /* make sure code section is null
                    986:                                  terminated */
                    987: 
                    988:     }                         /* end of main while (1) loop */
                    989: };
                    990: 
                    991: /*
                    992:  * copy input file to backup file
                    993:  * if in_name is /blah/blah/blah/file, then backup file
                    994:  * will be ".Bfile"
                    995:  * then make the backup file the input and original
                    996:  * input file the output
                    997:  */
                    998: bakcopy () {
                    999:     int     n,
                   1000:             bakchn;
                   1001:     char    buff[512];
                   1002:     register char  *p;
                   1003: 
                   1004:  /* construct file name .Bfile */
                   1005:     for (p = in_name; *p; p++);/* skip to end of string */
                   1006:     while (p > in_name && *p != '/')/* find last '/' */
                   1007:        p--;
                   1008:     if (*p == '/')
                   1009:        p++;
                   1010:     sprintf (bakfile, ".B%s", p);
                   1011: 
                   1012:  /* copy in_name to backup file */
                   1013:     bakchn = creat (bakfile, 0600);
                   1014:     if (bakchn < 0) {
                   1015:        printf ("can't create backup file \"%s\"\n", bakfile);
                   1016:        exit ();
                   1017:     }
                   1018:     while (n = read (input, buff, 512))
                   1019:        write (bakchn, buff, n);
                   1020:     close (bakchn);
                   1021:     close (input);
                   1022: 
                   1023:  /* re-open backup file as the input file */
                   1024:     input = open (bakfile, 0);
                   1025:     if (input < 0) {
                   1026:        printf ("can't re-open backup file\n");
                   1027:        exit ();
                   1028:     }
                   1029: 
                   1030:  /* now the original input file will be the output */
                   1031:     output = creat (in_name, 0644);
                   1032:     if (output < 0) {
                   1033:        printf ("can't create %s\n", in_name);
                   1034:        unlink (bakfile);
                   1035:        exit ();
                   1036:     }
                   1037: }
                   1038: 
                   1039: 
                   1040: set_option (arg)
                   1041: char   *arg;
                   1042: {
                   1043:     register    j;
                   1044:     for (j = 0; options[j].str != 0; ++j) {
                   1045:                               /* look thru list of possible options */
                   1046:        if (eqin (options[j].str, arg)) {
                   1047:            set_var (j, arg);
                   1048:            break;             /* get out of for loop */
                   1049:        }
                   1050:     }
                   1051: 
                   1052:     if (options[j].str == 0) { /* illegal arg given */
                   1053:        printf ("Unknown parameter: %s\n", arg);
                   1054:        exit ();
                   1055:     }
                   1056: }
                   1057: 
                   1058: 
                   1059: set_var (j, arg)
                   1060: char   *arg;
                   1061: {
                   1062:     switch (options[j].code) {
                   1063:        case 1:                /* have -lnnn */
                   1064:            max_col = atoi (&arg[2]);
                   1065:            break;
                   1066:        case 2:                /* have -cnnn */
                   1067:            com_ind = atoi (&arg[2]);
                   1068:            break;
                   1069:        case 3:                /* have -innn */
                   1070:            ind_size = atoi (&arg[2]);
                   1071:            break;
                   1072:        case 4:                /* have -cdnnn */
                   1073:            decl_com_ind = atoi (&arg[3]);
                   1074:            break;
                   1075:        case 5:                /* have -v */
                   1076:            verbose = true;
                   1077:            break;
                   1078:        case 6:                /* have -nv */
                   1079:            verbose = false;
                   1080:            break;
                   1081:        case 7:                /* have -dj */
                   1082:            ljust_decl = true;
                   1083:            break;
                   1084:        case 8:                /* have -ndj */
                   1085:            ljust_decl = false;
                   1086:            break;
                   1087:        case 9:                /* -nbc */
                   1088:            leave_comma = true;
                   1089:            break;
                   1090:        case 10:               /* -bc */
                   1091:            leave_comma = false;
                   1092:            break;
                   1093:        case 13:               /* -dnnn */
                   1094:            unindent_displace = atoi (&arg[2]);
                   1095:            break;
                   1096:        case 14:               /* -br */
                   1097:            btype_2 = true;
                   1098:            break;
                   1099:        case 15:               /* -bl */
                   1100:            btype_2 = false;
                   1101:            break;
                   1102:        case 16:
                   1103:            if(input<0) input = 0;
                   1104:            if(output<0) output = 1;
                   1105:            break;
                   1106:     }
                   1107: }
                   1108: 
                   1109: 
                   1110: /*
                   1111:  * GETPRO - get profile file
                   1112:  * profile file is max 127 characters
                   1113:  */
                   1114: getpro (name, buf)
                   1115: char   *name,                 /* profile file name, as in '.indent.pro' 
                   1116:                               */
                   1117:        *buf;                  /* will receive contents of .pro file */
                   1118: {
                   1119:     register    chn,
                   1120:                 n;
                   1121:     char    file[32];
                   1122: 
                   1123:     file[0] = 0;
                   1124:     strcat (file, getenv ("HOME"));
                   1125:     strcat (file, "/");
                   1126:     strcat (file, name);
                   1127:     chn = open (file, 0);
                   1128:     if (chn < 0)
                   1129:        return (-1);
                   1130:     n = read (chn, buf, 127);
                   1131:     if (n < 0)
                   1132:        return (-1);
                   1133:     buf[n--] = 0;             /* null terminate line */
                   1134:     if (buf[n] == '\n')
                   1135:        buf[n] = 0;
                   1136:     close (chn);
                   1137:     return (0);
                   1138: }
                   1139: 
                   1140: 
                   1141: /*
                   1142:  * strip off arguments in a string:
                   1143:  * p is address of a character pointer
                   1144:  * nextchr returns pointer to front of first arg
                   1145:  * arg is null terminated.
                   1146:  * p is reset to after arg for subsequent calls
                   1147:  */
                   1148: char   *nxtarg (p)
                   1149: char  **p;
                   1150: {
                   1151:     register char  *f,
                   1152:                    *b;
                   1153:     f = b = *p;
                   1154:     while (*f && (*f == ' ' || *f == '\t'))
                   1155:        f++;
                   1156:     while (*b && (*b != ' ' && *b != '\t'))
                   1157:        b++;
                   1158:     if (*b != 0)
                   1159:        *b++ = 0;
                   1160:     *p = b;
                   1161:     return (f);
                   1162: }
                   1163: 
                   1164: 
                   1165: set_profile () {
                   1166:     char    line[128],
                   1167:            *b;
                   1168:     register char  *f;
                   1169:     extern char *nxtarg ();
                   1170: 
                   1171:     if (getpro (".indent.pro", line) < 0)
                   1172:        return;
                   1173:     b = line;
                   1174:     if(verbose) printf ("profile: %s\n", b);
                   1175:     while (*(f = nxtarg (&b)))
                   1176:        set_option (f);
                   1177: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.