[comp.sources.misc] v02i064: split -- V1.1

richard@gryphon.CTS.COM (Richard Sexton) (03/06/88)

Approved: allbery@ncoast.UUCP
Comp.sources.misc: Volume 2, Issue 64
Submitted-By: "Richard Sexton" <richard@gryphon.CTS.COM>
Archive-Name: split-1.1

Comp.sources.misc: Volume 2, Issue 64
Submitted-By: "Richard Sexton" <richard@gryphon.CTS.COM>
Archive-Name: split-1.1

After a humbling lesson in argument passing, here is a fixed
up version of split.

This one should work on Apollos and Suns.

Usage:

split file  --  makes file.ps from fil

split -ifile -oblat.ps   --  makes blat.ps from file

split file1 file2 file3 -fCourier  -- makes file1.ps, file3.ps, file3.ps in 
                                      the courier font.

Note that you can go "split files switches" or "split switches files"

The -i and -o switches are mostly for you PC guys who cant handle filenames
like this.that.and.the.other, as the program wants to just stuff a .ps
on the end.

Let me know if there are any problems.

=============== snip ========== snipity snip =========== snip ============

#include "stdio.h"

/*  split.c  28-feb-88

	Copyright 1988 Richard John Sexton
	All rights reserved 

	Permission to use all or part of this program without fee is
	granted provided that it is not used or distributed for direct
	commercial gain, the above copyright notice appears, and
	notice is given that use is by permission of Richard J. Sexton

		richard@gryphon.CTS.COM
		rutgers!marque!gryphon!richard
*/


#define _toupper(x) ((x)&0x5f)

#define CR 10
#define LF 13

#define TRUE 1
#define FALSE 0

#define TOP_MARGIN_DEFAULT 25
#define BOTTOM_MARGIN_DEFAULT 25

#define POINTS_ACROSS ((85 * 72) / 10)
#define POINTS_DOWN ((110 * 72) / 10)

FILE *in, *out;
unsigned char *fword, swarray [26], fontname[256] = "Helvetica";
unsigned long swvalues [26];
short i, fontsize, pt_row_cntr, lines, linecntr, col_nbr, nbr_cols, xpos;
short  ypos, yils, page_nbr, colums = 1, rotate = 0, maxx, maxy, temp1;
short temp2, switch_num, border_value, lm_offset, title;
short top_margin, bottom_margin;
short nbr_copies = 1;
short infsw;
unsigned char title_text[256] ="", outfilename[1081] = "", infilename[1081] = "";

char *sploptstr = "123b:c:f:h:i:l:n:o:p:r:t:";

int	opterr = 1;
int	optind = 1;
int filind = 1;
int	optopt;
int fillo, filhi, filenum;
int saved = 1;

char *optarg, saved_c;

