home *** CD-ROM | disk | FTP | other *** search
Wrap
From: patsch@ubka.uni-karlsruhe.de (Patrick Dockhorn) Newsgroups: comp.sources.misc Subject: v43i036: prg - PostScript report generator V1.1, Part05/06 Date: 10 Jun 1994 10:22:52 -0500 Organization: Sterling Software Sender: kent@sparky.sterling.com Approved: kent@sparky.sterling.com Message-ID: <2ta0gc$7b6@sparky.sterling.com> X-Md4-Signature: 96a86d1ab8814f522e3359ce6e0a8e6f Submitted-by: patsch@ubka.uni-karlsruhe.de (Patrick Dockhorn) Posting-number: Volume 43, Issue 36 Archive-name: prg/part05 Environment: postscript, UNIX #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # Contents: prg/INSTALL prg/README # prg/doc/videos-by-actors-first-name-starts-A-or-B.ps # prg/lib/prg.awk prg/lib/prg.sed.UU # Wrapped by kent@sparky on Thu Jun 9 12:32:34 1994 PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 5 (of 6)."' if test -f 'prg/INSTALL' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'prg/INSTALL'\" else echo shar: Extracting \"'prg/INSTALL'\" \(1173 characters\) sed "s/^X//" >'prg/INSTALL' <<'END_OF_FILE' X------------------------------------------ XPostScript report generator - INSTALLATION X------------------------------------------ X XIf you got the package from USENET News skip steps X1 to 3; they are required only if you got a gzip'ed Xtar file from our ftp server. X X1. copy the file prg.tar.gz into a local subdirectory X of yours - you need write permission there in order X to unpack the file. X2. uncompress the file with the command 'gunzip prg.tar.gz' X3. untar the file with the command 'tar xf prg.tar.gz' X4. change to the prg directory : 'cd prg' X XYou can start working with prg immediately now. XThe prg shell skript resides in the prg directory, Xthe awk and sed skripts required are located in Xthe lib subdirectory, but the default settings Xknow about this. XYou may move the prg shell script into a directory Xthat is contained in the PATH environment variable Xany time you want. X XFor a personal installation with a different directory Xstructure take a look at the configuration section Xof the prg script and adjust the following variables XPRGDATAPATH (location of your data) XPRGLIBPATH (location of your awk and sed skript) XTMPDIR (directory for temporary files) X X END_OF_FILE if test 1173 -ne `wc -c <'prg/INSTALL'`; then echo shar: \"'prg/INSTALL'\" unpacked with wrong size! fi # end of 'prg/INSTALL' fi if test -f 'prg/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'prg/README'\" else echo shar: Extracting \"'prg/README'\" \(2767 characters\) sed "s/^X//" >'prg/README' <<'END_OF_FILE' XWHAT IS PRG ? X------------- X Xprg is a PostScript report generator based on generic input data. The Xdata consists of two parts: A description file and a data file. The Xfirst file describes the logical structure of the data file. X Xprg can be used to manage all kinds of data, like your personal phone Xbook, addresses, books, music cassettes and so on. Once you've entered Xyour data you can create reports that contain an arbitrary combination Xof fields from your data and you may sort them by whatever keys you Xwant. You may also retrieve only a subset of the records stored in Xthe data file; prg contains a parser for simple selection expressions Xto support this. X XPRG runs in a UNIX environment; it only requires standard-tools X(awk, shell...), there's no need for any compiler. X XWHAT'S NEW IN RELEASE 1.1 : X--------------------------- X X1. MAJOR NEW FEATURES X X1.1. SELECTORS ADDED: X X It is now possible to print a report of a selection of records only. X The selection is implemented as an expression that is parsed at X runtime to determine whether a record qualifies for a report or not. X See the new SELECTION section in the OnLine-Documentation and the X manual page for details. X X1.2. ONLINE-HELP: X You may now query prg for the meaning of any of its parameters using X the '-info yourOption' option, i.e. X prg -info -select X shows you information about the '-select' option. X X1.3. SUPPORTING LARGE DATA FILES X The PostScript code has been rewritten in order to support arbitrary X large data files. X X X2. MINOR NEW FEATURES X X2.1. Time-Field allows seconds to be used if field data is preceeded by 's' X X2.2. If you want hash characters in your strings replace them by '\hash' X X2.3. If a column has the same contents for two succeeding rows i and i+1 X you may want to use the option '-noDuplicates' to avoid the repetitive X printing of this identical contents. X X2.4. If the contents of the first column change, a delimiting horizontal X line is drawn between these two rows. X X2.5. Enhanced handling of time fields (option '-accuracy' added). X X2.6. The command line used to produce the program now appears on the X title page. X X XWHERE TO GET IT: X---------------- X XThe new release 1.1 is currently available from the ftp site X Xftp.ubka.uni-karlsruhe.de X Xin the directory X X/pub/prg X XGet the file prg-1.1.tar.gz using binary transfer mode. X XIf you have any comments, find bugs etc., drop me a line. X X-patsch X X-- XPatrick Dockhorn \ Uni-Bibliothek \ Kaiserstrasse 12 \ 76131 Karlsruhe \ X\ e-mail: patsch@ubka.uni-karlsruhe.de,finger=ubkaaix3\ Germany __o \ X \ There are two rules for success in life: \ _`\<,_ \ X \ Rule 1: Don't tell people everything you know. \ (_)/ (_) \ X END_OF_FILE if test 2767 -ne `wc -c <'prg/README'`; then echo shar: \"'prg/README'\" unpacked with wrong size! fi # end of 'prg/README' fi if test -f 'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps'\" else echo shar: Extracting \"'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps'\" \(26882 characters\) sed "s/^X//" >'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps' <<'END_OF_FILE' X%! X%%Creator: patsch on ubkaaix3 using prg X%%Title: Videoliste X%%CreationDate: Fri Jun 3 16:25:12 MST 1994 X%%DocumentFonts: AvantGarde-Book X%%EndComments X X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X% % X% prg - patsch's PostScript report generator Release 1.1 % X% % X% Copyright (C) 1994 Patrick Dockhorn % X% Permission to use and modify this software and its % X% documentation for any purpose other than its incorporation % X% into a commercial product is hereby granted without fee. % X% Permission to copy and distribute this software and its % X% documentation only for non-commercial use is also granted % X% without fee, provided, however, that the above copyright % X% notice appear in all copies, that both that copyright % X% notice and this permission notice appear in supporting % X% documentation. The author makes no representations about % X% the suitability of this software for any purpose. It is % X% provided ``as is'' without express or implied warranty. % X% % X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X X%%EndProlog X X% recode font vector to enable foreign special characters X% copied from PostScript cookbook X X/reencsmalldict 12 dict def X/ReEncodeSmall X{ X reencsmalldict begin X /newcodesandnames exch def X /newfontname exch def X /basefontname exch def X X /basefontdict basefontname findfont def X /newfont basefontdict maxlength dict def X X basefontdict X { X exch dup /FID ne X { X dup /Encoding eq X { exch dup length array copy X newfont 3 1 roll put } X { exch newfont 3 1 roll put } X ifelse X } X { pop pop } X ifelse X } forall X X newfont /FontName newfontname put X newcodesandnames aload pop X newcodesandnames length 2 idiv X { newfont /Encoding get 3 1 roll put } repeat X newfontname newfont definefont pop X end X} def X X% ------------------------------------------------------------------ X% X% germanvec is an array that contains positions and character X% names. The given characters, - they are usually not included X% in the standard font encoding - are activated at the given X% positions in the character set. X% To use your own characters (i.e. /ccedilla, modify X% the font vector accordingly. X% The PostScript Language Reference contains the names X% of characters available as well as a map of unused X% regions in the standard text encoding. X% The following octal regions can be used in a standard X% text encoding without removing other characters: X% \260, \300, \321-\341, \354-\360, \362-\364, \366-\367, \374-\376 X% X% ------------------------------------------------------------------ X X/germanvec [ X 8#300 /adieresis X 8#311 /Adieresis X 8#321 /odieresis X 8#322 /Odieresis X 8#323 /udieresis X 8#324 /Udieresis X 8#325 /germandbls X 8#326 /eacute X 8#327 /egrave X 8#330 /ecircumflex X 8#331 /ccedilla X 8#332 /otilde X 8#333 /atilde X 8#334 /ntilde X 8#335 /copyright X 8#336 /registered X 8#337 /trademark X 8#340 /Ccedilla X 8#341 /aacute X] def X X% ------------------------------------------------------------------ X% X% - Umlaute - X% X% Activate the new font encoding that includes foreign umlauts X% for the font selected by the user by FONTNAME. X% X% ------------------------------------------------------------------ X X/Umlaute X{ X /AvantGarde-Book /GermanFont germanvec ReEncodeSmall X} def X X% ------------------------------------------------------------------ X% X% (text) width clipshow - X% X% The given text is shown at the current point. Before the text X% is displayed, a clip rectangle is placed around it with the X% given width. This avoids overlapping text in adjacent columns. X% X% ------------------------------------------------------------------ X X/clipshow X{ X gsave X newpath x0 1 add y0 1 add moveto 2 sub dup 0 rlineto X 0 lsize 2 sub rlineto neg 0 rlineto closepath clip X newpath x0 xboff add y0 descent add yboff add moveto show X grestore X} def X X% ------------------------------------------------------------------ X% X% prg-array optimizeColumns - X% X% optimizeColumns uses the given array of application specific data X% to update its internal state as far as the maximum column width X% required is concerned. X% X% ------------------------------------------------------------------ X X/optimizeColumns X{ X % -------------------------------------------------------------------------- X % use all the information given to compute optimal column widths & font size X % -------------------------------------------------------------------------- X { X /elem exch def % define current element X % (elem is) == elem == X 0 1 nColumns 1 sub % loop through all columns X { X /i exch def X fieldMulti i get (W) eq X { X % Weightened Selection: Column Width is constant, i.e. X % compute only once X maxSizes i get 0 eq % not yet computed -> do it X { X /legend true def X /len 0 def X multiWeightSelTitles i get X { X stringwidth pop multiOff dup add add len add /len exch def X } forall % for all strings in the multi weight info array X % put information about the size of the field into the array X maxSizes i len put X } if X } % end if current column is weightened selection X { % if current column is NOT a weightened selection X % simply compute the width of the given strings using X % their maximum multiplicity as given in /colMultiplicity X % the strings are concatenated using the delimiter string X /cnt 0 def % counter for maximum multiplicity X /len xboff dup add def X /maxMultiplicity colMultiplicity i get def X elem i get X dup /nMultis exch length def X { X /len exch stringwidth pop len add X % should I append the delimiter ? X /cnt cnt 1 add def X cnt nMultis ne X cnt maxMultiplicity ne and X { X delimiter stringwidth pop add def X } X { X def exit X } ifelse X } forall X % if size exceeds maximum, store it X maxSizes i get len lt X { X maxSizes i len put X } if X } ifelse % end if current column is *not* a weightened selection X } for % for all selected columns X } forall % end optimization loop through the input array X} def X X% ------------------------------------------------------------------ X% X% - postOptimization - X% X% Uses the information obtained from calling optimizeColumns X% (several times, if the input data is too large) X% and mixes it with field widths given by the user to compute X% the new font size and applies the resulting scaling factor X% to a number of internal parameters. X% X% ------------------------------------------------------------------ X X/postOptimization X{ X 0 1 nColumns 1 sub X { X /i exch def X colSizes i get -1 eq % no size given -> use the computed size X { X colSizes i maxSizes i get put X debug X { X (\012 Computed width for column ') print colNames i get print X (' to ) print colSizes i get 12 string cvs print X } if X } X { X debug X { X (\012 Using specified width \() print colSizes i get X 12 string cvs print ( points\) for column ') print X colNames i get print X } if X } ifelse X } for X 0 colSizes { add } forall X /total exch def X /factor hspace total div def % scaling factor X /fsize fsize factor mul def X /GermanFont findfont fsize scalefont setfont X % update column size information X [ colSizes { factor mul } forall ] /colSizes exch def X /multiOff multiOff factor mul def X X /sbbox 4 array def %% compute scaled bounding box X 0 1 3 X { X /i exch def X sbbox i bbox i get fsize mul 1000 div put X } for X X % size of one line, taking descent and font size into account X /lsize sbbox 3 get sbbox 1 get X sub yboff dup add add def X X % current descent value, used to position the characters vertically X % within a line X /descent sbbox 1 get neg def %% 0 is origin, lly is therefore negative descent X X debug { (\012 Descent set to ) print descent 10 string cvs print (\012) print } if X /nLines vspace lsize div cvi def %% number of lines on one page according to line size X X % update available vertical space X /vspace nLines lsize mul def X X % compute expected number of pages X totalEntries nLines 1 sub idiv totalEntries nLines 1 sub mod 0 ne { 1 add } if X /nPages exch def X /nPagesStr nPages 10 string cvs def X X debug { (\012 Report will consist of ) print nLines 10 string cvs print ( lines per page.) print } if X debug { (\012 Optimization finished, using font size ) print fsize 10 string cvs print } if X X % ------------------------------------------------------------------ X % print title page X % ------------------------------------------------------------------ X X showtitle X { X 16 dict begin X top X newpath X gsave X 0 0 moveto title true charpath pathbbox X /tury exch def X /turx exch def X /tlly exch def X /tllx exch def X % the '18 sub' is to leave some space at the border for X % additional infos X newpath hspace 18 sub turx tllx sub div /sfak exch def X hspace 2 div vspace 2 div translate sfak sfak scale X tllx turx sub 2 div tlly tury sub 2 div moveto title show X grestore X % compute positions required for user name and sorting criteria X % debug { (\012 size of title string is ) print turx tllx sub 10 string cvs print } if X % debug { (\012 scaling factor is ) print sfak 10 string cvs print } if X /topoff vspace tury tlly sub sfak mul add 2 div yboff add lsize add def X /botoff sortFields length lsize mul def X userstr stringwidth pop ( presents) stringwidth pop add neg hspace add 2 div X topoff moveto userstr show ( presents) show X % display the sort keys X (Sorting Criteria:) stringwidth pop neg hspace add 2 div /scx exch def X scx botoff moveto (Sorting Criteria:) show X sortFields X { X /botoff botoff lsize sub def X scx botoff moveto show X } forall X % show date and page info X 0 vspace lsize sub moveto datestr show X hspace timestr stringwidth pop sub vspace lsize sub moveto timestr show X 0 0 moveto totalEntries 16 string cvs show ( lines) show X % display total number of pages X hspace ( pages) stringwidth pop sub X nPagesStr stringwidth pop sub 0 moveto X nPagesStr show ( pages) show X gsave X /GermanFont findfont 6 scalefont setfont X gsave X 0 vspace 2 div translate 90 rotate X commandLine dup stringwidth pop 2 div neg 0 X moveto show X grestore X gsave X hspace vspace 2 div translate -90 rotate X (thanks for using patsch's PostScript Report Generator - (C) 1994 Patrick Dockhorn) X dup stringwidth pop 2 div neg 0 X moveto show X grestore X grestore X end X showpage X } if X X % ------------------------------------------------------------------ X % print legend if any weightened selection present X % ------------------------------------------------------------------ X X legend X { X 12 dict begin X top X /y0 vspace lsize sub def X newpath (Additional Information) dup X stringwidth pop neg X dup /tmpsw exch def X hspace add 2 div y0 moveto show X tmpsw 0 rlineto stroke X /y0 y0 lsize dup add sub def X /nhits 0 def X 0 1 nColumns 1 sub X { X /i exch def X fieldMulti i get (W) eq X { X /ybuf y0 def X /nhits nhits 1 add def X nhits 2 mod 0 eq X { X /x0 hspace 2 div xboff add def X } X { X /x0 xboff def X } ifelse X newpath x0 y0 moveto (Explanation for column ') show X colNames i get show (' :) show X x0 y0 lineto stroke newpath X /mss 0 def X /scarr multiWeightSelTitles i get def X /ltarr multiWeightSelFullTitles i get def X scarr X { X stringwidth pop dup mss gt { /mss exch def } { pop } ifelse X } forall X X 0 1 scarr length 1 sub X { X /j exch def X /y0 y0 lsize sub def X x0 y0 moveto scarr j get show X x0 mss add xboff dup add add y0 moveto ltarr j get show X } for X nhits 2 mod 0 eq X { X /y0 y0 lsize dup add sub def X } X { X /y0 ybuf def X } ifelse X } if X } for X showpage X end X } if X} def X X X% ------------------------------------------------------------------ X% X% prg-array createReport - X% X% Prints the data given in prg-array (which is in a format specified X% through the -format option) nicely formatted. Does all the pagebreak, X% handling, rotation etc. X% X% ------------------------------------------------------------------ X X/createReport X{ X % ------------------------------------------------------------------ X % handle all array elements X % ------------------------------------------------------------------ X X { X /elem exch def % define current element X line 0 eq % Top of page ? X { X top X /x0 0 def X /y0 vspace def % start value for y X 0 setlinewidth % set line width for bounding box X newpath 0 0 moveto hspace 0 rlineto 0 vspace rlineto X hspace neg 0 rlineto closepath X /y0 y0 lsize sub def X 0 y0 moveto hspace 0 rlineto stroke X X gsave X /GermanFont findfont 6 scalefont setfont X newpath 0 vspace yboff add moveto title show delimiter show datestr show X newpath hspace (Page ) stringwidth pop sub page 1 add 10 string cvs /pagestr exch def X pagestr stringwidth pop sub ( / ) stringwidth pop sub nPagesStr stringwidth pop sub X vspace yboff add moveto (Page ) show pagestr show ( / ) show nPagesStr show X grestore X X 0 1 nColumns 1 sub X { X /i exch def X /cs colSizes i get def X debug X { X (\012 Column size for ') print colNames i get print (' is ) print X cs 10 string cvs print (\012) print X } if X X fieldMulti i get (W) eq % multi-field -> special title X { X /xbuf x0 def X /j 0 def X /offArr colMultiOffsets i get def X % debug { (\012 offArr for column ) print colNames i get print ( is \012) print offArr == } if X /mwsl multiWeightSelTitles i get length def X multiWeightSelTitles i get X { X dup stringwidth pop /mssize exch def % save string size X newpath x0 multiOff add y0 yboff add descent add moveto % position X show X offArr j x0 put % save current x position X j 0 gt j mwsl ne and X { X x0 y0 lsize add moveto 0 vspace neg X rlineto stroke X } if X /j j 1 add def X mssize multiOff dup add add X dup x0 add /x0 exch def X neg cs add /cs exch def X } forall X /x0 xbuf def X X% debug X% { X% (\012 Updated colMultiOffsets[) print i 10 string cvs print X% (] to the following offset array:\012) print offArr == X% } if X X colMultiOffsets i offArr put X } X { X colNames i get cs clipshow X } ifelse X i 0 gt { newpath x0 y0 lsize add moveto 0 vspace neg rlineto stroke } if X /x0 x0 colSizes i get add def X } for % end for all columns X debug { (\012 Multi-Column offset array:\012) print colMultiOffsets == } if X X /y0 y0 lsize sub def X } if % end if first line of page X X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X % X % Standard Procedure for a single entry X % X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X X newpath X /x0 0 def X 0 1 nColumns 1 sub X { X /i exch def X fieldMulti i get (W) eq % Weightened selection X { X /done false def X % debug { (\012 Handling multi field ') print colNames i get print ('\012) print } if X elem i get X { X % debug { (\012 Checking weightened selection ) print dup == } if X dup 1 get /val exch def X 0 get /cat exch def X % search for the position of the category X /idx 0 def X multiWeightSelTitles i get X { X cat eq % category match -> show the corr. value X { X colMultiOffsets i get idx get multiOff add X cat stringwidth pop add val stringwidth pop sub X y0 yboff add descent add moveto val show X /done true def X exit X } if X /idx idx 1 add def X } forall X done { exit } if X } forall X } % end if current column is weightened selection X { % if current column is NOT a weightened selection X % simply compute the width of the given strings using X % their maximum multiplicity as given in /colMultiplicity X % the strings are concatenated using the delimiter string X X % first check if the current element is the same X % as the previous one, if so, and duplicate elim. X % is selected, nothing is displayed X % (except if this is the first line of a new page) X X /displayThis true def X noDupls line 0 ne and X { X /tidx 0 def X true X elem i get X { X lastElem i get tidx get eq and X /tidx tidx 1 add def X } forall X not /displayThis exch def X } if X X displayThis X { X line 0 ne i 0 eq and X { X 0 y0 lsize add yboff add moveto hspace 0 rlineto stroke X } if X /cnt 0 def % counter for maximum multiplicity X /xwidth colSizes i get def X /maxMultiplicity colMultiplicity i get def X /xbuf x0 def X elem i get X dup /nMultis exch length def X nMultis 1 eq X { X % only one entry -> check for the field type and X % display numeric values right justified X X X 0 get X fieldTypes i get dup (N) eq exch (T) eq or X { X dup stringwidth pop neg x0 add xwidth add X xboff dup add sub X /x0 exch def xwidth clipshow X } X { X % no numeric field X xwidth clipshow X } ifelse X } X { X % more than one entry X { X dup X xwidth clipshow X stringwidth pop dup neg xwidth add /xwidth exch def X x0 add /x0 exch def X % should I append the delimiter ? X /cnt cnt 1 add def X cnt nMultis ne X cnt maxMultiplicity ne and X { X delimiter xwidth clipshow X delimiter stringwidth pop dup X x0 add /x0 exch def neg xwidth add X /xwidth exch def X } X { X exit % leave if maximum multiplicity reached X } ifelse X } forall X } ifelse X /x0 xbuf def X } if % if entry should be shown at all X } ifelse % end if not a weightened selection X X /x0 x0 colSizes i get add def X X } for % end for all columns X X % one line is finished X % debug { (\012 Line ) print line 10 string cvs print ( printed.) print } if X X /line line 0 eq X { line 2 add } { line 1 add } ifelse X dup nLines ge { pop 0 /page page 1 add def showpage } if def X /y0 y0 lsize sub def % new y starting position X /lastElem elem def % remember last element for duplicate elimination X } forall % end for all data X} def X X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X%% X%% M M A III N N X%% MM MM A A I NN N X%% M M M M A A I N N N X%% M M M A A I N N N X%% M M AAAAAAA I N N N X%% M M A A I N NN X%% M M A A III N N X%% X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X X128 dict begin % start a large user dictionary X XUmlaute % activate german (or, more generally, foreign Umlauts) X X/GermanFont findfont 12 scalefont setfont % select font X X% Dynamic data for output header X X/cm { 28.346456 mul } def %% definition of a cm based in points X/pageWidth 21.0 cm def %% Width of a page X/pageHeight 29.7 cm def %% Height of a page X/hoff 1.2 cm def %% horizontal skip value X/voff 1.2 cm def %% vertical skip value X X/landscape false def %% Print in landscape mode ? X/datestr (03.06.94) def %% today's date X/timestr (16:25:13) def %% current time X/userstr (patsch) def %% user running the program X/fsize 12 def %% base font used X/title (Videoliste) def %% title for the report X/delimiter (, ) def %% delimiter string for multi-fields X/noDupls true def %% display values if same for two succeeding rows ? X X% define size variables depending on landscape parameter X Xlandscape X{ X /lph pageWidth def X /lpw pageHeight def X} X{ X /lpw pageWidth def X /lph pageHeight def X} ifelse X X% procedure called when new page is started X X/top X{ X landscape X { X -90 rotate pageHeight neg 0 translate X } if X hoff voff translate X} def X X X%% ------------------------------------------------------------------ X%% the following arrays were created by the prg.awk program X%% ------------------------------------------------------------------ X X% requested size of the selected columns X/colSizes [ -1 -1 -1 -1 -1 ] def X X% Titles of the selected columns X/colNames [ (Actor/Actress) (Title) (Nr.) (Index) (Length) ] def X X% Maximum multiplicity of the selected columns X/colMultiplicity [ 1 1 1 1 1 ] def X X% Offsets within fields with multiplicity greater than one X/colMultiOffsets [ [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] ] def X X% fieldTypes: describe the type of the fields to be shown X/fieldTypes [ (A) (A) (N) (N) (T) ] def X X% fieldMulti: holds the information whether a field may hold multiple elements X/fieldMulti [ (M) (O) (O) (O) (O) ] def X X% titles for weightened multiple selection fields X/multiWeightSelTitles [ [] [] [] [] [] ] def X X X% full titles for weightened multiple selection fields X/multiWeightSelFullTitles [ [] [] [] [] [] ] def X X% fields used for sorting X/sortFields [(Ascending 'Actor/Actress')(Ascending 'Title') ] def X X% total entries in this report X/totalEntries 399 def X X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X%% define global variables used for optimization X%% and printing X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X X/optimize true def %% optimize output size ? X/debug false def %% PostScript debugging X/showtitle true def %% display title page ? X/commandLine (command line used: /u/patsch/bin/prg videos -format ACT#TIT#NUM#IDX#LEN -sortby ACT#TIT -noDuplicates -cbsc 0 -select stdin) def %% how the program was invoked X/line 0 def %% current line X/page 0 def %% current page X/hspace lpw hoff dup add sub def %% space available horizontally X/vspace lph voff dup add sub def %% space available vertically X/xboff 3 def %% box offset horizontally X/yboff 2 def %% box offset horizontally X/multiOff 2 def %% Offset for multiple weightened selection X/x0 0 def %% start value for x X X/nColumns colSizes length def %% number of columns X/bbox /GermanFont findfont X/FontBBox get [ exch aload pop ] def %% Bounding-Box (scale-independent) X/legend false def %% draw a legend on the second page ? X/maxSizes nColumns array def %% array to hold the maximum values X X0 1 nColumns 1 sub %% NULL the maxSizes array X{ X maxSizes exch 0 put X} for X X%% compute default values for column widths if no optimization requested X Xoptimize not X{ X % compute default sizes for the columns (if no explicit data given) X 0 1 nColumns 1 sub X { X /i exch def colSizes i colSizes i get X dup -1 eq { pop hspace nColumns div } if put X fieldMulti i get (W) eq { /legend true def } if X } for X} if % no optimization -> compute default values X X% ------------------------------------------------------------------ X% ------------------------------ DATA ------------------------------ X% ------------------------------------------------------------------ X X[ X[[(Beasley,Allyce)][(Monstrum,Das)][(24)][(2)][(3:00:00)]] X[[(Bedelia,Bonnie)][(Stirb Langsam II)][(2)][(1)][(1:58:00)]] X[[(Bedelia,Bonnie)][(Stirb Langsam)][(2)][(0)][(2:05:00)]] X[[(Blessed,Brian)][(Robin Hood - K\321nig der Diebe)][(8)][(0)][(2:17:00)]] X[[(Brown,Bryan)][(Der Auftragskiller)][(28)][(1)][()]] X[[(Brown,Bryan)][(FX 2)][(10)][(0)][(1:43:00)]] X[[(Call,Brandon)][(Blinde Wut)][(6)][(1)][(1:22:00)]] X[[(Cobbs,Bill)][(New Jack City)][(22)][(0)][(1:36:00)]] X[[(Corley,Annie)][(Monstrum,Das)][(24)][(2)][(3:00:00)]] X[[(Datcher,Alex)][(Passagier 57)][(24)][(1)][(1:20:00)]] X[[(Dennehy,Brian)][(Einsame Zeit f\323r Helden)][(16)][(0)][(1:41:00)]] X[[(Dennehy,Brian)][(FX 2)][(10)][(0)][(1:43:00)]] X[[(Desalvo,Anne)][(Ich bin Du und Du bist nichts)][(13)][(1)][(1:49:00)]] X[[(DeSando,Anthony)][(New Jack City)][(22)][(0)][(1:36:00)]] X[[(Djola,Badja)][(The Last Boy Scout)][(18)][(1)][(1:42:00)]] X[[(Doyle-Murray,Brian)][(Und t\300glich gr\323\325t das Murmeltier)][(26)][(0)][(1:37:00)]] X[[(Doyon,Bruno)][(Stirb Langsam)][(2)][(0)][(2:05:00)]] X[[(Duke,Bill)][(Predator)][(17)][(0)][(1:40:00)]] X[[(Evans,Art)][(Stirb Langsam II)][(2)][(1)][(1:58:00)]] X[[(Finney,Albert)][(Miller's Crossing)][(10)][(1)][(1:50:00)]] X[[(Fonda,Bridget)][(Doc Hollywood)][(9)][(1)][(1:37:00)]] X[[(Garcia,Andy)][(Ein ganz normaler Held)][(21)][(1)][()]] X[[(Glover,Brian)][(Alien III)][(23)][(1)][(1:51:00)]] X[[(Godunov,Alexander)][(Stirb Langsam)][(2)][(0)][(2:05:00)]] X[[(Greenwood,Bruce)][(Passagier 57)][(24)][(1)][(1:20:00)]] X[[(Halsey,Brett)][(Lion of the Desert)][(9)][(0)][(2:07:00)]] X[[(Heald,Anthony)][(Das Schweigen der L\300mmer)][(5)][(1)][(1:50:00)]] X[[(Hopkins,Anthony)][(Das Schweigen der L\300mmer)][(5)][(1)][(1:50:00)]] X[[(Hughes,Barnard)][(Doc Hollywood)][(9)][(1)][(1:37:00)]] X[[(James,Brion)][(Blade Runner)][(22)][(1)][(1:50:00)]] X[[(Janner,Brigitte)][(Manta - Der Film)][(8)][(1)][(1:29:00)]] X[[(Katarina,Anna)][(Jugger,Die)][(13)][(0)][(1:39:00)]] X[[(MacDowell,Andie)][(Und t\300glich gr\323\325t das Murmeltier)][(26)][(0)][(1:37:00)]] X[[(Matthews,Al)][(Aliens II)][(4)][(1)][(24:00)]] X[[(McGill,Bruce)][(The Last Boy Scout)][(18)][(1)][(1:42:00)]] X[[(McKinney,Bill)][(T\321dliches Abenteuer)][(16)][(1)][(1:37:00)]] X[[(Motta,Bess)][(Terminator)][(3)][(0)][(1:43:00)]] X[[(Murray,Bill)][(Und t\300glich gr\323\325t das Murmeltier)][(26)][(0)][(1:37:00)]] X[[(Nunn,Bill)][(New Jack City)][(22)][(0)][(1:36:00)]] X[[(Paton,Angela)][(Und t\300glich gr\323\325t das Murmeltier)][(26)][(0)][(1:37:00)]] X[[(Paxton,Bill)][(Aliens II)][(4)][(1)][(24:00)]] X[[(Paxton,Bill)][(Einsame Zeit f\323r Helden)][(16)][(0)][(1:41:00)]] X[[(Payne,Allen)][(New Jack City)][(22)][(0)][(1:36:00)]] X[[(Payne,Bruce)][(Passagier 57)][(24)][(1)][(1:20:00)]] X[[(Reynolds,Burt)][(T\321dliches Abenteuer)][(16)][(1)][(1:37:00)]] X[[(Rickman,Alan)][(Robin Hood - K\321nig der Diebe)][(8)][(0)][(2:17:00)]] X[[(Rickman,Alan)][(Stirb Langsam)][(2)][(0)][(2:05:00)]] X[[(Schwarzenegger,Arnold)][(Predator)][(17)][(0)][(1:40:00)]] X[[(Schwarzenegger,Arnold)][(Terminator II - Judgement Day)][(3)][(1)][(2:08:00)]] X[[(Schwarzenegger,Arnold)][(Terminator)][(3)][(0)][(1:43:00)]] X[[(Smith,Brooke)][(Das Schweigen der L\300mmer)][(5)][(1)][(1:50:00)]] X[[(Wallage,Basil)][(Wedlock)][(6)][(0)][(1:36:00)]] X[[(Willis,Bruce)][(Stirb Langsam II)][(2)][(1)][(1:58:00)]] X[[(Willis,Bruce)][(Stirb Langsam)][(2)][(0)][(2:05:00)]] X[[(Willis,Bruce)][(The Last Boy Scout)][(18)][(1)][(1:42:00)]] X[[(Wisniewski,Andreas)][(Stirb Langsam)][(2)][(0)][(2:05:00)]] X] dup optimizeColumns postOptimization createReport Xline 0 eq not { showpage } if Xend % end large user dictionary X%%TRAILER X END_OF_FILE if test 26882 -ne `wc -c <'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps'`; then echo shar: \"'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps'\" unpacked with wrong size! fi # end of 'prg/doc/videos-by-actors-first-name-starts-A-or-B.ps' fi if test -f 'prg/lib/prg.awk' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'prg/lib/prg.awk'\" else echo shar: Extracting \"'prg/lib/prg.awk'\" \(31418 characters\) sed "s/^X//" >'prg/lib/prg.awk' <<'END_OF_FILE' XBEGIN { X passOne = 1; X scanDES = 0; X exprError = 0; X selectAll=0; X if (length(select) == 0) X selectAll=1; X nSortFields = split(sortby,sortFields); X selectionIndex=1; X} X X$1 == "END_DESCRIPTION" { X scanDES = 0; X newEntry = 1; X nEntries = 0; X # index variable for selection, X # equal to nEntries during buildup X cec = 0; X lastNum = -1; X desLines = NR; X} X XscanDES == 1 { X name=$1; X # define name for the fields X fieldName[name] = $2; X # define field type X fieldType[name] = $3; X # define field multiplicity X fieldMulti[name] = $4; X if ( ( $4 == "W" ) || ( $4 == "S" ) ) X { X fieldNSelections[name] = NF - 4; X for (i = 5 ; i <= NF ; i++) X fieldSelection[name,i-5] = $i; X } X} X X$1 == "BEGIN_DESCRIPTION" { X scanDES = 1; X} X X(scanDES == 0) && (NF == 0) { X if (lastEmpty == 0) X { X # special for videos: compute offset ! X videos[nEntries,"OFF",1] = timeCount; X timeCount+=videos[nEntries,"LEN",1]; X # check whether the entry is selected at all X if (selectAll) X { X nEntries++; X cec = nEntries; X } X else X { X if (isSelected()) X { X if (debugExpr) X printf("\n-------> ENTRY SELECTED (MATCH)!\n"); X nEntries++; X cec = nEntries; X } X else X { X # restore current entry X for (name in fieldName ) X videos[nEntries,name,0] = 0; X } X } X if ((nEntries % 100) == 0) printf("."); X } X lastEmpty=1; X} X X(scanDES == 0) && (NF > 0) && ($1 != "END_DESCRIPTION") { X lastEmpty=0; X if (($1 == "NUM") && ($2 != lastNum)) X { X lastNum = $2; X timeCount=0; X } X X if (fieldName[$1] == "") X printf("\nWarning in line %d : No description for the field <%s> exists !\n",NR-desLines,$1); X X offset = videos[nEntries,$1,0]; X videos[nEntries,$1,0] = offset+NF-1; X for (i = 2 ; i <= NF ; i++) X videos[nEntries,$1,i-1+offset] = $i; X videos[nEntries,$1,NF+offset] = NR-desLines; X if ((videos[nEntries,$1,0] > 1) && X (!((fieldMulti[$1] == "M") || (fieldMulti[$1] == "W")))) X { X printf("\nFehler in Zeile %d: Feld hat kein Multi-Attribut (weder 'M' noch 'W' sondern '%s'.",NR,fieldMulti[$1]); X printf("\nKontext: Field <%s>, line <%s>.",$1,$0); X } X} X XEND { X if (exprError) exit -77; X passOne = 0; X if (debugExpr) X printf("\n------------------------------------------------------------------\n PASS ONE COMPLETE\n------------------------------------------------------------------"); X if (debug) X { X for ( name in fieldName ) X { X printf("\nFeld %s [ Typ %s] : %s",name,fieldType[name],fieldName[name]); X if ( ( fieldMulti[name] == "W" ) || X ( fieldMulti[name] == "S" ) ) X for (i = 0 ; i < fieldNSelections[name] ; i++) X printf("\n : Selektion No.%2d : %s",i+1,fieldSelection[name,i]); } X printf("\n------------------------------------------------------------------"); X for (n = 0 ; n < nEntries; n++) X { X for (name in fieldName) X { X nMultis = videos[n,name,0]; X printf("\n%s: ",name); X for (i = 1 ; i <= nMultis ; i++) X { X if (i > 1) printf(","); X printf("%s",videos[n,name,i]); X } X } X } X } X X ################################################################## X # X # create the postscript header information X # X ################################################################## X X nFields = split(format,formatStrings); X X printf("%% requested size of the selected columns\n/colSizes [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X printf(" %g",extractColumnWidth(formatStrings[i])) > tmpHeader; X X printf(" ] def\n\n%% Titles of the selected columns \n/colNames [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X printf(" (%s)",fieldName[extractColumnName(formatStrings[i])]) > tmpHeader; X X printf(" ] def\n\n%% Maximum multiplicity of the selected columns \n/colMultiplicity [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X printf(" %s",extractColumnMultiplicity(formatStrings[i])) > tmpHeader; X X printf(" ] def\n\n%% Offsets within fields with multiplicity greater than one\n/colMultiOffsets [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X { X printf(" [") > tmpHeader; X nm = extractColumnMultiplicity(formatStrings[i]); X for (j = 0 ; j < nm ; j++) X printf(" 0") > tmpHeader; X printf(" ]") > tmpHeader; X } X X printf(" ] def\n") > tmpHeader; X X # Feld-Typ Info X printf("\n%% fieldTypes: describe the type of the fields to be shown\n/fieldTypes [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X printf(" (%s)",fieldType[extractColumnName(formatStrings[i])]) > tmpHeader; X X printf(" ] def\n") > tmpHeader; X X # Feld-Multi Info X printf("\n%% fieldMulti: holds the information whether a field may hold multiple elements\n/fieldMulti [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X printf(" (%s)",fieldMulti[extractColumnName(formatStrings[i])]) > tmpHeader; X X printf(" ] def\n") > tmpHeader; X X # X # create the titles for weightened selections X # X X printf("\n%% titles for weightened multiple selection fields\n/multiWeightSelTitles [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X { X name = extractColumnName(formatStrings[i]); X if ( fieldMulti[name] == "W" ) X { X printf(" [") > tmpHeader; X for (k = 0 ; k < fieldNSelections[name] ; k++) X { X selstr=fieldSelection[name,k]; X printf("(") > tmpHeader; X do X { X j = index(selstr,"_"); X if (j > 0) X { X printf("%s",substr(selstr,j+1,1)) > tmpHeader; X selstr=substr(selstr,j+2); X } X } while (j > 0); X printf(")") > tmpHeader; X } X printf("]") > tmpHeader; X } X else printf(" []") > tmpHeader; X } X printf(" ] def\n") > tmpHeader; X X # compute the full titles X printf("\n\n%% full titles for weightened multiple selection fields\n/multiWeightSelFullTitles [") > tmpHeader; X for ( i = 1 ; i <= nFields ; i++ ) X { X name = extractColumnName(formatStrings[i]); X if ( fieldMulti[name] == "W" ) X { X printf(" [ ") > tmpHeader; X for (j = 0 ; j < fieldNSelections[name] ; j++) X { X selstr=fieldSelection[name,j]; X gsub("_","",selstr); X printf(" (%s)",selstr) > tmpHeader; X } X printf(" ]") > tmpHeader; X } X else X printf(" []") > tmpHeader; X } X printf(" ] def\n") > tmpHeader; X X # X # parse the data stored in the videos array and create the appropriate X # output that is then sorted using standard unix procedures X # X # create sorting information first X X X # return number of sort fields X printf("%d\n",nSortFields+1) > sprintf("%s.nsf",tmpHeader); X X # check if sort fields are valid at all X printf("#!/bin/sh\nsort -t '#' ") > sortFileName; X X printf("\n%% fields used for sorting\n/sortFields [") > tmpHeader; X for (i = 1 ; i <= nSortFields ; i++) X { X reverse=doReverseSort(sortFields[i]); X name = extractSortFieldName(sortFields[i]); X X if (reverse) X printf("(Descending") > tmpHeader; X else X printf("(Ascending") > tmpHeader; X printf(" '%s')",fieldName[name]) > tmpHeader; X X if ((fieldType[name] == "A") || X (fieldType[name] == "N") || X (fieldType[name] == "T")) X { X if (fieldMulti[name] == "W") X { X printf("\nIt's not possible to sort using a weightened multiple selection"); X printf("\nfield as you tried with the field <%s>.\n",name); X exit -1; X } X else X { X printf(" +%db",i-1) > sortFileName; X if (reverse) X printf("r") > sortFileName; X if ((fieldType[name] == "N") || (fieldType[name] == "T")) X printf("n") > sortFileName; X if (casecomp == 0) X printf("f") > sortFileName; X } X } X else X { X printf("\nYou selected the field <%s> for sorting, but it has got the illegal type <%s>.\n", X name,fieldType[name]); X exit -2; X } X } X printf(" ] def\n") > tmpHeader; X X printf(" -o ${1}.srt $1") > sortFileName; X X # loop through all the tapes I got X X totalEntries = 0; X X if (nEntries == 0) X { X printf("\nNo entries selected !\n"); X printf(" ") > tmpData; X exit -3; X } X for (n = 0 ; n < nEntries; n++) X { X for (i = 1 ; i <= nSortFields ; i++) sortCounter[i] = 1; X # loop over multiple selection fields used as sort keys X entryDone = 0; X do X { X totalEntries++; X if ((totalEntries % 100) == 0) printf("."); X # buffer for the sort keys X lbuf="" X X ########################################### X # handle the prefixed sort keys X ########################################### X X for (i = 1 ; i <= nSortFields ; i++) X { X name = extractSortFieldName(sortFields[i]); X sstr=videos[n,name,sortCounter[i]]; X z = index(sstr,"$"); X if (z > 0) X lbuf=lbuf sprintf("%s,%s#",substr(sstr,z+1),substr(sstr,1,z-1)); X else X { X if (length(sstr) == 0) X { X # if string is empty prefix it with some special X # characters to have it appear at the end of the report X if (doReverseSort(sortFields[i])) X lbuf = lbuf sprintf("!!!!!#"); X else X lbuf = lbuf sprintf("}}}}}#"); X } X else X { X if (fieldType[name] == "T") X lbuf = lbuf sprintf("%d#",getTimeNumeric(sstr)); X else X lbuf = lbuf sprintf("%s#",sstr); X } X } X } X X printMe=1; X lbuf = lbuf "["; X for ( i = 1 ; (i <= nFields) && (printMe) ; i++ ) X { X name = extractColumnName(formatStrings[i]); X # X # X # create postscript string depending on input data type X # X # X # check whether the current column is a key; if so, force the X # currently selected key to appear in the column ! X special=0; X if (!(selectAll)) X { X # check whether the current entry is selected at all ! X for (j = 1 ; (j <= nSortFields) && (printMe) ; j++) X { X sname = extractSortFieldName(sortFields[j]); X if ((sname == name) && (fieldMulti[name] == "M")) X { X cec = n; X selectionIndex = sortCounter[j]; X printMe = isSelected(); X } X } X } X if (printMe) X { X for (j = 1 ; j <= nSortFields; j++) X { X sname = extractSortFieldName(sortFields[j]); X if (sname == name) X { X special=1; X sstr=videos[n,sname,sortCounter[j]]; X # time data type ? X if ((fieldType[sname] == "T") && (length(sstr) > 0)) X lbuf = lbuf getTime(videos[n,sname,1]); X else X { X z = index(sstr,"$"); X if (z > 0) X lbuf = lbuf sprintf("[(%s,%s)]",substr(sstr,z+1),substr(sstr,1,z-1)); X else X lbuf = lbuf sprintf("[(%s)]",sstr); X } X } X } X X if (special == 0) X { X # time data type X if (fieldType[name] == "T") X lbuf=lbuf getTime(videos[n,name,1]); X else X { X # ASCII or NUMERIC X lbuf = lbuf "["; X if (fieldMulti[name] == "M") # multiple values possible X { X nMultis = videos[n,name,0]; X for (j = 1 ; j <= nMultis ; j++) X { X namstr=videos[n,name,j]; X gsub("\\$"," ",namstr); X lbuf = lbuf sprintf("(%s)",namstr); X } X } X else X { X # weightened selection X if (fieldMulti[name] == "W") X { X nMultis = videos[n,name,0]; X for (j = 1 ; j <= nMultis ; j++) X { X selstr=videos[n,name,j]; X gsub("\\$"," ",selstr); X len = length(selstr); X val=substr(selstr,len,1); X if ((val < "0") || (val > "9")) X { X printf("\nFehler in Zeile %d der Eingabedatei:",videos[n,name,nMultis+1]); X printf("\nEin Feld der Kategorie 'Weightened Selection'"); X printf("\nwurde nicht mit der erforderlichen Wertung (0-9) beendet.\n"); X exit -4; X } X lbuf = lbuf sprintf("[(%s)(%s)]",substr(selstr,1,len-1),val); X } X } X else X { X selstr=videos[n,name,1]; X if ((fieldMulti[name] == "S") && (selstr != "")) X { X selOk = 0; X # consistency check X for (j = 0 ; j < fieldNSelections[name] ; j++) X if (fieldSelection[name,j] == selstr) selOk = 1; X if (selOk == 0) X { X printf("\nFehler in Zeile %d der Eingabedatei:",videos[n,name,nMultis+1]); X printf("\nEinem Feld der Kategorie 'Selection' wurde ein nicht definierter"); X printf("\nWert (%s) zugewiesen. Erlaubt sind die folgenden Werte:\n",selstr); X for (j = 0 ; j < fieldNSelections[name] ; j++) X { X if (j > 0) printf(", "); X printf("%s",fieldSelection[name,j]); X } X exit -5; X } X } X # just the standard one-entry field category X gsub("\\$"," ",selstr); X lbuf = lbuf sprintf("(%s)",selstr); X } X } X # end if no multiple field X lbuf = lbuf "]"; X } X # end if field type is *not* time X } X # end if no special case (key appears in format string) X } X # end if entry should be printed at all X } X # end for all fields selected in the format string X X # print the current line into the output file X if (printMe) X printf("%s]\n",lbuf) >> tmpData; X X # increase counter until all multiple fields are done X entryDone=0; X i = nSortFields; X do X { X carry=0; X sname = extractSortFieldName(sortFields[i]); X sortCounter[i]=sortCounter[i]+1; X if (sortCounter[i] > videos[n,sname,0]) X { X carry=1; X sortCounter[i] = 1; X i--; X if (i <= 0) X entryDone = 1; X } X } while ((carry == 1) && (entryDone == 0)); X } while (entryDone == 0); X } X printf("\n%% total entries in this report\n/totalEntries %d def\n",totalEntries) >> tmpHeader; X # end for all entries in the database X} X X################################################################## X################################################################## X# FUNCTION DEFINITIONS X################################################################## X################################################################## X X################################################################## X# X# Extract functions for format specifiers X# Generic format is: X# COLUMN_NAME:WIDTH-NUMBER X# X# where X# COLUMN_NAME is the name of the column to display X# WIDTH is the width to be used to display the column (in cm) X# NUMBER is the maximal number of hits to be displayed if X# the field has a multiplicity higher than one. X# X# WIDTH defaults to a very simple value computed by dividing X# the total page width by the number of columns, NUMBER defaults to 1. X# X################################################################## X Xfunction extractColumnName(str) X{ X # look for colon which indicates space information to use X z1 = index(str,":"); X z2 = index(str,"-"); X # no info specified X if ( (z1 == 0) && (z2 == 0) ) return str; X else X { X if (z1 == 0) X return substr(str,1,z2-1); X else X { X if (z2 == 0) X return substr(str,1,z1-1); X else X { X if (z2 < z1) { tmp = z1; z1 = z2; z2 = tmp; } X return substr(str,z1,z2-z1); X } X } X } X} X X#################################################################### X# extracts the width of a column specified in a format string X#################################################################### X Xfunction extractColumnWidth(str) X{ X # look for colon which indicates space information to use X z1 = index(str,":"); X z2 = index(str,"-"); X # no info specified X if (z1 == 0) return -1; X else X { X val = -1; X if (z2 == 0) X val = substr(str,z1+1); X else X { X if (z2 > z1) X val = substr(str,z1+1,z2-z1-1); X else X val = substr(str,z1+1); X } X return val*unit; X } X} X X####################################################################### X# extracts the multiplicity of a column specified in the format string X####################################################################### X Xfunction extractColumnMultiplicity(str) X{ X # look for colon which indicates space information to use X name = extractColumnName(str); X X # Weightened Selection always displays all its members X if (fieldMulti[name] == "W") X return fieldNSelections[name]; X z1 = index(str,":"); X z2 = index(str,"-"); X if (z2 == 0) return "1"; # no info specified X else X { X if (z1 == 0) X return substr(str,z2+1); # no width info given X else X { X if (z1 > z2) # width info follows X return substr(str,z2+1,z1-z2-1); X else X return substr(str,z2+1); # multi info at end X } X } X} X X################################################################## X# extract the field name from a sort field, i.e. X# removes a leading dash, if there is one X################################################################## X Xfunction extractSortFieldName(str) X{ X z = index(str,"-"); X if (z == 0) return str; X else X { X if (z == 1) X return substr(str,2); X else X { X printf("\n in a sort field specification."); X printf("\nA dash indicating the reverse ordering of"); X printf("\na field may *ONLY* appear in front of the sort field's name."); X printf("\nThe sort field <%s> does not match this requirement.\n",str); X exit -6; X } X } X} X################################################################## X# extract the information whether a sort field should be ordered X# in reverse order. X################################################################## X Xfunction doReverseSort(str) X{ X return index(str,"-"); X} X X################################################################## X# getTime: gets time formatted X################################################################## X Xfunction getTime(data) X{ X if (index(data,"s") == 1) X seconds = substr(data,2); X else X seconds = data*60; X X if (seconds == 0) X return "[()]"; X else X { X if (accuracy == "minutes") X seconds=int(seconds/60); X if (accuracy == "hours") X seconds=int(seconds/3600); X X hours=int(seconds/3600); X hseconds=seconds%3600; X minutes=int(hseconds/60); X seconds=seconds%60; X X if (hours == 0) X { X if (minutes == 0) X return(sprintf("[(%2d)]",seconds)); X else X return(sprintf("[(%d:%02d)]",minutes,seconds)); X } X else X return(sprintf("[(%d:%02d:%02d)]",hours,minutes,seconds)); X } X} X X##################################################################### X# getTimeNumeric: prints a time record as a numeric value (seconds) X##################################################################### X Xfunction getTimeNumeric(data) X{ X if (index(data,"s") == 1) X return(substr(data,2)); X else X return 60*data; X} X X################################################################## X# isSelected: Checks whether the current record is selected X# as far as the given selector is concerned. X################################################################## X Xfunction isSelected() X{ X if (debugExpr) X { X printf("\n\n------------------------------------------------------------------"); X printf("\nDebugging expression '%s' for entry %d.",select,cec); X printf("\n------------------------------------------------------------------\n"); X } X X return evalExpr(select); X} X X X################################################################## X# evalExpr: evaluates the given expression with respect to X# the current record (indicated by cec). X################################################################## X Xfunction evalExpr(expr,ex1,ex2,operator,name,flag,i) X{ X if (debugExpr) X printf("\nevalExpr<%s>",expr); X if (index(expr,"!") == 1) X { X if (debugExpr) X printf("\n<%s> : returning !evalExpr(%s).",expr,substr(expr,2)); X return !(evalExpr(substr(expr,2))); X } X X X if (!(bracesOk(expr))) X { X showSelector();printf("The expression <%s> has a problem with its round brackets.\n",expr); X exprError=1; exit -7; X } X X if (index(expr,"(") == 0) X { X if (debugExpr) X printf("\nevalExpression: Expression is simple <%s>.",expr); X return expr; X } X X # get operators and operands X X ex1=evalExpr(getOperand1(expr)); X operator = getOperator(expr); X ex2 = evalExpr(getOperand2(expr)); X X if (operator == "contains") X { X # special handling of 'contains' operator of the X # field used is a sort key ! X # this should not be done, better use == directly. X X if (substr(ex1,1,3) == "_M_") X ret = fieldContains(substr(ex1,4),ex2); X else X { X showSelector(); X exprError = 1; X printf("The 'contains' operator must not be applied if the field does not have"); X printf("\nthe 'M' attribute for the ability to hold multiple entries."); X printf("\nThis error also occurs if you specified the correct field, i.e. one"); X printf("\nwith the 'M' attribute, but also specified it as a sort key."); X printf("\nIn this case use the == operator instead.\n"); X exit -21; X } X } X else X { X # another special handling: if a field with attribute 'M' X # was compared using *not* the contains operator. X # this is only possible if the field appears in the sort key fields ! X X flag = 0; X if (substr(ex1,1,3) == "_M_") X { X name=substr(ex1,4); X X if (isSortKey(name)) X { X # if the user attempts to select a single entry X # from a field with 'M' attribute, the evaluation X # of the selection expression has to be postponed X # until the single entries are evaluated during X # the data buildup phase, i.e. AFTER the whole X # file with raw data has been read. X X if (debugExpr) X printf("\n\n*** EVALUATION OF '%s' %s '%s' POSTPONED, SET TO 1 FOR NOW.", X ex1,operator,ex2,ret); X return 1; X } X else X { X if (debugExpr) X { X printf("\n%s not in SortFields =",name); X for (sf in sortFields) printf("\n%s",sf); X } X flag=1; X } X } X X if (flag) X { X showSelector();printf("The operator '%s' may not be used with the field <%s>",operator,substr(ex1,4)); X printf("\n which may hold multiple entries. Use the 'contains' operator instead !\n"); X exprError=1; exit -9; X } X } X X if (operator == "==") X ret = (strequal(ex1,ex2)); X X if (operator == "!=") X ret = (!(strequal(ex1,ex2))); X X if (operator == ">=") X ret = (ex1 >= ex2); X if (operator == "<=") X ret = (ex1 <= ex2); X if (operator == ">") X ret = (ex1 > ex2); X if (operator == "<") X ret = (ex1 < ex2); X if (operator == "&&") X ret = (ex1 && ex2); X if (operator == "||") X ret = (ex1 || ex2); X X if (debugExpr) X printf("\n\n*** RESULT: '%s' %s '%s' -> %d.", X ex1,operator,ex2,ret); X return ret; X} X X################################################################## X# bracesOk: check whether the braces are alright within an expression X################################################################## X Xfunction bracesOk(str,ob,cb,dummy) X{ X ob = split(str,dummy,"("); X cb = split(str,dummy,")"); X if (ob != cb) X { X if (debugExpr) X showSelector();printf("There are %d opening and %d closing round brackets in <%s>.", X ob,cb,str); X return 0; X } X else X return 1; X} X X################################################################## X# getOperand1 : gets the first operand from a compound expression X# this involves isolating the field identifier and getting the X# current value for it. X################################################################## X Xfunction getOperand1(str,xstr,eop,name) X{ X # forget about first bracket X xstr = substr(str,2); X if (index(xstr,"(")) X { X if (debugExpr) X printf("\nOperand1 of expression <%s> is the expression <%s>.", X str,getExpression(xstr)); X return getExpression(xstr); X } X # operand is simple X eop = index(xstr," "); X if (eop == 0) X { X showSelector();printf("Could not identify the end of operand 1 in <%s>.\n",str); X exprError=1; exit -10; X } X name=substr(xstr,1,eop-1); X X # if a field has the multi attribute, a special value is returned IFF X # the call is made during the buildup phase and the field is a sort key ! X # in the second pass the current name is used instead. X if ((fieldMulti[name] == "M") && ((passOne) || (!(isSortKey(name))))) X { X if (debugExpr) X printf("\nMulti-Field <%s> selected. Returning special value _M_%s",name,name); X return sprintf("_M_%s",name); X } X else X { X if (debugExpr) X printf("\nOperand1 is field <%s> which currently holds <%s>.",name,videos[cec,name,selectionIndex]); X return videos[cec,name,selectionIndex]; X } X} X X################################################################## X# getExpression: returns an expression enclosed in brackets. X################################################################## X Xfunction getExpression(str,nstr,z,nB,i,c) X{ X z = index(str,"("); X if (z == 0) X { X if (debugExpr) X printf("\ngetExpression: <%s> does not contain any brackets.",str); X return str; X } X nstr = substr(str,z); X len = length(nstr); X nB = 1; X for (i = 2 ; ( i < len ) && ( nB > 0 ) ; i++) X { X c = substr(nstr,i,1); X if (c == "(") nB++; X if (c == ")") nB--; X } X if (nB == 0) X { X if (debugExpr) X printf("\ngetExpression: got <%s> from <%s>.",substr(nstr,1,i-1),str); X return substr(nstr,1,i-1); X } X else X { X showSelector();printf("Could not get expression with balanced brackets from <%s>.",nxstr); X exprError=1; exit -11; X } X} X X################################################################## X# getOperator: returns the name of the operator within the X# current expression X################################################################## X Xfunction getOperator(zstr,str,z1,z2) X{ X str = skipExpr(zstr); X z1 = index(str," "); X if (z1 == 0) X { X showSelector();printf("Could not find prefixed space in <%s>;\ncould not identify operator.",str); X exprError=1; exit -12; X } X X while ((substr(str,z1,1) == " ") && (z1 < length(str))) z1++; X X z2 = index(substr(str,z1)," ")+z1; X X if (z2 == 0) X { X showSelector();printf("Could not find postfixed space in <%s>;\ncould not identify operator.",str); X exprError=1; exit -13; X } X X if (debugExpr) X printf("\ngetOperator: got <%s> from <%s> (z1 = %d, z2 = %d)",substr(str,z1,z2-z1-1),str,z1,z2); X return substr(str,z1,z2-z1-1); X} X X################################################################## X# skipExpr - skip any expression in the given string, i.e. X# skipExpr( ((ACT == Mich*) && (TIT == Das*)) ) returns " && (TIT == Das*))" X################################################################## X Xfunction skipExpr(str,nB,len,c,i) X{ X if (substr(str,2,1) == "(") X { X if (debugExpr) X printf("\nSkipping first operand in expression <%s>",str); X nB=1; X len=length(str); X for (i = 3 ; (i <= len) && (nB != 0) ; i++) X { X c = substr(str,i,1); X if (c == "(") nB++; X if (c == ")") nB-- X } X if (nB == 0) X { X if (debugExpr) X printf("\nOperand skipped, returning <%s>",substr(str,i)); X return (substr(str,i)); X } X else X { X showSelector(); X printf("Could not skip first operand in expression <%s>,\nbraces do not match.",substr(str,2)); X exprError=1; X exit -20; X } X } X else X { X if (debugExpr) X printf("\nskipExpr<%s> - no complex operand found, nothing done.",str); X return str; X } X} X################################################################## X# getOperand2: returns the second operand from an expression X################################################################## X Xfunction getOperand2(zstr,str,z1,z2,val,z,x) X{ X str = skipExpr(zstr); X z1 = index(str," "); X if (z1 == 0) X { X showSelector(); X printf("Could not find prefixed space before operator in <%s>;",str); X printf("\ncould not identify second operand."); X exprError=1; exit -14; X } X X while (substr(str,z1,1) == " ") z1++; X z2 = index(substr(str,z1)," ") + z1; X X if (z2 == 0) X { X showSelector();printf("Could not find postfixed space after operator in <%s>;",str); X printf("\ncould not identify second operand."); X exprError=1; exit -15; X } X X while (substr(str,z2,1) == " ") z2++; X X val = substr(str,z2); X if (debugExpr) X printf("\ngetOperand2: found start of operand = <%s>",val); X X if (index(val,"(")) X { X if (debugExpr) X printf("\nOperand2 of expression <%s> is the expression <%s>.", X str,getExpression(val)); X return getExpression(val); X } X X if (index(val,"\042") == 1) X { X z = index(substr(val,2),"\042"); X if (z == 0) X { X showSelector();printf("Could not find closing double quote for value <%s>.\n",val); X exprError=1; exit -16; X } X if (debugExpr) X printf("\ngetOperand2: returning <%s>.",substr(val,2,z-2)); X return substr(val,2,z-2); X } X X # search end of value (i.e. space or bracket) X z1 = index(val," "); X z2 = index(val,")"); X if ((z1 == 0) && (z2 == 0)) X { X if (debugExpr) X printf("\ngetOperand2: returning whole val = <%s>.",val); X return val; X } X X if (z1 == 0) X x = z2; X else X { X if (z2 == 0) X x = z1; X else X { X if (z1 < z2) X x = z1; X else X x = z2; X } X } X X if (debugExpr) X printf("\ngetOperand2: returning <%s>.",substr(val,1,x-1)); X return substr(val,1,x-1); X} X X################################################################## X# fieldContains: Check if the given field contains an entry X# with the given value. X################################################################## X Xfunction fieldContains(name,value,i) X{ X for (i = 1 ; i <= videos[cec,name,0] ; i++) X { X containerValue=videos[cec,name,i]; X if (debugExpr) X printf("\nfieldContains: Comparing field[%d]=<%s> with value=<%s>.", X i,containerValue,value); X if (strequal(containerValue,value)) X return 1; X } X if (debugExpr) X printf("\nfieldContains: Sorry, no match in the %d entries stored for field <%s>.", X videos[cec,name,0],name); X return 0; X} X X################################################################## X# strequal - check two strings for equality taking the '*' effect X# into acount X################################################################## X Xfunction strequal(str1,str2,l2,sci) X{ X # string comparison is based on sorting criteria, X # i.e. (ACT == H*) finds Anthony$Hopkins, not Harold$Ramis ! X if (compareLastNames) X { X sci = index(str1,"$"); X if (sci > 0) X str1 = substr(str1,sci+1); X } X l2 = length(str2); X # check for joker X if (substr(str2,l2,1) == "*") X { X if (length(str1) > (l2-1)) X return (substr(str1,1,l2-1) == substr(str2,1,l2-1)); X else X return 0; X } X else X return str1 == str2; X} X X################################################################## X# showSelector - display the current selector string X# as a context to the following error message. X################################################################## X Xfunction showSelector() X{ X printf("\n\nAn error occured while parsing the selector expression"); X printf("\nyou gave, i.e. <%s>\n",select); X} X X################################################################## X# isSortKey - returns 1 if the given string is a sort key X################################################################## X Xfunction isSortKey(name,i) X{ X smatch=0; X for (i = 1 ; (i <= nSortFields) ; i++) X if (name == extractSortFieldName(sortFields[i])) X return 1; X return 0; X} END_OF_FILE if test 31418 -ne `wc -c <'prg/lib/prg.awk'`; then echo shar: \"'prg/lib/prg.awk'\" unpacked with wrong size! fi # end of 'prg/lib/prg.awk' fi if test -f 'prg/lib/prg.sed.UU' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'prg/lib/prg.sed.UU'\" else echo shar: Extracting \"'prg/lib/prg.sed.UU'\" \(476 characters\) sed "s/^X//" >'prg/lib/prg.sed.UU' <<'END_OF_FILE' Xbegin 664 prg/lib/prg.sed XM<R\@*2\I+V<*<R]<7&AA<V@O(R]G"G,OY"]<7#,P,"]G"G,O]B]<7#,R,2]G XM"G,O_"]<7#,R,R]G"G,OQ"]<7#,Q,2]G"G,OUB]<7#,R,B]G"G,OW"]<7#,R XM-"]G"G,OWR]<7#,R-2]G"G,O7%Q<(F$O7%PS,# O9PIS+UQ<7")O+UQ<,S(Q XM+V<*<R]<7%PB=2]<7#,R,R]G"G,O7%Q<(D$O7%PS,3$O9PIS+UQ<7")/+UQ< XM,S(R+V<*<R]<7%PB52]<7#,R-"]G"G,O7%Q<<W-[?2]<7#,R-2]G"G,O7")A XM+UQ<,S P+V<*<R]<(F\O7%PS,C$O9PIS+UPB=2]<7#,R,R]G"G,O7")!+UQ< XM,S$Q+V<*<R]<(D\O7%PS,C(O9PIS+UPB52]<7#,R-"]G"G,O7'-S>WTO7%PS X%,C4O9PH* X Xend END_OF_FILE if test 476 -ne `wc -c <'prg/lib/prg.sed.UU'`; then echo shar: \"'prg/lib/prg.sed.UU'\" unpacked with wrong size! else echo shar: Uudecoding \"'prg/lib/prg.sed'\" \(320 characters\) cat prg/lib/prg.sed.UU | uudecode if test 320 -ne `wc -c <'prg/lib/prg.sed'`; then echo shar: \"'prg/lib/prg.sed'\" uudecoded with wrong size! else rm prg/lib/prg.sed.UU fi fi # end of 'prg/lib/prg.sed.UU' fi echo shar: End of archive 5 \(of 6\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 exit 0 # Just in case...