Annotation of 43BSD/contrib/dipress/src/bin/maha/maha.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  maharani - a czarina-like program that generates interpress files
        !             3:  *
        !             4:  *  Written for Xerox Corporation by William LeFebvre
        !             5:  *
        !             6:  *  Copyright (c)  1984, 1985 Xerox Corporation
        !             7:  *
        !             8:  *  HISTORY
        !             9:  * 13-Jan-86  lee at Xerox, WRC
        !            10:  *     Changed a call to strcpyn to strncpy.
        !            11:  *
        !            12:  *    8-apr-85  ed flint       conditional compilation for vax11-c (vms)
        !            13:  *    26-mar-85  ed @ Xerox, WRC
        !            14:  *     add fclose after do_file to prevent running out of open file descriptors
        !            15:  */
        !            16: 
        !            17: #ifdef vax11c
        !            18: # include stdio
        !            19: # include ssdef
        !            20: # include ctype
        !            21: # include descrip
        !            22: #else
        !            23: # include <stdio.h>
        !            24: # include <pwd.h>
        !            25: # include <strings.h>
        !            26: # include <sys/types.h>
        !            27: # include <sys/stat.h>
        !            28: # include <sys/time.h>
        !            29: #endif
        !            30: 
        !            31: # include "iptokens.h"
        !            32: # include "literal.h"
        !            33: # include "operator.h"
        !            34: 
        !            35: # define  QIP          "qip"
        !            36: 
        !            37: # define  Break_size   1024
        !            38: # define  Default_universal_prefix     "Xerox/XC1-1-1/"
        !            39: # define  Line_size    128
        !            40: 
        !            41: /* All page boundaries are computed in the 1/10 point co-ordinate system */
        !            42: /*
        !            43:  *  Orig_y is an offset from the top of the page.  It must be converted
        !            44:  *  to a measurement from the bottom of the page (a calculation that is
        !            45:  *  rotation-dependent).
        !            46:  */
        !            47: 
        !            48: # define  INCH         720
        !            49: # define  Half_INCH    360
        !            50: # define  Sixth_INCH   120                     /* one line at 6 lpi */
        !            51: # define  Page_width   (8 * INCH + Half_INCH)
        !            52: # define  Page_length  (11 * INCH)
        !            53: # define  Orig_x       (9 * INCH / 10)
        !            54: # define  Orig_y       (Sixth_INCH * 5)
        !            55: # define  Header_to_orig_x     0
        !            56: # define  Header_to_orig_y     (2 * Sixth_INCH)
        !            57: 
        !            58: /* Frame variable defines */
        !            59: # define  F_transform  0
        !            60: # define  F_headfont   1
        !            61: # define  F_bodyfont   2
        !            62: # define  F_italicfont 3
        !            63: 
        !            64: # define  No   0
        !            65: # define  Yes  1
        !            66: 
        !            67: extern int errno;
        !            68: 
        !            69: /* enum, perhaps? */
        !            70: typedef char boolean;
        !            71: 
        !            72: /* routines that return something other than int */
        !            73: char *strecpy();
        !            74: char *allocate();
        !            75: char *next_arg();
        !            76: char *sbrk();
        !            77: char *getenv();
        !            78: char *itoa();
        !            79: char *rindex();
        !            80: 
        !            81: /* option flags */
        !            82: boolean lflg = No;     /* line printer mode */
        !            83: boolean rflg = No;     /* rotation - landscape mode */
        !            84: boolean tflg = No;     /* omit title */
        !            85: 
        !            86: /* valued options */
        !            87: int  columns   = 1;
        !            88: char *bodyfont_name = "Vintage-Printwheel/10";
        !            89: char *headfont_name = "Modern-Bold/12";
        !            90: char *italicfont_name = "Modern-Bold-Italic/12";
        !            91: char *banner   = NULL;
        !            92: char *copies   = "1";
        !            93: char *header   = "%f            %t            Page %p, line %l";
        !            94: char *name     = NULL;
        !            95: char *output   = NULL;
        !            96: char *pages    = NULL;
        !            97: 
        !            98: #ifdef vax11c
        !            99: char *template = "IPPXXXXXX";
        !           100: #endif
        !           101: 
        !           102: /*
        !           103:  *  page characteristics:  these variables define the extremes for the
        !           104:  *  current page or column.  'column_separation' is the distance between
        !           105:  *  the left sides of each column on the page.
        !           106:  */
        !           107: int left_margin = Orig_x;
        !           108: int right_margin;
        !           109: int top_margin;
        !           110: int bottom_margin;
        !           111: int column_separation;
        !           112: 
        !           113: /* sundries */
        !           114: boolean send_to_printer = Yes;
        !           115: char real_header[256];         /* header built here */
        !           116: char *myname;                  /* name invoked with */
        !           117: char *filename;
        !           118: int  *page_select = NULL;      /* array of page selections */
        !           119: int  *curr_page_select;
        !           120: int  page_low;
        !           121: int  page_high;
        !           122: int  ipress_file;              /* interpress file descriptor */
        !           123: int  null_file;                        /* fd for /dev/null */
        !           124: int  line_number;
        !           125: int  page_number;
        !           126: int  pages_printed = 0;                /* total pages for this interpress file */
        !           127: int  special_font = 0;         /* fonts that require special handling */
        !           128: int  line_spacing;
        !           129: int  tab_amount = 8;
        !           130: #ifndef vax11c
        !           131: struct passwd *pwd;            /* passwd entry for this user */
        !           132: struct stat   file_stat;       /* stat of current file */
        !           133: #endif
        !           134: 
        !           135: # define  Font_Terminal  1
        !           136: 
        !           137: /* current arguments */
        !           138: int  argc;
        !           139: char **argv;
        !           140: 
        !           141: /* font structure definition */
        !           142: struct font
        !           143: {
        !           144:     char *ft_universal_name;
        !           145:     char *ft_leaf_name;
        !           146:     int  ft_size;
        !           147: };
        !           148: 
        !           149: /* fonts used */
        !           150: struct font headfont;
        !           151: struct font bodyfont;
        !           152: struct font italicfont;
        !           153: 
        !           154: main(_argc, _argv)
        !           155: 
        !           156: int  _argc;
        !           157: char **_argv;
        !           158: 
        !           159: {
        !           160:     char *ptr;         /* temporary pointers used for loops and such */
        !           161:     char *src;
        !           162:     char *dest;
        !           163:     int length;
        !           164:     int i;
        !           165:     FILE *file;                /* file currently processing */
        !           166: #ifdef vax11c
        !           167:     int error;
        !           168:     int retlen;
        !           169:     char command[256];
        !           170:     $DESCRIPTOR(mahadesc,"MAHAENV");
        !           171:     $DESCRIPTOR(cmddesc,command);
        !           172: #endif
        !           173: 
        !           174:     /* get our name */
        !           175:     if (_argc < 1)
        !           176:     {
        !           177:        exit(1);
        !           178:     }
        !           179: 
        !           180: #ifdef vax11c
        !           181:     myname= _argv[0];
        !           182: #else
        !           183:     if ((myname = rindex(_argv[0], '/')) == NULL)
        !           184:     {
        !           185:        myname = _argv[0];
        !           186:     }
        !           187:     else
        !           188:     {
        !           189:        myname++;
        !           190:     }
        !           191: #endif
        !           192: 
        !           193:     /* get the options specified in the environment (defaults) */
        !           194: 
        !           195: #ifdef vax11c
        !           196:     if ( (error= lib$get_symbol(&mahadesc,&cmddesc,&retlen)) == SS$_NORMAL )
        !           197:     {
        !           198:        if ( retlen != 0 )
        !           199:        {
        !           200:            command[retlen & 0xff]= '\0';               /* null terminate string */
        !           201:            src= command;
        !           202:        /* break the string up into null terminated arguments */
        !           203:        /* half the length is a good upper bound on number of arguments */
        !           204:                argv = (char **)allocate(strlen(src) / 2);
        !           205:                for (argc = 1, ptr = src; *ptr != '\0'; argc++)
        !           206:                {
        !           207:                    while (*ptr == ' ')
        !           208:                        ptr++;
        !           209:                    argv[argc] = ptr;
        !           210:                    while (*ptr != ' ' && *ptr != '\0')
        !           211:                    {
        !           212:                        if (*ptr == '"')
        !           213:                        {
        !           214:                            while (*++ptr != '"' && *ptr != '\0');
        !           215:                        }
        !           216:                        else if (*ptr == '\'')
        !           217:                        {
        !           218:                            while (*++ptr != '\'' && *ptr != '\0');
        !           219:                        }
        !           220:                        ptr++;
        !           221:                    }
        !           222:                    *ptr++ = '\0';
        !           223:                }
        !           224: 
        !           225:        /* terminate the argument list */
        !           226:                argv[argc] = NULL;
        !           227: 
        !           228:        /* process the options found in the environment */
        !           229:                get_options();
        !           230:        }
        !           231:     }
        !           232: 
        !           233: #else
        !           234:     if ((src = getenv("MAHA")) != NULL)
        !           235:     {
        !           236:        /* break the string up into null terminated arguments */
        !           237:        /* half the length is a good upper bound on number of arguments */
        !           238:        argv = (char **)allocate(strlen(src) / 2);
        !           239:        for (argc = 1, ptr = src; *ptr != '\0'; argc++)
        !           240:        {
        !           241:            while (*ptr == ' ')
        !           242:                ptr++;
        !           243:            argv[argc] = ptr;
        !           244:            while (*ptr != ' ' && *ptr != '\0')
        !           245:            {
        !           246:                if (*ptr == '"')
        !           247:                {
        !           248:                    while (*++ptr != '"' && *ptr != '\0');
        !           249:                }
        !           250:                else if (*ptr == '\'')
        !           251:                {
        !           252:                    while (*++ptr != '\'' && *ptr != '\0');
        !           253:                }
        !           254:                ptr++;
        !           255:            }
        !           256:            *ptr++ = '\0';
        !           257:        }
        !           258: 
        !           259:        /* terminate the argument list */
        !           260:        argv[argc] = NULL;
        !           261: 
        !           262:        /* process the options found in the environment */
        !           263:        get_options();
        !           264:     }
        !           265: #endif
        !           266: 
        !           267:     /* use the real arguments */
        !           268:     argc = _argc;
        !           269:     argv = _argv;
        !           270: 
        !           271:     /* process (real) arguments */
        !           272:     get_options();
        !           273: 
        !           274:     /* establish and verify the requested fonts */
        !           275:     establish_font(headfont_name, &headfont);
        !           276:     establish_font(bodyfont_name, &bodyfont);
        !           277:     establish_font(italicfont_name, &italicfont);
        !           278: 
        !           279: #ifndef vax11c
        !           280:     /* get passwd entry for future reference */
        !           281:     pwd = getpwuid(geteuid());
        !           282: #endif
        !           283: 
        !           284:     /* setup output file */
        !           285:     if (output == NULL)
        !           286:     {
        !           287: 
        !           288:        /* build a temporary file name */
        !           289: 
        !           290: #ifdef vax11c
        !           291:        output= mktemp(template);
        !           292: #else
        !           293:        output = allocate(1 + 5 + 1 + 2 + 1);
        !           294:        (void) sprintf(output, "/tmp/@%d.ip", getpid());
        !           295: #endif
        !           296:     }
        !           297: 
        !           298: #ifdef vax11c
        !           299:     if ((ipress_file = creat(output, 0, "rfm=udf")) == -1)
        !           300: #else
        !           301:     if ((ipress_file = creat(output, 0666)) == -1)
        !           302: #endif
        !           303:     {
        !           304:        system_error(output);
        !           305:        exit(1);
        !           306:     }
        !           307:     ip_select(ipress_file);
        !           308: 
        !           309: #ifndef vax11c
        !           310:     /* open the null device for throwing away output */
        !           311:     null_file = open("/dev/null", 1);
        !           312: 
        !           313:     /* set null strings to default values */
        !           314:     if (name == NULL)
        !           315:     {
        !           316:        /* banner name defaults to full name from gecos field */
        !           317:        name = pwd->pw_gecos;
        !           318: 
        !           319:        /* perform expansion and stripping */
        !           320:        if ((ptr = index(name, ',')) != NULL)
        !           321:        {
        !           322:            *ptr = '\0';        /* this affects pwd->pw_gecos, too! */
        !           323:        }
        !           324:        if (index(name, '&') != NULL)
        !           325:        {
        !           326:            name = allocate(strlen(name) + strlen(pwd->pw_name) + 1);
        !           327:            for (src = pwd->pw_gecos, dest = name; *src != '\0'; src++, dest++)
        !           328:            {
        !           329:                if (*src == '&')
        !           330:                {
        !           331:                    for (ptr = pwd->pw_name; *ptr != '\0'; ptr++)
        !           332:                    {
        !           333:                        *dest++ = *ptr;
        !           334:                    }
        !           335:                }
        !           336:                else
        !           337:                {
        !           338:                    *dest = *src;
        !           339:                }
        !           340:            }
        !           341:        }
        !           342:     }
        !           343: #endif
        !           344: 
        !           345:     if (banner == NULL)
        !           346:     {
        !           347:        /* banner defaults to file name(s) */
        !           348:        if (argc == 0)
        !           349:        {
        !           350:            banner = "out of the blue";
        !           351:        }
        !           352:        else
        !           353:        {
        !           354:            for (length = 0, i = 0; i < argc; i++)
        !           355:            {
        !           356:                length += strlen(argv[i]) + 2;
        !           357:            }
        !           358:            banner = allocate(length + 1);
        !           359:            for (ptr = banner, i = 0; i < argc; i++)
        !           360:            {
        !           361:                ptr = strecpy(ptr, argv[i]);
        !           362:                ptr = strecpy(ptr, ", ");
        !           363:            }
        !           364:            ptr -= 2;
        !           365:            *ptr = '\0';
        !           366:        }
        !           367:     }
        !           368: 
        !           369:     /* unravel the page specifiation */
        !           370:     /* we will never need more than strlen(pages) ints to hold the info */
        !           371:     if (pages != NULL)
        !           372:     {
        !           373:        page_select = (int *)allocate(strlen(pages) * sizeof(int));
        !           374:        unravel_pages(pages, page_select);
        !           375:     }
        !           376: 
        !           377:     /* write the preamble for the interpress file */
        !           378:     Op(beginBlock);
        !           379:     Op(beginBody);     /* preamble start */
        !           380: 
        !           381:     /* setup font definitions in frame */
        !           382:     SetupFont(headfont.ft_universal_name,
        !           383:              headfont.ft_size * 10.,
        !           384:              F_headfont);
        !           385:     SetupFont(bodyfont.ft_universal_name,
        !           386:              bodyfont.ft_size * 10.,
        !           387:              F_bodyfont);
        !           388:     SetupFont(italicfont.ft_universal_name,
        !           389:              headfont.ft_size * 10.,           /* use headfont's size */
        !           390:              F_italicfont);
        !           391: 
        !           392:     /* remember special fonts */
        !           393:     if (strcmp(bodyfont.ft_leaf_name, "Terminal") == 0)
        !           394:     {
        !           395:        special_font = Font_Terminal;
        !           396:     }
        !           397: 
        !           398:     /* save scaling transform that uses 1/10 point co-ordinate system */
        !           399:     top_margin = (rflg ? Page_width : Page_length) - Orig_y;
        !           400:     bottom_margin = 2 * Sixth_INCH;
        !           401:     right_margin = (rflg ? Page_length : Page_width) - Orig_x;
        !           402:     column_separation = (right_margin - Orig_x) / columns;
        !           403:     line_spacing = (bodyfont.ft_size + 2) * 10;
        !           404:     if (rflg)
        !           405:     {
        !           406:        /* we need a rotation transform, too */
        !           407:        Rotate(90.);
        !           408:        Translate((double)Page_width, (double)0);
        !           409:     }
        !           410:     AppendRational(353L,10000000L);
        !           411:     Op(scale);
        !           412:     if (rflg)
        !           413:     {
        !           414:        Op(concat);
        !           415:        Op(concat);
        !           416:     }
        !           417:     AppendInteger((long) F_transform);
        !           418:     Op(fset);
        !           419: 
        !           420:     Op(endBody);       /* end preamble */
        !           421: 
        !           422:     if (argc == 0)
        !           423:     {
        !           424:        /* no filenames -- do standard input */
        !           425:        filename = NULL;
        !           426:        do_file(stdin);
        !           427:     }
        !           428: 
        !           429:     for (; argc > 0; argc--, argv++)
        !           430:     {
        !           431:        filename = argv[0];
        !           432:        if (strcmp(filename, "-") == 0)
        !           433:        {
        !           434:            /* this is really standard input */
        !           435:            filename = NULL;
        !           436:            do_file(stdin);
        !           437:        }
        !           438:        else
        !           439:        {
        !           440:            /* open the file */
        !           441:            if ((file = fopen(filename, "r")) == NULL)
        !           442:            {
        !           443:                system_error(filename);
        !           444:            }
        !           445:            else
        !           446:            {
        !           447:                do_file(file);
        !           448:                (void) fclose(file);
        !           449:            }
        !           450:        }
        !           451:     }
        !           452: 
        !           453:     /* wrap up the output */
        !           454:     ip_select(ipress_file);
        !           455:     Op(endBlock);
        !           456:     ip_close();
        !           457: 
        !           458:     /* send to the printer */
        !           459:     if (send_to_printer)
        !           460:     {
        !           461:        if (pages_printed == 0)
        !           462:        {
        !           463:            /* don't print anything but remove temporary */
        !           464: #ifdef vax11c
        !           465:            delete(output);
        !           466: #else
        !           467:            (void) unlink(output);
        !           468: #endif
        !           469:        }
        !           470:        else
        !           471:        {
        !           472: #ifdef vax11c
        !           473:            char buff[256];
        !           474:            int wait= 0;
        !           475:            $DESCRIPTOR(buffdesc,buff);
        !           476: 
        !           477:            (void) strcpy(buff,"xpress/noformat ");
        !           478:            (void) strcat(buff,output);
        !           479:            buffdesc.dsc$w_length= strlen(buff);
        !           480:            if ( (error= lib$spawn(&buffdesc,0,0,&wait)) != SS$_NORMAL )
        !           481:            {
        !           482:                fprintf(stderr,"\nFile %s contains interpress master\n",output);
        !           483:                exit(error);
        !           484:            }
        !           485:            delete(output);
        !           486: #else
        !           487:            char *buff;
        !           488:     
        !           489:            /* exec a "qip" to queue the file */
        !           490:            buff = allocate(strlen(name) + 1 + 1);
        !           491:            (void) strcpy(buff, "F");
        !           492:            (void) strcat(buff, name);
        !           493:            execl(QIP, "qip", "-c", copies, "-nc", "-nk",
        !           494:                    "-t", banner, "-x", buff, output, 0);
        !           495:            perror(QIP);
        !           496:            fprintf(stderr, "File %s contains interpress master.\n", output);
        !           497: #endif
        !           498:        }
        !           499:     }
        !           500: }
        !           501: 
        !           502: get_options()
        !           503: 
        !           504: {
        !           505:     while (--argc > 0)
        !           506:     {
        !           507:        argv++;
        !           508:        if (!process_arg())
        !           509:        {
        !           510:            break;
        !           511:        }
        !           512:     }
        !           513: }
        !           514: 
        !           515: /*
        !           516:  *  unravel_pages(str, spec) - unravel the page range specification in "str"
        !           517:  *                            into integer pairs in "spec".  The first two
        !           518:  *                            ints in "spec" bound the first range of pages,
        !           519:  *                            the next two bound the second range, and so on.
        !           520:  *                            The array is terminated with the pair 0, 0.
        !           521:  */
        !           522: 
        !           523: unravel_pages(str, spec)
        !           524: 
        !           525: char *str;
        !           526: int  *spec;
        !           527: 
        !           528: {
        !           529:     int last_num = 0;
        !           530:     int this_num = 0;
        !           531:     register char ch;
        !           532:     boolean is_range = No;
        !           533:     boolean bad_spec = No;
        !           534:     boolean done = No;
        !           535: 
        !           536: # define    Start_new_num      (last_num = this_num, this_num = 0)
        !           537: 
        !           538:     while (!done)
        !           539:     {
        !           540:        if ((ch = *str++) == '\0')
        !           541:        {
        !           542:            /* set "done" flag and pretend it's the end of a number */
        !           543:            done = Yes;
        !           544:            ch = ',';
        !           545:        }
        !           546:        if (ch >= '0' && ch <= '9')
        !           547:        {
        !           548:            this_num *= 10;
        !           549:            this_num += ch - '0';
        !           550:        }
        !           551:        else if (ch == '-')
        !           552:        {
        !           553:            if (this_num < last_num && *str != '\0')
        !           554:            {
        !           555:                bad_spec = Yes;
        !           556:            }
        !           557:            *spec++ = this_num;
        !           558:            Start_new_num;
        !           559:            is_range = Yes;
        !           560:        }
        !           561:        else if (ch == ',')
        !           562:        {
        !           563:            if (this_num < last_num)
        !           564:            {
        !           565:                bad_spec = Yes;
        !           566:            }
        !           567:            *spec++ = this_num;
        !           568:            if (is_range)
        !           569:            {
        !           570:                is_range = No;
        !           571:            }
        !           572:            else
        !           573:            {
        !           574:                *spec++ = this_num;
        !           575:            }
        !           576:            Start_new_num;
        !           577:        }
        !           578:        else
        !           579:        {
        !           580:            fprintf(stderr, "%s: bad character in page specification\n",
        !           581:                myname);
        !           582:            exit(1);
        !           583:        }
        !           584:     }
        !           585:     if (*--spec == 0)
        !           586:     {
        !           587:        *spec = 1 << 15;        /* infinity */
        !           588:     }
        !           589:     if (bad_spec)
        !           590:     {
        !           591:        fprintf(stderr,
        !           592:            "%s: pages should be given in non-descending order.\n",
        !           593:            myname);
        !           594:     }
        !           595: }
        !           596: 
        !           597: process_arg()
        !           598: 
        !           599: {
        !           600:     register char ch;
        !           601:     register int  temp;
        !           602:     register char *p1;
        !           603:     register char *p2;
        !           604: 
        !           605:     if (argv[0][0] == '-')
        !           606:     {
        !           607:        if ((ch = argv[0][1]) > '0' && ch <= '9')
        !           608:        {
        !           609:            /* this is a column count specifier */
        !           610:            columns = ch - '0';
        !           611:        }
        !           612:        else switch(ch)
        !           613:        {
        !           614:            case '\0':          /* not an option */
        !           615:                return(No);
        !           616: 
        !           617:            case 'b':
        !           618:                banner = next_arg();
        !           619:                break;
        !           620: 
        !           621:            case 'c':
        !           622:                temp = atoi(copies = next_arg());
        !           623:                if (temp < 1)
        !           624:                {
        !           625:                    fprintf(stderr,
        !           626:                        "%s: bogus number of copies; you only get one!\n",
        !           627:                        myname);
        !           628:                        copies = "1";
        !           629:                }
        !           630:                break;
        !           631: 
        !           632:            case 'f':
        !           633:                bodyfont_name = next_arg();
        !           634:                break;
        !           635: 
        !           636:            case 'F':
        !           637:                headfont_name = next_arg();
        !           638:                break;
        !           639: 
        !           640:            case 'H':                   /* replace header */
        !           641:                header = next_arg();
        !           642:                break;
        !           643: 
        !           644:            case 'h':                   /* append to header */
        !           645:                p1 = next_arg();
        !           646:                p2 = allocate(strlen(header) + strlen(p1) + 1);
        !           647:                (void) strcpy(p2, header);
        !           648:                (void) strcat(p2, "      ");
        !           649:                (void) strcat(p2, p1);
        !           650:                header = p2;
        !           651:                break;
        !           652: 
        !           653:            case 'l':
        !           654:                tflg = lflg = Yes;
        !           655:                break;
        !           656: 
        !           657:            case 'n':
        !           658:                name = next_arg();
        !           659:                break;
        !           660: 
        !           661:            case 'o':
        !           662:                output = next_arg();
        !           663:                send_to_printer = No;
        !           664:                break;
        !           665: 
        !           666:            case 'r':
        !           667:                rflg = Yes;
        !           668:                break;
        !           669: 
        !           670:            case 'R':
        !           671:                rflg = No;
        !           672:                break;
        !           673: 
        !           674:            case 's':
        !           675:                pages = next_arg();
        !           676:                break;
        !           677: 
        !           678:            case 't':
        !           679:                tflg = Yes;
        !           680:                break;
        !           681: 
        !           682:            default:
        !           683:                fprintf(stderr, "%s: unknown option '%c'\n", myname, ch);
        !           684:        }
        !           685:        return(Yes);
        !           686:     }
        !           687:     else
        !           688:     {
        !           689:        return(No);
        !           690:     }
        !           691: }
        !           692: 
        !           693: char *next_arg()
        !           694: 
        !           695: {
        !           696:     if (argv[0][2] == '\0')
        !           697:     {
        !           698:        if (--argc > 0)
        !           699:        {
        !           700:            return((++argv)[0]);
        !           701:        }
        !           702:        else
        !           703:        {
        !           704:            argv++;
        !           705:            return(NULL);
        !           706:        }
        !           707:     }
        !           708:     else
        !           709:     {
        !           710:        return(&(argv[0][2]));
        !           711:     }
        !           712: }
        !           713: 
        !           714: /*
        !           715:  *  establish_font(name, font) - break apart the parts of the string "name"
        !           716:  *                              and fill in the structure pointed to by
        !           717:  *                              "font".  Also, verify that the font requested
        !           718:  *                              actually exists.  This routine also
        !           719:  *                              understands universal font names.
        !           720:  */
        !           721: 
        !           722: establish_font(name, font)
        !           723: 
        !           724: char *name;
        !           725: struct font *font;
        !           726: 
        !           727: {
        !           728:     register char *unamep;
        !           729:     register char *ptr;
        !           730:     char *slashp;
        !           731:     register int size;
        !           732: 
        !           733:     if (name[0] != '/')
        !           734:     {
        !           735:        /* not a universal name -- put the default on the front */
        !           736:        font->ft_universal_name = unamep =
        !           737:                allocate(strlen(Default_universal_prefix) +
        !           738:                         strlen(name) + 1);
        !           739:        (void) strcpy(unamep, Default_universal_prefix);
        !           740:        (void) strcat(unamep, name);
        !           741:     }
        !           742:     else
        !           743:     {
        !           744:        /* already is a universal name -- just allocate space for it */
        !           745:        font->ft_universal_name = unamep = allocate(strlen(name));
        !           746: 
        !           747:        /* copy in the whole name, without the leading slash */
        !           748:        (void) strcpy(unamep, name + 1);
        !           749:     }
        !           750: 
        !           751:     /* strip size off the end, if it is there */
        !           752:     if ((slashp = ptr = rindex(unamep, '/')) != NULL)
        !           753:     {
        !           754:        register char ch;
        !           755: 
        !           756:        size = 0;
        !           757:        while ((ch = *++ptr) != '\0')
        !           758:        {
        !           759:            if (ch < '0' || ch > '9')
        !           760:            {
        !           761:                /* last element is not a number -- no point size */
        !           762:                size = 0;
        !           763:                break;
        !           764:            }
        !           765: 
        !           766:            /* shift this digit in */
        !           767:            size *= 10;
        !           768:            size += (ch - '0');
        !           769:        }
        !           770: 
        !           771:        /* if no point size, use default */
        !           772:        if (size == 0)
        !           773:        {
        !           774:            font->ft_size = 10;
        !           775:        }
        !           776:        else
        !           777:        {
        !           778:            font->ft_size = size;
        !           779:            *slashp = '\0';
        !           780:        }
        !           781:     }
        !           782: 
        !           783:     /* set pointer to last element */
        !           784:     if ((ptr = rindex(unamep, '/')) != NULL)
        !           785:     {
        !           786:        font->ft_leaf_name = ptr + 1;
        !           787:     }
        !           788:     else
        !           789:     {
        !           790:        font->ft_leaf_name = font->ft_universal_name;
        !           791:     }
        !           792: }
        !           793: 
        !           794: do_file(file)
        !           795: 
        !           796: FILE *file;
        !           797: 
        !           798: {
        !           799:     char *src;
        !           800:     char *dest;
        !           801:     char input_line[Line_size];
        !           802:     char line_buffer[Line_size];
        !           803:     char ch;
        !           804:     int current_line;
        !           805:     int lines_on_page;
        !           806:     int length;
        !           807:     int column;
        !           808:     
        !           809: #ifndef vax11c
        !           810:     /* fstat it to get information displayed in the header */
        !           811:     if (fstat(fileno(file), &file_stat) == -1)
        !           812:     {
        !           813:        system_error("fstat botched");
        !           814:        return;
        !           815:     }
        !           816: #endif
        !           817: 
        !           818:     /* reset essentials */
        !           819:     page_number = 0;
        !           820:     line_number = 1;
        !           821:     lines_on_page = 0;
        !           822:     curr_page_select = page_select;
        !           823:     if (pages != NULL)
        !           824:     {
        !           825:        page_low  = page_select[0];
        !           826:        page_high = page_select[1];
        !           827:     }
        !           828:     current_line = top_margin;
        !           829: 
        !           830:     /*
        !           831:      *  Strangeness:  page_number is incremented by page_start and
        !           832:      *  line_number is incremented in the "while(fgets..." loop.
        !           833:      */
        !           834: 
        !           835:     /* start the first page */
        !           836:     page_start();
        !           837: 
        !           838:     /*
        !           839:      *  More strangeness:  we had to set line_number to 1 to trick
        !           840:      *  page_start into reporting the right line count in the header.  Now
        !           841:      *  we reset it to 0 before entering the read/print loop.
        !           842:      */
        !           843:     line_number = 0;
        !           844: 
        !           845:     while (fgets(input_line, Line_size, file) != NULL)
        !           846:     {
        !           847:        /* new line */
        !           848:        line_number++;
        !           849: 
        !           850:        /* remember the length */
        !           851:        length = strlen(input_line);
        !           852: 
        !           853:        /* nuke any trailing newline */
        !           854:        if (input_line[length - 1] == '\n')
        !           855:        {
        !           856:            input_line[--length] = '\0';
        !           857:        }
        !           858: 
        !           859:        if (lflg ? lines_on_page >= 66 : current_line < bottom_margin)
        !           860:        {
        !           861:            /* start a new page */
        !           862:            page_end(No);
        !           863:            page_start();
        !           864:            lines_on_page = 0;
        !           865: 
        !           866:            /* remember, y goes backwards */
        !           867:            current_line = top_margin;
        !           868:        }
        !           869: 
        !           870:        /* make sure that the line actually contains something */
        !           871:        if (input_line[0] != '\0')
        !           872:        {
        !           873:            /* set x and y for the beginning of the line */
        !           874:            Setxy((double)left_margin, (double)current_line);
        !           875: 
        !           876:            /* copy from input_line to line_buffer making any necessary
        !           877:               changes along the way */
        !           878:            column = 0;
        !           879:            src = input_line;
        !           880:            dest = line_buffer;
        !           881:            while ((ch = *src) != '\0')
        !           882:            {
        !           883:                switch(ch)
        !           884:                {
        !           885:                    case '\f':          /* new page after this line */
        !           886:                        current_line = bottom_margin;
        !           887:                        lines_on_page = 66;
        !           888:                        break;
        !           889: 
        !           890:                    case '\t':          /* tab expansion */
        !           891:                        do
        !           892:                        {
        !           893:                            *dest++ = ' ';
        !           894:                            column++;
        !           895:                        } while (column % tab_amount != 0);
        !           896:                        break;
        !           897: 
        !           898:                    case '$':
        !           899:                        *dest++ = '\244';
        !           900:                        column++;
        !           901:                        break;
        !           902: 
        !           903:                    case '-':
        !           904:                        if (special_font == Font_Terminal)
        !           905:                        {
        !           906:                            /* heavy hackery here */
        !           907:                            *dest = '\0';
        !           908:                            ShowString(line_buffer);
        !           909:                            Setyrel(-20.);
        !           910:                            ShowString("\305");
        !           911:                            Setyrel(20.);
        !           912:                            dest = line_buffer;
        !           913:                            column++;
        !           914:                            break;
        !           915:                        }
        !           916:                        /* else fall thru ... */
        !           917: 
        !           918:                    default:
        !           919:                        *dest++ = ch;
        !           920:                        column++;
        !           921:                }
        !           922:                src++;
        !           923:            }
        !           924:            *dest = '\0';
        !           925:            if (line_buffer[0] != '\0')
        !           926:            {
        !           927:                ShowString(line_buffer);
        !           928:            }
        !           929:        }
        !           930: 
        !           931:        /* advance the line counters */
        !           932:        current_line -= line_spacing;
        !           933:        lines_on_page++;
        !           934:     }
        !           935: 
        !           936:     /* wrap up the file */
        !           937:     page_end(Yes);
        !           938: }
        !           939: 
        !           940: /*
        !           941:  *  page handling:  a distinction is made between virtual pages and actual
        !           942:  *  pages.  A virtual page is one series of lines from the file that appears
        !           943:  *  vertically on the printed page.  The actual page is the page as the
        !           944:  *  printer prints it (a printed page, if you will).  There may be several
        !           945:  *  virtual pages on one actual page.  The page_start and page_end routines
        !           946:  *  that follow start and terminate virtual pages.  The mapping between
        !           947:  *  virtual and actual pages is a function of the options specified by the
        !           948:  *  user.  If the user requests two column output then there will be two
        !           949:  *  virtual pages for every actual page.  These pages will sit side-by-side on
        !           950:  *  the actual page.  The mapping is accomplished by changing the variables
        !           951:  *  left_margin and right_margin.  "page_start" also handles printing of the
        !           952:  *  page header, since there is only one of these on every actual page.
        !           953:  */
        !           954: 
        !           955: static int current_column;
        !           956: 
        !           957: page_start()
        !           958: 
        !           959: {
        !           960:     boolean in_set;
        !           961: 
        !           962: #ifdef vax11c
        !           963:     long bintim;
        !           964: #endif
        !           965: 
        !           966:     /* reset the column count if starting a new file */
        !           967:     if (line_number == 1)
        !           968:     {
        !           969:        current_column = 0;
        !           970:     }
        !           971: 
        !           972:     /* either move the left margin or put out a new page */
        !           973:     if (current_column != 0)
        !           974:     {
        !           975:        left_margin += column_separation;
        !           976:     }
        !           977:     else
        !           978:     {
        !           979:        /* increment page count and reset margin */
        !           980:        page_number++;
        !           981:        left_margin = Orig_x;
        !           982: 
        !           983:        /* is it in the page specification set? */
        !           984:        if (page_select == NULL)
        !           985:        {
        !           986:            /* every page is in the set if there is no specification */
        !           987:            in_set = Yes;
        !           988:        }
        !           989:        else
        !           990:        {
        !           991:            if (page_low <= page_number && page_number <= page_high)
        !           992:            {
        !           993:                in_set = Yes;
        !           994:                ip_select(ipress_file);
        !           995:                if (page_number == page_high)
        !           996:                {
        !           997:                    /* at the top of the current range -- time to move up */
        !           998:                    curr_page_select += 2;
        !           999:                    page_low  = curr_page_select[0];
        !          1000:                    page_high = curr_page_select[1];
        !          1001:                }
        !          1002:            }
        !          1003:            else
        !          1004:            {
        !          1005:                /* not in set -- redirect output to null device */
        !          1006:                in_set = No;
        !          1007:                ip_select(null_file);
        !          1008:            }
        !          1009:        }
        !          1010: 
        !          1011:        if (in_set)
        !          1012:        {
        !          1013:            register char *src;
        !          1014:            register char *dst;
        !          1015:            register char ch;
        !          1016: 
        !          1017:            /* increment total page count */
        !          1018:            pages_printed++;
        !          1019: 
        !          1020:            /* output stuff for new ip page */
        !          1021:            Op(beginBody);
        !          1022:        
        !          1023:            /* set the transformation */
        !          1024:            Fget(F_transform);
        !          1025:            Op(concatt);
        !          1026: 
        !          1027:            /* build the header if we need to print it */
        !          1028:            if (!tflg)
        !          1029:            {
        !          1030:                /* move characters from header to real_header */
        !          1031:                /* and expand format items along the way.     */
        !          1032:                src = header;
        !          1033:                dst = real_header;
        !          1034:                while ((ch = *src) != '\0')
        !          1035:                {
        !          1036:                    if (ch == '%')
        !          1037:                    {
        !          1038:                        switch(ch = *++src)
        !          1039:                        {
        !          1040:                            case 'f':           /* file name */
        !          1041:                                dst = strecpy(dst,
        !          1042:                                            filename == NULL ? 
        !          1043:                                                "Standard input" :
        !          1044:                                                filename);
        !          1045:                                break;
        !          1046:     
        !          1047:                            case 't':           /* mtime */
        !          1048: #ifdef vax11c
        !          1049: 
        !          1050:                                time(&bintim);
        !          1051:                                strncpy(dst,ctime(&bintim), 24);
        !          1052:                                dst += 24;
        !          1053: #else
        !          1054:                                /*
        !          1055:                                 *  ctime returns a 26 character string that
        !          1056:                                 *  has a newline and null at the end.
        !          1057:                                 *  26 - 2 == 24.
        !          1058:                                 */
        !          1059:                                if (file_stat.st_mtime != 0)
        !          1060:                                {
        !          1061:                                    (void) strncpy(dst,ctime(&file_stat.st_mtime),24);
        !          1062:                                    dst += 24;
        !          1063:                                }
        !          1064: #endif
        !          1065:                                break;
        !          1066:     
        !          1067:                            case 'p':           /* page number */
        !          1068:                                dst = itoa(dst, page_number);
        !          1069:                                break;
        !          1070:     
        !          1071:                            case 'l':           /* line number */
        !          1072:                                dst = itoa(dst, line_number);
        !          1073:                                break;
        !          1074:     
        !          1075:                            case '\0':          /* end of the string */
        !          1076:                                src--;          /* maintain loop invariant */
        !          1077:                                break;
        !          1078:     
        !          1079:                            default:            /* copy the character */
        !          1080:                                *dst++ = ch;
        !          1081:                                /* break; */
        !          1082:                        }
        !          1083:                    }
        !          1084:                    else
        !          1085:                    {
        !          1086:                        *dst++ = ch;
        !          1087:                    }
        !          1088:                    src++;
        !          1089:                }
        !          1090:     
        !          1091:                /* terminate the real header */
        !          1092:                *dst = '\0';
        !          1093:            
        !          1094:                /* display the header */
        !          1095:                Setxy((double)(left_margin - Header_to_orig_x),
        !          1096:                      (double)(top_margin + Header_to_orig_y));
        !          1097:                Setfont(F_headfont);
        !          1098:                ShowString(real_header);
        !          1099:            }
        !          1100:        }
        !          1101:     }
        !          1102: 
        !          1103:     /* select the body font */
        !          1104:     Setfont(F_bodyfont);
        !          1105: }
        !          1106: 
        !          1107: page_end(eof)
        !          1108: 
        !          1109: int eof;
        !          1110: 
        !          1111: {
        !          1112:     if ((current_column = ++current_column % columns) == 0 || eof)
        !          1113:     {
        !          1114:        Op(endBody);
        !          1115:     }
        !          1116: }
        !          1117: 
        !          1118: char *strecpy(dest, src)
        !          1119: 
        !          1120: register char *src;
        !          1121: register char *dest;
        !          1122: 
        !          1123: {
        !          1124:     while (*dest++ = *src++)
        !          1125:        ;
        !          1126:     return(--dest);
        !          1127: }
        !          1128: 
        !          1129: char *itoa(buff, val)
        !          1130: 
        !          1131: char *buff;
        !          1132: int  val;
        !          1133: 
        !          1134: {
        !          1135:     char tbuff[12];    /* will build number here -- max of 10 digits */
        !          1136:     register char *ptr = tbuff + 11;
        !          1137: 
        !          1138:     *ptr-- = '\0';
        !          1139:     while (val != 0)
        !          1140:     {
        !          1141:        *ptr-- = (val % 10) + '0';
        !          1142:        val /= 10;
        !          1143:     }
        !          1144:     return(strecpy(buff, ++ptr));
        !          1145: }
        !          1146: 
        !          1147: /*
        !          1148:  *  allocate(space) - allocate "space" bytes with sbrk.  This routine uses a
        !          1149:  *                   fairly naive algorithm.  It sbrk-s space in Break_size
        !          1150:  *                   chunks and allocates space from a chunk until a request
        !          1151:  *                   for more space than is left in the chunk is made.  Then,
        !          1152:  *                   it allocates a new chunk.  The unused space at the end
        !          1153:  *                   of the old chunk remains unused.  This does NOT depend
        !          1154:  *                   on sbrk returning contiguous chunks of memory during the
        !          1155:  *                   life of the program.
        !          1156:  */
        !          1157: 
        !          1158: char *allocate(space)
        !          1159: 
        !          1160: int space;
        !          1161: 
        !          1162: {
        !          1163:     static char *hi_water = NULL;
        !          1164:     static char *max_alloc = NULL;
        !          1165:     register char *ptr;
        !          1166: 
        !          1167:     /* this works with max_alloc = hi_water = NULL, although we probably
        !          1168:        shouldn't depend on that! */
        !          1169:     if (max_alloc + space > hi_water)
        !          1170:     {
        !          1171:        hi_water = sbrk(Break_size);
        !          1172:        if ((int)hi_water == -1)
        !          1173:        {
        !          1174:            system_error("out of space");
        !          1175:            exit(1);
        !          1176:        }
        !          1177:        max_alloc = hi_water + Break_size - 1;
        !          1178:     }
        !          1179: 
        !          1180:     ptr = hi_water;
        !          1181:     hi_water += space;
        !          1182:     return(ptr);
        !          1183: }
        !          1184: 
        !          1185: system_error(message)
        !          1186: 
        !          1187: char *message;
        !          1188: 
        !          1189: {
        !          1190:     int saved_errno;
        !          1191: 
        !          1192:     /* value of errno not preserved by fprintf */
        !          1193:     saved_errno = errno;
        !          1194:     fprintf(stderr, "%s: ", myname);
        !          1195:     errno = saved_errno;
        !          1196:     perror(message);
        !          1197: }
        !          1198: 
        !          1199: #ifdef vax11c
        !          1200: char *rindex(string, c)
        !          1201: char *string, c;
        !          1202: {
        !          1203:        register char *pos;
        !          1204: 
        !          1205:        pos = 0;
        !          1206:        do {
        !          1207:                if (*string == c)
        !          1208:                        pos = string;
        !          1209:        } while (*string++);
        !          1210:        return(pos);
        !          1211: }
        !          1212: 
        !          1213: #endif
        !          1214: 

unix.superglobalmegacorp.com

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