main (argc, argv)
short argc;
unsigned char *argv[];
   {
   unsigned short ctemp;
   unsigned char c, *s, *d;


   printf ("\n   Split V1.1  Copyright 1988 by Richard J. Sexton.  All rights reserved.\n   Never to be sold.\n\n");
  
   init_data (); 

   /* Get values of switches, if any */

   if (argc == 1)
      {
      print_help ('\0', argv);    /* no files or switches, print help */
	  exit (0);
      }

	infsw = 0;				/* assume we got no input files */

	set_optind (argc, argv);

    pass_switches (argc, argv);

	if (argc == optind)
		{
		fillo = 1; filhi = saved;   /* files came first, then switches */
		}
	else
		{
		fillo = optind; filhi = argc;  /* switches came first, then files */
		}

/* main loop */

	filenum = fillo;

	do {

	reinit_data ();

	if (*infilename == '\0')
		{
		scopy (argv[filenum] + infsw, infilename);
		}

   if (!lines) 
      {
      lines = (rotate ? 500 : 675) / (((fontsize ? fontsize : 10) * 3) / 2);
      }

   in = fopen (infilename, "r");


	if (!(*outfilename))
		{
   		d = outfilename;
   		s = infilename;

   		for (;*s;)
   		   {
   		   *d++ = *s++;
           }

		scopy (".ps", d);
		}

   out = fopen (outfilename, "w");

   if (in == 0)  {printf ("(%s): Can't open file '%s' for input.\n", argv[0], infilename); exit(1);}
   if (out == 0) {printf ("(%s): Can't open %s.ps for output.\n", argv[0], outfilename); exit (2);}

   printf ("\n%s --> %s\n", infilename, outfilename);

   /* Insert stupid Adobe header */

   fprintf (out, "%%!PS-Adobe-1.0\n");
   fprintf (out, "%%Creator: The program '%s'\n", argv[0]);
   fprintf (out, "%%Title: %s\n", outfilename);
   fprintf (out, "%%Pages: (atend)\n");
   fprintf (out, "%%DocumentFonts: (atend)\n");
   fprintf (out, "%%EndComments\n\n");

   fprintf (out, "/yline %d def\n/xline %d def\n/%s findfont %d scalefont setfont\n/yils %d def\n",
   (rotate ? (-lm_offset) : 725), lm_offset, fontname, fontsize, fontsize + (fontsize / 2));

   /* Define clipping path(s) */

   for (i = 0; i < nbr_cols; i++)
      {
      temp1 = lm_offset + (((maxx - 110) / (nbr_cols)) * i);

      temp2 = lm_offset + (((maxx - 110) / (nbr_cols)) * (i + 1));
      temp2 -= 6;
 
      fprintf (out, "/clippath%d { newpath %d 999 moveto %d -999 lineto",
      i, temp1, temp1);

      fprintf (out, " %d -999 lineto %d 999 lineto closepath} def\n",
      temp2, temp2);
      }

   fprintf (out, "/nl {/yline yline yils sub def xline yline moveto show } def\n");
   fprintf (out, "/move {moveto} def\n/draw {lineto} def\n");

   if (rotate)
      {
      fprintf (out, "90 rotate\n");
      }

   fprintf (out, "gsave\nclippath0 clip\n");

   fprintf (out, "%%EndProlog\n%%Page 0 1\n");

   fprintf (out, "\n(");

   while ((c = getc (in)) != 0xff)
      {
      if ((c == CR) || (c == LF))
         {
         /* Hit a CR or LF, move to a new line */
         /* If your files have CR LF then you have a problem */
         /* Mine don't */

         fprintf (out, ") nl");
         pt_row_cntr -= yils;
         linecntr++;

         if (((lines == 0) && (pt_row_cntr <= 150)) ||
            ((lines) && (linecntr == lines)))
            {
            colum_break ();
            pt_row_cntr = maxy;
            linecntr = 0;
            }

         fprintf (out, "\n(");
         }
      else
         {
         /* Output a line of text */

         if (c == '/' || c == '\\' 
		 ||  c == '(' || c == ')'
		 ||  c == '[' || c == ']'
		 ||  c == '{' || c == '}')
            {
            fprintf (out, "\\");
            }
         fprintf (out, "%c", c);
         }
      }

   fprintf (out, ")\n/yline yline yils sub def\nxline yline moveto\nshow\n");

   draw_border ();
   draw_title ();

	for (i = 0; i < nbr_copies; i++)  fprintf (out, "copypage\n");

   fprintf (" erasepage grestore\n");

   fprintf (out, "%%Trailer\n%%DocumentFonts: %s", fontname);

   if ((strcmp (fontname, "Helvetica") != NULL) && title)
	{
	fprintf (out, ", Helvetica");
	}

   fprintf (out, "\n%%Pages: %d\n", page_nbr);

   fclose (out);
   fclose (in);

   printf ("%d page%s printed.\n\n", page_nbr, (page_nbr == 1 ? "" : "s"));

   *infilename = '\0';
   *outfilename = '\0';


	if (infsw == 2) {filenum--; infsw = 0;}

   } while (++filenum < filhi);

  }

/******************** Local support routines ***************************/

scopy (s, d)
unsigned char *s, *d;
   {
   while (*s) *d++ = *s++; *d = 0;
   }

colum_break ()
   {
   if (col_nbr++ >= nbr_cols - 1)
      {
      page_break ();
      col_nbr = 0;
      }
   else
      {
      xpos = lm_offset + (((maxx - 110) / (nbr_cols)) * col_nbr);  /*  used to be nbr_cols + 1 */

      ypos = rotate ? (-lm_offset) : 725;
      fprintf (out, "/yline %d def\n/xline %d def\n", ypos, xpos);
      }
   fprintf (out, "grestore gsave\nclippath%d clip\n", col_nbr);
   }

page_break()
   {
   draw_border ();
   draw_title ();

   for (i = 0; i < nbr_copies; i++) fprintf (out, "\ncopypage\n");

   fprintf (out, "erasepage\n%%Page %d %d\n", page_nbr - 1, page_nbr);
   if (rotate) fprintf (out, "90 rotate");

   xpos = lm_offset; ypos = (rotate ? (-lm_offset) : 725);
   fprintf (out, "/yline %d def\n/xline %d def\n", ypos, xpos);
   col_nbr = 0;
   page_nbr++;
   }

