home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume06 / halign < prev    next >
Encoding:
Text File  |  1988-09-11  |  9.8 KB  |  368 lines

  1. Subject: v06i016:  halign - line up columns (halign)
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: talcott!mcgill-vision!garfield!mouse (der Mouse)
  6. Mod.sources: Volume 6, Issue 16
  7. Archive-name: halign
  8.  
  9. Here is a  handy  little program I wrote...it  produces nicely  lined-up
  10. columns from messy out-of-alignment columns.  For example, it can turn
  11.  
  12. 3 9
  13. 9 81
  14. 81 6561
  15. 6561 43046721
  16. 43046721 (overflow)
  17.  
  18. into
  19.  
  20.        3          9
  21.        9         81
  22.       81       6561
  23.     6561   43046721
  24. 43046721 (overflow)
  25.  
  26. Read the man page for a full description.
  27.  
  28. --------------------------------cut here--------------------------------
  29. #! /bin/sh
  30. #
  31. # Shar: Shell Archiver
  32. #
  33. # This archive created Wed Jun 11 04:53:03 1986
  34. # Run this through sh to create:
  35. #    halign.1
  36. #    halign.c
  37. echo x - halign.1 \(2051 characters\)
  38. sed 's/^X//' > halign.1 << \SHAR_EOF
  39. X.TH HALIGN 1 "11 June 1986"
  40. X.UC 4
  41. X.SH NAME
  42. Xhalign - produce lined-up columns
  43. X.SH SYNOPSIS
  44. X.nf
  45. X.ft B
  46. Xhalign [lrc][\fIn\fP] ...
  47. X.PP
  48. X.fi
  49. X.SH DESCRIPTION
  50. X\fIHalign\fP is a program to produce nicely lined-up columns from almost any
  51. Xsort of columnized input.  For example, if you have a program which prints
  52. Xlines with two numbers on each line, halign can adjust things so they line up
  53. Xnicely.  For example, let us suppose you have a program (here called `foo')
  54. Xwhich produces the following output:
  55. X.PP
  56. X.in +8
  57. X.nf
  58. X% foo
  59. X3 9
  60. X9 81
  61. X81 6561
  62. X6561 43046721
  63. X43046721 (overflow)
  64. X.PP
  65. X.fi
  66. XNow, to get things lined up and right-justified:
  67. X.PP
  68. X.in +8
  69. X.nf
  70. X% foo | halign r r
  71. X       3          9
  72. X       9         81
  73. X      81       6561
  74. X    6561   43046721
  75. X43046721 (overflow)
  76. X.PP
  77. X.fi
  78. XEach argument to halign must be a letter followed by an optional number.  The
  79. Xletter specifies how the column is to be aligned; \fIl\fP specifies that the
  80. Xcolumn is to be set flush left, \fIr\fP indicates flush right, and \fIc\fP
  81. Xspecifies centering.  Of course, centering cannot always be exact; if unable
  82. Xto center an entry exactly, halign will put the extra space on the right.  If
  83. Xthe number is given, it is a minimum width for the column; normally, a column
  84. Xis only as wide as necessary to contain the widest entry in that column.  For
  85. Xexample, \fIl10\fP specifies a column at least 10 characters wide (though it
  86. Xwill be wider if there is an entry wider than 10 characters), with the entry
  87. Xset at the left and padded on the right (if necessary).
  88. X.SH NOTES
  89. XHalign must of course read all of its input before printing anything; the
  90. Xinput is stored in files on /tmp (one file per column).  Because these files
  91. Xare all kept open at once, halign will break if more than NFILE-3 (currently
  92. X17 on most UNIX systems) columns are specified.
  93. X.SH BUGS
  94. XHalign thinks control characters, such as backspace and escape, are normal
  95. Xprinting characters, so the columns may not line up if the entries contain
  96. Xsuch characters.
  97. X.SH AUTHOR
  98. Xder Mouse (Mike Parker, mcgill-vision!mouse), September, 1985.
  99. SHAR_EOF
  100. if test 2051 -ne "`wc -c halign.1`"
  101. then
  102. echo shar: error transmitting halign.1 \(should have been 2051 characters\)
  103. fi
  104. echo x - halign.c \(6462 characters\)
  105. sed 's/^X//' > halign.c << \SHAR_EOF
  106. X/*
  107. X * halign - program to produce lined-up columns
  108. X *
  109. X * Halign reads input in the form of columns of data separated by whitespace;
  110. X *  the output is similar except that all the columns line up.  This was
  111. X *  inspired by the common uses of the \halign command in TeX; knowing how
  112. X *  TeX's \halign command works will make this program almost self-evident.
  113. X *
  114. X * Usage is
  115. X *
  116. X *    halign [clr][n] ...
  117. X *
  118. X *  where each argument corresponds to one column in the input.
  119. X *
  120. X * The letter indicates how the column is to be justified; r indicates
  121. X *  flush-right, l indicates flush-left, and c indicates centered.  Of
  122. X *  course, centering cannot be perfect without half-character resolution; if
  123. X *  an item cannot be centered exactly the extra space will go on the right.
  124. X *
  125. X * The number n, if given, indicates a minimum width for the column.  The
  126. X *  default is to make the column just wide enough to contain the widest
  127. X *  entry; if this entry is narrower than n the column will be n characters
  128. X *  wide anyway.
  129. X *
  130. X * Halign always puts one space between columns on output.
  131. X *
  132. X * All adjusting is done with spaces; if tabs are desired pipe the output
  133. X *  through /usr/ucb/unexpand -a.
  134. X *
  135. X * Examples:
  136. X *
  137. X *    % cat x
  138. X *    root 0 10 / /bin/csh
  139. X *    mailer 0 10 / /bin/csh
  140. X *    daemon 1 666 / 
  141. X *    uucp 66 1 /usr/spool/uucppublic /usr/lib/uucp/uucico
  142. X *    wnj 8 10 /u1/guest/wnj /bin/csh
  143. X *    mckusick 9 10 /u1/guest/mckusick /bin/csh
  144. X *    % halign l l l l l < x
  145. X *    root     0  10  /                     /bin/csh            
  146. X *    mailer   0  10  /                     /bin/csh            
  147. X *    daemon   1  666 /                                         
  148. X *    uucp     66 1   /usr/spool/uucppublic /usr/lib/uucp/uucico
  149. X *    wnj      8  10  /u1/guest/wnj         /bin/csh            
  150. X *    mckusick 9  10  /u1/guest/mckusick    /bin/csh            
  151. X *    % halign l r5 r5 c c < x
  152. X *    root         0    10           /                 /bin/csh      
  153. X *    mailer       0    10           /                 /bin/csh      
  154. X *    daemon       1   666           /                               
  155. X *    uucp        66     1 /usr/spool/uucppublic /usr/lib/uucp/uucico
  156. X *    wnj          8    10     /u1/guest/wnj           /bin/csh      
  157. X *    mckusick     9    10  /u1/guest/mckusick         /bin/csh      
  158. X *
  159. X * Halign must of course read to the end of its input before generating any
  160. X *  output, so that it knows how wide the columns must be.  The input column
  161. X *  entries are copied into temporary files (on /tmp).
  162. X *
  163. X * The current incarnation cannot deal with more than about 17 columns; this
  164. X *  is because a separate temporary file is used for each column, so not more
  165. X *  than NFILE-3 (3 for stdin/stdout/stderr) columns will work.
  166. X *
  167. X * Copyright 1985 by Mike Parker.  Permission is granted for redistribution
  168. X *  of this code, or modified versions of it, for any purpose as long as this
  169. X *  notice remains intact and that no additional restrictions are placed on
  170. X *  further redistribution.  I have tried to make sure that this program
  171. X *  functions as the above description indicates, but I make no guarantees
  172. X *  that this code does anything useful, or even that it does not do anything
  173. X *  harmful.
  174. X *
  175. X * If you find any bugs I would appreciate hearing, especially if you also
  176. X *  fix them.  Write to
  177. X *    {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse
  178. X */
  179. X
  180. X#include <stdio.h>
  181. X#include <ctype.h>
  182. X#include <sys/file.h>
  183. X
  184. Xchar *malloc();
  185. Xchar *realloc();
  186. X#define NEW(type) ((type *) malloc(sizeof(type)))
  187. X#define OLD(x) free((char *) x)
  188. X
  189. Xchar **argvec;
  190. X
  191. Xtypedef struct _spec {
  192. X      char spec;
  193. X      int tfd;
  194. X      FILE *tf;
  195. X      char *buf;
  196. X      int maxwidth; } SPEC;
  197. X
  198. Xint errs;
  199. Xint ncols;
  200. Xint nlines;
  201. XSPEC *spec;
  202. Xchar tfilename[80];
  203. X
  204. Xmain(ac,av)
  205. Xint ac;
  206. Xchar **av;
  207. X{
  208. X int i;
  209. X int j;
  210. X int k;
  211. X char *cp;
  212. X char *dp;
  213. X char c;
  214. X int inspace;
  215. X int colwidth;
  216. X
  217. X argvec = av;
  218. X errs = 0;
  219. X ncols = ac - 1;
  220. X if (ncols <= 0)
  221. X  { fprintf(stderr,"Usage: %s [clr][n] [clr][n] ...\n",argvec[0]);
  222. X    exit(1);
  223. X  }
  224. X spec = (SPEC *) malloc(ncols*sizeof(SPEC));
  225. X sprintf(tfilename,"/tmp/halign.%d",getpid());
  226. X av ++;
  227. X for (i=0;i<ncols;i++)
  228. X  { spec[i].maxwidth = 0;
  229. X    switch (av[i][0])
  230. X     { case 'c':
  231. X       case 'l':
  232. X       case 'r':
  233. X      if (av[i][1])
  234. X       { spec[i].maxwidth = atoi(av[i]+1);
  235. X       }
  236. X      spec[i].spec = av[i][0];
  237. X      unlink(tfilename);
  238. X      spec[i].tfd = open(tfilename,O_RDWR|O_CREAT|O_TRUNC,0644);
  239. X      unlink(tfilename);
  240. X      if (spec[i].tfd < 0)
  241. X       { fprintf(stderr,"%s: cannot open temporary file %s: ",
  242. X                        argvec[0],tfilename);
  243. X         perror(0);
  244. X         errs ++;
  245. X       }
  246. X      break;
  247. X       default:
  248. X      fprintf(stderr,
  249. X        "%s: `%c' is not a valid specification (c, l, or r)\n",
  250. X                            argvec[0],av[i][0]);
  251. X      errs ++;
  252. X      break;
  253. X     }
  254. X  }
  255. X for (i=0;i<ncols;i++)
  256. X  { if (spec[i].tfd >= 0)
  257. X     { spec[i].tf = fdopen(spec[i].tfd,"r+");
  258. X       if (! spec[i].tf)
  259. X    { fprintf(stderr,"%s: cannot fdopen, serious failure: ",argvec[0]);
  260. X      perror(0);
  261. X      errs ++;
  262. X    }
  263. X     }
  264. X  }
  265. X if (errs)
  266. X  { exit(1);
  267. X  }
  268. X nlines = 0;
  269. X i = 0;
  270. X inspace = 1;
  271. X colwidth = 0;
  272. X while (1)
  273. X  { c = getchar();
  274. X    if (feof(stdin))
  275. X     { if ((i > 0) || (colwidth > 0))
  276. X    { c = '\n';
  277. X    }
  278. X       else
  279. X    { break;
  280. X    }
  281. X     }
  282. X    else if (isspace(c))
  283. X     { if (! inspace)
  284. X    { inspace = 1;
  285. X      if (colwidth > spec[i].maxwidth)
  286. X       { spec[i].maxwidth = colwidth;
  287. X       }
  288. X      if (i < ncols-1)
  289. X       { putc('\n',spec[i].tf);
  290. X         i ++;
  291. X       }
  292. X      colwidth = 0;
  293. X    }
  294. X       if (c == '\n')
  295. X    { for (;i<ncols;i++)
  296. X       { putc('\n',spec[i].tf);
  297. X       }
  298. X      nlines ++;
  299. X      i = 0;
  300. X      colwidth = 0;
  301. X      inspace = 1;
  302. X    }
  303. X     }
  304. X    else
  305. X     { putc(c,spec[i].tf);
  306. X       colwidth ++;
  307. X       inspace = 0;
  308. X     }
  309. X  }
  310. X for (i=0;i<ncols;i++)
  311. X  { fseek(spec[i].tf,0L,0);
  312. X    spec[i].buf = malloc(spec[i].maxwidth+2);
  313. X  }
  314. X for (;nlines>0;nlines--)
  315. X  { for (i=0;i<ncols;i++)
  316. X     { fgets(spec[i].buf,spec[i].maxwidth+2,spec[i].tf);
  317. X       j = strlen(spec[i].buf);
  318. X       if (j > 0)
  319. X    { spec[i].buf[--j] = '\0';
  320. X    }
  321. X       k = spec[i].maxwidth - j;
  322. X       cp = spec[i].buf;
  323. X       cp[spec[i].maxwidth] = '\0';
  324. X       spacefill(cp+j,k);
  325. X       switch (spec[i].spec)
  326. X    { case 'l':
  327. X         break;
  328. X      case 'c':
  329. X         k /= 2;
  330. X         /* fall through */
  331. X      case 'r':
  332. X         cp += j;
  333. X         dp = cp + k;
  334. X         for (;j>0;j--)
  335. X          { *--dp = *--cp;
  336. X          }
  337. X         for (;k>0;k--)
  338. X          { *--dp = ' ';
  339. X          }
  340. X         break;
  341. X    }
  342. X       if (i)
  343. X    { putchar(' ');
  344. X    }
  345. X       fputs(spec[i].buf,stdout);
  346. X     }
  347. X    putchar('\n');
  348. X  }
  349. X}
  350. X
  351. Xspacefill(ptr,nb)
  352. Xregister char *ptr;
  353. Xregister int nb;
  354. X{
  355. X for (;nb>0;nb--)
  356. X  { *ptr++ = ' ';
  357. X  }
  358. X}
  359. SHAR_EOF
  360. if test 6462 -ne "`wc -c halign.c`"
  361. then
  362. echo shar: error transmitting halign.c \(should have been 6462 characters\)
  363. fi
  364. exit 0
  365. # end of shell archive
  366.  
  367.  
  368.