Annotation of 42BSD/ucb/indent/indent.c, revision 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.