init_data ()
   {
   register unsigned short i;

   fontsize = 10;             /* Set default font size */
   yils = 15;                 /* Y InterLine Spacing = fontsize * 1.5 */
   pt_row_cntr = POINTS_DOWN;         /* Start counter (in points) at T.O.P - 725 */
   col_nbr = 0;
   saved_c = '\0';
   nbr_cols = 1;
   linecntr = 0;
   page_nbr = 1;
   border_value = 0;
   lines = 0;
   switch_num = -1;
   lm_offset = 45;             /* Left margin offset */
   title = 0;                  /* default to no title */

   top_margin = TOP_MARGIN_DEFAULT;
   bottom_margin = BOTTOM_MARGIN_DEFAULT;

   maxx = POINTS_ACROSS; maxy = POINTS_DOWN;
   }

reinit_data ()
   {
   register unsigned short i;

   pt_row_cntr = POINTS_DOWN;         /* Start counter (in points) at T.O.P - 725 */
   col_nbr = 0;
   linecntr = 0;
   lines = 0;
   lm_offset = 45;             /* Left margin offset */
   page_nbr = 1;
   }

/* 
 * printhelp
 *
 * takes a char, and if its binary zero, displays general
 * help message, else it's assumed to be a character and
 * displays the help screen for that charater.
 *
 */

print_help (helpqual,argv)
unsigned char helpqual;
char **argv;
   {
   switch (toupper (helpqual))
      {
      case 0:
         {
         printf ("\n Usage:   '%s -ifile',  output goes to 'file.ps'.\n\n", argv[0], argv[0]);
         printf ("\n Options are:\n");
         printf ("    -bn    Draw border around text, format 'n'\n");
         printf ("    -cn    Set text in 'n' colums across\n");
         printf ("    -fname Set text in font 'name'\n");
         printf ("    -h[s]  '%s -h' gets help. '%s -hs' gets help about subject 's'.\n", argv[0], argv[0]);
		 printf ("    -ifile Input file name.\n");
         printf ("    -ln    Limit text to 'n' lines per column\n");
         printf ("    -n     Print 'n' copies\n");
		 printf ("    -ofile Output file name.\n");
         printf ("    -rn    rendering orientation 'n'. n = l for landscape, p for portrait\n");
         printf ("    -pn    Set text 'n' points tall\n");
         printf ("    -n     Use predefined format n:\n");
         printf ("\n         1 = portrait, 2 columns of 6pt Helvetica\n");
         printf ("         2 = landscape, 2 columns of 6pt Helvetica\n");
         printf ("         3 = landscape, 1 column, 18pt Times Roman\n\n");
         printf ("    -ttext Print title = text and page # on every page\n");
         printf ("\nThe default output format is portrait, 10pt Helvetica\n");
         break;
         }

      case 'B':
         {
           printf ("\n                         ** Border formats **\n\n");
           printf ("       The qualifier for the -b switch is a number 0 - 127.\n");
           printf ("       -b0 draws a box around the whole page.\n\n");
           printf ("       The individual lines are binary encoded as follows:\n\n");
 /*border shit */          printf ("              1 = left border line          2 = top line\n");
           printf ("              4 = right border line         8 = bottom line\n");
           printf ("             16 = middle line (does not connect with top and bottom\n");
           printf ("             32 = middle connecting line (top)\n");
           printf ("             64 = middle connecting line (bottom)\n\n");
           printf ("       These last two connect the middle line to the top and bottom and\n");
           printf ("       draw a small cross where they intersect to aid registration.\n\n");
           printf ("       These numbers can be used alone or added together. For example:\n\n");
           printf ("       -b16 would draw a line between columns\n");
           printf ("       -b15 would draw the four lines forming a box around the column(s)\n");
           printf ("        (15 = 8 + 4 + 2 + 1)\n");
         break;

         }

      case 'C':
         {
         break;
         }

      case 'F':
         {
         break;
         }

      case 'H':
         {
         break;
         }

      case 'L':
         {
         break;
         }

      case 'N':
         {
         break;
         }

      case 'O':
         {
         break;
         }

      case 'P':
         {
         }

      }      /* End switch */
  exit (0);
   }

/*   pass_switches - pass command line switches for split

**  options:
**
**		-b 		
**		-c	
**		-f
**		-l
**		-n
**		-o
**		-p
*/

pass_switches (argc, argv)
int argc;
char **argv;
	{
	register unsigned c;

/*
**  Process command line arguments
*/
	while ((c = getopt(argc, argv, sploptstr)) != EOF) {

		switch ( c ) {

		case 'b':
			{
			/* box stuff. */

			if (*optarg)
				{
				border_value = atoi (optarg);
				if (border_value < 1 || border_value > 256)
					{
					border_value = 15; /* default to box */
					}
				}
			break;
			}

		case NULL:
			{
			printf ("Oh shit!\n");
			break;
			}

		case 'c':
			{

			/* colums, number of */

			if (*optarg)
				{
				nbr_cols = atoi (optarg);
				if (nbr_cols < 1 || nbr_cols > 256)
					{
					nbr_cols = 15; /* default to box */
					}
				}
			break;
			}
		
		case 'f':
			{

			/* fontname */

			(void) strcopy (fontname, optarg);
			break;
			}


		case 'h':
			{
			char tc;

			/* help */

			if (tc = *optarg)
				{
				print_help (tc,argv);
				}	
			break;
			}


		case 'i':
			{

			/* input file name */

			(void) strcopy (infilename, optarg);
			infsw = 2;
			break;
			}

		
		case 'o':
			{

			/* output file name */

			(void) strcopy (outfilename, optarg);
			break;
			}


		case 'r':
			{

			/* rendering orientation. -rp = portrait mode, -rl = landscape mode */

			register char tc;

			tc = *optarg;

			if (tc = *optarg)
				{
				if (toupper (tc) == 'P')
					{
					set_rotate (0);
					}
				else
					{
					if (toupper (tc) == 'L')
						{
						set_rotate (1);
						}
					}
				}
			
			break;
			}
			

		case 'l':
			{

			/* number of lines per column */

			if (*optarg) lines = atoi (optarg);
			break;
			}

		case 'n':
			{

			/* number of copies */

			if (*optarg) nbr_copies = atoi (optarg);
			break;
			}


		case 'p':
			{

			/* point size */

			if (*optarg) fontsize = atoi (optarg);
			break;
			}

		case 't':
			{

			/* Title */

			if (*optarg) scopy (optarg, title_text);
			title = 1;
			break;
			}


         case '1':
            {
            fontsize = 6; nbr_cols = 2;
            break;
            }

          case '2':
            {
            set_rotate (1);
            fontsize = 6; nbr_cols = 2;
            break;
            }

         case '3':
            {
            fontsize = 18;
            scopy ("Times-Roman", fontname);
			break;
		    }

		case '?':
			{

			/* getopt error'd */

			break;
			}

		default:
			{
			printf ("%s: valid flags are %s\n", argv[0], sploptstr);
			exit (0);
			}

		}   /* end switch */
	}    /* end while */

	}  /* end pass_switches */


set_rotate (num)
short num;
   {
   short t;

   if (num != rotate)
      {
      t = maxx; maxx = maxy; maxy = t;
      pt_row_cntr = maxy;
      rotate ^= 1;
      }
   }

draw_border ()
   {
   short tx1, ty1, tx2, ty2;

    if (border_value)
      {
      tx1 = 40; ty1 = rotate ? (-lm_offset) : 760;
      tx2 = rotate ? 750 : 580; ty2 = rotate ? (-580) : 35;

      fprintf (out, "\ngrestore gsave newpath\n");
      fprintf (out, "%d %d move ", tx1, ty1);

      /* Draw */

      if (border_value & 1)
         {
         fprintf (out, "%d %d draw ", tx1, ty2);
         }
      else
         {
         fprintf (out, "%d %d move ", tx1, ty2);
         }

      if (border_value & 8)
         {
         fprintf (out, "%d %d draw ", tx2, ty2);
         }
      else
         {
         fprintf (out, "%d %d move ", tx2, ty2);
         }

      if (border_value & 4)
         {
         fprintf (out, "%d %d draw ", tx2, ty1);
         }
      else
         {
         fprintf (out, "%d %d move ", tx2, ty1);
         }

      if (border_value & 2)
         {
         fprintf (out, "%d %d draw ", tx1, ty1);
         }
      else
         {
         fprintf (out, "%d %d move ", tx1, ty1);
         }

      fprintf (out, "\nclosepath\n");

      if (border_value & (16 + 32))
         {
         short tempx, indx;

         for (indx = 0; indx < nbr_cols - 1; indx++)
            {
            tempx = lm_offset + (((maxx - 110) / (nbr_cols)) * (indx + 1));
            tempx -= 6;  /* Bump over a bit */

            if (border_value & 16)
               {
               fprintf (out, "%d %d move %d %d draw\n",
			   tempx, ty1 - 20, tempx, ty2 + 20);    
               }

            if (border_value & 32)
               {printf ("32\n");
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx, ty1, tempx, ty1 - 20);
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx - 20, ty1, tempx + 20, ty1);

               fprintf (out, "%d %d move %d %d draw\n",
                       tempx, ty2, tempx, ty2 + 20);
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx - 20, ty2, tempx + 20, ty2);
               }
            }
         }
      fprintf (out, "stroke\n");
      }
   }


draw_title ()
   {
   if (title)
      {
	  fprintf (out, "\ngrestore gsave\n"); 
      if (strcmp ("Helvetica", fontname) != NULL)
         {
         fprintf (out, "/Helvetica findfont 12 scalefont setfont\n");
         }

      if (rotate)
         {
		 fprintf (out, "40 -593 move (%s) show\n", title_text);
		 fprintf (out, "600 -593 move (Page %d) show\n", page_nbr);
         }
      else
         {
         fprintf (out, "40 20 move (%s) show\n", title_text);
         fprintf (out, "400 20 move (Page %d) show\n", page_nbr);
         }

      if (strcmp ("Helvetica", fontname) != NULL)
         {
         fprintf (out, "/%s findfont %d scalefont setfont\n", fontname, fontsize);
         }
      }
   }

   
/*
**	based on: @(#)getopt.c	2.5 (smail) 9/15/87
*/

int getopt(argc, argv, opts)
int	argc;
char	**argv, *opts;
{
	extern char *strchr();
	static int sp = 1;
	register int c;
	register char *cp;

	if(sp == 1)
		if(optind >= argc ||
		   argv[optind][0] != '-' || argv[optind][1] == '\0')
			return(EOF);
		else if(strcmp(argv[optind], "--") == NULL) {
			optind++;
			return(EOF);
		}
	saved_c = optopt = c = argv[optind][sp];


	if(c == ':' || (cp=strchr(opts, c)) == (char *)NULL) {
		printf ("(%s) illegal option -- '%c'\n", argv[0], c);
		if(argv[optind][++sp] == '\0') {
			optind++;
			sp = 1;
		}
		return('?');
	}

	if(*++cp == ':') {
		if(argv[optind][sp+1] != '\0')
			optarg = &argv[optind++][sp+1];
		else if(++optind >= argc) {
			sp = 1;
			if (c == 'h') {
				print_help ('\0', argv);
				}
			else {
			      printf("(%s) %c option requires an argument.\n", argv[0], c);
			      }
			return('?');
		} else {
			optarg = argv[optind++];
		  }
		sp = 1;
	} else {
		if(argv[optind][++sp] == '\0') {
			sp = 1;
			optind++;
		}
		optarg = NULL;
	}

	return(c);
}

get_file_name (argv)
char **argv;
	{
	char *ptr;
	}

strcopy (d, s)
char *s, *d;
	{
	while (*s) *d++ = *s++;
	*d = '\0';
	}

set_optind (argc, argv)
int argc;
char **argv;
	{
	static int i;

	/* First find the first option (argument with a dash) */

	for (i = 1; i < argc; i++)
		{
		if (argv[i][0] == '-')
			{
			optind = i;
			i = argc + 1;
			saved = optind;
			}
		}
	
	for (i = 1; i < argc; i++)
		{
		if (argv[i][0] != '-')
			{
			filind = i;
			i = argc + 1;
			}
		}
	}


printit (a, b, c, d, argv)
int a, b, c, d;
char **argv;
	{
	int i;

	printf ("\n\nFiles = ");

	for (i = a; i < b; i++)
		{
		printf ("  %s", argv[i]);
		}
	
	printf ("\nswitches = ");

	for (i = c; i < d; i++)
		{
		printf ("  %s", argv[i]);
		}

	printf ("\n");
	}


================= congratulations ! ============= you got the whole thing ======



thats it.


-- 
    "Each morning when I wake up to rise, I'm living in a dreamland" 
                          richard@gryphon.CTS.COM 
   {ihnp4!scgvaxd!cadovax, rutgers!marque, codas!ddsw1} gryphon!richard