grap-1.43/examples/400mpairs.d000640 004133 000000 00000000340 06537272750 016310 0ustar00faberwheel000000 000000 1896 54.2 1900 49.4 1904 49.2 1908 50 1912 48.2 1920 49.6 1924 47.6 1928 47.8 1932 46.2 1936 46.5 1948 46.2 1952 45.9 1956 46.7 1960 44.9 1964 45.1 1968 43.8 1972 44.66 1976 44.26 1980 44.60 1984 44.27 1988 43.87 1992 43.50 grap-1.43/examples/400mtimes.d000640 004133 000000 00000000162 06537272750 016315 0ustar00faberwheel000000 000000 54.2 49.4 49.2 50 48.2 49.6 47.6 47.8 46.2 46.5 46.2 45.9 46.7 44.9 45.1 43.8 44.66 44.26 44.60 44.27 43.87 43.50 grap-1.43/examples/400wpairs.d000640 004133 000000 00000000122 06537272750 016320 0ustar00faberwheel000000 000000 1964 52 1968 52 1972 51.08 1976 49.29 1980 48.88 1984 48.83 1988 48.95 1992 48.83 grap-1.43/examples/Makefile.in000640 004133 000000 00000000554 06721357406 016475 0ustar00faberwheel000000 000000 # This file is (c) 1998 Ted Faber (faber@lunabase.org) see COPYRIGHT # for the full copyright and limitations of liabilities. MACROS=-ms example.ps: example.ms grap example.ms | groff -pe $(MACROS) > example.ps local.example.ps: example.ms ../grap -d ../grap.defines example.ms | groff -pe $(MACROS) > local.example.ps clean: rm -f *.ps *.pdf *.ps.gz *core grap-1.43/examples/army.d000640 004133 000000 00000000441 06537272750 015543 0ustar00faberwheel000000 000000 40 17 0.9 249 1 42 190 12 2867 1 43 521 36 6358 55 44 692 48 7144 71 45 773 63 7284 91 46 241 17 1606 17 50 63 4 512 7 55 106 5 977 8 60 87 4 762 8 65 98 3 846 9 70 138 5 1141 11 75 85 5 641 38 80 78 7 613 61 85 84 11 599 68 90 80 12 567 73 91 77 12 564 71 92 74 12 496 65 93 66 10 443 57 grap-1.43/examples/boyhts.d000640 004133 000000 00000000452 06537272750 016105 0ustar00faberwheel000000 000000 2 32.2 33.8 36.6 3 35.0 37.4 40.2 4 37.7 40.6 43.4 5 40.2 43.4 46.1 6 42.5 45.7 48.6 7 44.5 47.9 51.0 8 46.5 50.0 53.4 9 48.4 52.0 55.7 10 50.3 54.0 58.2 11 52.1 56.4 60.8 12 54.1 58.8 63.8 13 56.0 61.5 66.5 14 58.5 64.1 69.2 15 61.0 66.4 71.5 16 63.4 68.2 72.9 17 64.8 69.4 73.6 18 65.2 69.5 73.8 grap-1.43/examples/example.ms000640 004133 000000 00000165312 11073777630 016431 0ustar00faberwheel000000 000000 .\" This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT .\" for the full copyright and limitations of liabilities. .EQ delim $$ .EN .PP This is a collection of example graphs that are mostly taken from Bentley and Kernighan's paper on .I grap that is referenced from the manual page. Please check that for an explanation of the graphs' meaning. I use them primarily as a regression test suite. .PP Each graph is accompanied by a brief description and the .I grap code that produced it. .KS .PP A simple copy. The data is the winning time for the mens' 400m run taken from the Pittsburgh Press's .I 1994 World Almanac and Book of Facts. .R .EQ delim off .EN .DS .ft CW \&.G1 \© "400mtimes.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 copy "400mtimes.d" .G2 .KE .KS .PP A simple copy with both $x$ and $y$ coordinates. The data is from the same source, but includes the year. .EQ delim off .EN .DS .ft CW \&.G1 \© "400mpairs.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 copy "400mpairs.d" .G2 Simple connection of points. Same data. .EQ delim off .EN .DS .ft CW \&.G1 \&draw solid \© "400mpairs.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 draw solid copy "400mpairs.d" .G2 .KE .KS .PP Spruced up a bit. We add axis labels and remove some frame boundaries. Note that my version of .I grap positions left and right axis labels parallel to the axis. That feature can be disabled by specifying .CW unaligned as a justification for the label. The same data is used. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis ht 2 wid 3 left solid bot solid \&label left "Time (in seconds)" left .25 \&label bot "Olympic 400 Meter Run: Winning Times" \&draw solid \© "400mpairs.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis ht 2 wid 3 left solid bot solid label left "Time (in seconds)" left .25 label bot "Olympic 400 Meter Run: Winning Times" draw solid copy "400mpairs.d" .G2 .KE .KS .PP User specified axes, and a font change in the graph. You must restore the font after the terminating .CW .G2 . Commands to .I groff or .I pic are issued at the same place relative to other .I grap commands in the file (as of version 1.50). The frame is drawn before the first plotted element (invisible lines count) or when the frame statement is executed. .EQ delim off .EN .DS .ft CW \&.G1 \&.ft H \&frame invis ht 2 wid 3 left solid bot solid \&label left "Time (in seconds)" left .25 \&label bot "Olympic 400 Meter Run: Winning Times" \&coord x 1894, 1994 y 42, 56 \&draw solid \© "400mpairs.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 .ft H frame invis ht 2 wid 3 left solid bot solid label left "Time (in seconds)" left .25 label bot "Olympic 400 Meter Run: Winning Times" coord x 1894, 1994 y 42, 56 draw solid copy "400mpairs.d" .G2 .KE .KS .PP User specified tick placement, and a return to the Roman font. Same data. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis ht 2 wid 3 left solid bot solid \&label left "Time (in seconds)" left .25 \&label bot "Olympic 400 Meter Run: Winning Times" \&coord x 1894, 1994 y 42, 56 \&ticks left out at 44 "44", 46, 48 "48", 50, 52 "52", 54 \&ticks bot in from 1900 to 1980 by 20 \&draw solid \© "400mpairs.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis ht 2 wid 3 left solid bot solid label left "Time (in seconds)" left .25 label bot "Olympic 400 Meter Run: Winning Times" coord x 1894, 1994 y 42, 56 ticks left out at 44 "44", 46, 48 "48", 50, 52 "52", 54 ticks bot in from 1900 to 1980 by 20 draw solid copy "400mpairs.d" .G2 .KE .KS .PP This graph adds the womens' times (from the same source) and includes different plotting styles and labels. My version of this graph also uses the .CW until keyword to include the data rather than external files. .CW until appears before and after the macro definition. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis ht 2 wid 3 left solid bot solid \&label left "Time (in seconds)" \&label bot "Olympic 400 Meter Run: Winning Times" \&coord x 1894, 1994 y 42, 56 \&ticks left out at 44 , 46 "", 48, 50 "", 52, 54 "" \&ticks bot in from 1900 to 1980 by 20 \&draw solid \© until "END" thru {next at $1, $2;} \&1896 54.2 \&1900 49.4 \&[...] \&1992 43.50 \&END \&new dotted \© until "END" \&1964 52. \&1968 52. \&[...] \&1992 48.83 \&END \&"Women" size -3 at 1958,52 \&"Men" size -3 at 1910,47 \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis ht 2 wid 3 left solid bot solid label left "Time (in seconds)" label bot "Olympic 400 Meter Run: Winning Times" coord x 1894, 1994 y 42, 56 ticks left out at 44 , 46 "", 48, 50 "", 52, 54 "" ticks bot in from 1900 to 1980 by 20 draw solid copy until "END" thru {next at $1, $2;} 1896 54.2 1900 49.4 1904 49.2 1908 50 1912 48.2 1920 49.6 1924 47.6 1928 47.8 1932 46.2 1936 46.5 1948 46.2 1952 45.9 1956 46.7 1960 44.9 1964 45.1 1968 43.8 1972 44.66 1976 44.26 1980 44.60 1984 44.27 1988 43.87 1992 43.50 END new dotted copy until "END" 1964 52. 1968 52. 1972 51.08 1976 49.29 1980 48.88 1984 48.83 1988 48.95 1992 48.83 END "Women" size -3 at 1958,52 "Men" size -3 at 1910,47 .G2 .KE .KS .PP Another simple copy. Bentley and Kernighan use phone installations, I use numbers of hosts on the Internet. The data is from .CW ftp://nic.merit.edu/nsfnet/statistics/history.hosts , maintained by: .DS Merit Network 4251 Plymouth Road Suite C Ann Arbor, MI 48105-2785 734-764-9430 .DE .EQ delim off .EN .DS .ft CW \&.G1 \© "internet.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 copy "internet.d" .G2 .KE .KS .PP The same data plotted on a logarithmic $y$ scale, and rescaled to megahosts, which is less humorous than megaphones. The placement of the bottom ticks shows the .CW from .. to .. by .R construct. The filename is given after the macro for variety (and to test that feature). .EQ delim off .EN .DS .ft CW \&.G1 \&coord x 80,100 y 1e-4, 30 log y \&ticks bot at 80 "1980", 100 "2000" \&ticks bot from 85 to 95 by 5 "' %g" \&ticks left \&label left "Millions of Hosts" left .25 \&label bot "Year" \&draw solid \© thru { next at $1, $2/1e6;} "internet.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 coord x 80,100 y 1e-4, 30 log y ticks bot at 80 "1980", 100 "2000" ticks bot from 85 to 95 by 5 "' %g" ticks left label left "Millions of Hosts" left .25 label bot "Year" draw solid copy thru { next at $1, $2/1e6;} "internet.d" .G2 .KE .KS .PP A demo of .I grap 's annotation abilities, mostly. The data is all in the graph specification. .EQ delim off .EN .DS .ft CW \&.G1 \&frame ht 2 wid 2 \&coord x 0,100 y 0,100 \&grid bot dotted from 20 to 80 by 20 \&grid left dotted from 20 to 80 by 20 \& \&"Text above" above at 50,50 \&"Text rjust " rjust at 50,50 \&bullet at 80,90 \&vtick at 80,80 \&box at 80,70 \× at 80,60 \& \&circle at 50,50 \&circle at 50,80 radius .25 \&line dashed from 10,90 to 30,90 \&arrow from 10,70 to 30,90 \& \&draw A solid \&draw B dashed delta \&next A at 10,10 \&next B at 10,20 \&next A at 50,20 \&next A at 90,10 \&next B at 50,30 \&next B at 90,30 \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame ht 2 wid 2 coord x 0,100 y 0,100 grid bot dotted from 20 to 80 by 20 grid left dotted from 20 to 80 by 20 "Text above" above at 50,50 "Text rjust " rjust at 50,50 bullet at 80,90 vtick at 80,80 box at 80,70 times at 80,60 circle at 50,50 circle at 50,80 radius .25 line dashed from 10,90 to 30,90 arrow from 10,70 to 30,90 draw A solid draw B dashed delta next A at 10,10 next B at 10,20 next A at 50,20 next A at 90,10 next B at 50,30 next B at 90,30 .G2 .KE .KS .PP A simple macro demo. Again, no data. .EQ delim off .EN .DS .ft CW \&.G1 \&frame ht 1.5 wid 1.5 \&define square {($1) * ($1)} \&define root {($1)^.5 } \&define P { \& times at i, square(i); i = i +1; \& circle at j, root(j); j= j+5; \&} \&i = 1; j = 5 \&P; P; P; P; P \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame ht 1.5 wid 1.5 define square {($1) * ($1)} define root {($1)^.5 } define P { times at i, square(i); i = i +1; circle at j, root(j); j= j+5; } i = 1; j = 5 P; P; P; P; P .G2 .KE .KS .PP The number of Representatives to the U.S. Congress versus population of the states. My data is more recent than that of Bentley/Kernighan, so the graph is different from theirs. Data is from the U.S. Census Bureau at .CW http://www.census.gov/ , specificly .CW http://www.census.gov/population/www/censusdata/apportionment.html . .EQ delim off .EN .DS .ft CW \&.G1 \&label left "Representatives to Congress" \&label bot "Population (Millions)" \&coord x .3, 35 y .8, 60 log log \&define PlotState { circle at $3/1e6, $2; } \© "states.d" thru PlotState \&.G2 .ft .DE .EQ delim $$ .EN .G1 label left "Representatives to Congress" label bot "Population (Millions)" coord x .3, 35 y .8, 60 log log define PlotState { circle at $3/1e6, $2; } copy "states.d" thru PlotState .G2 .KE .KS .PP A 2-axis plot. We redefine square because the macro example graph changed it. I advise against changing the predefined macro definitions because macros persist across graphs. The same data is plotted. .EQ delim off .EN .DS .ft CW \&.G1 \&define square {"\\s-2\\(sq\\s0"} \&frame ht 3 wid 3.5 \&label left "Population in Millions (Plotted as \\(bu)" \&label bot "Rank in Population" \&label right "Representatives (Plotted as \\(sq)" \&coord pop x 0,51 y .2,35 log y \&coord rep x 0,51 y .3,100 log y \&ticks left out at pop .3,1,3,10,30 \&ticks bot out at pop 1,50 \&ticks right out at rep 1,3,10,30,100 \&thisrank = 50 \© "states.d" thru { \& bullet at pop thisrank,$3/1e6 \& square at rep thisrank,$2 \& thisrank = thisrank -1 \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 define square {"\s-2\(sq\s0"} frame ht 3 wid 3.5 label left "Population in Millions (Plotted as \(bu)" label bot "Rank in Population" label right "Representatives (Plotted as \(sq)" coord pop x 0,51 y .2,35 log y coord rep x 0,51 y .3,100 log y ticks left out at pop .3,1,3,10,30 ticks bot out at pop 1,50 ticks right out at rep 1,3,10,30,100 thisrank = 50 copy "states.d" thru { bullet at pop thisrank,$3/1e6 square at rep thisrank,$2 thisrank = thisrank -1 } .G2 .KE .KS .PP A sine wave plotted by a .CW for loop with \(*p calculated with the internal .CW atan2() function. No data. .EQ delim off .EN .DS .ft CW \&.G1 \&frame ht 1 wid 3 \&draw solid \&pi = atan2(0,-1) \&for i from 0 to 2* pi by .1 do { next at i, sin(i); } \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame ht 1 wid 3 draw solid pi = atan2(0,-1) for i from 0 to 2* pi by .1 do { next at i, sin(i); } .G2 .KE .KS .PP Bentley and Kernighan do this graph with Kentucky Derby winning times. I don't have them, so I used the 400m times again. My program is slightly different because the 400m run times have gaps. .EQ delim off .EN .DS .ft CW \&.G1 \&label left "Winning Time" left .3 \&label bot "Olympics Men's 400 m" \&bestsofar = 1000 \&anchor = 0 \© "400mpairs.d" thru { \& bullet at $1,$2 \& if ( anchor != 0 ) then { \& line from anchor, bestsofar to $1,bestsofar \& } \& bestsofar = min(bestsofar,$2) \& if ( bestsofar == $2 ) then { \& anchor = $1 \& } \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 label left "Winning Time" left .3 label bot "Olympics Men's 400 m" bestsofar = 1000 anchor = 0 copy "400mpairs.d" thru { bullet at $1,$2 if ( anchor != 0 ) then { line from anchor, bestsofar to $1,bestsofar } bestsofar = min(bestsofar,$2) if ( bestsofar == $2 ) then { anchor = $1 } } .G2 .KE .KS .PP Bentley and Kernighan discuss the regression and modeling that these graphs reflect. The data is the U.S. population from the U.S. Census bureau. This shows off the ability to place two plots relative to each other using the .CW graph statement. .EQ delim off .EN .DS .ft CW \&.G1 \&graph Linear \&coord x 1785, 1955 y 0, 160 \&label left "Population in Millions" left .3 \&label right "Linear Scale" unaligned "Linear Fit" right .4 \&ticks bot off \© "usapop.d" \&define fit { 35 + 1.4 * ($1-1870) } \&line from 1850, fit(1850) to 1950,fit(1950) \&graph Exponential with .Frame.n at Linear.Frame.s - (0, .05) \&coord x 1785, 1955 y 3, 160 log y \&label left "Population in Millions" left .3 \&label right "Logarithmic Scale" unaligned "Exponential Fit" right .4 \© "usapop.d" \&define fit { exp(.75 + .012 * ($1-1800)) } \&line from 1790, fit(1790) to 1920,fit(1920) \&.G2 .ft .DE .EQ delim $$ .EN .G1 graph Linear coord x 1785, 1955 y 0, 160 label left "Population in Millions" left .3 label right "Linear Scale" unaligned "Linear Fit" right .4 ticks bot off copy "usapop.d" define fit { 35 + 1.4 * ($1-1870) } line from 1850, fit(1850) to 1950,fit(1950) graph Exponential with .Frame.n at Linear.Frame.s - (0, .05) coord x 1785, 1955 y 3, 160 log y label left "Population in Millions" left .3 label right "Logarithmic Scale" unaligned "Exponential Fit" right .4 copy "usapop.d" define fit { exp(.75 + .012 * ($1-1800)) } line from 1790, fit(1790) to 1920,fit(1920) .G2 .KE .KS .PP Another re-expression of the U.S. population data. Uses plenty of .I grap arithmetic and an .I eqn axis label (which is .CW unaligned ). .EQ delim off .EN .DS .ft CW \&.G1 \&label left "Population in Millions" left .3 \&label right "$x$ re-expressed as" unaligned "" "$space 0 left \& ( { date -1600 } over 100 right ) sup 7$" right .4 \&define newx { exp(7*(log(($1-1600)/100))) } \&ticks bot out at newx(1800) "1800", newx(1850) "1850", \\ \& newx(1900) "1900" \© "usapop.d" thru { \& if $1 <= 1900 then { bullet at newx($1),$2 } \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 label left "Population in Millions" left .3 label right "$x$ re-expressed as" unaligned "" "$space 0 left ( { date -1600 } over 100 right ) sup 7$" right .4 define newx { exp(7*(log(($1-1600)/100))) } ticks bot out at newx(1800) "1800", newx(1850) "1850", \ newx(1900) "1900" copy "usapop.d" thru { if $1 <= 1900 then { bullet at newx($1),$2 } } .G2 .KE .KS .PP A simple copy of a multiple field data file. The data is the 5th, 50th, and 95th percentiles for the heights of boys in America at different ages. The data is reported from Thomas J. Glover's remarkable .I Pocket .I Ref , which reports data from the National Center for Health Statistics. .I Pocket Ref .R is published by Sequoia Publishing, Littleton, CO. .EQ delim off .EN .DS .ft CW \&.G1 \© "boyhts.d" \&.G2 .ft .DE .EQ delim $$ .EN .G1 copy "boyhts.d" .G2 .KE .KS .PP The same data with a linear regression, and the 90% confidence intervals drawn as lines. Note the cascading assignment statements (patch courtesy of Bruce Lilly). (Bentley and Kernighan's data is in centimeters, mine is in inches, so a different conversion to feet is used.) .EQ delim off .EN .DS .ft CW \&.G1 \&label left "Heights in Feet" \&label bot "Heights of Boys in the US Ages 2-18" \&cmpft = 12 \&minx = 1e12; maxx = -1e12 \&n = sigx = sigx2 = sigy = sigxy = 0; \© "boyhts.d" thru { \& line from $1, $2/cmpft to $1, $4/cmpft \& ty = $3 / cmpft \& bullet at $1, ty \& n = n+1 \& sigx = sigx + $1; sigx2 = sigx2 + $1 * $1 \& sigy = sigy + ty; sigxy = sigxy + $1*ty \& minx = min(minx,$1); maxx = max(maxx,$1); \&} \&slope = ( n*sigxy - sigx* sigy) / (n*sigx2 - sigx * sigx) \&inter = ( sigy - slope * sigx) / n \&line from minx, slope * minx+inter to maxx, slope * maxx + inter \&.G2 .ft .DE .EQ delim $$ .EN .G1 label left "Heights in Feet" label bot "Heights of Boys in the US Ages 2-18" cmpft = 12 minx = 1e12; maxx = -1e12 n = sigx = sigx2 = sigy = sigxy = 0; copy "boyhts.d" thru { line from $1, $2/cmpft to $1, $4/cmpft ty = $3 / cmpft bullet at $1, ty n = n+1 sigx = sigx + $1; sigx2 = sigx2 + $1 * $1 sigy = sigy + ty; sigxy = sigxy + $1*ty minx = min(minx,$1); maxx = max(maxx,$1); } slope = ( n*sigxy - sigx* sigy) / (n*sigx2 - sigx * sigx) inter = ( sigy - slope * sigx) / n line from minx, slope * minx+inter to maxx, slope * maxx + inter .G2 .KE .KS .PP This is a 4 linestyle plot with a copy statement that adds labels. The scales are user-defined, and the $y$ axis is logarithmic. The data is the number of male and female officers and enlisted personnel in the U.S. Armed forces from 1940-1993 from the Pittsburgh Press .I World Almanac and Book of Facts. .R This graph has more data than the equivalent from Bentley and Kernighan. .EQ delim off .EN .DS .ft CW \&.G1 \&coord x 38, 95 y .8, 10000 log y \&label bot "U.S. Military Personnel" \&label left "Thousands" left .25 \&draw of solid \&draw ef dashed \&draw om dotted \&draw em solid \© "army.d" thru { \& next of at $1, $3 \& next ef at $1, $5 \& next om at $1, $2 \& next em at $1, $4 \&} \© until "XXX" thru { "$1 $2" size -3 at 60, $3; } \&Enlisted Men 1200 \&Male Officers 140 \&Enlisted Women 12 \&Female Officers 2.5 \&XXX \&.G2 .ft .DE .EQ delim $$ .EN .G1 coord x 38, 95 y .8, 10000 log y label bot "U.S. Military Personnel" label left "Thousands" left .25 draw of solid draw ef dashed draw om dotted draw em solid copy "army.d" thru { next of at $1, $3 next ef at $1, $5 next om at $1, $2 next em at $1, $4 } copy until "XXX" thru { "$1 $2" size -3 at 60, $3; } Enlisted Men 1200 Male Officers 140 Enlisted Women 12 Female Officers 2.5 XXX .G2 .KE .KS .PP Obfuscation of data via scatter plots. Three aligned graphs are produced that plot the numbers of enlisted men as functions of male officers, female officers, and enlisted women. The plotting symbol is the year in question. Same data as above. .EQ delim off .EN .DS .ft CW \&.G1 \&graph A \&frame ht 1.6667 wid 1.6667 \&label bot "Male_Officers" \&label left "Enlisted_Men" \&coord log log \&ticks off \© "army.d" thru { "\s-3$1\s+3" at $2,$4; } \&graph A with .Frame.w at A.Frame.e +(.1,0) \&frame ht 1.6667 wid 1.6667 \&label bot "Female_Officers" \&coord log log \&ticks off \© "army.d" thru { "\s-3$1\s+3" at $3,$4; } \&graph A with .Frame.w at A.Frame.e +(.1,0) \&frame ht 1.6667 wid 1.6667 \&label bot "Enlisted_Women" \&coord log log \&ticks off \© "army.d" thru { "\s-3$1\s+3" at $5,$4; } \&.G2 .ft .DE .EQ delim $$ .EN .G1 graph A frame ht 1.6667 wid 1.6667 label bot "Male_Officers" label left "Enlisted_Men" coord log log ticks off copy "army.d" thru { "\s-3$1\s+3" at $2,$4; } graph A with .Frame.w at A.Frame.e +(.1,0) frame ht 1.6667 wid 1.6667 label bot "Female_Officers" coord log log ticks off copy "army.d" thru { "\s-3$1\s+3" at $3,$4; } graph A with .Frame.w at A.Frame.e +(.1,0) frame ht 1.6667 wid 1.6667 label bot "Enlisted_Women" coord log log ticks off copy "army.d" thru { "\s-3$1\s+3" at $5,$4; } .G2 .KE .KS .PP One of my favorites. The solution of a differential equation and the slope field it passes through. It shows off nested .CW for loops (one using = as a synonym for from) and .I eqn labels. The data is in the graph description. .EQ delim off .EN .DS .ft CW \&.G1 \&frame ht 2.5 wid 2.5 \&coord x 0,1 y 0,1 \&label bot "Direction Field is $y prime = x sup 2 / y$" \&label left "$y = sqrt { ( 2 x sup 3 + 1 ) / 3 }$" \&ticks left in 0 left .1 at 0,1 \&ticks bot in 0 down .1 at 0,1 \&len = .04 \&for tx from .01 to .91 by .1 do { \& for ty from .01 to .91 by .1 do { \& deriv = tx*tx/ty \& scale = len / sqrt(1 + deriv*deriv) \& line from tx,ty to tx+scale, ty+scale*deriv \& } \&} \&draw solid \&for tx = 0 to 1 by .05 do { \& next at tx, sqrt((2*tx*tx*tx+1)/3) \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame ht 2.5 wid 2.5 coord x 0,1 y 0,1 label bot "Direction Field is $y prime = x sup 2 / y$" label left "$y = sqrt { ( 2 x sup 3 + 1 ) / 3 }$" ticks left in 0 left .1 at 0,1 ticks bot in 0 down .1 at 0,1 len = .04 for tx from .01 to .91 by .1 do { for ty from .01 to .91 by .1 do { deriv = tx*tx/ty scale = len / sqrt(1 + deriv*deriv) line from tx,ty to tx+scale, ty+scale*deriv } } draw solid for tx = 0 to 1 by .05 do { next at tx, sqrt((2*tx*tx*tx+1)/3) } .G2 .KE .KS .PP More population studies. State population rank vs. population, with the population on a log scale. A regression line is also plotted. I used the same line as Bentley and Kernighan, although my data is more recent. The top labels are generated by a series of macros, the frame size is enlarged, and the plotting symbol is the state abbreviation. This graph uses the same census data as above. .EQ delim off .EN .DS .ft CW \&.G1 \&frame wid 5 ht 4 \&label left "Rank in Population" \&label bot "Population (in Millions)" \&label top "$log sub 2$ Population" \&coord x .3, 35 y 0, 51 log x \&define L { (2.0^$1)/1e6 "$1" } \&ticks bot out at .5, 1, 2, 5, 10, 20 \&ticks left out from 10 to 50 by 10 \&ticks top out at L(19), L(20), L(21), L(22), L(23), L(24), L(25) \&thisy = 50 \© "states.d" thru { \& "$1" size -4 at $3/1e6, thisy \& thisy = thisy-1 \&} \&line dotted from 15.3,1 to .515, 50 \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame wid 5 ht 4 label left "Rank in Population" label bot "Population (in Millions)" label top "$log sub 2$ Population" coord x .3, 35 y 0, 51 log x define L { (2.0^$1)/1e6 "$1" } ticks bot out at .5, 1, 2, 5, 10, 20 ticks left out from 10 to 50 by 10 ticks top out at L(19), L(20), L(21), L(22), L(23), L(24), L(25) thisy = 50 copy "states.d" thru { "$1" size -4 at $3/1e6, thisy thisy = thisy-1 } line dotted from 15.3,1 to .515, 50 .G2 .KE .KS .PP A nearly useless plot of the populations of different states. Same data. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis ht .3 wid 5 bottom solid \&label bot "Populations (in Millions) of the 50 States" \&coord x .3, 35 y 0, 1 log x \&ticks bot out at .5, 1, 2, 5, 10, 20 \&ticks left off \© "states.d" thru { vtick at $3/1e6, .5; } \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis ht .3 wid 5 bottom solid label bot "Populations (in Millions) of the 50 States" coord x .3, 35 y 0, 1 log x ticks bot out at .5, 1, 2, 5, 10, 20 ticks left off copy "states.d" thru { vtick at $3/1e6, .5; } .G2 .KE .KS .PP A slight improvement, as the states are spread out and plotted with their symbols. The .CW rand() function is used to position them vertically, which shows off the function, but doesn't guarantee a legible graph. Same data. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis ht 1 wid 5 bottom solid \&label bot "Populations (in Millions) of the 50 States" \&coord x .3, 35 y 0, 1000 log x \&ticks bot out at .5, 1, 2, 5, 10, 20 \&ticks left off \© "states.d" thru { "$1" size -4 at $3/1e6, 100+900*rand(); } \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis ht 1 wid 5 bottom solid label bot "Populations (in Millions) of the 50 States" coord x .3, 35 y 0, 1000 log x ticks bot out at .5, 1, 2, 5, 10, 20 ticks left off copy "states.d" thru { "$1" size -4 at $3/1e6, 100+900*rand(); } .G2 .KE .KS .PP A histogram of the same data. The input file is a result of running the census data through the .I awk script that Bentley and Kernighan describe. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis bot solid \&label bot "Populations (in Millions) of the 50 States" \&label left "Number of States" left .1 \&ticks bot out from 0 to 35 by 5 \&coord x 0, 35 y 0, 13 \© "states2.d" thru { \& line from $1,0 to $1,$2 \& line from $1, $2 to $1+1, $2 \& line from $1+1,$2 to $1+1,0 \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis bot solid label bot "Populations (in Millions) of the 50 States" label left "Number of States" left .1 ticks bot out from 0 to 35 by 5 coord x 0, 35 y 0, 13 copy "states2.d" thru { line from $1,0 to $1,$2 line from $1, $2 to $1+1, $2 line from $1+1,$2 to $1+1,0 } .G2 .KE .KS .PP A \*Qlolliplot \*U histogram of the same data. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis bot solid \&label bot "Populations (in Millions) of the 50 States" \&label left "Number of States" left .1 \&ticks bot out from 0 to 35 by 5 \&coord x 0, 35 y 0, 13 \© "states2.d" thru { \& line dotted from $1+.5,0 to $1+.5,$2 \& "\(bu" size +3 at $1+.5, $2 \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis bot solid label bot "Populations (in Millions) of the 50 States" label left "Number of States" left .1 ticks bot out from 0 to 35 by 5 coord x 0, 35 y 0, 13 copy "states2.d" thru { line dotted from $1+.5,0 to $1+.5,$2 "\(bu" size +3 at $1+.5, $2 } .G2 .KE .KS .PP A histogram of state abbreviations. The data has been massaged by the .I awk program described by Bentley and Kernighan. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis wid 4 ht 2.5 bot solid \&label bot "Populations (in Millions) of the 50 States" \&ticks bot out from 0 to 35 by 5 \&ticks left off \&coord x 0, 35 y 0, 13 \© "states3.d" thru {"$1" size -4 at $2+.5, $3+.5; } \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis wid 4 ht 2.5 bot solid label bot "Populations (in Millions) of the 50 States" ticks bot out from 0 to 35 by 5 ticks left off coord x 0, 35 y 0, 13 copy "states3.d" thru {"$1" size -4 at $2+.5, $3+.5; } .G2 .KE .KS .PP A bar graph of profiler output. The output is from running .I grap on this file. .EQ delim off .EN .DS .ft CW \&.G1 \&ticks left off \&cury = 0 \&barht = .7 \© "prof2.d" thru { \& line from 0,cury to $1, cury \& line from $1, cury to $1, cury-barht \& line from 0, cury-barht to $1, cury-barht \& " $2" ljust at 0, cury-barht/2 \& cury = cury-1 \&} \&line from 0,0 to 0,cury+1-barht \&bars = -cury \&frame invis ht bars/3 wid 3 \&.G2 .ft .DE .EQ delim $$ .EN .G1 ticks left off cury = 0 barht = .7 copy "prof2.d" thru { line from 0,cury to $1, cury line from $1, cury to $1, cury-barht line from 0, cury-barht to $1, cury-barht " $2" ljust at 0, cury-barht/2 cury = cury-1 } line from 0,0 to 0,cury+1-barht bars = -cury frame invis ht bars/3 wid 3 .G2 .KE .KS .PP The creative graph of state heights and volcano heights from their grap paper. The data was included in the graph description, which (according to Bruce Lilly) is from John W. Tukey's classic 1977 text .I Exploratory Data Analysis, .R Chapter 10. Tukey cites \*QThe World Almanac, 1966, page 269. Their source: National Geographic Society.\*U The format of the graph is also similar to a graph on pg. 40 (exhibit 5, chapter 2). All those attributions are from Bruce Lilly. I don't have the relevant material to verify it, but have no reason to doubt the accuracy of the information. .EQ delim off .EN .DS .ft CW .ps 8 .vs 10 \&.G1 \&frame invis ht 4 wid 3 bot solid \&ticks off \&coord x .5, 3.5 y 0,25 \&define Ht { "- $1,000 -" size -3 at 2, $1 } \&Ht(5); Ht(10); Ht(15); Ht(20); \&"Highest Point" "in 50 States" at 1,23 \&"Heights of" "219 Volcanos" at 3,23 \&"Feet" at 2,21.5; arrow from 2,22.5 to 2,24 \&define box { \& xc = $1; xl = xc - boxwidth/2; xh = xc+boxwidth/2 \& y1 = $2; y2 = $3; y3 = $4; y4= $5; y5 = $6 \& bullet at xc,y1 \& " $7" size -3 ljust at xc, y1 \& line from (xc,y1) to (xc,y2) \& line from (xl,y2) to (xh,y2) \& line from (xl,y3) to (xh,y3) \& line from (xl,y4) to (xh,y4) \& line from (xl,y2) to (xl,y4) \& line from (xh,y2) to (xh,y4) \& line from (xc,y4) to (xc,y5) \& bullet at xc,y5 \& " $8" ljust size -3 at (xc,y5) \&} \&boxwidth = .3 \&box(1, .3, 2.0, 4.6, 11.2,20.3, Florida, Alaska) \&box(3,.2, 3.7, 6.5, 9.5, 19.9, Ilhanova, Guallatiri) \&.G2 .ft .DE .KE .KS .EQ delim $$ .EN .G1 frame invis ht 4 wid 3 bot solid ticks off coord x .5, 3.5 y 0,25 define Ht { "- $1,000 -" size -3 at 2, $1 } Ht(5); Ht(10); Ht(15); Ht(20); "Highest Point" "in 50 States" at 1,23 "Heights of" "219 Volcanos" at 3,23 "Feet" at 2,21.5; arrow from 2,22.5 to 2,24 define box { xc = $1; xl = xc - boxwidth/2; xh = xc+boxwidth/2 y1 = $2; y2 = $3; y3 = $4; y4= $5; y5 = $6 bullet at xc,y1 " $7" size -3 ljust at xc, y1 line from (xc,y1) to (xc,y2) line from (xl,y2) to (xh,y2) line from (xl,y3) to (xh,y3) line from (xl,y4) to (xh,y4) line from (xl,y2) to (xl,y4) line from (xh,y2) to (xh,y4) line from (xc,y4) to (xc,y5) bullet at xc,y5 " $8" ljust size -3 at (xc,y5) } boxwidth = .3 box(1, .3, 2.0, 4.6, 11.2,20.3, Florida, Alaska) box(3,.2, 3.7, 6.5, 9.5, 19.9, Ilhanova, Guallatiri) .G2 .KE .KS .PP A large but boring graph. No data, but it does show off passing size parameters to .I pic , and using non-brace macro delimiters. .EQ delim off .EN .DS .ft CW \&.ps 14 \&.vs 18 \&.G1 4 \&frame ht 2 wid 2 \&label left "Response Variable" left .2 \&label bot "Factor Variable" down .1 \&line from 0,0 to 1,1 \&line dotted from .5,0 to .5,1 \&define blob X "\\v'.1m'\\(bu\\v'-.1m'" X \&blob at 0,.5; blob at .5, .5; blob at 1,.5 \&.G2 \&.ps 10 \&.vs 12 .ft .DE .EQ delim $$ .EN .ps 14 .vs 18 .G1 4 frame ht 2 wid 2 label left "Response Variable" left .2 label bot "Factor Variable" down .1 line from 0,0 to 1,1 line dotted from .5,0 to .5,1 define blob X "\v'.1m'\(bu\v'-.1m'" X blob at 0,.5; blob at .5, .5; blob at 1,.5 .G2 .ps 10 .vs 12 .KE .KS .PP This displays all the macros defined in .CW grap.defines . No data. .EQ delim off .EN .DS .ft CW \&.G1 \&define box {"\\s-2\\f(ZD\\N'110'\\fP\\s0"} \&frame ht 2 wid 2 \&coord x 0,3 y 0,6 \&ticks off \&ticks left in left .1 from 1 to 5 \&ticks right in from 1 to 5 "" \&ticks bot in down .1 from 1 to 2 \&ticks top in from 1 to 2 "" \&bullet at 1,1 \&plus at 1,2 \&box at 1,3 \&star at 1,4 \&dot at 1,5 \× at 2,1 \&htick at 2,2 \&vtick at 2,3 \&square at 2,4 \&delta at 2,5 \&.G2 .ft .DE .EQ delim $$ .EN .G1 define box {"\s-2\f(ZD\N'110'\fP\s0"} frame ht 2 wid 2 coord x 0,3 y 0,6 ticks off ticks left in left .1 from 1 to 5 ticks right in from 1 to 5 "" ticks bot in down .1 from 1 to 2 ticks top in from 1 to 2 "" bullet at 1,1 plus at 1,2 box at 1,3 star at 1,4 dot at 1,5 times at 2,1 htick at 2,2 vtick at 2,3 square at 2,4 delta at 2,5 .G2 .KE .KS .PP We saw this graph earlier using line drawing commands. This version uses the .CW bar extension. Bars are centered, so the 0.5 unit fudge factor is used. If I were graphing this from scratch, I would rewrite the .I awk script to place the bars correctly. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis bot solid \&label bot "Populations (in Millions) of the 50 States" \&label left "Number of States" left .1 \&ticks bot out from 0 to 35 by 5 \&coord x 0, 35 y 0, 13 \© "states2.d" thru { \& bar up $1+0.5 ht $2 fill 0.125 \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis bot solid label bot "Populations (in Millions) of the 50 States" label left "Number of States" left .1 ticks bot out from 0 to 35 by 5 coord x 0, 35 y 0, 13 copy "states2.d" thru { bar up $1+0.5 ht $2 fill 0.125 } .G2 .KE .KS .PP The same graph with bars extending in the x direction. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis bot solid \&label left "Populations (in Millions) of the 50 States" \&label bot "Number of States" \&ticks left out from 0 to 35 by 5 \&coord x 0, 13 y -0, 35 \© "states2.d" thru { \& bar right $1+0.5 ht $2 fill 0.125 \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis bot solid label left "Populations (in Millions) of the 50 States" label bot "Number of States" ticks left out from 0 to 35 by 5 coord x 0, 13 y 0, 35 copy "states2.d" thru { bar right $1+0.5 ht $2 fill 0.125 } .G2 .KE .KS .PP Demonstration of negative bar heights. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis bot solid \© until "DONE" thru { \& bar up $1 ht $2 \&} \&1 -2 \&2 -1 \&3 0 \&4 1 \&5 2 \&DONE \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis bot solid copy until "DONE" thru { bar up $1 ht $2 } 1 -2 2 -1 3 0 4 1 5 2 DONE .G2 .KE .KS .PP A display of two timing measurements and the components thereof. The data is fabricated, I just wanted to show the format, including both formats of .CW bar statement. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis bot solid left solid \&ticks bottom off \&grid bottom invis at 1 "OS 1", 2 "OS2" \&coord y 0, 10 \© until "DONE" thru { \& bar up $1 ht $2 wid 0.5 base $3 fill $4 \&} \&1 3 0 0.25 \&1 1 3 0.5 \&1 4 4 0.9 \&2 1 0 0.25 \&2 4 1 0.5 \&2 2 5 0.9 \&DONE \© until "DONE" thru { \& bar 1.5,$1, 1.75, $1+0.2 fill $2 \& $3 size -2 ljust at 1.8,$1+0.1 \&} \&9 0.25 "Copying" \&8.5 0.5 "Initialization" \&8 0.9 "Checksum" \&DONE \&bar 1.45,9.35, 2.25, 7.85 dashed \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis bot solid left solid ticks bottom off grid bottom invis at 1 "OS 1", 2 "OS2" coord y 0, 10 copy until "DONE" thru { bar up $1 ht $2 wid 0.5 base $3 fill $4 } 1 3 0 0.25 1 1 3 0.5 1 4 4 0.9 2 1 0 0.25 2 4 1 0.5 2 2 5 0.9 DONE copy until "DONE" thru { bar 1.5,$1, 1.75, $1+0.2 fill $2 $3 size -2 ljust at 1.8,$1+0.1 } 9 0.25 "Copying" 8.5 0.5 "Initialization" 8 0.9 "Checksum" DONE bar 1.45,9.35, 2.25, 7.85 dashed .G2 .KE .KS .PP This shows the new filling and linestyle capabilities of the .CW circle and .CW bar commands .EQ delim off .EN .DS .ft CW \&.G1 \&bar (1,1), (0,0) fill 0.25 \&circle at 0.5,0.5 rad 0.5 dashed 0.05 fill 0.5 \&.G2 .ft .DE .G1 bar (1,1), (0,0) fill 0.25 circle at 0.5,0.5 rad 0.5 dashed 0.05 fill 0.5 .G2 .KE .KS This is a more complex example of nested macros from Anindo Banerjea's thesis. This originally caught errors in the use of multiple positioning commands for labels. I don't know what the data are, but a full explanation is in his Ph.D thesis. In-line data and the groff for the caption are elided. Two lines present in the real graph are missing from this one. .DS .ft CW .ps 8 .vs 10 \&.ds ** \\v'+.2m'\\fB*\\fP\\v'-.2m' \&.vs 10 \&.G1 \&define myplot % # (symbol) \&next linename at $1,$2 \&symb at $1,$2 \&% \&graph A \&frame invis ht 1.667 wid 2.0 left solid bot solid \&coord y 0,70 \&label bot "delay (ms)" "\\fIi)\\fP" down 0.3 \&label left "load" unaligned "index" up .9 \&label right "Xmin = 2: \\(bu" unaligned ljust size -3 "Xmin = 4:\\(sq" \\ \& "Xmin = 8:\\(ci" "Xmin = 16: \\*(**" left 1.4 up 0.5 \&draw a solid \&define symb % bullet % \&define linename { a } \© until "XXX" thru myplot \&50 42.000 \&... \&XXX \&draw b solid \&define symb % square % \&define linename { b } \© until "XX1" thru myplot \&50 22.000 \&... \&XX1 \&.G2 .ft .ps 10 .vs 12 .DE .ds ** \v'+.2m'\fB*\fP\v'-.2m' .vs 10 .G1 2i define myplot % # (symbol) next linename at $1,$2 symb at $1,$2 % graph A frame invis ht 1.667 wid 2.0 left solid bot solid coord y 0,70 label bot "delay (ms)" "\fIi)\fP" down 0.3 label left "load" unaligned "index" up .9 label right "Xmin = 2: \(bu" unaligned ljust size -3 "Xmin = 4:\(sq" \ "Xmin = 8:\(ci" "Xmin = 16: \*(**" left 1.4 up 0.5 draw a solid define symb % bullet % define linename { a } copy until "XXX" thru myplot 50 42.000 60 41.800 70 41.400 80 40.000 90 39.000 100 37.800 110 36.400 120 33.000 130 31.000 140 28.800 150 26.400 160 21.000 170 18.000 180 14.800 190 11.400 200 4.000 210 4.000 220 4.000 XXX draw b solid define symb % square % define linename { b } copy until "XX1" thru myplot 50 22.000 60 21.800 70 21.600 80 20.800 90 20.200 100 19.600 110 18.800 120 17.000 130 16.000 140 14.800 150 13.600 160 10.800 170 9.200 180 7.600 190 5.800 200 2.000 210 2.000 220 2.000 XX1 .G2 .LP \fB Figure 1.\fP Queueing Delay index vs. other load indices: Graph \fIi)\fP shows that the proposed load index is monotonically decreasing as a function of delay if all other factors are constant. Graph \fIii)\fP shows that it is linear in bandwidth and graph \fIiii)\fP shows that it is linear in the path length of the route provided the delay requirement per hop remains constant. .vs 12 .KE .KS .PP This graph is pretty brutal all around. Nested macros and constructed filenames produce a bar graph (some of the components separated by dots in the included filenames were originally pathname components). This source is also from Anindo Banerjea, and caught bugs related to .CW if and .CW for statements. Anindo wrote this to display a graph for his thesis, not to demonstrate perfect .CW grap programming form. His graphs are used with his permission, I've made minor tweaks to his code to make them more pretty under this version of .CW grap . .DS .ft CW .ps 8 .vs 10 \&.G1 \&define write_name % #(code,X,Y) \& if ($1 == 1) then { \& "\\s-2G\\s+2" above at $2,$3 \& } \& if ($1 == 2) then { \& "\\s-2H\\s+2" above at $2,$3 \& } \& if ($1 == 3) then { \& "\\s-2L\\s+2" above at $2,$3 \& } \& if ($1 == 4) then { \& "\\s-2I\\s+2" above at $2,$3 \& } \& if ($1 == 5) then { \& "\\s-2R1\\s+2" above at $2,$3 \& } \& if ($1 == 6) then { \& "\\s-2R2\\s+2" above at $2,$3 \& } \& if ($1 == 7) then { \& "\\s-2R3\\s+2" above at $2,$3 \& } \& if ($1 == 8) then { \& "\\s-2S\\s+2" above at $2,$3 \& } \&% \&define dashedbar % #(X,Y) \& line from $1,0 to $1,$2 dashed \& line from $1,$2 to $1+9,$2 dashed \& line from $1+9,$2 to $1+9,0 dashed \&% \&define abar % #(X,Y) \& line from $1,0 to $1,$2 \& line from $1,$2 to $1+9,$2 \& line from $1+9,$2 to $1+9,0 \&% \&define bar_succ % #(load,y,junk) \& abar(curx,$2) \& write_name(name,curx+5,$2) \& curx = curx + jump \& if (Maxy < $2) then { Maxy = $2 } \&% \&define bar_goodness % #(load,y,junk) \& abar(curx,$3-100) \& write_name(name,curx+5,$3-100) \& curx = curx + jump \& if (Maxy < ($3-100) ) then { Maxy = $3-100 } \&% \&define bar_avmax % #(load,average,max) \& abar(curx,$2) \& dashedbar(curx,$3) \& write_name(name,curx+5,$3) \& curx = curx+jump \& if (Maxy < $3) then { Maxy = $3 } \&% \&define bar_set % #(filename,jump,startX,name,function) \& jump = $2 \& curx = $3 \& name = $4 \& copy $1 thru bar_$5 \&% \&define setload % #(load, junk, junk \& ticks bot in 0.0 at ((2*count+1)*jump-gap/2)/2 "$1" \& count = count + 1 \&% \&define mkgraphTiming % #(Timing,Name,file,function,number,ylabel,dir,toplable) \& Maxy = 0.0 \& Nbars = 3 \& start = 1 \& gap = 15 \& jump = Nbars * 10 + gap \& bar_set("$7.Global.$1.$3.result",jump,start,1,$4) \& bar_set("$7.Hybrid.$1.$3.result",jump,start + 10,2,$4) \& bar_set("$7.Local.$1.$3.result",jump,start + 2*10,3,$4) \& line from 0,0 to jump*4-gap,0 \& count = 0 \& copy "$7.Local.$1.$3.result" through setload \& label top "\\fI$5)\\fP Timing = $2, $8" up .2 \& label left $6 unaligned up 1.8 right .2 \& label bot "load" \& frame invis ht 3 wid 3 left solid bot solid \&% \&graph A \& mkgraphTiming(Random1500,Random-1500 ms,succ,succ,i,"SR (%)",\\ \& result.SQ_MESH.Fail1.S3.R0,Square mesh) \&.G2 .ft .ps 10 .vs 12 .DE .G1 2.5i define write_name % #(code,X,Y) if ($1 == 1) then { "\s-2G\s+2" above at $2,$3 } if ($1 == 2) then { "\s-2H\s+2" above at $2,$3 } if ($1 == 3) then { "\s-2L\s+2" above at $2,$3 } if ($1 == 4) then { "\s-2I\s+2" above at $2,$3 } if ($1 == 5) then { "\s-2R1\s+2" above at $2,$3 } if ($1 == 6) then { "\s-2R2\s+2" above at $2,$3 } if ($1 == 7) then { "\s-2R3\s+2" above at $2,$3 } if ($1 == 8) then { "\s-2S\s+2" above at $2,$3 } % define dashedbar % #(X,Y) line from $1,0 to $1,$2 dashed line from $1,$2 to $1+9,$2 dashed line from $1+9,$2 to $1+9,0 dashed % define abar % #(X,Y) line from $1,0 to $1,$2 line from $1,$2 to $1+9,$2 line from $1+9,$2 to $1+9,0 % define bar_succ % #(load,y,junk) abar(curx,$2) write_name(name,curx+5,$2) curx = curx + jump if (Maxy < $2) then { Maxy = $2 } % define bar_goodness % #(load,y,junk) abar(curx,$3-100) write_name(name,curx+5,$3-100) curx = curx + jump if (Maxy < ($3-100) ) then { Maxy = $3-100 } % define bar_avmax % #(load,average,max) abar(curx,$2) dashedbar(curx,$3) write_name(name,curx+5,$3) curx = curx+jump if (Maxy < $3) then { Maxy = $3 } % define bar_set % #(filename,jump,startX,name,function) jump = $2 curx = $3 name = $4 copy $1 thru bar_$5 % define setload % #(load, junk, junk ticks bot in 0.0 at ((2*count+1)*jump-gap/2)/2 "$1" count = count + 1 % define mkgraphTiming % #(Timing,Name,file,function,number,ylabel,dir,toplable) Maxy = 0.0 Nbars = 3 start = 1 gap = 15 jump = Nbars * 10 + gap bar_set("$7.Global.$1.$3.result",jump,start,1,$4) bar_set("$7.Hybrid.$1.$3.result",jump,start + 10,2,$4) bar_set("$7.Local.$1.$3.result",jump,start + 2*10,3,$4) line from 0,0 to jump*4-gap,0 count = 0 copy "$7.Local.$1.$3.result" through setload label top "\fI$5)\fP Timing = $2, $8" up .2 label left $6 unaligned up 1.8 right .2 label bot "load" frame invis ht 3 wid 3 left solid bot solid % graph A mkgraphTiming(Random1500,Random-1500 ms,succ,succ,i,"SR (%)",result.SQ_MESH.Fail1.S3.R0,Square mesh) .G2 .KE .KS .PP This is a graph donated by Bruce Lilly, after it demonstrated a couple .CW grap bugs and incompatibilities with DWB .CW grap . But mostly I include it because it's a cool timing diagram, although I have no idea for what. I shrunk it for this example, so this version is a little more cramped than his. Remove the 4 that follows the .G1 to see the diagram in its full glory. .DS .ft CW .ps 8 .vs 10 \&.G1 4 \&.ps 14 \&frame ht 5 wid 6 top invis right invis left invis bot invis \&ticks off \&coord x -21, 21 y 0, 70 \&line dashed from (0,0) to (0,68) \&line dotted from (-11,0) to (-11,70) \&line dotted from (11,0) to (11,70) \&"clock" rjust at -21, 3.5 \&"data" rjust at -21, 35 \&"timing reference" below at 0, -1 \&"recovery window" at 0, 70 \&arrow from (-6,70) to (-10,70) \&arrow from (6,70) to (10,70) \&"``perfect'' data" at 0, 13.5 \&"jitter" at 0, 23.5 \&"timing offset" at 0, 38.3 \&"timing offset + jitter" at 0, 58.3 \&.\\" clock \&draw solid \&[inline data elided] \&.\\" perfect data \&new solid \&[inline data elided] \&new solid \&[inline data elided] \&.\\" data with jitter +-3 ns \&new solid \&[inline data elided] \&new solid \&[inline data elided] \&.\\" +3 ns \&new dashed \&[inline data elided] \&new dashed \&[inline data elided] \&.\\" -3 ns \&new dashed \&[inline data elided] \&new dashed \&[inline data elided] \&.\\" timing offset +3 ns \&new solid \&[inline data elided] \&new solid \&[inline data elided] \&.\\" timing offset -3 ns \&new solid \&[inline data elided] \&new solid \&[inline data elided] \&.\\" +3 ns timing offset +-3 ns jitter \&.\\" +3 ns timing offset \&new solid \&[inline data elided] \&new solid \&[inline data elided] \&.\\" -3 ns jitter around +3 ns timing offset \&new dashed \&[inline data elided] \&new dashed \&[inline data elided] \&.\\" +3 ns jitter around +3 ns timing offset \&new dashed \&[inline data elided] \&new dashed \&[inline data elided] \&.\\" -3 ns timing offset +-3 ns jitter \&.\\" -3 ns timing offset \&new solid \&[inline data elided] \&new solid \&[inline data elided] \&.\\" -3 ns jitter around -3 ns timing offset \&new dashed \&[inline data elided] \&new dashed \&[inline data elided] \&.\\" +3 ns jitter around -3 ns timing offset \&new dashed \&[inline data elided] \&new dashed \&[inline data elided] \&.ps \&.G2 .ft .DE .G1 4 .ps 14 frame ht 5 wid 6 top invis right invis left invis bot invis ticks off coord x -21, 21 y 0, 70 line dashed from (0,0) to (0,68) line dotted from (-11,0) to (-11,70) line dotted from (11,0) to (11,70) "clock" rjust at -21, 3.5 "data" rjust at -21, 35 "timing reference" below at 0, -1 "recovery window" at 0, 70 arrow from (-6,70) to (-10,70) arrow from (6,70) to (10,70) "``perfect'' data" at 0, 13.5 "jitter" at 0, 23.5 "timing offset" at 0, 38.3 "timing offset + jitter" at 0, 58.3 .\" clock draw solid -21, 7 -16, 0 -2.5, 0 2.5, 7 16, 7 21, 0 .\" perfect data new solid -21, 17 -16, 10 16, 10 21, 17 new solid -21, 10 -16, 17 16, 17 21, 10 .\" data with jitter +-3 ns new solid -21, 27 -16, 20 16, 20 21, 27 new solid -21, 20 -16, 27 16, 27 21, 20 .\" +3 ns new dashed -21, 27 -18, 27 -13, 20 19, 20 21, 22.8 new dashed -21, 20 -18, 20 -13, 27 19, 27 21, 24.2 .\" -3 ns new dashed -21, 22.8 -19, 20 13, 20 18, 27 21, 27 new dashed -21, 24.2 -19, 27 13, 27 18, 20 21, 20 .\" timing offset +3 ns new solid -21, 37 -18, 37 -13, 30 19, 30 21, 32.8 new solid -21, 30 -18, 30 -13, 37 19, 37 21, 34.2 .\" timing offset -3 ns new solid -21, 44.2 -19, 47 13, 47 18, 40 21, 40 new solid -21, 42.8 -19, 40 13, 40 18, 47 21, 47 .\" +3 ns timing offset +-3 ns jitter .\" +3 ns timing offset new solid -21, 57 -18, 57 -13, 50 19, 50 21, 52.8 new solid -21, 50 -18, 50 -13, 57 19, 57 21, 54.2 .\" -3 ns jitter around +3 ns timing offset new dashed -21, 57 -15, 57 -10, 50 21, 50 new dashed -21, 50 -15, 50 -10, 57 21, 57 .\" +3 ns jitter around +3 ns timing offset new dashed -21, 57 -16, 50 16, 50 21, 57 new dashed -21, 50 -16, 57 16, 57 21, 50 .\" -3 ns timing offset +-3 ns jitter .\" -3 ns timing offset new solid -21, 64.2 -19, 67 13, 67 18, 60 21, 60 new solid -21, 62.8 -19, 60 13, 60 18, 67 21, 67 .\" -3 ns jitter around -3 ns timing offset new dashed -21, 67 10, 67 15, 60 21, 60 new dashed -21, 60 10, 60 15, 67 21, 67 .\" +3 ns jitter around -3 ns timing offset new dashed -21, 60 -16, 67 16, 67 21, 60 new dashed -21, 67 -16, 60 16, 60 21, 67 .ps .G2 .\" " .KE .KS Bruce Lilly also suggests this example. He says: .QP I've attached a small data file and simple grap specification which shows one way to handle missing data (and perhaps also how to ignore a column header row in a data file). The data is annual US bicyclist fatalities as published by the National Highway Transportation Safety Administration .I http://www.nhtsa.dot.gov/people/ncsa/factshet.html ; ( the \*Qfact sheets\*U for \*Qpedalcyclists\*U for 1998 and for 1993) and by the National Center for Injury Prevention and Control .I http://www.cdc.gov/ncipc/osp/us9693/mvpctr.htm ; ( change the numbers for different years). CDC data hasn't yet been published for 1997 or 1998. Don't ask me why two groups of bureaucrats in the US Federal Government can't agree on the numbers. The data is, of course, public information, and there's no reason why you can't use the trivial grap specification (though you might wish to embellish it). .LP I did embellish it by adding labels and a key. .DS .CW \&.G1 \&label top "Bicycling Deaths by Year" \&label left "Deaths" left 0.2 \&label bottom "Year" \© "cy_fatal.d" through { \& # ignore missing data (zero or negative values \& # used as placeholders). It also happens to ignore column \& # header rows in data. \& if $2 > 0 then {square at $1,$2 } \& if $3 > 0 then {bullet at $1,$3 } \&} \&square at 1993, 925 \&"NHTSA data" ljust at 1993.5, 925 \&bullet at 1993, 900 \&"CDC data" ljust at 1993.5, 900 \&line from 1992.5,940 to 1998,940 \&line from 1998,940 to 1998,890 \&line from 1998,890 to 1992.5, 890 \&line from 1992.5, 890 to 1992.5,940 \&.G2 .DE .G1 label top "Bicycling Deaths by Year" label left "Deaths" left 0.2 label bottom "Year" copy "cy_fatal.d" through { # ignore missing data (zero or negative values # used as placeholders). It also happens to ignore column # header rows in data. if $2 > 0 then {square at $1,$2 } if $3 > 0 then {bullet at $1,$3 } } square at 1993, 925 "NHTSA data" ljust at 1993.5, 925 bullet at 1993, 900 "CDC data" ljust at 1993.5, 900 line from 1992.5,940 to 1998,940 line from 1998,940 to 1998,890 line from 1998,890 to 1992.5, 890 line from 1992.5, 890 to 1992.5,940 .G2 .KE .KS This example shows off the new automatic tick generation for named coordinate systems. It is a re-plot of earlier data. The automatic ticks do not look great here because they are generated on a logarithmic axis. Still, it means that the graph can be generated without constants in the grap code. .DS .CW \&.G1 \&define square {"\\s-2\\(sq\\s0"} \&frame ht 3 wid 3.5 \&label left "Population in Millions (Plotted as \(bu)" \&label bot "Rank in Population" \&label right "Representatives (Plotted as \(sq)" \&coord pop log y \&coord rep log y \&ticks left out auto pop \&ticks bot out auto pop \&ticks right out auto rep \&thisrank = 50 \© "states.d" thru { \& bullet at pop thisrank,$3/1e6 \& square at rep thisrank,$2 \& thisrank = thisrank -1 \&} \&.G2 .DE .G1 define square {"\s-2\(sq\s0"} frame ht 3 wid 3.5 label left "Population in Millions (Plotted as \(bu)" label bot "Rank in Population" label right "Representatives (Plotted as \(sq)" coord pop log y coord rep log y ticks left out auto pop ticks bot out auto pop ticks right out auto rep thisrank = 50 copy "states.d" thru { bullet at pop thisrank,$3/1e6 square at rep thisrank,$2 thisrank = thisrank -1 } .G2 .KE .KS .PP This is a demonstration of the new line clipping. The right graph is a detail of the left, created by simply respecifying the coordinate limits. (The region plotted in the right graph is the dotted rectangle in the left.) Note that the data is clipped leaving the area plotted and returning. The data is the 400 Meter Run Olympic data from before. .EQ delim off .EN .DS .ft CW \&graph Main \&frame invis ht 2 wid 2.5 left solid bot solid \&label left "Time (in seconds)" \&label bot "Olympic 400 Meter Run: Winning Times" right 1.75 \&coord x 1894, 1994 y 42, 56 \&ticks left out at 44 "44", 46, 48 "48", 50, 52 "52", 54 \&ticks bot in from 1900 to 1980 by 20 \&draw solid \© "400mpairs.d" \&bar (1908,46), (1940,49) dashed \&# detail graph \&graph Detail with .w at Main.Frame.e +(0.1,0) \&frame dashed ht 2 wid 2.5 right solid bot solid \&label right "Time (in seconds)" \&ticks left off \&ticks right on \&ticks bot in \&draw solid \© "400mpairs.d" \&coord x 1908,1942 y 45,49 .ft .DE .EQ delim $$ .EN .G1 graph Main frame invis ht 2 wid 2.5 left solid bot solid label left "Time (in seconds)" label bot "Olympic 400 Meter Run: Winning Times" right 1.75 coord x 1894, 1994 y 42, 56 ticks left out at 44 "44", 46, 48 "48", 50, 52 "52", 54 ticks bot in from 1900 to 1980 by 20 draw solid copy "400mpairs.d" bar (1908,46), (1940,49) dashed # detail graph graph Detail with .w at Main.Frame.e +(0.1,0) frame dashed ht 2 wid 2.5 right solid bot solid label right "Time (in seconds)" ticks left off ticks right on ticks bot in draw solid copy "400mpairs.d" coord x 1908,1942 y 45,49 .G2 .KE .KS .PP Revisiting the boy heights example to demonstrate some other .CW grap features. New to this version is the ability to use x and y directly as variable names anywhere but a .CW coord statement. Fixed as of release 1.10 is the ability to start a new line of the named style (or the default if no name is given) using the .CW new statement. The variable .CW y is directly used in the computation of the regression, and each dashed error bar is drawn using the conf line style. Otherwise this is the earlier graph. .EQ delim off .EN .DS .ft CW \&.G1 \&label left "Heights in Feet" \&label bot "Heights of Boys in the US Ages 2-18" \&cmpft = 12 \&minx = 1e12; maxx = -1e12 \&n = sigx = sigx2 = sigy = sigxy = 0; \&draw conf dashed \© "boyhts.d" thru { \& new conf \& next conf at $1, $2/cmpft \& next conf at $1, $4/cmpft \& y = $3 / cmpft \& bullet at $1, y \& n = n+1 \& sigx = sigx + $1; sigx2 = sigx2 + $1 * $1 \& sigy = sigy + y; sigxy = sigxy + $1*y \& minx = min(minx,$1); maxx = max(maxx,$1); \&} \&slope = ( n*sigxy - sigx* sigy) / (n*sigx2 - sigx * sigx) \&inter = ( sigy - slope * sigx) / n \&line from minx, slope * minx+inter to maxx, slope * maxx + inter \&.G2 .ft .DE .EQ delim $$ .EN .G1 label left "Heights in Feet" label bot "Heights of Boys in the US Ages 2-18" cmpft = 12 minx = 1e12; maxx = -1e12 n = sigx = sigx2 = sigy = sigxy = 0; draw conf dashed copy "boyhts.d" thru { new conf next conf at $1, $2/cmpft next conf at $1, $4/cmpft y = $3 / cmpft bullet at $1, y n = n+1 sigx = sigx + $1; sigx2 = sigx2 + $1 * $1 sigy = sigy + y; sigxy = sigxy + $1*y minx = min(minx,$1); maxx = max(maxx,$1); } slope = ( n*sigxy - sigx* sigy) / (n*sigx2 - sigx * sigx) inter = ( sigy - slope * sigx) / n line from minx, slope * minx+inter to maxx, slope * maxx + inter .G2 .KE .KS .PP Some fun with embedded pic and troff to show that they work. The plotting points are made by a troff font change to Helvetica, drawing an \*Qx\*U in grap, then a pic box around it, a second troff font change and another grap label. This example will almost certainly fail under TeX. .EQ delim off .EN .DS .ft CW \&.G1 \&coord x 5,35 y 5, 35 \&ticks off \© until "END" thru { \&. ft H \& "x" at $1, $2 \& pic box ht 0.1 wid 0.1 at Here \&. ft R \& "" "$3" below at $1, $2 \&} \&10 10 here's \&20 20 some \&30 30 pic/troff \&END \&.G2 .DE .EQ delim $$ .EN .ft .G1 coord x 5,35 y 5, 35 ticks off copy until "END" thru { . ft H "x" at $1, $2 pic box ht 0.1 wid 0.1 at Here . ft R "" "$3" below at $1, $2 } 10 10 here's 20 20 some 30 30 pic/troff END .G2 .KE .KS .PP .CW grap is now .I much more context sensitive in how it picks out keywords. There are still some places where it will resolutely not allow variables with keyword names, but it's enormously better about it. Here's a short somewhat pathological example. I couldn't decide which for loop was less readable, so I used both. .EQ delim off .EN .DS .ft CW \&.G1 \&from=0 \&to = 10 \&ht =3 \&wid = 5 \&frame ht ht wid wid \&for i from from to to do { \& delta at i, i \&} \&for j = from to to do { \& bullet at to - j, j \&} \&.G2 .ft .DE .EQ delim $$ .EN .G1 from=0 to = 10 ht =3 wid = 5 frame ht ht wid wid for i from from to to do { delta at i, i } for j = from to to do { bullet at to - j, j } .G2 .KE .bp .KS .PP At the request of Bruce Lilly, coordinate spaces and variables now have distinct name spaces, and those names spaces can (usually) overlap both each other and keywords. The result is that things like this are legal. .DS .ft CW \&.G1 \&from = 0 \&to = 10 \&new next dotted delta \&for next from from to to do { \& next next at next next, next \&} \&ticks left on next \&ticks bot on next \&.G2 .ft .DE .G1 from = 0 to = 10 new next dotted delta for next from from to to do { next next at next next, next } ticks left on next ticks bot on next .G2 .PP I think we're now ready for the first obfuscated .CW grap contest. The following is a more readable version: .DS .ft CW \&.G1 \&start = 0 \&finish = 10 \&new line_style dotted delta \&coord coord_space \&for i from start to finish do { \& next line_style at coord_space i, i \&} \&ticks left on coord_space \&ticks bot on coord_space \&.G2 .ft .DE .KE .KS One of the few things that one couldn't do under recent versions of .CW grap was redefining keywords. Now you can. Here's an example that redefines the bar keyword. This also demonstrates the new undefine keyword that restores the original bar semantics. .DS .ft CW \&.G1 \&define bar { "_" } \&for i = 1 to 10 do { \& bar at i,i \&} \&undefine bar \&bar up 5 ht 3 \&.G2 .G1 define bar { "_" } for i = 1 to 10 do { bar at i,i } undefine bar bar up 5 ht 3 .G2 .DE .KE .KS .PP Bruce Lilly tells me that DWB .CW grap defines some macros to make embedding pic code easier. The macros are named .CW x_ .I coordname , .CW y_ .I coordname , and .CW xy_ .I coordname . The first 2 return a pic location corresponding to that x or y coordinate in the given name space. The third generates a pair of coordinates in the given coordinate space. The default coordinate space is given by .CW x_gg , .CW y_gg , and .CW xy_gg . If you define a coordinate space named gg, the macros will map one or the other, but I don't know which. .PP DWB .CW grap may use these as part of their implementation. They're an extra feature for compatibility here. .PP Here's a simple example of using these. Note that the fors loop are pic for loops. You don't have access to grap variables from pic. .DS .ft CW \&.G1 \&coord test x 0, 10 y 0, 10 \&coord x 0, 20 y 0, 20 \&frame \&ticks bot on test \&ticks left on test \&pic for i = 0 to 9 do { \&pic "x" at Frame.Origin + xy_test(i,i) \&pic } \&pic for i = 0 to 9 do { \&pic "o" at Frame.Origin + xy_gg(1,i) \&pic } \&.G2 .G1 coord test x 0, 10 y 0, 10 coord x 0, 20 y 0, 20 frame ticks bot on test ticks left on test pic for i = 0 to 9 do { pic "x" at Frame.Origin + xy_test(i,i) pic } pic for i = 0 to 9 do { pic "o" at Frame.Origin + xy_gg(1,i) pic } .G2 .DE .KE .KS .PP A demo of .I grap 's ability to directly manipulate label and plotting sizes. The data is all in the graph specification. .EQ delim off .EN .DS .ft CW \&.G1 \&frame ht 2 wid 2 \&coord x 0,100 y 0,100 \&grid bot dotted from 20 to 80 by 20 "%g" size +5 \&grid left dotted from 20 to 80 by 20 "%g" size -3 \& \&"Text above" above at 50,50 \&"Text rjust " rjust at 50,50 \&bullet at 80,90 \&vtick at 80,80 \&box at 80,70 \× at 80,60 \& \&circle at 50,50 \&circle at 50,80 radius .25 \&line dashed from 10,90 to 30,90 \&arrow from 10,70 to 30,90 \& \&draw A solid \&draw B dashed delta size 15 \&next A at 10,10 \&next B at 10,20 \&next A at 50,20 \&next A at 90,10 \&next B at 50,30 \&next B at 90,30 \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame ht 2 wid 2 coord x 0,100 y 0,100 grid bot dotted from 20 to 80 by 20 "%g" size +5 grid left dotted from 20 to 80 by 20 "%g" size -3 "Text above" above at 50,50 "Text rjust " rjust at 50,50 bullet at 80,90 vtick at 80,80 box at 80,70 times at 80,60 circle at 50,50 circle at 50,80 radius .25 line dashed from 10,90 to 30,90 arrow from 10,70 to 30,90 draw A solid draw B dashed delta size 15 next A at 10,10 next B at 10,20 next A at 50,20 next A at 90,10 next B at 50,30 next B at 90,30 .G2 .KE .bp .EQ delim $$ .EN .PP .KS .PP A gratuitous color graph. Don't ever produce anything this ugly. The data is the 400m times used earlier. There's a circle to show the color and fillcolor attributes. I've also added a thickness to one line and the circle. .EQ delim off .EN .DS .ft CW \&.G1 \&frame invis ht 2 wid 3 left solid color "blue" \\ \& bot solid color "orange" \&label left "Time (in seconds)" left .15 \&label bot "Olympic 400 Meter Run: Winning Times" \&coord x 1894, 1994 y 42, 56 \&ticks left out at 44 , 46 "", 48, 50 "", 52, 54 "" \&ticks bot in from 1900 to 1980 by 20 \&grid bot ticks off color "yellow" from 1900 to 1980 by 20 \&grid left ticks off color "yellow" at 44, 46, 48, 50, 52, 54 \&draw solid color "green" delta color "violet" \© "400mpairs.d" \&new color "red" thickness 2.5 \© "400wpairs.d" \&"Women" size -3 at 1958,52 \&"Men" size -3 at 1910,47 \&circle at 1940, 52 rad 0.25 color "blue" fillcolor "red" \\ \& fill 0.5 thickness 2 \&.G2 .ft .DE .EQ delim $$ .EN .G1 frame invis ht 2 wid 3 left solid color "blue" \ bot solid color "orange" label left "Time (in seconds)" left .15 label bot "Olympic 400 Meter Run: Winning Times" coord x 1894, 1994 y 42, 56 ticks left out at 44 , 46 "", 48, 50 "", 52, 54 "" ticks bot in from 1900 to 1980 by 20 grid bot ticks off color "yellow" from 1900 to 1980 by 20 grid left ticks off color "yellow" at 44, 46, 48, 50, 52, 54 draw solid color "green" delta color "violet" copy "400mpairs.d" new color "red" thickness 2.5 copy "400wpairs.d" "Women" size -3 at 1958,52 "Men" size -3 at 1910,47 circle at 1940, 52 rad 0.25 color "blue" fillcolor "red" \ fill 0.5 thickness 2 .G2 .KE .bp .PP Some people have tripped over .CW grap 's fairly limited string manipulation capabilities. Simply .CW grap can only compare two quoted strings for equality. Strings cannot be assigned to variables. Surprisingly, when combined with macros, that's enough to do simple data selection, but not much more. Here's an example. .KS .EQ delim off .EN .DS .ft CW \&.G1 \© until "END" thru { \& if ( "$1" == "yes" ) then { \& next at $2, $3 \& } \&} \&yes 1 1 \&yes 2 2 \&no 3 3 \&yes 4 4 \&yes 5 5 \&END \&.G2 .ft .DE .G1 copy until "END" thru { if ( "$1" == "yes" ) then { next at $2, $3 } } yes 1 1 yes 2 2 no 3 3 yes 4 4 yes 5 5 END .G2 .KE .LP Note that while data files can contain quotes, putting quotes in the data file will .B not collect words into strings containing whitespace; .CW grap splits lines of data files into words separated by whitespace. .CW Grap 's macro substitution and line splitting are very literal and know nothing about the language structure. Overall, if you're planning anything more complex than conditionals based on the contents of a single word parameter to a macro call, do it outside .CW grap . .CW Perl and other scripting languages make complex text manipulations very easy. Here's the same example with quotes in the file; notice the change in the expression in the .CW if . .KS .EQ delim off .EN .DS .ft CW \&.G1 \© until "END" thru { \& if ( $1 == "yes" ) then { \& next at $2, $3 \& } \&} \&"yes" 1 1 \&"yes" 2 2 \&"no" 3 3 \&"yes" 4 4 \&"yes" 5 5 \&END \&.G2 .ft .DE .G1 copy until "END" thru { if ( $1 == "yes" ) then { next at $2, $3 } } "yes" 1 1 "yes" 2 2 "no" 3 3 "yes" 4 4 "yes" 5 5 END .G2 .KE grap-1.43/examples/hist.awk000640 004133 000000 00000000142 06537272750 016077 0ustar00faberwheel000000 000000 BEGIN { bzs; bw = 1e6 } { count [int(($3-bzs)/bw)]++ } END { for (i in count) print i, count[i] } grap-1.43/examples/hist2.awk000640 004133 000000 00000000135 06537272750 016163 0ustar00faberwheel000000 000000 BEGIN {bzs = 0; bw=1e6 } { thisbin = int(($3-bzs)/bw); print $1, thisbin, count[thisbin]++ } grap-1.43/examples/internet.d000640 004133 000000 00000000201 06537272750 016415 0ustar00faberwheel000000 000000 81 213 83 562 85 1961 87 28174 89 159000 90 313000 91 617000 92 1136000 93 2056000 94 3864000 95 6642000 96 12881000 97 19540000 grap-1.43/examples/prof2.d000640 004133 000000 00000000304 06537272750 015621 0ustar00faberwheel000000 000000 39.0 mcount 6.6 _strlen 6.0 _yylex__Fv 5.2 _write 4.6 _yyparse__Fv 2.6 ___as__6StringRC6String 2.5 ___13DisplayStringG6Stringidi 2.5 _malloc_bytes 2.1 __IO_dtoa grap-1.43/examples/states.d000640 004133 000000 00000001230 06537272750 016073 0ustar00faberwheel000000 000000 WY 1 453588 AK 1 550043 VT 1 562758 ND 1 638800 DE 1 666168 SD 1 696004 MT 1 799065 RI 2 1003464 ID 2 1006749 HI 2 1108229 NH 2 1109252 NV 2 1201833 ME 2 1227928 NM 3 1515069 NE 3 1578385 UT 3 1722850 WV 3 1793477 AR 4 2350725 KS 4 2477574 MS 5 2573216 IA 5 2776755 OR 5 2842321 OK 6 3145585 CT 6 3287116 CO 6 3294394 SC 6 3486703 AZ 6 3665228 KY 6 3685296 AL 7 4040587 LA 7 4219973 MN 8 4375099 MD 8 4781468 WA 8 4866692 TN 9 4877185 WI 9 4891769 MO 9 5117073 IN 10 5544159 MA 11 6016425 VA 11 6187358 GA 11 6478216 NC 12 6628637 NJ 13 7730188 MI 16 9295297 OH 19 10847115 IL 20 11430602 PA 21 11881643 FL 23 12937926 TX 30 16986510 NY 31 17990455 CA 52 29760021 grap-1.43/examples/states2.d000640 004133 000000 00000000103 06537272750 016153 0ustar00faberwheel000000 000000 0 7 1 10 2 5 3 6 4 7 5 2 6 4 7 1 9 1 10 1 11 2 12 1 16 1 17 1 29 1 grap-1.43/examples/states3.d000640 004133 000000 00000000545 06537272750 016166 0ustar00faberwheel000000 000000 WY 0 0 AK 0 1 VT 0 2 ND 0 3 DE 0 4 SD 0 5 MT 0 6 RI 1 0 ID 1 1 HI 1 2 NH 1 3 NV 1 4 ME 1 5 NM 1 6 NE 1 7 UT 1 8 WV 1 9 AR 2 0 KS 2 1 MS 2 2 IA 2 3 OR 2 4 OK 3 0 CT 3 1 CO 3 2 SC 3 3 AZ 3 4 KY 3 5 AL 4 0 LA 4 1 MN 4 2 MD 4 3 WA 4 4 TN 4 5 WI 4 6 MO 5 0 IN 5 1 MA 6 0 VA 6 1 GA 6 2 NC 6 3 NJ 7 0 MI 9 0 OH 10 0 IL 11 0 PA 11 1 FL 12 0 TX 16 0 NY 17 0 CA 29 0 grap-1.43/examples/usapop.d000640 004133 000000 00000000273 06537272750 016105 0ustar00faberwheel000000 000000 1790 3.93 1800 5.31 1810 7.24 1820 9.64 1830 12.86 1840 17.06 1850 23.19 1860 31.44 1870 38.56 1880 50.19 1890 62.98 1900 76.21 1910 92.23 1920 106.02 1930 123.20 1940 132.16 1950 151.33 grap-1.43/examples/cy_fatal.d000640 004133 000000 00000000317 06765403633 016356 0ustar00faberwheel000000 000000 1983 839 794 1984 849 814 1985 890 820 1986 941 886 1987 948 922 1988 911 859 1989 832 776 1990 859 814 1991 843 794 1992 723 679 1993 816 789 1994 802 730 1995 833 783 1996 765 695 1997 814 -1 1998 761 -1 grap-1.43/examples/result.SQ_MESH.Fail1.S3.R0.Global.Random1500.succ.result000640 004133 000000 00000000114 06743301644 025710 0ustar00faberwheel000000 000000 270 94.619 108.211 616 92.083 105.421 777 77.489 107.958 858 49.073 116.177 grap-1.43/examples/result.SQ_MESH.Fail1.S3.R0.Local.Random1500.succ.result000640 004133 000000 00000000114 06743301645 025543 0ustar00faberwheel000000 000000 270 88.136 124.610 616 67.455 115.707 777 45.545 114.643 858 18.587 112.161 grap-1.43/examples/result.SQ_MESH.Fail1.S3.R0.Hybrid.Random1500.succ.result000640 004133 000000 00000000114 06743301644 025731 0ustar00faberwheel000000 000000 270 97.358 121.811 616 88.838 109.360 777 75.579 113.143 858 44.126 111.896 grap-1.43/configure000770 004133 000000 00000606076 11076254731 014531 0ustar00faberwheel000000 000000 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.62 for grap 1.43. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='grap' PACKAGE_TARNAME='grap' PACKAGE_VERSION='1.43' PACKAGE_STRING='grap 1.43' PACKAGE_BUGREPORT='faber@lunabase.org' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT GXXFLAGS NO_UNDEF SUPPRESS_OPT LEX LEX_OUTPUT_ROOT LEXLIB YACC YFLAGS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA MKDEP MKDEPFLAGS OS_VERSION CX0FLAGS DEFINES_DIR EXAMPLE_DIR DOC_DIR INSTALL_DOCS CXXCPP GREP EGREP LIBOBJS INSTALL_DEPS LTLIBOBJS' ac_subst_files='' ac_user_opts=' enable_option_checking with_defines_dir with_example_dir with_doc_dir enable_optimize_grap_tokenizer with_freebsd_ports with_safer_mode ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC YACC YFLAGS CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { $as_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { $as_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: Unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { $as_echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures grap 1.43 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/grap] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of grap 1.43:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-optimize-grap_tokenizer do not prevent optimization of the grap_tokenize.cc file Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-defines-dir=dir directory in which to install grap.defines --with-example-dir=dir directory in which to install examples --with-doc-dir=dir directory in which to install documents --with-freebsd-ports configure called by a FreeBSD ports makefile --with-safer-mode disable sprintf to avoid attacks Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory YACC The `Yet Another C Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF grap configure 1.43 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by grap $as_me 1.43, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 $as_echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test -r "$ac_site_file"; then { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 $as_echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { $as_echo "$as_me:$LINENO: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } if test -z "$ac_file"; then $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # Set g++ specific compiler options if test "$GXX" = "yes" ; then GXXFLAGS="-Wall" else GXXFLAGS="" fi # Set g++ specific compiler options if test "$GXX" = "yes" ; then NO_UNDEF="-Wno-unused" else NO_UNDEF="" fi # Set g++ specific compiler options if test "$GXX" = "yes" ; then SUPPRESS_OPT="-O0" else SUPPRESS_OPT="" fi for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_LEX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:$LINENO: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { yyless (input () != 0); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { (ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$LINENO: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if test "${ac_cv_prog_lex_root+set}" = set; then $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else { { $as_echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 $as_echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:$LINENO: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if test "${ac_cv_lib_lex+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat >conftest.$ac_ext <<_ACEOF `cat $LEX_OUTPUT_ROOT.c` _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_lex=$ac_lib else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat >conftest.$ac_ext <<_ACEOF #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_prog_lex_yytext_pointer=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then cat >>confdefs.h <<\_ACEOF #define YYTEXT_POINTER 1 _ACEOF fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_YACC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:$LINENO: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:$LINENO: checking whether $INSTALL supports -d" >&5 $as_echo_n "checking whether $INSTALL supports -d... " >&6; } if test "${tvf_cv_prog_install_d+set}" = set; then $as_echo_n "(cached) " >&6 else if $INSTALL -d /tmp/test$$ && test -d /tmp/test$$ ; then tvf_cv_prog_install_d="yes" else tvf_cv_prog_install_d="no" fi rm -rf /tmp/test$$ fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_prog_install_d" >&5 $as_echo "$tvf_cv_prog_install_d" >&6; } if test "$tvf_cv_prog_install_d" = "no" ; then INSTALL=$ac_install_sh fi for ac_prog in mkdep gcc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_MKDEP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$MKDEP"; then ac_cv_prog_MKDEP="$MKDEP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MKDEP="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MKDEP=$ac_cv_prog_MKDEP if test -n "$MKDEP"; then { $as_echo "$as_me:$LINENO: result: $MKDEP" >&5 $as_echo "$MKDEP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$MKDEP" && break done test -n "$MKDEP" || MKDEP="cp" # depending on which mkdep method has been found, the args are # slightly different. -f is redundant on FreeBSD, but needed other places. # The test for that is completely superfluous. if test $ac_ext = "C" || test $ac_ext = "cc" ; then tvf_compflags='${CXXFLAGS}' tvf_mk_gcc=g++ tvf_mk_include="" else tvf_compflags='${CFLAGS}' tvf_mk_gcc=gcc tvf_mk_include="" fi # make sure that mkdep plays well with others. Be careful. Bad mkdep # implementations are very cranky about parameter order. if test "$MKDEP" = mkdep; then tvf_here=`pwd` cd /tmp mkdir test.$$ cd test.$$ # solaris mkdep wants a .depend there already touch .depend touch test.h cat > test.$ac_ext << END #include $tvf_mk_include #include "test.h" int main(int argc, char **argv) { } END $MKDEP -f .depend -MM test.$ac_ext 2> /dev/null > /dev/null grep test.h .depend > /dev/null 2>&1 if test "$?" != "0"; then # MKDEP does not play well with us, use gcc or cp cd $tvf_here unset ac_cv_prog_MKDEP unset MKDEP for ac_prog in gcc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_MKDEP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$MKDEP"; then ac_cv_prog_MKDEP="$MKDEP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MKDEP="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MKDEP=$ac_cv_prog_MKDEP if test -n "$MKDEP"; then { $as_echo "$as_me:$LINENO: result: $MKDEP" >&5 $as_echo "$MKDEP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$MKDEP" && break done test -n "$MKDEP" || MKDEP="cp" else cd $tvf_here fi rm -rf /tmp/test.$$ fi case "$MKDEP" in mkdep) if test `uname` = 'FreeBSD'; then MKDEPFLAGS=" -MM $tvf_compflags \${SOURCES}" else MKDEPFLAGS="-f .depend -MM $tvf_compflags \${SOURCES}" fi ;; gcc) MKDEP=$tvf_mk_gcc MKDEPFLAGS="-MM $tvf_compflags \${SOURCES} >> .depend" ;; cp) MKDEPFLAGS='default_depend .depend' ;; esac { $as_echo "$as_me:$LINENO: checking for OS version" >&5 $as_echo_n "checking for OS version... " >&6; } if test "${tvf_cv_os_version+set}" = set; then $as_echo_n "(cached) " >&6 else tvf_cv_os_version=`uname -sr` fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_os_version" >&5 $as_echo "$tvf_cv_os_version" >&6; } OS_VERSION=$tvf_cv_os_version cat >>confdefs.h <<_ACEOF #define OS_VERSION "$OS_VERSION" _ACEOF { $as_echo "$as_me:$LINENO: checking if ${CXX} supports -std=c++0x" >&5 $as_echo_n "checking if ${CXX} supports -std=c++0x... " >&6; } old_cxxflags="$CXXFLAGS" old_cppflags="$CPPFLAGS" CXXFLAGS="$CXXFLAGS -std=c++0x" CPPFLAGS="$CPPFLAGS -std=c++0x" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then CX0FLAGS="-std=c++0x" { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CX0FLAGS="" CXXFLAGS="$old_cxxflags" CPPFLAGS="$old_cppflags" { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Check whether --with-defines-dir was given. if test "${with_defines_dir+set}" = set; then withval=$with_defines_dir; DEFINES_DIR=$withval else DEFINES_DIR="$datadir/grap" fi # Check whether --with-example-dir was given. if test "${with_example_dir+set}" = set; then withval=$with_example_dir; EXAMPLE_DIR=$withval else EXAMPLE_DIR="$datadir/examples/grap" fi # Check whether --with-doc-dir was given. if test "${with_doc_dir+set}" = set; then withval=$with_doc_dir; DOC_DIR=$withval else DOC_DIR="$datadir/doc/grap" fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi if test $ac_cv_header_stdc = "no"; then # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if test `eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------- ## ## Report this to faber@lunabase.org ## ## --------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi if test `eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done fi for ac_header in unistd.h errno.h limits do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------- ## ## Report this to faber@lunabase.org ## ## --------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi if test `eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in unordered_map hash_map ext/hash_map do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------- ## ## Report this to faber@lunabase.org ## ## --------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi if test `eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_UNORDERED_MAP #include #endif #ifdef HAVE_HASH_MAP #include #endif #ifdef HAVE_EXT_HASH_MAP #include #endif int main () { std::hash h; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HASH_SPACE std _ACEOF break else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_UNORDERED_MAP #include #endif #ifdef HAVE_HASH_MAP #include #endif #ifdef HAVE_EXT_HASH_MAP #include #endif int main () { __gnu_cxx::hash h; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >>confdefs.h <<\_ACEOF #define HASH_SPACE __gnu_cxx _ACEOF break; else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi done { $as_echo "$as_me:$LINENO: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_size_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((size_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 $as_echo "$ac_cv_type_size_t" >&6; } if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi for ac_func in snprintf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if test `eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "$ac_cv_func_snprintf" = "yes" ; then { $as_echo "$as_me:$LINENO: checking for declaration of snprintf" >&5 $as_echo_n "checking for declaration of snprintf... " >&6; } if test "${tvf_cv_decl_snprintf+set}" = set; then $as_echo_n "(cached) " >&6 else for f in stdio.h; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$f> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "snprintf" >/dev/null 2>&1; then tvf_cv_decl_snprintf="yes" else tvf_cv_decl_snprintf="no" fi rm -f conftest* if test $tvf_cv_decl_snprintf = "yes"; then break; fi done fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_decl_snprintf" >&5 $as_echo "$tvf_cv_decl_snprintf" >&6; } if test "$tvf_cv_decl_snprintf" = "yes"; then cat >>confdefs.h <<\_ACEOF #define SNPRINTF_DECLARED 1 _ACEOF fi fi for ac_func in strdup do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if test `eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else case " $LIBOBJS " in *" $ac_func.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; esac fi done if test "$ac_cv_func_strdup" = "yes" ; then { $as_echo "$as_me:$LINENO: checking for declaration of strdup" >&5 $as_echo_n "checking for declaration of strdup... " >&6; } if test "${tvf_cv_decl_strdup+set}" = set; then $as_echo_n "(cached) " >&6 else for f in stdio.h string.h; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$f> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strdup" >/dev/null 2>&1; then tvf_cv_decl_strdup="yes" else tvf_cv_decl_strdup="no" fi rm -f conftest* if test $tvf_cv_decl_strdup = "yes"; then break; fi done fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_decl_strdup" >&5 $as_echo "$tvf_cv_decl_strdup" >&6; } if test "$tvf_cv_decl_strdup" = "yes"; then cat >>confdefs.h <<\_ACEOF #define STRDUP_DECLARED 1 _ACEOF fi fi for ac_func in strerror do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if test `eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else case " $LIBOBJS " in *" $ac_func.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; esac fi done if test "$ac_cv_func_strerror" = "yes" ; then { $as_echo "$as_me:$LINENO: checking for declaration of strerror" >&5 $as_echo_n "checking for declaration of strerror... " >&6; } if test "${tvf_cv_decl_strerror+set}" = set; then $as_echo_n "(cached) " >&6 else for f in stdio.h string.h; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$f> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strerror" >/dev/null 2>&1; then tvf_cv_decl_strerror="yes" else tvf_cv_decl_strerror="no" fi rm -f conftest* if test $tvf_cv_decl_strerror = "yes"; then break; fi done fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_decl_strerror" >&5 $as_echo "$tvf_cv_decl_strerror" >&6; } if test "$tvf_cv_decl_strerror" = "yes"; then cat >>confdefs.h <<\_ACEOF #define STRERROR_DECLARED 1 _ACEOF fi fi if test "x$ac_cv_header_stdc" = "x" -a "x$ac_cv_header_stdlib_h" = "x"; then { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi if test $ac_cv_header_stdc = "no"; then for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------- ## ## Report this to faber@lunabase.org ## ## --------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi if test `eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done fi fi for ac_func in random do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if test `eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test $ac_cv_func_random = "no"; then for ac_func in rand do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if test `eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` = yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done else # not really, but we never need it if we have random ac_cv_func_rand="no" fi if test "$ac_cv_func_random" = "no" -a "$ac_cv_func_rand" = "no"; then # It's possible to get here because the above tests failed due to # autoconf freakiness. These tests are more portable. Look for random # with either a long or int return type, and try rand with an int. If # none of these show up, punt. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern "C" { long random(); } int main () { long x = random(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then cat >>confdefs.h <<\_ACEOF #define HAVE_RANDOM 1 _ACEOF ac_cv_func_random="yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern "C" { int random(); } int main () { int x = random(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then cat >>confdefs.h <<\_ACEOF #define HAVE_RANDOM 1 _ACEOF ac_cv_func_random="yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern "C" { int rand(); } int main () { int x = rand(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then cat >>confdefs.h <<\_ACEOF #define HAVE_RAND 1 _ACEOF ac_cv_func_random="yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_func_random" = "no" -a $ac_cv_func_rand = "no"; then { { $as_echo "$as_me:$LINENO: error: requires either random or rand" >&5 $as_echo "$as_me: error: requires either random or rand" >&2;} { (exit 1); exit 1; }; } fi fi if test "$ac_cv_func_random" = "yes" ; then { $as_echo "$as_me:$LINENO: checking for location of random() declaration" >&5 $as_echo_n "checking for location of random() declaration... " >&6; } if test "${tvf_cv_header_random_declared+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$ac_cv_header_stdc" = "yes" -o "x$ac_cv_header_stdlib_h" = "xyes"; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "srandom" >/dev/null 2>&1; then tvf_cv_header_random_declared="stdlib.h" else tvf_cv_header_random_declared="none" fi rm -f conftest* else tvf_cv_header_random_declared="none" fi if test "$tvf_cv_header_random_declared" = "none"; then #check math.h cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "srandom" >/dev/null 2>&1; then tvf_cv_header_random_declared="math.h" else tvf_cv_header_random_declared="none" fi rm -f conftest* fi fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_header_random_declared" >&5 $as_echo "$tvf_cv_header_random_declared" >&6; } case "$tvf_cv_header_random_declared" in "stdlib.h" ) cat >>confdefs.h <<\_ACEOF #define RANDOM_DECLARED 1 _ACEOF ;; "math.h" ) cat >>confdefs.h <<\_ACEOF #define RANDOM_DECLARED 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define RANDOM_IN_MATH 1 _ACEOF ;; esac else { $as_echo "$as_me:$LINENO: checking for location of rand() declaration" >&5 $as_echo_n "checking for location of rand() declaration... " >&6; } if test "${tvf_cv_header_rand_declared+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$ac_cv_header_stdc" = "yes"; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "srand" >/dev/null 2>&1; then tvf_cv_header_rand_declared="stdlib.h" else tvf_cv_header_rand_declared="none" fi rm -f conftest* else tvf_cv_header_rand_declared="none" fi if test "$tvf_cv_header_rand_declared" = "none"; then #check math.h cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "srand" >/dev/null 2>&1; then tvf_cv_header_rand_declared="math.h" else tvf_cv_header_rand_declared="none" fi rm -f conftest* fi fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_header_rand_declared" >&5 $as_echo "$tvf_cv_header_rand_declared" >&6; } case "$tvf_cv_header_rand_declared" in "stdlib.h" ) cat >>confdefs.h <<\_ACEOF #define RAND_DECLARED 1 _ACEOF ;; "math.h" ) cat >>confdefs.h <<\_ACEOF #define RAND_DECLARED 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define RAND_IN_MATH 1 _ACEOF ;; esac fi if test "$ac_cv_header_unistd_h" = "yes" ; then { $as_echo "$as_me:$LINENO: checking for optarg in unistd.h" >&5 $as_echo_n "checking for optarg in unistd.h... " >&6; } if test "${tvf_cv_header_optarg+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "optarg" >/dev/null 2>&1; then tvf_cv_header_optarg="yes"; else tvf_cv_header_optarg="no" fi rm -f conftest* fi { $as_echo "$as_me:$LINENO: result: $tvf_cv_header_optarg" >&5 $as_echo "$tvf_cv_header_optarg" >&6; } if test "$tvf_cv_header_optarg" = "yes"; then cat >>confdefs.h <<\_ACEOF #define OPTARG_DEFINED 1 _ACEOF fi fi if test "$ac_cv_func_snprintf" = "no"; then { $as_echo "$as_me:$LINENO: checking if sprintf returns an int" >&5 $as_echo_n "checking if sprintf returns an int... " >&6; } if test "${grap_cv_sprintf_int+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then echo "" else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main(int argc, char **argv) { char a[10]; if ( (char *) sprintf(a,"ten") == a ) return 1; else return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then grap_cv_sprintf_int="yes" else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) grap_cv_sprintf_int="no" fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $grap_cv_sprintf_int" >&5 $as_echo "$grap_cv_sprintf_int" >&6; } if test "$grap_cv_sprintf_int" = "no" ; then cat >>confdefs.h <<\_ACEOF #define SPRINTF_NOT_INT 1 _ACEOF fi fi test "x$prefix" = xNONE && prefix="$ac_default_prefix" # expand the data directory parameter. Repeatedly eval the contents # of ddir until it has no $ in it. ddir=$datadir while echo $ddir | grep '\$' > /dev/null ; do ddir=`eval echo $ddir` done cat >>confdefs.h <<_ACEOF #define DEFINES "${ddir}/grap/grap.defines" _ACEOF # expand the examples directory parameter. Repeatedly eval the contents # of ddir until it has no $ in it. ddir=$EXAMPLE_DIR while echo $ddir | grep '\$' > /dev/null ; do ddir=`eval echo $ddir` done cat >>confdefs.h <<_ACEOF #define EXAMPLES_DIR "${ddir}" _ACEOF # expand the data directory parameter. Repeatedly eval the contents # of ddir until it has no $ in it. ddir=$DOC_DIR while echo $ddir | grep '\$' > /dev/null ; do ddir=`eval echo $ddir` done cat >>confdefs.h <<_ACEOF #define DOCS_DIR "${ddir}" _ACEOF { $as_echo "$as_me:$LINENO: checking whether to optimize grap_tokenizer" >&5 $as_echo_n "checking whether to optimize grap_tokenizer... " >&6; } # Check whether --enable-optimize-grap_tokenizer was given. if test "${enable_optimize_grap_tokenizer+set}" = set; then enableval=$enable_optimize_grap_tokenizer; ac_cv_grap_opt_tok="yes" else if test "${ac_cv_grap_opt_tok+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_grap_opt_tok="no" fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_grap_opt_tok" >&5 $as_echo "$ac_cv_grap_opt_tok" >&6; } if test "$ac_cv_grap_opt_tok" = "yes" ; then SUPPRESS_OPT="" fi { $as_echo "$as_me:$LINENO: checking whether configure called from a FreeBSD port" >&5 $as_echo_n "checking whether configure called from a FreeBSD port... " >&6; } # Check whether --with-freebsd-ports was given. if test "${with_freebsd_ports+set}" = set; then withval=$with_freebsd_ports; ac_cv_grap_opt_port="yes" else if test "${ac_cv_grap_opt_port+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_grap_opt_port="no" fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_grap_opt_port" >&5 $as_echo "$ac_cv_grap_opt_port" >&6; } if test $ac_cv_grap_opt_port = "no" ; then INSTALL_DEPS="all grap.defines grap.1 install-docs" else INSTALL_DEPS="all grap.defines grap.1" fi { $as_echo "$as_me:$LINENO: checking whether to force safer mode" >&5 $as_echo_n "checking whether to force safer mode... " >&6; } # Check whether --with-safer-mode was given. if test "${with_safer_mode+set}" = set; then withval=$with_safer_mode; ac_cv_grap_safer_mode="yes" else if test "${ac_cv_grap_safer_mode+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_grap_safer_mode="no" fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_grap_safer_mode" >&5 $as_echo "$ac_cv_grap_safer_mode" >&6; } if test $ac_cv_grap_safer_mode = "yes" ; then cat >>confdefs.h <<\_ACEOF #define GRAP_SAFER 1 _ACEOF fi { $as_echo "$as_me:$LINENO: result: creating default depend file" >&5 $as_echo "creating default depend file" >&6; } # Create an empty .depend that is older than Makefile # if touch will take a time, set the time explicitly, # if not wait a bit so that the created Makefile is newer if test "$MKDEP" = "cp" ; then cp default_depend .depend else cat < /dev/null > .depend touch -t 9912311000 .depend > /dev/null 2>&1 || sleep 1 fi ac_config_files="$ac_config_files examples/Makefile Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 $as_echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by grap $as_me 1.43, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ grap config.status 1.43 configured by $0, generated by GNU Autoconf 2.62, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { $as_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` = $ac_delim_num; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\).*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\).*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] if (D_is_set[macro]) { # Preserve the white space surrounding the "#". prefix = substr(line, 1, index(line, defundef) - 1) print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", line, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 $as_echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$ac_file_inputs '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } fi ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: Unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: Unrecognized options: $ac_unrecognized_opts" >&2;} fi grap-1.43/configure.ac000660 004133 000000 00000012323 11076254702 015071 0ustar00faberwheel000000 000000 dnl -*-m4-*- dnl Process this file with autoconf to produce a configure script. AC_INIT(grap, 1.43, faber@lunabase.org) AC_CONFIG_HEADER(config.h) AC_LANG_CPLUSPLUS dnl Note to self: it's possible to get separate tables out of byacc. It dnl is confusing because g++ optimizes away the const static tables that dnl byacc generates, and compiling those tables aren't the problem dnl anyway. So don't try it again. dnl Checks for programs. AC_PROG_CXX dnl Set g++ specific compiler options TVF_PROG_GXX_SUBST(GXXFLAGS,-Wall) TVF_PROG_GXX_SUBST(NO_UNDEF,-Wno-unused) TVF_PROG_GXX_SUBST(SUPPRESS_OPT,-O0) AC_PROG_LEX AC_PROG_YACC AC_PROG_INSTALL TVF_PROG_INSTALL_D TVF_PROG_MKDEP TVF_OS_VERSION AC_MSG_CHECKING(if ${CXX} supports -std=c++0x) old_cxxflags="$CXXFLAGS" old_cppflags="$CPPFLAGS" CXXFLAGS="$CXXFLAGS -std=c++0x" CPPFLAGS="$CPPFLAGS -std=c++0x" AC_TRY_COMPILE([], [], [ CX0FLAGS="-std=c++0x" AC_MSG_RESULT(yes) ], [ CX0FLAGS="" CXXFLAGS="$old_cxxflags" CPPFLAGS="$old_cppflags" AC_MSG_RESULT(no) ]) AC_SUBST(CX0FLAGS) AC_ARG_WITH(defines-dir, [ --with-defines-dir=dir directory in which to install grap.defines], AC_SUBST(DEFINES_DIR,$withval), AC_SUBST(DEFINES_DIR, "$datadir/grap")) AC_ARG_WITH(example-dir, [ --with-example-dir=dir directory in which to install examples], AC_SUBST(EXAMPLE_DIR,$withval), AC_SUBST(EXAMPLE_DIR, "$datadir/examples/grap")) AC_ARG_WITH(doc-dir, [ --with-doc-dir=dir directory in which to install documents], AC_SUBST(DOC_DIR,$withval), AC_SUBST(DOC_DIR,"$datadir/doc/grap")) AC_SUBST(INSTALL_DOCS) dnl Checks for libraries. dnl Checks for header files. AC_HEADER_STDC if test $ac_cv_header_stdc = "no"; then AC_CHECK_HEADERS(stdlib.h) fi AC_CHECK_HEADERS(unistd.h errno.h limits) AC_CHECK_HEADERS(unordered_map hash_map ext/hash_map, [ AC_COMPILE_IFELSE( AC_LANG_PROGRAM([ #ifdef HAVE_UNORDERED_MAP #include #endif #ifdef HAVE_HASH_MAP #include #endif #ifdef HAVE_EXT_HASH_MAP #include #endif ],[ std::hash h; ]), [ AC_DEFINE(HASH_SPACE, std) break], AC_COMPILE_IFELSE( AC_LANG_PROGRAM([ #ifdef HAVE_UNORDERED_MAP #include #endif #ifdef HAVE_HASH_MAP #include #endif #ifdef HAVE_EXT_HASH_MAP #include #endif ],[ __gnu_cxx::hash h; ]), [ AC_DEFINE(HASH_SPACE, __gnu_cxx) break;],[]))] ) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T dnl Checks for library functions. TVF_FUNC_DECL(snprintf,stdio.h) TVF_FUNC_DECL(strdup, stdio.h string.h,REPLACE) TVF_FUNC_DECL(strerror, stdio.h string.h,REPLACE) TVF_DECL_RANDOM TVF_DECL_OPTARG if test "$ac_cv_func_snprintf" = "no"; then AC_CACHE_CHECK(if sprintf returns an int, grap_cv_sprintf_int, AC_TRY_RUN([ changequote(<<, >>)dnl #include int main(int argc, char **argv) { char a<<[10]>>; if ( (char *) sprintf(a,"ten") == a ) return 1; else return 0; } changequote([, ])dnl ],grap_cv_sprintf_int="yes",grap_cv_sprintf_int="no",echo "")) if test "$grap_cv_sprintf_int" = "no" ; then AC_DEFINE(SPRINTF_NOT_INT) fi fi test "x$prefix" = xNONE && prefix="$ac_default_prefix" # expand the data directory parameter. Repeatedly eval the contents # of ddir until it has no $ in it. ddir=$datadir while echo $ddir | grep '\$' > /dev/null ; do ddir=`eval echo $ddir` done AC_DEFINE_UNQUOTED(DEFINES,"${ddir}/grap/grap.defines") # expand the examples directory parameter. Repeatedly eval the contents # of ddir until it has no $ in it. ddir=$EXAMPLE_DIR while echo $ddir | grep '\$' > /dev/null ; do ddir=`eval echo $ddir` done AC_DEFINE_UNQUOTED(EXAMPLES_DIR,"${ddir}") # expand the data directory parameter. Repeatedly eval the contents # of ddir until it has no $ in it. ddir=$DOC_DIR while echo $ddir | grep '\$' > /dev/null ; do ddir=`eval echo $ddir` done AC_DEFINE_UNQUOTED(DOCS_DIR,"${ddir}") dnl if the caller has overridden the decision on suppressing dnl optimization, use their decision, otherwise optimization has already dnl been suppressed above AC_MSG_CHECKING(whether to optimize grap_tokenizer) AC_ARG_ENABLE(optimize-grap_tokenizer, [ --enable-optimize-grap_tokenizer do not prevent optimization of the grap_tokenize.cc file], ac_cv_grap_opt_tok="yes", AC_CACHE_VAL(ac_cv_grap_opt_tok, ac_cv_grap_opt_tok="no")) AC_MSG_RESULT($ac_cv_grap_opt_tok) if test "$ac_cv_grap_opt_tok" = "yes" ; then SUPPRESS_OPT="" fi AC_MSG_CHECKING(whether configure called from a FreeBSD port) AC_ARG_WITH(freebsd-ports, [ --with-freebsd-ports configure called by a FreeBSD ports makefile], ac_cv_grap_opt_port="yes", AC_CACHE_VAL(ac_cv_grap_opt_port, ac_cv_grap_opt_port="no")) AC_MSG_RESULT($ac_cv_grap_opt_port) if test $ac_cv_grap_opt_port = "no" ; then INSTALL_DEPS="all grap.defines grap.1 install-docs" else INSTALL_DEPS="all grap.defines grap.1" fi AC_SUBST(INSTALL_DEPS) AC_MSG_CHECKING(whether to force safer mode) AC_ARG_WITH(safer-mode, [ --with-safer-mode disable sprintf to avoid attacks], ac_cv_grap_safer_mode="yes", AC_CACHE_VAL(ac_cv_grap_safer_mode, ac_cv_grap_safer_mode="no")) AC_MSG_RESULT($ac_cv_grap_safer_mode) if test $ac_cv_grap_safer_mode = "yes" ; then AC_DEFINE(GRAP_SAFER) fi TVF_CREATE_DOT_DEPEND AC_OUTPUT(examples/Makefile Makefile) grap-1.43/Makefile.in000640 004133 000000 00000007614 11073311004 014637 0ustar00faberwheel000000 000000 # This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT # for the full copyright and limitations of liabilities. # Allow staged install. Set this to install in a temporary location to make # sure this all works, or make a tar file. DESTDIR needs to end with a / if # prefix is not absolute. DESTDIR= prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir=@datarootdir@ datadir=@datadir@ BINDIR = @bindir@ DEFINESDIR = @DEFINES_DIR@ EXAMPLEDIR = @EXAMPLE_DIR@ DOCDIR = @DOC_DIR@ MANDIR = @mandir@/man1 PROGS=grap INSTALL=@INSTALL@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ RM=rm -f RMDIR=rm -rf MKDIR=mkdir LEX=@LEX@ YACC=@YACC@ CXX=@CXX@ LD=${CXX} LIBOBJS=@LIBOBJS@ PREMKDEP= grep "^\#" grap.y > grap.cc ; grep "^\#" grap_lex.l > grap_lex.cc; touch y.tab.h POSTMKDEP=${RM} grap.cc grap_lex.cc y.tab.h MKDEP= @MKDEP@ MKDEPFLAGS=@MKDEPFLAGS@; SOURCES=grap.cc grap_lex.cc *.cc DISTDIR=@PACKAGE_TARNAME@-@PACKAGE_VERSION@ CXXFLAGS +=@GXXFLAGS@ @DEFS@ @CX0FLAGS@ # To suppress optimization of certain files under g++ where # optimization is costly at compilation time and of minimial use at # runtime. SUPPRESS_OPT=@SUPPRESS_OPT@ NO_UNDEF=@NO_UNDEF@ OBJS=grap.o grap_lex.o grap_draw.o grap_pic.o grap_parse.o grap_tokenizer.o \ ${LIBOBJS} CLEANFILES=y.output VERYCLEANFILES=grap.cc grap_lex.cc y.tab.h SPOTLESSFILES=grap.1 grap.ps grap.man include Makefile.common grap: ${OBJS} ${CXX} ${CXXFLAGS} ${LDFLAGS} ${OBJS} ${LDLIBS} -o grap .l.cc: ${LEX} -o$@ $< grap.cc: grap.y ${YACC} -d grap.y mv y.tab.c grap.cc y.tab.h: grap.cc grap_lex.cc: grap_lex.l y.tab.h # Under g++ the memory overhead for optimization of grap_tokenizer is # high. Compilation time becomes prohibitive and the function is only # called once per execution, so this rule disables optimization for # that file under g++ by default. If --optimize-grap_tokenizer is # given to configure, no attempt to suppress optimization is made. grap_tokenizer.o: grap_tokenizer.cc ${CXX} ${CXXFLAGS} ${SUPPRESS_OPT} -c grap_tokenizer.cc # flex defines an unused static function. This rule supresses that # warning under g++. grap_lex.o: grap_lex.cc ${CXX} ${CXXFLAGS} ${NO_UNDEF} -c grap_lex.cc y.output: grap.y ${YACC} -v grap.y grap.man: grap.1 groff -mdoc -Tascii grap.1 > grap.man grap.ps: grap.1 groff -mdoc grap.1 > grap.ps # This used to be more complex. The stub's here so that the grap.doc # records in my CVS stay where they are. grap.1: grap.doc cp grap.doc grap.1 # The || true lines allow make to continue on systems where install -d # fails on existing directories. install: @INSTALL_DEPS@ strip grap || true ${INSTALL} -d ${DESTDIR}${BINDIR} || true ${INSTALL} -d ${DESTDIR}${MANDIR} || true ${INSTALL} -d ${DESTDIR}${DEFINESDIR} || true ${INSTALL} -d ${DESTDIR}${EXAMPLEDIR} || true ${INSTALL_PROGRAM} grap ${DESTDIR}${BINDIR} ${INSTALL_DATA} grap.1 ${DESTDIR}${MANDIR} ${INSTALL_DATA} grap*.defines ${DESTDIR}${DEFINESDIR} ${INSTALL_DATA} examples/*.d examples/example.ms \ examples/*.result examples/Makefile ${DESTDIR}${EXAMPLEDIR} #BSD ports may not want these installed install-docs: ${INSTALL} -d ${DESTDIR}${DOCDIR} || true ${INSTALL_DATA} README CHANGES COPYRIGHT grap.man ${DESTDIR}${DOCDIR} deinstall: ${RM} ${DESTDIR}${BINDIR}/grap ${RM} ${DESTDIR}${MANDIR}/grap.1 ${RM} ${DESTDIR}${DEFINESDIR}/grap*.defines ${DESTDIR}${DOCDIR}/README \ ${DESTDIR}${DOCDIR}/CHANGES ${DESTDIR}${DOCDIR}/COPYRIGHT \ ${DESTDIR}${DOCDIR}/grap.man ${RM} ${DESTDIR}${EXAMPLEDIR}/*.d ${DESTDIR}${EXAMPLEDIR}/*.ms \ ${DESTDIR}${EXAMPLEDIR}/*result ${RMDIR} ${DESTDIR}${DOCDIR}/examples ${RMDIR} ${DESTDIR}${DOCDIR} ${RMDIR} ${DESTDIR}${DEFINESDIR} ${RMDIR} ${DESTDIR}${EXAMPLEDIR} check: grap grap.defines examples/example.ms cd examples && \ if ../grap -d ../grap.defines example.ms > /dev/null; then \ echo "pass";\ exit 0; \ else \ echo "fail"; \ exit 1; \ fi dist: grap.man grap.ps include .depend grap-1.43/grap.defines000640 004133 000000 00000000774 07404051124 015071 0ustar00faberwheel000000 000000 .G1 .\" This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT .\" for the full copyright and limitations of liabilities. define delta {"\(*D" size 8} define bullet {"\v'0.1m'\(bu\v'-0.1m'" size 9} define vtick {"|" size 8} define square {"\(sq" size 8} .\"define box {"\f(ZD\s8\N'110'\s0\fP"} define box {"\f(ZD\N'110'\fP" size 8} define times {"\(mu" size 8} define htick {"\(em" size 8} define plus {"\(pl" size 8} define star {"\(**" size 8} define dot {"\v'-0.2m'.\v'0.2m'" size 8} .G2 grap-1.43/grap.doc000640 004133 000000 00000104741 11016431761 014223 0ustar00faberwheel000000 000000 .\"-*-nroff-*- .\" This file is (c) 1998-2006 Ted Faber (faber@lunabase.org) see .\" COPYRIGHT for the full copyright and limitations of liabilities. .Dd March 11, 2006 .Os .Dt GRAP 1 .Sh NAME .Nm grap .Nd Kernighan and Bentley's language for typesetting graphs .Sh SYNOPSIS .Nm .Op Fl d Ar defines_file .Op Fl D .Op Fl l .Op Fl M Ar include path .Op Fl R .Op Fl r .Op Fl v .Op Fl u .Op Fl C .Op Fl c .Op Fl h .Op Ar filename ... .Sh DESCRIPTION .Nm is an implementation of Kernighan and Bentley's language for typesetting graphs, as described in ``Grap-A Language for Typesetting Graphs, Tutorial and User Manual,'' by Jon L. Bentley and Brian W. Kernighan, revised May 1991, which is the primary source for information on how to use .Nm grap . As of this writing, it is available electronically at .Li http://www.kohala.com/start/troff/cstr114.ps . Additional documentation and examples, packaged with .Nm , may have been installed locally as well. If available, paths to them can be displayed using .Nm .Fl h or .Nm .Fl v (or .Nm .Fl -help / .Nm .Fl -version ) .Pp This version is a black box implementation of .Nm grap , and some inconsistencies are to be expected. The remainder of this manual page will briefly outline the .Nm language as implemented here. .Pp .Nm is a .Xr pic 1 pre-processor. It takes commands embedded in a .Xr troff 1 source file which are surrounded by .Ic .G1 and .Ic .G2 macros, and rewrites them into .Xr pic commands to display the graph. Other lines are copied. Output is always to the standard output, which is usually redirected. Input is from the given .Ar filename Ns No s , which are read in order. A .Ar filename of .Fl is the standard input. If no .Ar filename Ns No s are given, input is read from the standard input. .Pp Because .Nm is a .Xr pic preprocessor, and GNU .Xr pic will output TeX, it is possible to use .Nm with TeX. .Pp The .Fl d option specifies a file of macro definitions to be read at startup, and defaults to /usr/local/share/grap/grap.defines . The .Fl D option inhibits the reading of any initial macros file (the .Fl l flag is a synonym for .Fl D , though I do not remember why). The defines file can also be given using the .Ev GRAP_DEFINES environment variable. (See below). .Pp .Fl v prints the version information on the standard output and exits. .Fl -version is a synonym for .Fl v . .Pp .Fl u makes labels unaligned by default. This version of .Nm uses new features of GNU .Xr pic to align the left and right labels with the axes, that is that the left and right labels run at right angles to the text of the paper. This may be useful in porting old .Nm programs. .Fl c makes plot strings unclipped by default. Some versions of .Nm allow users to place a string anywhere in the coordinate space, rather than only in the frame. By default this version of .Nm does not plot any string centered outside the frame. .Fl c allows strings to be placed anywhere. See also the .Ic clipped and .Ic unclipped string modifiers described in the .Ic plot statement. .Pp .Fl M is followed by a colon-separated list of directories used to search for relative pathnames included via .Ic copy . The path is also used to locate the defines file, so if the .Fl d changes the defines file name to a relative name, it will be searched for in the path given by .Fl M . The search path always includes the current directory, and by default that directory is searched last. .Pp All numbers used internally by .Nm are double precision floating point values. Sometimes using floating point numbers has unintended consequences. To help avoid these problems, .Nm can use two thresholds for comparison of floating point numbers, set by .Fl R or .Fl r . The .Fl R flag sets coarse comparison mode, which is suitable for most applications. If you are plotting small values \(en less than 1e-6 or so \(en consider using .Fl r which uses very fine comparisons between numbers. You may also want to rescale your plotted values to be larger in magnitude. The coarse comarisons are used by default. .Pp To be precise, the value by which two numbers must differ for .Nm to consider them not equal is called the comparison limit and the smallest non-zero number is called the minimum value. The values a given version of .Nm uses for these are included in the output of .Fl v or .Fl h . .Pp All .Nm commands are included between .Ic .G1 and .Ic .G2 macros, which are consumed by .Nm grap . The output contains .Xr pic between .Ic .PS and .Ic .PE macros. Any arguments to the .Ic .G1 macro in the input are arguments to the .Ic .PS macro in the output, so graphs can be scaled just like .Xr pic diagrams. If .Fl C is given, any macro beginning with \&.G1 or \&.G2 is treated as a \&.G1 or \&.G2 macro, for compatibility with old versions of troff. Using .Fl C also forces pure troff syntax on embedded font change commands when strings have the .Ic size attribute, and all strings to be .Ic unclipped . .Pp The .Fl h flag prints a brief help message and exits. .Fl -help is a synonym for .Fl h . .Pp It is possible for someone to cause .Nm to fail by passing a bad format string and data to the .Ic sprintf command. If .Nm is integrated as part of the printing system, this could conceivably provided a path to breaching security on the machine. If you choose to use .Nm as part of a printing system run by the super-user, you should disable .Ic sprintf commands. This can be done by calling .Nm with the .Fl S flag, setting the .Ev GRAP_SAFER environment variable, or compiling with the GRAP_SAFER preprocessor symbol defined. (The GNU configure script included with .Nm will define that preprocessor symbol if the .Fl -with-grap-safe option is given.) .Pp The .Nm commands are sketched below. Refer to Kernighan and Bentley's paper for the details. .Pp New versions of .Xr groff 1 will invoke .Nm if .Fl G is given. .Ss Commands .Pp Commands are separated from one another by newlines or semicolons (;). .Pp .Ic frame .Op Ar line_description .Oo .Bk -words .Cm ht Ar height No \(or Cm wid Ar width .Ek .Oc .Oo .Bk -words .Oo .Sm off .Cm ( top No \(or Cm bottom No \(or .Cm left No \(or .Sm on .Cm right ) .Ar line_description .Ek .Oc \&... .Oc .sp .Ic frame .Oo .Bk -words .Cm ht Ar height No \(or Cm wid Ar width .Ek .Oc .Op Ar line_description .Oo .Bk -words .Oo .Sm off .Cm ( top No \(or Cm bottom No \(or .Cm left No \(or .Sm on .Cm right ) .Ar line_description .Ek .Oc \&... .Oc .Bd -filled -offset indent This describes how the axes for the graph are drawn. A .Ar line_description is a .Xr pic line description, e.g., .Li dashed .Li 0.5 , or the literal .Li solid . It may also include a .Ic color keyword followed by the color to draw the string in double quotes. Any color understood by the underlying groff system can be used. Color can only be used under GNU pic, and is not available in compatibility mode. Similarly, for pic implementations that understand .Ic thickness , that attribute may be used with a real valued parameter. .Ic Thickness is not available in compatibility mode. .Pp If the first .Ar line_description is given, the frame is drawn with that style. The default is .Li solid . The height and width of the frame can also be specified in inches. The default line style can be over-ridden for sides of the frame by specifying additional parameters to .Ic frame . .Pp If no plotting commands have been given before the .Ic frame command is issued, the frame will be output at that point in the plotting stream relative to embedded .Xr troff or .Xr pic commands. Otherwise the frame is output before the first plotted object (even invisible ones). .Pp .Ic ht and .Ic wid are in inches by default, but can be any .Xr groff unit. If omitted, the dimensions are 2 inches high by 3 inches wide. .Ed .Pp .Ic coord .Op Ar name .Op Cm x Ar expr , expr .Op Cm y Ar expr , expr .Oo .Cm log x No \(or .Cm log y No \(or .Cm log log .Oc .Bd -filled -offset indent The .Ic coord command specifies a new coordinate system or sets limits on the default system. It defines the largest and smallest values that can be plotted, and therefore the scale of the data in the frame. The limits for the x and y coordinate systems can be given separately. If a .Ar name is given, that coordinate system is defined, if not the default system is modified. .Pp A coordinate system created by one .Ic coord command may be modified by subsequent .Ic coord commands. A .Nm program may declare a coordinate space using .Ic coord , .Ic copy a file of data through a macro that plots the data and finds its maxima and minima, and then define the size of the coordinate system with a second .Ic coord statement. .Pp This command also determines if a scale is plotted logarithmically. .Cm log log means the same thing as .Cm log x log y . .Ed .Pp .Ic draw .Op Ar line_name .Op Ar line_description .Op Ar plot_string .Bd -filled -offset indent The .Ic draw command defines the style with which a given line will be plotted. If .Ar line_name is given, the style is associated with that name, otherwise the default style is set. .Ar line_description is a .Xr pic line description, and the optional .Ar plot_string is a string to be centered at each point. The default line description is .Li invis , and the default plotting string is a centered bullet, so by default each point is a filled circle, and they are unconnected. If points are being connected, each .Ic draw command ends any current line and begins a new one. .Pp When defining a line style, that is the first .Ic draw command for a given line name, specifying no plot string means that there are to be no plot strings. Omitting the plot string on subsequent .Ic draw commands addressing the same named line means not to change the plot string. If a line has been defined with a plot string, and the format is changed by a subsequent .Ic draw statement, the plot string can be removed by specifying "" in the .Ic draw statement. .Pp The plot string can have its format changed through several string_modifiers. String_modifiers are described in the description of the .Ic plot command. .Pp The standard defines file includes several macros useful as plot strings, including .Ic bullet , .Ic square , and .Ic delta . .Pp .Ic new is a synonym for .Ic draw . .Ed .Pp .Ic next .Op Ar line_name .Cm at .Op Ar coordinates_name .Ar expr , expr .Op Ar line_description .Bd -filled -offset indent The .Ic next command plots the given point using the line style given by .Ar line_name , or the default if none is given. If .Ar line_name is given, it should have been defined by an earlier .Ic draw command, if not a new line style with that name is created, initialized the same way as the default style. The two expressions give the point's x and y values, relative to the optional coordinate system. That system should have been defined by an earlier .Ic coord command, if not, grap will exit. If the optional .Ar line_description is given, it overrides the style's default line description. You cannot over-ride the plotting string. To use a different plotting string use the .Ic plot command. .Pp The coordinates may optionally be enclosed in parentheses: .Ar ( expr , expr ) .Ed .Pp .Ar quoted_string .Op Ar string_modifiers .Oo .No , Ar quoted_string .Oo .Ar string_modifiers .Oc .Oc \&... .Cm at .Op Ar coordinates_name .Ar expr , expr .Pp .Ic plot .Ar expr .Op Ar format_string .Cm at .Op Ar coordinates_name .Ar expr , expr .Bd -filled -offset indent These commands both plot a string at the given point. In the first case the literal strings are stacked above each other. The string_modifiers include the .Xr pic justification modifiers .Ns No ( Ic ljust , .Ic rjust , .Ic above , and .Ic below Ns No ), and absolute and relative .Li size modifiers. See the .Xr pic documentation for the description of the justification modifiers. .Nm also supports the .Ic aligned and .Ic unaligned modifiers which are briefly noted in the description of the .Ic label command. .Pp The standard defines file includes several macros useful as plot strings, including .Ic bullet , .Ic square , and .Ic delta . .Pp Strings placed by either format of the .Ic plot command are restricted to being within the frame. This can be overriden by using the .Ic unclipped attribute, which allows a string to be plotted in or out of the frame. The .Fl c and .Fl C flags set .Ic unclipped on all strings, and to prevent a string from being plotted outside the frame when those flags are active, the .Ic clipped attribute can be used to retore clipping behavior. Though .Ic clipped or .Ic unclipped can be applied to any string, it only has meaning for .Ic plot statements. .Pp .Li size .Ar expr sets the string size to .Ar expr points. If .Ar expr is preceded by a + or -, the size is increased or decreased by that many points. .Pp If .Ic color and a color name in double quotes appears, the string will be rendered in that color under a version of GNU troff that supports color. Color is not available in compatibility mode. .Pp In the second version, the .Ar expr is converted to a string and placed on the graph. .Ar format_string is a .Xr printf 3 format string. Only formatting escapes for printing floating point numbers make sense. The format string is only respected if the .Ic sprintf command is also active. See the description of .Ic sprintf for the various ways to disable it. .Ic Plot and .Ic sprintf respond differently when .Nm is running safely. .Ic Sprintf ignores any arguments, passing the format string through without substitution. .Ic plot ignores the format string completely, plotting .Ar expr using the .Qq %g format. .Pp Points are specified the same way as for .Ic next commands, with the same consequences for undefined coordinate systems. .Pp The second form of this command is because the first form can be used with a .Nm .Ic sprintf expression (See .Sx Expressions ) . .Ed .Pp .Ic ticks .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Oo .Sm on .Xo ( Cm in Ns No \(or Ns Cm out ) .Xc .Op Ar expr .Oc .Sm off .Oo .Cm on \(or Cm auto .Sm on .Ar coord_name .Oc .Pp .Ic ticks .Sm off .Xo ( Cm left No \(or Cm right No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Xo ( Cm in Ns No \(or Ns Cm out ) .Xc .Op Ar expr .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm at .Op Ar coord_name .Ar expr .Op Ar format_string .Oo .Oo .No , Ar expr .Oo .Ar format_string .Oc .Oc .No ... .Oc .Pp .Ic ticks .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Xo ( Cm in Ns No \(or Ns Cm out ) .Xc .Op Ar expr .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm from .Op coord_name .Ar start_expr .Cm to .Ar end_expr .Oo .Cm by .Sm off .Oo .No + \(or - \(or * \(or / .Sm on .Oc .Ar by_expr .Oc .Op format_string .Pp .Ic ticks .Sm off .Oo .Cm left Xo No \(or Cm right .No \(or Cm top No \(or Cm bottom .Oc .Xc .Sm on .Cm off .Bd -filled -offset indent This command controls the placement of ticks on the frame. By default, ticks are automatically generated on the left and bottom sides of the frame. .Pp The first version of this command turns on the automatic tick generation for a given side. The .Cm in or .Cm out parameter controls the direction and length of the ticks. If a .Ar coord_name is specified, the ticks are automatically generated using that coordinate system. If no system is specified, the default coordinate system is used. As with .Ic next and .Ic plot , the coordinate system must be declared before the .Ic ticks statement that references it. This syntax for requesting automatically generated ticks is an extension, and will not port to older .Nm implementations. .Pp The second version of the .Ic ticks command overrides the automatic placement of the ticks by specifying a list of coordinates at which to place the ticks. If the ticks are not defined with respect to the default coordinate system, the .Ar coord_name parameter must be given. For each tick a .Xr printf 3 style format string can be given. The .Ar format_string defaults to .Qq %g . The format string can also take string modifiers as described in the .Ic plot command. To place ticks with no labels, specify .Ar format_string as .Qq \& . .Pp If .Ic sprintf is disabled, .Ic ticks behaves as .Ic plot with respect to the format string. .Pp The labels on the ticks may be shifted by specifying a direction and the distance in inches to offset the label. That is the optional direction and expression immediately preceding the .Cm at . .Pp The third format of the .Ic ticks command over-rides the default tick generation with a set of ticks ar regular intervals. The syntax is reminiscent of programming language for loops. Ticks are placed starting at .Ar start_expr ending at .Ar end_expr one unit apart. If the .Cm by clause is specified, ticks are .Ar by_expr units apart. If an operator appears before .Ar by_expr each tick is operated on by that operator instead of +. For example .Bd -literal -offset indent-two ticks left out from 2 to 32 by *2 .Ed .Pp will put ticks at 2, 4, 8, 16, and 32. If .Ar format_string is specified, all ticks are formatted using it. .Pp The parameters preceding the .Cm from act as described above. .Pp The .Cm at and .Cm for forms of tick command may both be issued on the same side of a frame. For example: .Bd -literal -offset indent-two ticks left out from 2 to 32 by *2 ticks left in 3, 5, 7 .Ed .Pp will put ticks on the left side of the frame pointing out at 2, 4, 8, 16, and 32 and in at 3, 5, and 7. .Pp The final form of .Ic ticks turns off ticks on a given side. If no side is given the ticks for all sides are cancelled. .Pp .Ic tick is a synonym for .Ic ticks . .Ed .Pp .Ic grid .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Op Li ticks off .Op Ar line_description .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Oo .Sm off .Cm on \(or Cm auto .Sm on .Op Ar coord_name .Oc .Pp .Ic grid .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Op Li ticks off .Op Ar line_description .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm at .Op Ar coord_name .Ar expr .Op Ar format_string .Oo .Oo .No , Ar expr .Oo .Ar format_string .Oc .Oc .No ... .Oc .Pp .Ic grid .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Op Li ticks off .Op Ar line_description .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm from .Op coord_name .Ar start_expr .Cm to .Ar end_expr .Oo .Cm by .Sm off .Oo .No + \(or - \(or * \(or / .Sm on .Oc .Ar by_expr .Oc .Op format_string .Bd -filled -offset indent The .Ic grid command is similar to the .Ic ticks command except that .Ic grid specifies the placement of lines in the frame. The syntax is similar to .Ic ticks as well. .Pp By specifying .Li ticks off in the command, no ticks are drawn on that side of the frame. If ticks appear on a side by default, or have been declared by an earlier .Ic ticks command, .Ic grid does not cancel them unless .Li ticks off is specified. .Pp Instead of a direction for ticks, .Ic grid allows the user to pick a line description for the grid lines. The usual .Xr pic line descriptions are allowed. .Pp Grids are labelled by default. To omit labels, specify the format string as .Qq \& . .Pp If .Ic sprintf is disabled, .Ic grid behaves as .Ic plot with respect to the format string. .Ed .Pp .Ic label .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Ar quoted_string .Op Ar string_modifiers .Oo .No , Ar quoted_string .Oo .Ar string_modifiers .Oc .Oc \&... .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Bd -filled -offset indent The .Ic label command places a label on the given axis. It is possible to specify several labels, which will be stacked over each other as in .Xr pic . The final argument, if present, specifies how many inches the label is shifted from the axis. .Pp By default the labels on the left and right labels run parallel to the frame. You can cancel this by specifying .Li unaligned as a .Ar string_modifier . .Ed .Pp .Ic circle .Cm at .Op Ar coordinate_name .Ar expr , expr .Op Cm radius Ar expr .Op Ar linedesc .Bd -filled -offset indent This draws an circle at the point indicated. By default, the circle is small, 0.025 inches. This can be over-ridden by specifying a radius. The coordinates of the point are relative to the named coordinate system, or the default system if none is specified. .Pp This command has been extended to take a line description, e.g., .Li dotted . It also accepts the filling extensions described below in the .Ic bar command. It will also accept a .Ic color keyword that gives the color of the outline of the circle in double quotes and a .Ic fillcolor command that sets the color to fill the circle with similarly. Colors are only available when compatibility mode is off, and using a version of GNU pic that supports color. .Ed .Pp .Ic line .Op Ar line_description .Cm from .Op Ar coordinate_name .Ar expr , expr .Cm to .Op Ar coordinate_name .Ar expr , expr .Op Ar line_description .Pp .Ic arrow .Op Ar line_description .Cm from .Op Ar coordinate_name .Ar expr , expr .Cm to .Op Ar coordinate_name .Ar expr , expr .Op Ar line_description .Bd -filled -offset indent This draws a line or arrow from the first point to the second using the given style. The default line style is .Li solid . The .Ar line_description can be given either before the .Cm from or after the .Cm to clause. If both are given the second is used. It is possible to specify one point in one coordinate system and one in another, note that if both points are in a named coordinate system (even if they are in the same named coordinate system), both points must have .Ar coordinate_name given. .Ed .Pp .Pp .Ic copy .Op Qq Ar filename .Op Cm until Qq Ar string .Op Cm thru Ar macro .Bd -filled -offset indent The .Ic copy command imports data from another file into the current graph. The form with only a filename given is a simple file inclusion; the included file is simply read into the input stream and can contain arbitrary .Nm commands. The more common case is that it is a number list; see .Sx Number Lists below. .Pp The second form takes lines from the file, splits them into words delimited by one or more spaces, and calls the given macro with those words as parameters. The macro may either be defined here, or be a macro defined earlier. See .Sx Macros for more information on macros. .Pp The .Ar filename may be omitted if the .Cm until clause is present. If so the current file is treated as the input file until .Ar string is encountered at the beginning of the line. .Pp .Ic copy is one of the workhorses of .Nm grap . Check out the paper and .Pa /usr/local/share/examples/grap for more details. Confirm the location of the examples directory using the .Fl v flag. .Ed .Ic print .Sm off .Ar ( expr \(or string ) .Sm on .Bd -filled -offset indent Prints its argument to the standard error. .Ed .Pp .Ic sh Ar block .Bd -filled -offset indent This passes .Ar block to .Xr sh 1 . Unlike K&B .Nm no macro or variable expansion is done. I believe that this is also true for GNU .Xr pic version 1.10. See the .Sx Macros section for information on defining blocks. .Ed .Pp .Ic pic Ar pic_statement .Bd -filled -offset indent This issues the given .Xr pic statements in the enclosing .Ic .PS and .Ic .PE at the point where the command is issued. .Pp Statements that begin with a period are considered to be .Xr troff statements and are output in the enclosing .Ic .PS and .Ic .PE at the point where the command appears. .Pp For the purposes of relative placement of .Xr pic or .Xr troff commands, the frame is output immediately before the first plotted object, or the .Ic frame statement, if any. If the user specifies .Xr pic or .Xr troff commands and neither any plotable object nor a .Ic frame command, the commands will not be output. .Ed .Pp .Ic graph Ar Name pic_commands .Bd -filled -offset indent This command is used to position graphs with respect to each other. The current graph is given the .Xr pic name .Ar Name (names used by .Xr pic begin with capital letters). Any .Xr pic commands following the graph are used to position the next graph. The frame of the graph is available for use with .Xr pic name .Li Frame. The following places a second graph below the first: .Bd -literal -offset indent-two graph Linear [ graph description ] graph Exponential with .Frame.n at \\ Linear.Frame.s - (0, .05) [ graph description ] .Ed .Ed .Pp .Ar name = expr .Bd -filled -offset indent This assigns .Ar expr to the variable .Ar name . .Nm has only numeric (double) variables. .Pp Assignment creates a variable if it does not exist. Variables persist across graphs. Assignments can cascade; .Li a = b = 35 assigns 35 to .Li a and .Li b . .Ed .Pp .Ic bar .Sm off .No ( Cm up No \(or Cm right ) .Sm on .Op Ar coordinates_name .Ar offset .Cm ht .Ar height .Op Cm wid Ar width .Op Cm base Ar base_offset .Op Ar line_description .Pp .Ic bar .Op Ar coordinates_name .Ar expr , expr , .Op Ar coordinates_name .Ar expr , expr , .Op Ar line_description .Bd -filled -offset indent The .Ic bar command facilitates drawing bar graphs. The first form of the command describes the bar somewhat generally and has .Nm place it. The bar may extend up or to the right, is centered on .Ar offset and extends up or right .Ar height units (in the given coordinate system). For example .Bd -literal -offset indent-two bar up 3 ht 2 .Ed .Pp draws a 2 unit high bar sitting on the x axis, centered on x=3. By default bars are 1 unit wide, but this can be changed with the .Ic wid keyword. By default bars sit on the base axis, i.e., bars directed up will extend from y=0. That may be overridden by the .Ic base keyword. (The bar described above has corners (2.5, 0) and (3.5, 2).) .Pp The line description has been extended to include a .Ic fill Ar expr keyword that specifies the shading inside the bar. Bars may be drawn in any line style. They support the .Ic color and .Ic fillcolor keywords described under .Ic circle . .Pp The second form of the command draws a box with the two points as corners. This can be used to draw boxes highlighting certain data as well as bar graphs. Note that filled bars will cover data drawn under them. .Ed .Ss Control Flow .Pp .Ic if Ar expr Ic then Ar block .Op Ic else Ar block .Bd -filled -offset indent The .Ic if statement provides simple conditional execution. If .Ar expr is non-zero, the .Ar block after the .Ic then statement is executed. If not the .Ar block after the .Ic else is executed, if present. See .Sx Macros for the definition of blocks. Early versions of this implementation of .Nm treated the blocks as macros that were defined and expanded in place. This led to unnecessary confusion because explicit separators were sometimes called for. Now, .Nm inserts a separator (;) after the last character in .Ar block , so constructs like .Bd -literal if (x == 3) { y = y + 1 } x = x + 1 .Ed behave as expected. A separator is also appended to the end of a .Ic for block. .Ed .Pp .Ic for Ar name Ic from Ar from_expr Ic to Ar to_expr .Oo .Ic by .Op No +\(or-\(or*\(or/ .Ar by_expr .Oc .Ic do .Ar block .Bd -filled -offset indent This command executes .Ar block iteratively. The variable .Ar name is set to .Ar from_expr and incremented by .Ar by_expr until it exceeds .Ar to_expr . The iteration has the semantics defined in the .Ic ticks command. The definition of .Ar block is discussed in .Sx Marcos . See also the note about implicit separators in the description of the .Ic if command. .Pp An .Ic = can be used in place of .Ic from . .Ed .Ss Expressions .Pp .Nm supports most standard arithmetic operators: + - / * ^. The carat (^) is exponentiation. In an .Ic if statement .Nm also supports the C logical operators ==, !=, &&, || and unary !. Also in an .Ic if , == and != are overloaded for the comparison of quoted strings. Parentheses are used for grouping. .Pp Assignment is not allowed in an expression in any context, except for simple cascading of assignments. .Li a = b = 35 works as expected; .Li a = 3.5 * (b = 10) does not execute. .Pp .Nm supports the following functions that take one argument: .Ic log , exp , int , sin , cos , sqrt , rand . The logarithms are base 10 and the trigonometric functions are in radians. .Ic eexp returns Euler's number to the given power and .Ic ln returns the natural logarithm. The natural log and exponentiation functions are extensions and are probably not available in other .Nm implementations. .Pp .Ic rand returns a random number uniformly distributed on [0,1). The following two-argument functions are supported: .Ic atan2 , min , max . .Ic atan2 works just like .Xr atan2 3 . The random number generator can be seeded by calling .Ic srand with a single parameter (converted internally to an integer). Because its return value is of no use, you must use .Ic srand as a separate statement, it is not part of a valid expression. .Ic srand is not portable. .Pp The .Ic getpid function takes no arguments and returns the process id. This may be used to seed the random number generator, but do not expect cryptographically random values to result. .Pp Other than string comparison, no expressions can use strings. One string valued function exists: .Ic sprintf ( Ar format , .Oo .Ar expr .Op Ar \&, expr .Oc ). It operates like .Xr sprintf 3 , except returning the value. It can be used anywhere a quoted string is used. If .Nm is run with .Fl S , the environment variable .Ev GRAP_SAFER is defined, or .Nm has been compiled for safer operation, the .Ic sprintf command will return the format string. This mode of operation is only intended to be used only if .Nm is being used as part of a super-user enabled print system. .Ss Macros .Nm has a simple but powerful macro facility. Macros are defined using the .Ic define command : .Pp .Ic define Ar name block .br .Ic undefine Ar name .Bd -filled -offset indent Every occurrence of .Ar name in the program text is replaced by the contents of .Ar block . .Ar block is defined by a series of statements in nested { }'s, or a series of statements surrounded by the same letter. An example of the latter is .Bd -literal -offset indent-two define foo X coord x 1,3 X .Ed Each time .Li foo appears in the text, it will be replaced by .Li coord x 1,3 . Macros are literal, and can contain newlines. If a macro does not span multiple lines, it should end in a semicolon to avoid parsing errors. .Pp Macros can take parameters, too. If a macro call is followed by a parenthesized, comma-separated list the values starting with $1 will be replaced in the macro with the elements of the list. A $ not followed by a digit is left unchanged. This parsing is very rudimentary; no nesting or parentheses or escaping of commas is allowed. Also, there is no way to say argument 1 followed by a digit (${1}0 in sh(1)). .Pp The following will draw a line with slope 1. .Bd -literal -offset indent-two define foo { next at $1, $2 } for i from 1 to 5 { foo(i,i) } .Ed Macros persist across graphs. The file .Pa /usr/local/share/grap/grap.defines contains simple macros for plotting common characters. The .Ic undefine command deletes a macro. .Pp See the directory .Pa /usr/local/share/examples/grap for more examples of macros. Confirm the location of the examples directory using the .Fl v flag. .Ed .Ss Number Lists .Pp A whitespace-separated list of numbers is treated specially. The list is taken to be points to be plotted using the default line style on the default coordinate system. If more than two numbers are given, the extra numbers are taken to be additional y values to plot at the first x value. Number lists in DWB .Nm can be comma-separated, and this .Nm supports that as well. More precisely, numbers in number lists can be separated by either whitespace, commas, or both. .Bd -literal -offset indent 1 2 3 4 5 6 .Ed .sp Will plot points using the default line style at (1,2), (1,3),(4,5) and (4,6). A simple way to plot a set of numbers in a file named .Pa ./data is: .Bd -literal -offset indent \&.G1 copy "./data" \&.G2 .Ed .Ss Pic Macros .Pp .Nm defines pic macros that can be used in embedded pic code to place elements in the graph. The macros are .Ic x_gg , .Ic y_gg , and .Ic xy_gg . These macros define pic distances that correspond to the given argument. They can be used to size boxes or to plot pic constructs on the graph. To place a given construct on the graph, you should add Frame.Origin to it. Other coordinate spaces can be used by replacing .Ic gg with the name of the coordinate space. A coordinate space named .Ic gg cannot be reliably accessed by these macros. .Pp The macros are emitted immediately before the frame is drawn. .Pp DWB .Nm may use these as part of its implementation. This .Nm provides them only for compatibility. Note that these are very simple macros, and may not do what you expect under complex conditions. .Sh ENVIRONMENT VARIABLES .Pp If the environment variable .Ev GRAP_DEFINES is defined, .Nm will look for its defines file there. If that value is a relative path name the path specified in the .Fl M option will be searched for it. .Ev GRAP_DEFINES overrides the compiled in location of the defines file, but may be overridden by the .Fl d or .Fl D flags. .Pp If .Ev GRAP_SAFER is set, .Ic sprintf is disabled to prevent forcing .Nm to core dump or smash the stack. .Sh FILES .Pa /usr/local/share/grap/grap.defines .Sh SEE ALSO .Xr atan2 3 , .Xr groff 1 , .Xr pic 1 , .Xr printf 3 , .Xr sh 1 , .Xr sprintf 3 , .Xr troff 1 .Pp If documentation and examples have been installed, .Nm .Fl -version or .Nm .Fl -help will display the locations. .Sh BUGS .Pp There are several small incompatibilities with K&R .Nm grap . They include the .Ic sh command not expanding variables and macros, and a more strict adherence to parameter order in the internal commands. .Pp Although much improved, the error reporting code can still be confused. Notably, an error in a macro is not detected until the macro is used, and it produces unusual output in the error message. .Pp Iterating many times over a macro with no newlines can run .Nm out of memory. .Sh AUTHOR This implementation was done by .An Ted Faber Ao faber@lunabase.org Ac Ns . .An Bruce Lilly Ao blilly@erols.com Ac contributed many bug fixes, including a considerable revamp of the error reporting code. If you can actually find an error in your .Nm code, you can probably thank him. .Nm was designed and specified by .An Brian Kernighan and .An Jon Bentley . grap-1.43/grap_data.h000640 004133 000000 00000007035 10251747431 014700 0ustar00faberwheel000000 000000 //-*-c++-*- #ifndef GRAP_DATA_H #define GRAP_DATA_H // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. #ifdef STDC_HEADERS #include #endif #include #include #include inline void unquote(string *s) { int i; if ( (*s)[0] == '"' ) s->erase(0,1); i = s->length()-1; if ( (*s)[i] == '"' ) s->erase(i,1); } inline void quote(string *s) { s->insert((string::size_type) 0,1,'"'); s->append(1,'"'); } class macro { public: int next_arg; // the index into the next argument string *text; // the text of the macro vector arg; // The current argument values string *name; // the name of the macro if it's in a // dictionary. macro(string *t=0, string *n =0) : next_arg(0), text(t), arg(), name(n) { } ~macro() { delete text; text = 0; delete name; name = 0; while ( !arg.empty() ) { string *d = arg.back(); arg.pop_back(); delete d; } } int add_arg(string *s ) { arg.push_back(s); return 1; } string *invoke() { string *s = new string; // The expanded macro int argn =0; // the number of the arg to interpolate int dig; // Number of digits seen after this $ int i=0; // the current character offset const int lim=text->length();// number of characters to check while (i < lim ) { switch ((*text)[i] ) { default: *s += (*text)[i++]; break; case '$': dig = 0; i++; while (isdigit((*text)[i])) { argn *= 10; argn += (*text)[i] - 0x30; i++; dig++; } if ( argn > 0 && argn <= (int) arg.size() ) { if ( arg[argn-1] ) *s += *(arg[argn-1]); } argn = 0; // If there was no digit after the $ leave the $ // untouched and leave i as the offset of the // character immediately following the $ if ( !dig ) { *s += '$'; } break; } } next_arg = 0; while ( !arg.empty() ) { string *d = arg.back(); arg.pop_back(); delete d; } return s; } }; class copydesc { public: typedef enum { fname, until} type; type t; string *s; copydesc() : t(fname), s(0) {} ~copydesc() { if ( s ) { delete s; s = 0; } } }; // encapsulate the information about the simple keyword tokens. class keyword { public: vector add; // make these keywords active vector remove; // make these keywords inactive bool clear; // clear the active keyword list if this true int token; // the lex token that corresponds to this // string. keyword() : add(), remove(), clear(false), token(0) { } keyword(const keyword& k) : add(k.add), remove(k.remove), clear(k.clear), token(k.token) { } keyword(const vector& a, const vector& r, bool cl, int t) : add(a), remove(r), clear(cl), token(t) { } template keyword(I1 sa, I1 ea, I2 sr, I2 er, bool cl, int t) : add(sa, ea), remove(sr, er), clear(cl), token(t) { } keyword& operator=(const keyword& k) { add = k.add; remove = k.remove; clear = k.clear; token = k.token; return *this; } }; // we use this to make yacc happier typedef pair coordid; // bar parameter types class bar_param { public: double x; double ht; double wid; double base; bool have_x; bool have_ht; bar_param() : x(0.0), ht(0.0), wid(1.0), base(0.0), have_x(false), have_ht(false) { } }; #endif grap-1.43/grap.h000660 004133 000000 00000012573 11076024521 013706 0ustar00faberwheel000000 000000 // -*-c++-*- #ifndef GRAP_H #define GRAP_H // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. #ifndef DEFINES #define DEFINES "/usr/share/grap/grap.defines" #endif #ifndef STDC_HEADERS extern "C" { #ifndef __GNUC__ size_t strlen(const char*); char *strcpy(char *, const char *); int strcmp(const char *, const char *); #endif char *strcat(char *, const char *); char *strncpy(char *, const char *, const size_t); int strncmp(const char *, const char *, const size_t); }; #endif #ifndef HAVE_SNPRINTF #include "snprintf.h" #else // AIX seems to have snprintf, but not prototype it.. #ifndef SNPRINTF_DECLARED extern "C" { int snprintf(char *, size_t, const char *, ...); } #endif #endif using namespace std; #include #include #include #include class DisplayString; class line; class coord; class macro; class plot; class tick; class grid; class circle; class shiftdesc; class keyword; #if HAVE_HASH_MAP||HAVE_EXT_HASH_MAP||HAVE_UNORDERED_MAP #ifdef HAVE_UNORDERED_MAP #include typedef HASH_SPACE::unordered_map doubleDictionary; typedef HASH_SPACE::unordered_map coordinateDictionary; typedef HASH_SPACE::unordered_map lineDictionary; typedef HASH_SPACE::unordered_map macroDictionary; typedef HASH_SPACE::unordered_map keywordDictionary; #else #ifdef HAVE_HASH_MAP #include #else #include #endif // A functor for hashing strings - it is an adapter to get to the // standard library char * hash function. class Strhash : public unary_function { private: HASH_SPACE::hash h; public: size_t operator()(const string& s) const { return h(s.c_str()); } }; typedef HASH_SPACE::hash_map doubleDictionary; typedef HASH_SPACE::hash_map coordinateDictionary; typedef HASH_SPACE::hash_map lineDictionary; typedef HASH_SPACE::hash_map macroDictionary; typedef HASH_SPACE::hash_map keywordDictionary; #endif #else #include typedef less Strcmp; typedef map doubleDictionary; typedef map coordinateDictionary; typedef map lineDictionary; typedef map macroDictionary; typedef map keywordDictionary; #endif typedef list plotSequence; typedef vector doublevec; typedef list doublelist; typedef list ticklist; typedef list gridlist; typedef list linelist; typedef list stringSequence; typedef list circleSequence; typedef list lexStack; typedef list stringlist; typedef list shiftlist; // number of functions taking 0,1,2 args. The names of those // functions are in grap_lex.l and the implementations in the // jumptables in grap.y const int NVF1=1; const int NF0=2; const int NF1=8; const int NF2=3; enum size { ht = 0, wid}; typedef struct { int op; double expr; } bydesc; // this is complex enough to need a constructor/destructor class for_descriptor { public: double *loop_var; int dir; double limit; double by; int by_op; string *anything; for_descriptor() : loop_var(0), dir(0), limit(0.0), by(0.0), by_op(0), anything(0) { } for_descriptor(double *lv, int d, double l, double b, int bo, string *a) : loop_var(lv), dir(d), limit(l), by(b), by_op(bo), anything(a) { } ~for_descriptor() { if ( anything) { delete anything; anything = 0; } } }; typedef enum { GFILE=1, GMACRO, GINTERNAL } grap_input; class grap_buffer_state { public: struct yy_buffer_state *yy; for_descriptor *f; string *name; int line; int report_start; grap_input type; int tokenpos; grap_buffer_state() : yy(0), f(0), name(0), line(0), report_start(0), type(GFILE), tokenpos(0) { } grap_buffer_state(struct yy_buffer_state *yyb, for_descriptor *fo, string *n, int l, int rs, grap_input t, int tp=0) : yy(yyb), f(fo), name(n), line(l), report_start(rs), type(t), tokenpos(tp) { } // this does *not* call yy_delete_buffer ~grap_buffer_state() { if ( f ) { delete f; f = 0; } if ( name ) { delete name; name = 0; } } }; extern lexStack lexstack; // Set the coarse and fine limits for double comparisons. COARSE comparisons // are always within one millionth. If fine comarisons are requested, either // the values in limits are used or one trillionth (1e-12). #ifdef HAVE_LIMITS #include #define FINE_EPSILON numeric_limits::epsilon() #define FINE_MIN_DOUBLE numeric_limits::min() #define COARSE_EPSILON 1e-6 #define COARSE_MIN_DOUBLE 1e-6 #else #define FINE_EPSILON 1e-12 #define FINE_MIN_DOUBLE 1e-12 #define COARSE_EPSILON 1e-6 #define COARSE_MIN_DOUBLE 1e-6 #endif extern double epsilon; extern double min_double; #ifdef HAVE_RANDOM #ifndef RANDOM_DECLARED extern "C" { long random(); void srandom(unsigned long); } #endif #else #ifdef HAVE_RAND #define random rand #define srandom srand #ifndef RAND_DECLARED extern "C" { long rand(); void srand(unsigned); } #endif #endif #endif #endif grap-1.43/grap.y000640 004133 000000 00000067655 11073541237 013745 0ustar00faberwheel000000 000000 /* -*-c++-*- */ %{ /* This code is (c) 1998-2001 Ted Faber (faber@lunabase.org) see the COPYRIGHT file for the full copyright and limitations of liabilities. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef STDC_HEADERS #include #else // Best guess, really - limits should exist #ifndef LONG_MAX #define LONG_MAX 0x7fffffffL #endif #endif #if defined(STDC_HEADERS) | defined(HAVE_STDLIB_H) #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "grap.h" #include "grap_data.h" #include "grap_draw.h" doubleDictionary vars; graph *the_graph =0; lexStack lexstack; macroDictionary macros; stringSequence path; bool first_line; bool unaligned_default = false; // Should strings be unaligned by default bool clip_default = true; // Should strings be clipped by default extern bool do_sprintf; // true if it's acceptable to parse sprintf line* defline; coord *defcoord; string *graph_name; string *graph_pos; string *ps_param; // number of lines in a number list (used in grap_parse.cc) int nlines; // bison wants these defined.... int yyerror(const char*); int yylex(); void init_dict(); // defined in grap_lex.l extern bool include_file(string *, bool =false, bool=true); extern void lex_no_macro_expansion(); extern void lex_macro_expansion_ok(); extern void lex_begin_macro_text(); extern void lex_begin_rest_of_line(); extern void lex_no_coord(); extern void lex_coord_ok(); extern void lex_begin_copy( string*s=0); extern int include_string(string *,struct for_descriptor *f=0, grap_input i=GMACRO); extern void lex_hunt_macro(); extern int yyparse(void); // To shut yacc (vs. bison) up. void draw_graph(); void init_graph(); // Parsing utilities in grap_parse.cc. Locating them there reduces // compilation time (this file was getting very large) and eliminates // some code redundancy. extern graph *initial_graph(); extern linedesc* combine_linedesc(linedesc *, linedesc*); extern axis combine_logs(axis, axis); extern void draw_statement(string *, linedesc *, DisplayString *); extern void num_list(doublelist *); extern double assignment_statement(string *, double); extern stringlist *combine_strings(stringlist *, string *, strmod &); extern void plot_statement(double, DisplayString *, point *); extern void next_statement(string *, point *, linedesc *); extern ticklist *ticklist_elem(double, DisplayString *, ticklist *); extern ticklist *tick_for(coord *, double, double, bydesc, DisplayString *); extern void ticks_statement(sides, double, shiftlist *, ticklist *); extern void grid_statement(sides, int, linedesc *, shiftlist *, ticklist *); extern void line_statement(int, linedesc *, point *, point *, linedesc *); extern axisdesc axis_description(axis, double, double ); extern void coord_statement(string *, axisdesc&, axisdesc&, axis); extern void coord_statement(coord *, axisdesc&, axisdesc&, axis); extern void for_statement(string *, double, double, bydesc, string *); extern void process_frame(linedesc *, frame *, frame *); extern void define_macro(string *, string*); extern void bar_statement(coord *, sides, double, double, double, double, linedesc *); // adapters to return complex (complex-ish) functions void grap_srandom(double x) { srandom(static_cast(x)); } double grap_random() { return static_cast(random())/(static_cast(LONG_MAX)+1e-6); } double grap_getpid() { return static_cast(getpid());} double pow10(double x) { return pow(10,x); } double toint(double x) { return static_cast(int(x)); } double grap_min(double a, double b) { return (ab) ? a : b; } typedef void (*vfunction1)(double); typedef double (*function0)(); typedef double (*function1)(double); typedef double (*function2)(double, double); // jump tables for dispatching internal functions vfunction1 jtvf1[NVF1] = { grap_srandom }; function0 jtf0[NF0] = { grap_random, grap_getpid }; function1 jtf1[NF1] = { log10, pow10, toint, sin, cos, sqrt, exp, log }; function2 jtf2[NF2] = { atan2, grap_min, grap_max}; %} %token NUMBER START END IDENT COPY SEP STRING COORD_NAME UNDEFINE %token SOLID INVIS DOTTED DASHED DRAW LPAREN RPAREN FUNC0 FUNC1 FUNC2 COMMA %token LINE PLOT FROM TO AT NEXT FRAME LEFT RIGHT TOP BOTTOM UP DOWN HT WID %token IN OUT NONE TICKS OFF BY GRID LJUST RJUST ABOVE BELOW ALIGNED %token PLUS MINUS TIMES DIV CARAT EQUALS SIZE UNALIGNED LABEL RADIUS CIRCLE %token ARROW XDIM YDIM LOG_X LOG_Y LOG_LOG COORD TEXT DEFINE IF THEN ELSE %token EQ NEQ LT GT LTE GTE NOT OR AND FOR DO MACRO COPYTEXT THRU %token GRAPH REST PRINT PIC TROFF UNTIL COLOR SPRINTF SH BAR FILL FILLCOLOR %token BASE ON LHS VFUNC1 CLIPPED UNCLIPPED THICKNESS %start graphs %union { int val; double num; string *String; DisplayString *ds; frame *frameptr; shiftdesc *shift; shiftlist *shift_list; point *pt; linedesc *lined; stringlist *string_list; linelist *line_list; ticklist *tick_list; doublelist *double_list; doublevec *double_vec; macro *macro_val; coord *coordptr; line *lineptr; sides side; bydesc by; axisdesc axistype; axis axisname; strmod stringmod; copydesc *copyd; bar_param *bar_p; } %type NUMBER num_line_elem expr opt_expr direction radius_spec %type assignment_statement lexpr pure_lexpr right_hand_side %type strmod %type IDENT STRING opt_ident TEXT else_clause REST TROFF %type START string LHS %type opt_display_string %type VFUNC1 FUNC0 FUNC1 FUNC2 tickdir opt_tick_off line_token %type opt_coordname COORD_NAME autotick %type side bar_dir %type sides size size_elem final_size %type linedesc_elem linedesc opt_linedesc %type strlist %type num_line %type expr_list %type ticklist tickat tickfor tickdesc %type point coord_pair %type opt_shift %type shift %type by_clause %type x_axis_desc y_axis_desc %type log_list log_desc %type COPYTEXT %type MACRO %type until_clause %type bar_param bar_params %left OR AND %right NOT %left EQ NEQ LT GT LTE GTE %left PLUS MINUS %left TIMES DIV %left CARAT %% graphs: | graphs graph ; graph : START { if ( !the_graph) the_graph = initial_graph(); the_graph->init(); init_dict(); first_line = true; the_graph->begin_block($1); } prog END { the_graph->draw(0); the_graph->end_block(); } ; prog : { } | prog statement { } ; statement: assignment_statement { first_line = false;} | num_list { first_line = false; the_graph->is_visible(true);} | frame_statement { first_line = false; the_graph->queue_frame(); the_graph->is_visible(true); } | draw_statement { first_line = false; } | next_statement { first_line = false; the_graph->is_visible(true);} | plot_statement { first_line = false; the_graph->is_visible(true);} | ticks_statement { first_line = false; the_graph->is_visible(true);} | grid_statement { first_line = false; the_graph->is_visible(true);} | label_statement { first_line = false; the_graph->is_visible(true);} | circle_statement { first_line = false; the_graph->is_visible(true);} | bar_statement { first_line = false; the_graph->is_visible(true);} | line_statement { first_line = false; the_graph->is_visible(true);} | coord_statement { first_line = false;} | copy_statement { first_line = false;} | define_statement { first_line = false;} | undefine_statement { first_line = false;} | if_statement { first_line = false;} | for_statement { first_line = false;} | graph_statement { first_line = false;} | print_statement { first_line = false;} | sh_statement { first_line = false;} | pic_statement { first_line = false;} | troff_line { first_line = false;} | void_function { first_line = false;} | SEP ; from: FROM | EQUALS ; opt_coordname: { $$= defcoord; } | COORD_NAME { $$= $1;} ; opt_ident: { $$ = 0; } | IDENT { $$ = $1; } ; opt_display_string: { $$ = 0; } | string strmod { $$ = new DisplayString(*$1, $2.just, $2.size, $2.rel, $2.clip, $2.color); } ; string: STRING { $$ = $1; } | SPRINTF LPAREN STRING COMMA expr_list RPAREN { if ( do_sprintf ) { const int len = $3->length() < 128 ? 256 : 2*$3->length(); char *buf = new char[len]; // I really dislike this, but I dislike trying to do it // incrementally more. switch ($5->size()) { case 0: snprintf(buf, len, $3->c_str()); break; case 1: snprintf(buf, len, $3->c_str(), (*$5)[0]); break; case 2: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1]); break; case 3: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2]); break; case 4: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3]); break; case 5: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3], (*$5)[4]); break; case 6: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3], (*$5)[4], (*$5)[5]); break; case 7: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3], (*$5)[4], (*$5)[5], (*$5)[6]); break; case 8: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3], (*$5)[4], (*$5)[5], (*$5)[6], (*$5)[7]); break; case 9: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3], (*$5)[4], (*$5)[5], (*$5)[6], (*$5)[7], (*$5)[8]); break; default: cerr << "more that 10 arguments to sprintf. " << "Ignoring more than 10." << endl; case 10: snprintf(buf, len, $3->c_str(), (*$5)[0], (*$5)[1], (*$5)[2], (*$5)[3], (*$5)[4], (*$5)[5], (*$5)[6], (*$5)[7], (*$5)[8], (*$5)[9]); break; } delete $5; delete $3; $$ = new string(buf); delete[] buf; } else $$ = $3; } ; expr_list: expr { $$ = new doublevec; $$->push_back($1); } | expr_list COMMA expr { $$ = $1; $$->push_back($3); } ; opt_expr: { $$ = 0; } | expr { $$ = $1; } ; opt_linedesc: { $$ = new linedesc; $$ = 0;} | linedesc { $$ = $1;} ; opt_shift: { $$ = new shiftlist;} | shift opt_shift { $$ = $2; $$->push_back($1); } ; linedesc_elem: INVIS { $$ = new linedesc(invis); } | SOLID { $$ = new linedesc(solid); } | DOTTED opt_expr { $$ = new linedesc(dotted, $2); } | DASHED opt_expr { $$ = new linedesc(dashed, $2); } | COLOR string { $$ = new linedesc(def, 0, $2); } | FILL opt_expr { $$ = new linedesc(def, 0, 0, $2); } | FILLCOLOR string { $$ = new linedesc(def, 0, 0, 0, $2); } | THICKNESS opt_expr { $$ = new linedesc(def, 0, 0, 0, 0, $2); } ; linedesc: linedesc_elem { $$ = $1; } | linedesc linedesc_elem { $$ = combine_linedesc($1, $2); } ; draw_statement: DRAW { lex_no_coord(); } opt_ident opt_linedesc opt_display_string SEP { draw_statement($3, $4, $5); lex_coord_ok(); } ; num_list: num_line SEP { num_list($1); } ; num_line_elem: NUMBER { $$ = $1; } | MINUS NUMBER { $$ = -$2; } ; num_line: num_line_elem { $$ = new doublelist; $$->push_back($1); } | num_line num_line_elem { $$ = $1; $$->push_back($2); } | num_line COMMA num_line_elem { $$ = $1; $$->push_back($3); } ; expr: expr PLUS expr { $$ = $1 + $3; } | expr MINUS expr { $$ = $1 - $3; } | expr TIMES expr { $$ = $1 * $3; } | expr DIV expr { $$ = $1 / $3; } | expr CARAT expr { $$ = pow($1,$3);} | MINUS expr %prec CARAT { $$ = - $2;} | FUNC0 LPAREN RPAREN { $$ = ( $1 >=0 && $1 < NF0 ) ? jtf0[$1]() : 0; } | FUNC1 LPAREN expr RPAREN { $$ = ( $1 >=0 && $1 < NF1 ) ? jtf1[$1]($3) : 0; } | FUNC2 LPAREN expr COMMA expr RPAREN { $$ = ( $1 >=0 && $1 < NF2 ) ? jtf2[$1]($3, $5) : 0; } | LPAREN expr RPAREN { $$ = $2; } | IDENT { doubleDictionary::iterator di; if ( (di = vars.find(*$1)) != vars.end()) $$ = *(*di).second; else { cerr << *$1 << " is uninitialized, using 0.0" << endl; $$ = 0.0; } delete $1; } | NUMBER { $$ = $1; } ; lexpr: expr { $$ = $1; } | LPAREN pure_lexpr RPAREN { $$ = $2; } | pure_lexpr { $$ = $1; } ; pure_lexpr: lexpr EQ lexpr { $$ = ($1 == $3); } | lexpr NEQ lexpr { $$ = ($1 != $3); } | lexpr LT lexpr { $$ = ($1 < $3); } | lexpr GT lexpr { $$ = ($1 > $3); } | lexpr LTE lexpr { $$ = ($1 <= $3); } | lexpr GTE lexpr { $$ = ($1 >= $3); } | lexpr AND lexpr { $$ = ($1 && $3); } | lexpr OR lexpr { $$ = ($1 || $3); } | NOT lexpr %prec PLUS { $$ = ! ( (int) $2); } | string EQ string { $$ = (*$1 == *$3); delete $1; delete $3; } | string NEQ string { $$ = (*$1 != *$3); delete $1; delete $3; } ; right_hand_side: expr SEP { $$ = $1; } | assignment_statement { $$ = $1; } ; assignment_statement: LHS right_hand_side { $$ = assignment_statement($1, $2); } ; coord_pair: expr COMMA expr { $$ = new point($1, $3, 0); } | LPAREN expr COMMA expr RPAREN { $$ = new point($2, $4, 0); } ; point: opt_coordname coord_pair { $$ = new point($2->x, $2->y, $1); delete $2; } ; strmod: { $$.size = 0; $$.rel =0; $$.just = (unaligned_default) ? unaligned : 0; $$.clip = clip_default; $$.color = 0; } | strmod SIZE expr { $$.size = $3; $$.rel = ($3<0); } | strmod SIZE PLUS expr { $$.size = $4; $$.rel = 1; } | strmod LJUST { $$.just |= (int) ljust; } | strmod RJUST { $$.just |= (int) rjust; } | strmod ABOVE { $$.just |= (int) above; } | strmod BELOW { $$.just |= (int) below; } | strmod ALIGNED { $$.just |= (int) aligned; } | strmod UNALIGNED { $$.just |= (int) unaligned; } | strmod CLIPPED { $$.clip = true; } | strmod UNCLIPPED { $$.clip = false; } | strmod COLOR STRING { $$.color = $3; } ; strlist: string strmod { DisplayString *s; s = new DisplayString(*$1,$2.just,$2.size, $2.rel, $2.clip, $2.color); delete $1; $$ = new stringlist; $$->push_back(s); } | strlist string strmod { $$ = combine_strings($1, $2, $3); } ; plot_statement: strlist AT point SEP { the_graph->new_plot($1,$3); } | PLOT opt_expr opt_display_string AT point SEP { plot_statement($2, $3, $5); } ; next_statement: NEXT opt_ident AT point opt_linedesc SEP { next_statement($2, $4, $5); } ; size_elem: HT expr { $$ = new frame; $$->ht = $2; $$->wid = 0; } | WID expr { $$ = new frame; $$->wid = $2; $$->ht = 0; } ; size: size_elem { $$ = $1; } | size size_elem { $$ = $1; // Fill in non-default ht/wid if ( $2->ht != 0 ) $$->ht = $2->ht; if ( $2->wid != 0 ) $$->wid = $2->wid; } ; side: TOP { $$ = top_side;} | BOTTOM { $$= bottom_side;} | LEFT { $$ = left_side;} | RIGHT { $$ = right_side; } ; final_size: size { // This rule combines the explicit size settings with // the defaults. We create a new frame to have access // to the default sizes without needing to code them // explicitly (they're always implicit in a default // frame). N. B. that frames created by size (and // size_elem) use 0 to indicate no change to the ht or // wid. $$ = new frame; if ( $1->ht != 0) $$->ht = $1->ht; if ( $1->wid != 0) $$->wid = $1->wid; delete $1; } ; sides: side linedesc { $$ = new frame; $$->desc[$1] = *$2; delete $2; } | sides side linedesc { if ( !$1 ) $$ = new frame; else $$ = $1; $$->desc[$2] = *$3; delete $3; } ; /* Though this looks kludgy as Hell, it's about as clean as I can make it. Th * eproblem is that liesdescs are composed of lists of linedesc elements, and 2 * linedescs next to each other are impossible to tell apart. So, the global * linedesc for the frame cannot sit next to one of the linedescs for the * sides. for example is 'frame top dotted color "green"' a green frame with a * dotted top or a frame with a dotted green top? Writing a single list rule to * capture that constraint requires you to know where the size elements appear * in that list and life is horrible and complex. If it's even reasonably * tractable. This enumeration captures many of the possibilities that are * sane and minimizes the code complexity. You can't say things like 'frame * wid 3 dotted ht 5' to get a dotted 3x5 frame, but either 'frame dotted ht 3 * wid 5' or 'frame wid 3 ht 5 dotted' work. * This comment is primarily here to prevent me from wasting another hour * trying to clean this up. */ frame_statement: FRAME SEP { process_frame(0, 0, 0); } | FRAME linedesc SEP { process_frame($2, 0, 0); } | FRAME final_size SEP { process_frame(0, $2, 0); } | FRAME sides SEP { process_frame(0, 0, $2); } | FRAME final_size sides SEP { process_frame(0, $2, $3); } | FRAME linedesc sides SEP { process_frame($2, 0, $3); } | FRAME linedesc final_size SEP { process_frame($2, $3, 0); } | FRAME final_size linedesc SEP { process_frame($3, $2, 0); } | FRAME linedesc final_size sides SEP { process_frame($2, $3, $4);} | FRAME final_size linedesc sides SEP { process_frame($3, $2, $4); } ; shift: UP expr { $$ = new shiftdesc(top_side, $2); } | DOWN expr { $$ = new shiftdesc(bottom_side, $2); } | LEFT expr { $$ = new shiftdesc(left_side, $2); } | RIGHT expr { $$ = new shiftdesc(right_side, $2); } ; tickdir: IN { $$ = -1; } | OUT { $$ = 1; } ; direction: { $$ = 0.125; } | tickdir opt_expr { if ( $2 == 0 ) $$ = $1 * 0.125; else $$ = $1 * $2; } ; ticklist: expr opt_display_string { $$ = ticklist_elem($1, $2, 0); } | ticklist COMMA expr opt_display_string { $$ = ticklist_elem($3, $4, $1); } ; by_clause: { $$.op = PLUS; $$.expr = 1; } | BY expr { $$.op = PLUS; if ( $2 != 0.0 ) $$.expr = $2; else $$.expr = 1; } | BY PLUS expr { $$.op = PLUS; $$.expr = $3; } | BY TIMES expr { $$.op = TIMES; $$.expr = $3; } | BY DIV expr { $$.op = DIV; $$.expr = $3; } ; tickat: AT opt_coordname ticklist { $$ = $3; for (ticklist::iterator t= $3->begin(); t != $3->end(); t++) (*t)->c = $2; } ; tickfor: from opt_coordname expr TO expr by_clause opt_display_string { $$ = tick_for($2, $3, $5, $6, $7); } ; tickdesc : tickat { $$ = $1;} | tickfor { $$= $1; } ; autotick: ON opt_ident { coordinateDictionary::iterator ci; if ( $2 ) { ci = the_graph->coords.find(*$2); if ( ci != the_graph->coords.end()) $$ = (*ci).second; else { yyerror("Name must name a coordinate space"); } } else $$ = 0; } | { $$ = 0; } ; ticks_statement: TICKS side direction opt_shift tickdesc SEP { ticks_statement($2, $3, $4, $5); } | TICKS OFF SEP { for ( int i = 0; i< 4; i++ ) the_graph->base->tickdef[i].size = 0; } | TICKS side OFF SEP { the_graph->base->tickdef[$2].size = 0; } | TICKS side direction autotick SEP { the_graph->base->tickdef[$2].size = $3; if ( $4 ) the_graph->base->tickdef[$2].c = $4; } ; opt_tick_off: { $$ = 0; } | TICKS OFF { $$ = 1; } ; grid_statement: GRID side opt_tick_off opt_linedesc opt_shift tickdesc SEP { grid_statement($2, $3, $4, $5, $6); } | GRID side opt_tick_off opt_linedesc opt_shift autotick SEP { grid_statement($2, $3, $4, $5, 0); // Because turning on a grid on a given side disables // automatic tick generation there, this is sets up // that side with the proper coordinates. if ( $6 ) the_graph->base->griddef[$2].c = $6; } ; label_statement: LABEL side strlist opt_shift SEP { shiftdesc *sd; for (stringlist::iterator s = $3->begin(); s != $3->end(); s++) if ( ! ((*s)->j & unaligned) ) (*s)->j |= aligned; the_graph->base->label[$2] = $3; // Copy the label shifts into the frame while (!$4->empty() ) { sd = $4->front(); $4->pop_front(); the_graph->base->lshift[$2]->push_back(sd); } delete $4; } ; radius_spec: { $$ = 0.025; } | RADIUS expr { $$ = $2; } ; circle_statement: CIRCLE AT point radius_spec opt_linedesc SEP { the_graph->new_circle($3,$4,$5); delete $3; delete $5; } ; line_token: LINE { $$ = 1; } | ARROW { $$ = 0; } ; line_statement: line_token opt_linedesc FROM point TO point opt_linedesc SEP { line_statement($1, $2, $4, $6, $7); } ; x_axis_desc: { $$.which=none; } | XDIM expr COMMA expr { $$ = axis_description(x_axis, $2, $4); } ; y_axis_desc: { $$.which=none; } | YDIM expr COMMA expr { $$ = axis_description(y_axis, $2, $4); } ; log_list: log_list log_desc { $$ = combine_logs($1, $2); } | { $$ = none; } ; log_desc: LOG_X { $$ = x_axis; } | LOG_Y { $$ = y_axis; } | LOG_LOG { $$ = both; } ; coord_statement: COORD opt_ident x_axis_desc y_axis_desc log_list SEP { coord_statement($2, $3, $4, $5); delete $2; } ; until_clause: { $$ = 0; } | UNTIL string { unquote($2); $$ = new copydesc; $$->t = copydesc::until; $$->s = $2; } | string { unquote($1); $$ = new copydesc; $$->t = copydesc::fname; $$->s = $1; } ; // This is probably long enough to merit being removed to // grap_parse.cc, but because there are multiple actions in the same // rule, I want to leave them here where I can see how they // interrelate. copy_statement: COPY string SEP { unquote($2); if (!include_file($2, false)) return 0; } | COPY UNTIL string SEP { unquote($3); lex_begin_copy($3); } COPYTEXT { string s=""; while ($6 && !$6->empty() ) { string *ss; ss = $6->front(); $6->pop_front(); if ( ss ) { s+= *ss; s+= '\n'; delete ss; ss = 0; } } include_string(&s, 0, GINTERNAL); delete $6; } | COPY until_clause THRU { lex_hunt_macro(); } MACRO until_clause SEP { copydesc *c = 0; // To shut the compiler up about uninit if ( $2 && $6 ) { delete $2; delete $6; yyerror("Only specify 1 until or filename\n"); } else c = ($2) ? $2 : $6; // The else handles files with neither else clause, copying // text to the trailing .G2. Fix from Bruce Lilly if ( c ) { // lex_begin_copy takes command of the string that's // passed to it, so don't delete it. (I don't // remember why I did that...) if ( c->t == copydesc::until ) { lex_begin_copy(c->s); c->s = 0; } else { lex_begin_copy(0); include_file(c->s, false); } delete c; } else lex_begin_copy(0); } COPYTEXT { string *s; string *t; int lim; char end; stack st; while ( $9 && !$9->empty() ) { int i = 0; t = new string; s = $9->front(); $9->pop_front(); lim = s->length(); while ( i < lim ) { if ( (*s)[i] == ' ' || (*s)[i] == '\t' ) { if ( t->length() ) { if ( $5->add_arg(t)) t = new string; } } else *t += (*s)[i]; i++; } if ( t->length() ) $5->add_arg(t); else if (t) delete t; t = $5->invoke(); // "here" macros should end with a SEP. If the // user hasn't done so, we add a SEP for them. // Even named macros should get a sep when they're // copied through, end = (*t)[t->length()-1]; if ( end != ';' && end != '\n' ) *t += ';'; // Because include string stacks the strings, we stack them // here and call include_string in reverse order to ensure // correct ordered execution of multiple lines. st.push(t); delete s; } delete $9; while ( !st.empty() ) { include_string(st.top(), 0, GMACRO); delete st.top(); st.pop(); } // don't delete defined macros if ( !$5->name) delete $5; } ; define_statement: DEFINE { lex_no_coord(); lex_no_macro_expansion();} IDENT { lex_begin_macro_text(); } TEXT SEP { lex_macro_expansion_ok(); lex_coord_ok(); define_macro($3, $5); } ; undefine_statement: UNDEFINE { lex_no_coord(); lex_no_macro_expansion(); } IDENT SEP { lex_coord_ok(); lex_macro_expansion_ok(); macros.erase(*$3); delete $3; } ; sh_statement: SH { lex_begin_macro_text(); } TEXT SEP { int len = $3->length()+1 ; char *sys = new char [len]; int i=0; // String to char* while ((sys[i] = (*$3)[i])) i++; delete $3; system(sys); } ; else_clause: { $$ = 0; } | ELSE {lex_begin_macro_text(); } TEXT { // force else clause to end with a SEP *$3+= ';'; $$ = $3; } ; if_statement: IF lexpr THEN { lex_begin_macro_text(); } TEXT else_clause SEP { // force all if blocks to be terminated by a SEP. *$5 += ';'; // We use epsilon in loop tests if ( fabs($2) > epsilon ) include_string($5,0,GINTERNAL); else if ( $6 ) include_string($6,0,GINTERNAL); delete $5; delete $6; } ; for_statement: FOR IDENT from expr TO expr by_clause DO { lex_begin_macro_text(); } TEXT SEP { for_statement($2, $4, $6, $7, $10); delete $2; } ; graph_statement: GRAPH { lex_no_coord(); } IDENT { lex_begin_rest_of_line(); } REST SEP { if ( !first_line ) { // Only draw the graph and clear its internals if // it is visible. This allows a user to declare // things like coordinate spaces before the graph // itself is named. This is a compatibility // feature for DWB grap. if ( the_graph->is_visible() ) { the_graph->draw(0); the_graph->init($3, $5); init_dict(); } else the_graph->setname($3); } else { the_graph->init($3, $5); init_dict(); } if ( $3 ) delete $3; if ( $5 ) delete $5; } ; print_statement: PRINT print_param SEP ; print_param: string { unquote($1); cerr << *$1 << endl; } | expr { cerr << $1 << endl; } ; pic_statement: PIC { lex_begin_rest_of_line(); } REST SEP { the_graph->passthru_string(*$3); delete $3;} ; troff_line: TROFF SEP { the_graph->passthru_string(*$1); delete $1;} ; bar_dir: RIGHT { $$ = right_side; } | UP { $$ = top_side; } ; /* NB: the tokenizer only allows one instance of wid or base or ht per line * (you could have all 3) */ bar_param: HT expr { $$ = new bar_param; $$->ht = $2; $$->have_ht = true; } | WID expr { $$ = new bar_param; $$->wid = $2; } | BASE expr { $$ = new bar_param; $$->base = $2; } ; bar_params: bar_param { $$ = $1; } | bar_params bar_param { $$ = $1; if ( $2 ) { if ($2->have_x ) { $$->x = $2->x; $$->have_x = true; } if ($2->have_ht ) { $$->ht = $2->ht; $$->have_ht = true; } if ( $2->wid != 1.0 ) { $$->wid = $2->wid; } if ( $2->base != 0.0 ) { $$->base = $2->base; } delete $2; } } ; bar_statement: BAR point COMMA point opt_linedesc SEP { // The point parsing has already autoscaled the // coordinate system to include those points. the_graph->new_box($2, $4, $5); delete $2; delete $4; delete $5; } | BAR bar_dir opt_coordname expr bar_params opt_linedesc SEP { if ( !$5 || !$5->have_ht ) { yyerror("bar must have a position and ht "); } else { bar_statement($3, $2, $4, $5->ht, $5->wid, $5->base, $6); } delete $5; } ; void_function: VFUNC1 LPAREN expr RPAREN { if ( $1 >=0 && $1 < NVF1 ) jtvf1[$1]($3); } ; %% grap-1.43/grap.1000640 004133 000000 00000104741 11076255041 013617 0ustar00faberwheel000000 000000 .\"-*-nroff-*- .\" This file is (c) 1998-2006 Ted Faber (faber@lunabase.org) see .\" COPYRIGHT for the full copyright and limitations of liabilities. .Dd March 11, 2006 .Os .Dt GRAP 1 .Sh NAME .Nm grap .Nd Kernighan and Bentley's language for typesetting graphs .Sh SYNOPSIS .Nm .Op Fl d Ar defines_file .Op Fl D .Op Fl l .Op Fl M Ar include path .Op Fl R .Op Fl r .Op Fl v .Op Fl u .Op Fl C .Op Fl c .Op Fl h .Op Ar filename ... .Sh DESCRIPTION .Nm is an implementation of Kernighan and Bentley's language for typesetting graphs, as described in ``Grap-A Language for Typesetting Graphs, Tutorial and User Manual,'' by Jon L. Bentley and Brian W. Kernighan, revised May 1991, which is the primary source for information on how to use .Nm grap . As of this writing, it is available electronically at .Li http://www.kohala.com/start/troff/cstr114.ps . Additional documentation and examples, packaged with .Nm , may have been installed locally as well. If available, paths to them can be displayed using .Nm .Fl h or .Nm .Fl v (or .Nm .Fl -help / .Nm .Fl -version ) .Pp This version is a black box implementation of .Nm grap , and some inconsistencies are to be expected. The remainder of this manual page will briefly outline the .Nm language as implemented here. .Pp .Nm is a .Xr pic 1 pre-processor. It takes commands embedded in a .Xr troff 1 source file which are surrounded by .Ic .G1 and .Ic .G2 macros, and rewrites them into .Xr pic commands to display the graph. Other lines are copied. Output is always to the standard output, which is usually redirected. Input is from the given .Ar filename Ns No s , which are read in order. A .Ar filename of .Fl is the standard input. If no .Ar filename Ns No s are given, input is read from the standard input. .Pp Because .Nm is a .Xr pic preprocessor, and GNU .Xr pic will output TeX, it is possible to use .Nm with TeX. .Pp The .Fl d option specifies a file of macro definitions to be read at startup, and defaults to /usr/local/share/grap/grap.defines . The .Fl D option inhibits the reading of any initial macros file (the .Fl l flag is a synonym for .Fl D , though I do not remember why). The defines file can also be given using the .Ev GRAP_DEFINES environment variable. (See below). .Pp .Fl v prints the version information on the standard output and exits. .Fl -version is a synonym for .Fl v . .Pp .Fl u makes labels unaligned by default. This version of .Nm uses new features of GNU .Xr pic to align the left and right labels with the axes, that is that the left and right labels run at right angles to the text of the paper. This may be useful in porting old .Nm programs. .Fl c makes plot strings unclipped by default. Some versions of .Nm allow users to place a string anywhere in the coordinate space, rather than only in the frame. By default this version of .Nm does not plot any string centered outside the frame. .Fl c allows strings to be placed anywhere. See also the .Ic clipped and .Ic unclipped string modifiers described in the .Ic plot statement. .Pp .Fl M is followed by a colon-separated list of directories used to search for relative pathnames included via .Ic copy . The path is also used to locate the defines file, so if the .Fl d changes the defines file name to a relative name, it will be searched for in the path given by .Fl M . The search path always includes the current directory, and by default that directory is searched last. .Pp All numbers used internally by .Nm are double precision floating point values. Sometimes using floating point numbers has unintended consequences. To help avoid these problems, .Nm can use two thresholds for comparison of floating point numbers, set by .Fl R or .Fl r . The .Fl R flag sets coarse comparison mode, which is suitable for most applications. If you are plotting small values \(en less than 1e-6 or so \(en consider using .Fl r which uses very fine comparisons between numbers. You may also want to rescale your plotted values to be larger in magnitude. The coarse comarisons are used by default. .Pp To be precise, the value by which two numbers must differ for .Nm to consider them not equal is called the comparison limit and the smallest non-zero number is called the minimum value. The values a given version of .Nm uses for these are included in the output of .Fl v or .Fl h . .Pp All .Nm commands are included between .Ic .G1 and .Ic .G2 macros, which are consumed by .Nm grap . The output contains .Xr pic between .Ic .PS and .Ic .PE macros. Any arguments to the .Ic .G1 macro in the input are arguments to the .Ic .PS macro in the output, so graphs can be scaled just like .Xr pic diagrams. If .Fl C is given, any macro beginning with \&.G1 or \&.G2 is treated as a \&.G1 or \&.G2 macro, for compatibility with old versions of troff. Using .Fl C also forces pure troff syntax on embedded font change commands when strings have the .Ic size attribute, and all strings to be .Ic unclipped . .Pp The .Fl h flag prints a brief help message and exits. .Fl -help is a synonym for .Fl h . .Pp It is possible for someone to cause .Nm to fail by passing a bad format string and data to the .Ic sprintf command. If .Nm is integrated as part of the printing system, this could conceivably provided a path to breaching security on the machine. If you choose to use .Nm as part of a printing system run by the super-user, you should disable .Ic sprintf commands. This can be done by calling .Nm with the .Fl S flag, setting the .Ev GRAP_SAFER environment variable, or compiling with the GRAP_SAFER preprocessor symbol defined. (The GNU configure script included with .Nm will define that preprocessor symbol if the .Fl -with-grap-safe option is given.) .Pp The .Nm commands are sketched below. Refer to Kernighan and Bentley's paper for the details. .Pp New versions of .Xr groff 1 will invoke .Nm if .Fl G is given. .Ss Commands .Pp Commands are separated from one another by newlines or semicolons (;). .Pp .Ic frame .Op Ar line_description .Oo .Bk -words .Cm ht Ar height No \(or Cm wid Ar width .Ek .Oc .Oo .Bk -words .Oo .Sm off .Cm ( top No \(or Cm bottom No \(or .Cm left No \(or .Sm on .Cm right ) .Ar line_description .Ek .Oc \&... .Oc .sp .Ic frame .Oo .Bk -words .Cm ht Ar height No \(or Cm wid Ar width .Ek .Oc .Op Ar line_description .Oo .Bk -words .Oo .Sm off .Cm ( top No \(or Cm bottom No \(or .Cm left No \(or .Sm on .Cm right ) .Ar line_description .Ek .Oc \&... .Oc .Bd -filled -offset indent This describes how the axes for the graph are drawn. A .Ar line_description is a .Xr pic line description, e.g., .Li dashed .Li 0.5 , or the literal .Li solid . It may also include a .Ic color keyword followed by the color to draw the string in double quotes. Any color understood by the underlying groff system can be used. Color can only be used under GNU pic, and is not available in compatibility mode. Similarly, for pic implementations that understand .Ic thickness , that attribute may be used with a real valued parameter. .Ic Thickness is not available in compatibility mode. .Pp If the first .Ar line_description is given, the frame is drawn with that style. The default is .Li solid . The height and width of the frame can also be specified in inches. The default line style can be over-ridden for sides of the frame by specifying additional parameters to .Ic frame . .Pp If no plotting commands have been given before the .Ic frame command is issued, the frame will be output at that point in the plotting stream relative to embedded .Xr troff or .Xr pic commands. Otherwise the frame is output before the first plotted object (even invisible ones). .Pp .Ic ht and .Ic wid are in inches by default, but can be any .Xr groff unit. If omitted, the dimensions are 2 inches high by 3 inches wide. .Ed .Pp .Ic coord .Op Ar name .Op Cm x Ar expr , expr .Op Cm y Ar expr , expr .Oo .Cm log x No \(or .Cm log y No \(or .Cm log log .Oc .Bd -filled -offset indent The .Ic coord command specifies a new coordinate system or sets limits on the default system. It defines the largest and smallest values that can be plotted, and therefore the scale of the data in the frame. The limits for the x and y coordinate systems can be given separately. If a .Ar name is given, that coordinate system is defined, if not the default system is modified. .Pp A coordinate system created by one .Ic coord command may be modified by subsequent .Ic coord commands. A .Nm program may declare a coordinate space using .Ic coord , .Ic copy a file of data through a macro that plots the data and finds its maxima and minima, and then define the size of the coordinate system with a second .Ic coord statement. .Pp This command also determines if a scale is plotted logarithmically. .Cm log log means the same thing as .Cm log x log y . .Ed .Pp .Ic draw .Op Ar line_name .Op Ar line_description .Op Ar plot_string .Bd -filled -offset indent The .Ic draw command defines the style with which a given line will be plotted. If .Ar line_name is given, the style is associated with that name, otherwise the default style is set. .Ar line_description is a .Xr pic line description, and the optional .Ar plot_string is a string to be centered at each point. The default line description is .Li invis , and the default plotting string is a centered bullet, so by default each point is a filled circle, and they are unconnected. If points are being connected, each .Ic draw command ends any current line and begins a new one. .Pp When defining a line style, that is the first .Ic draw command for a given line name, specifying no plot string means that there are to be no plot strings. Omitting the plot string on subsequent .Ic draw commands addressing the same named line means not to change the plot string. If a line has been defined with a plot string, and the format is changed by a subsequent .Ic draw statement, the plot string can be removed by specifying "" in the .Ic draw statement. .Pp The plot string can have its format changed through several string_modifiers. String_modifiers are described in the description of the .Ic plot command. .Pp The standard defines file includes several macros useful as plot strings, including .Ic bullet , .Ic square , and .Ic delta . .Pp .Ic new is a synonym for .Ic draw . .Ed .Pp .Ic next .Op Ar line_name .Cm at .Op Ar coordinates_name .Ar expr , expr .Op Ar line_description .Bd -filled -offset indent The .Ic next command plots the given point using the line style given by .Ar line_name , or the default if none is given. If .Ar line_name is given, it should have been defined by an earlier .Ic draw command, if not a new line style with that name is created, initialized the same way as the default style. The two expressions give the point's x and y values, relative to the optional coordinate system. That system should have been defined by an earlier .Ic coord command, if not, grap will exit. If the optional .Ar line_description is given, it overrides the style's default line description. You cannot over-ride the plotting string. To use a different plotting string use the .Ic plot command. .Pp The coordinates may optionally be enclosed in parentheses: .Ar ( expr , expr ) .Ed .Pp .Ar quoted_string .Op Ar string_modifiers .Oo .No , Ar quoted_string .Oo .Ar string_modifiers .Oc .Oc \&... .Cm at .Op Ar coordinates_name .Ar expr , expr .Pp .Ic plot .Ar expr .Op Ar format_string .Cm at .Op Ar coordinates_name .Ar expr , expr .Bd -filled -offset indent These commands both plot a string at the given point. In the first case the literal strings are stacked above each other. The string_modifiers include the .Xr pic justification modifiers .Ns No ( Ic ljust , .Ic rjust , .Ic above , and .Ic below Ns No ), and absolute and relative .Li size modifiers. See the .Xr pic documentation for the description of the justification modifiers. .Nm also supports the .Ic aligned and .Ic unaligned modifiers which are briefly noted in the description of the .Ic label command. .Pp The standard defines file includes several macros useful as plot strings, including .Ic bullet , .Ic square , and .Ic delta . .Pp Strings placed by either format of the .Ic plot command are restricted to being within the frame. This can be overriden by using the .Ic unclipped attribute, which allows a string to be plotted in or out of the frame. The .Fl c and .Fl C flags set .Ic unclipped on all strings, and to prevent a string from being plotted outside the frame when those flags are active, the .Ic clipped attribute can be used to retore clipping behavior. Though .Ic clipped or .Ic unclipped can be applied to any string, it only has meaning for .Ic plot statements. .Pp .Li size .Ar expr sets the string size to .Ar expr points. If .Ar expr is preceded by a + or -, the size is increased or decreased by that many points. .Pp If .Ic color and a color name in double quotes appears, the string will be rendered in that color under a version of GNU troff that supports color. Color is not available in compatibility mode. .Pp In the second version, the .Ar expr is converted to a string and placed on the graph. .Ar format_string is a .Xr printf 3 format string. Only formatting escapes for printing floating point numbers make sense. The format string is only respected if the .Ic sprintf command is also active. See the description of .Ic sprintf for the various ways to disable it. .Ic Plot and .Ic sprintf respond differently when .Nm is running safely. .Ic Sprintf ignores any arguments, passing the format string through without substitution. .Ic plot ignores the format string completely, plotting .Ar expr using the .Qq %g format. .Pp Points are specified the same way as for .Ic next commands, with the same consequences for undefined coordinate systems. .Pp The second form of this command is because the first form can be used with a .Nm .Ic sprintf expression (See .Sx Expressions ) . .Ed .Pp .Ic ticks .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Oo .Sm on .Xo ( Cm in Ns No \(or Ns Cm out ) .Xc .Op Ar expr .Oc .Sm off .Oo .Cm on \(or Cm auto .Sm on .Ar coord_name .Oc .Pp .Ic ticks .Sm off .Xo ( Cm left No \(or Cm right No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Xo ( Cm in Ns No \(or Ns Cm out ) .Xc .Op Ar expr .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm at .Op Ar coord_name .Ar expr .Op Ar format_string .Oo .Oo .No , Ar expr .Oo .Ar format_string .Oc .Oc .No ... .Oc .Pp .Ic ticks .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Xo ( Cm in Ns No \(or Ns Cm out ) .Xc .Op Ar expr .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm from .Op coord_name .Ar start_expr .Cm to .Ar end_expr .Oo .Cm by .Sm off .Oo .No + \(or - \(or * \(or / .Sm on .Oc .Ar by_expr .Oc .Op format_string .Pp .Ic ticks .Sm off .Oo .Cm left Xo No \(or Cm right .No \(or Cm top No \(or Cm bottom .Oc .Xc .Sm on .Cm off .Bd -filled -offset indent This command controls the placement of ticks on the frame. By default, ticks are automatically generated on the left and bottom sides of the frame. .Pp The first version of this command turns on the automatic tick generation for a given side. The .Cm in or .Cm out parameter controls the direction and length of the ticks. If a .Ar coord_name is specified, the ticks are automatically generated using that coordinate system. If no system is specified, the default coordinate system is used. As with .Ic next and .Ic plot , the coordinate system must be declared before the .Ic ticks statement that references it. This syntax for requesting automatically generated ticks is an extension, and will not port to older .Nm implementations. .Pp The second version of the .Ic ticks command overrides the automatic placement of the ticks by specifying a list of coordinates at which to place the ticks. If the ticks are not defined with respect to the default coordinate system, the .Ar coord_name parameter must be given. For each tick a .Xr printf 3 style format string can be given. The .Ar format_string defaults to .Qq %g . The format string can also take string modifiers as described in the .Ic plot command. To place ticks with no labels, specify .Ar format_string as .Qq \& . .Pp If .Ic sprintf is disabled, .Ic ticks behaves as .Ic plot with respect to the format string. .Pp The labels on the ticks may be shifted by specifying a direction and the distance in inches to offset the label. That is the optional direction and expression immediately preceding the .Cm at . .Pp The third format of the .Ic ticks command over-rides the default tick generation with a set of ticks ar regular intervals. The syntax is reminiscent of programming language for loops. Ticks are placed starting at .Ar start_expr ending at .Ar end_expr one unit apart. If the .Cm by clause is specified, ticks are .Ar by_expr units apart. If an operator appears before .Ar by_expr each tick is operated on by that operator instead of +. For example .Bd -literal -offset indent-two ticks left out from 2 to 32 by *2 .Ed .Pp will put ticks at 2, 4, 8, 16, and 32. If .Ar format_string is specified, all ticks are formatted using it. .Pp The parameters preceding the .Cm from act as described above. .Pp The .Cm at and .Cm for forms of tick command may both be issued on the same side of a frame. For example: .Bd -literal -offset indent-two ticks left out from 2 to 32 by *2 ticks left in 3, 5, 7 .Ed .Pp will put ticks on the left side of the frame pointing out at 2, 4, 8, 16, and 32 and in at 3, 5, and 7. .Pp The final form of .Ic ticks turns off ticks on a given side. If no side is given the ticks for all sides are cancelled. .Pp .Ic tick is a synonym for .Ic ticks . .Ed .Pp .Ic grid .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Op Li ticks off .Op Ar line_description .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Oo .Sm off .Cm on \(or Cm auto .Sm on .Op Ar coord_name .Oc .Pp .Ic grid .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Op Li ticks off .Op Ar line_description .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm at .Op Ar coord_name .Ar expr .Op Ar format_string .Oo .Oo .No , Ar expr .Oo .Ar format_string .Oc .Oc .No ... .Oc .Pp .Ic grid .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Op Li ticks off .Op Ar line_description .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Cm from .Op coord_name .Ar start_expr .Cm to .Ar end_expr .Oo .Cm by .Sm off .Oo .No + \(or - \(or * \(or / .Sm on .Oc .Ar by_expr .Oc .Op format_string .Bd -filled -offset indent The .Ic grid command is similar to the .Ic ticks command except that .Ic grid specifies the placement of lines in the frame. The syntax is similar to .Ic ticks as well. .Pp By specifying .Li ticks off in the command, no ticks are drawn on that side of the frame. If ticks appear on a side by default, or have been declared by an earlier .Ic ticks command, .Ic grid does not cancel them unless .Li ticks off is specified. .Pp Instead of a direction for ticks, .Ic grid allows the user to pick a line description for the grid lines. The usual .Xr pic line descriptions are allowed. .Pp Grids are labelled by default. To omit labels, specify the format string as .Qq \& . .Pp If .Ic sprintf is disabled, .Ic grid behaves as .Ic plot with respect to the format string. .Ed .Pp .Ic label .Sm off .Xo ( Cm left No \(or Cm right .No \(or Cm top No \(or Cm bottom ) .Xc .Sm on .Ar quoted_string .Op Ar string_modifiers .Oo .No , Ar quoted_string .Oo .Ar string_modifiers .Oc .Oc \&... .Oo .Cm up Ar expr No \(or .Cm down Ar expr No \(or .Cm left Ar expr No \(or .Cm right Ar expr .Oc .Bd -filled -offset indent The .Ic label command places a label on the given axis. It is possible to specify several labels, which will be stacked over each other as in .Xr pic . The final argument, if present, specifies how many inches the label is shifted from the axis. .Pp By default the labels on the left and right labels run parallel to the frame. You can cancel this by specifying .Li unaligned as a .Ar string_modifier . .Ed .Pp .Ic circle .Cm at .Op Ar coordinate_name .Ar expr , expr .Op Cm radius Ar expr .Op Ar linedesc .Bd -filled -offset indent This draws an circle at the point indicated. By default, the circle is small, 0.025 inches. This can be over-ridden by specifying a radius. The coordinates of the point are relative to the named coordinate system, or the default system if none is specified. .Pp This command has been extended to take a line description, e.g., .Li dotted . It also accepts the filling extensions described below in the .Ic bar command. It will also accept a .Ic color keyword that gives the color of the outline of the circle in double quotes and a .Ic fillcolor command that sets the color to fill the circle with similarly. Colors are only available when compatibility mode is off, and using a version of GNU pic that supports color. .Ed .Pp .Ic line .Op Ar line_description .Cm from .Op Ar coordinate_name .Ar expr , expr .Cm to .Op Ar coordinate_name .Ar expr , expr .Op Ar line_description .Pp .Ic arrow .Op Ar line_description .Cm from .Op Ar coordinate_name .Ar expr , expr .Cm to .Op Ar coordinate_name .Ar expr , expr .Op Ar line_description .Bd -filled -offset indent This draws a line or arrow from the first point to the second using the given style. The default line style is .Li solid . The .Ar line_description can be given either before the .Cm from or after the .Cm to clause. If both are given the second is used. It is possible to specify one point in one coordinate system and one in another, note that if both points are in a named coordinate system (even if they are in the same named coordinate system), both points must have .Ar coordinate_name given. .Ed .Pp .Pp .Ic copy .Op Qq Ar filename .Op Cm until Qq Ar string .Op Cm thru Ar macro .Bd -filled -offset indent The .Ic copy command imports data from another file into the current graph. The form with only a filename given is a simple file inclusion; the included file is simply read into the input stream and can contain arbitrary .Nm commands. The more common case is that it is a number list; see .Sx Number Lists below. .Pp The second form takes lines from the file, splits them into words delimited by one or more spaces, and calls the given macro with those words as parameters. The macro may either be defined here, or be a macro defined earlier. See .Sx Macros for more information on macros. .Pp The .Ar filename may be omitted if the .Cm until clause is present. If so the current file is treated as the input file until .Ar string is encountered at the beginning of the line. .Pp .Ic copy is one of the workhorses of .Nm grap . Check out the paper and .Pa /usr/local/share/examples/grap for more details. Confirm the location of the examples directory using the .Fl v flag. .Ed .Ic print .Sm off .Ar ( expr \(or string ) .Sm on .Bd -filled -offset indent Prints its argument to the standard error. .Ed .Pp .Ic sh Ar block .Bd -filled -offset indent This passes .Ar block to .Xr sh 1 . Unlike K&B .Nm no macro or variable expansion is done. I believe that this is also true for GNU .Xr pic version 1.10. See the .Sx Macros section for information on defining blocks. .Ed .Pp .Ic pic Ar pic_statement .Bd -filled -offset indent This issues the given .Xr pic statements in the enclosing .Ic .PS and .Ic .PE at the point where the command is issued. .Pp Statements that begin with a period are considered to be .Xr troff statements and are output in the enclosing .Ic .PS and .Ic .PE at the point where the command appears. .Pp For the purposes of relative placement of .Xr pic or .Xr troff commands, the frame is output immediately before the first plotted object, or the .Ic frame statement, if any. If the user specifies .Xr pic or .Xr troff commands and neither any plotable object nor a .Ic frame command, the commands will not be output. .Ed .Pp .Ic graph Ar Name pic_commands .Bd -filled -offset indent This command is used to position graphs with respect to each other. The current graph is given the .Xr pic name .Ar Name (names used by .Xr pic begin with capital letters). Any .Xr pic commands following the graph are used to position the next graph. The frame of the graph is available for use with .Xr pic name .Li Frame. The following places a second graph below the first: .Bd -literal -offset indent-two graph Linear [ graph description ] graph Exponential with .Frame.n at \\ Linear.Frame.s - (0, .05) [ graph description ] .Ed .Ed .Pp .Ar name = expr .Bd -filled -offset indent This assigns .Ar expr to the variable .Ar name . .Nm has only numeric (double) variables. .Pp Assignment creates a variable if it does not exist. Variables persist across graphs. Assignments can cascade; .Li a = b = 35 assigns 35 to .Li a and .Li b . .Ed .Pp .Ic bar .Sm off .No ( Cm up No \(or Cm right ) .Sm on .Op Ar coordinates_name .Ar offset .Cm ht .Ar height .Op Cm wid Ar width .Op Cm base Ar base_offset .Op Ar line_description .Pp .Ic bar .Op Ar coordinates_name .Ar expr , expr , .Op Ar coordinates_name .Ar expr , expr , .Op Ar line_description .Bd -filled -offset indent The .Ic bar command facilitates drawing bar graphs. The first form of the command describes the bar somewhat generally and has .Nm place it. The bar may extend up or to the right, is centered on .Ar offset and extends up or right .Ar height units (in the given coordinate system). For example .Bd -literal -offset indent-two bar up 3 ht 2 .Ed .Pp draws a 2 unit high bar sitting on the x axis, centered on x=3. By default bars are 1 unit wide, but this can be changed with the .Ic wid keyword. By default bars sit on the base axis, i.e., bars directed up will extend from y=0. That may be overridden by the .Ic base keyword. (The bar described above has corners (2.5, 0) and (3.5, 2).) .Pp The line description has been extended to include a .Ic fill Ar expr keyword that specifies the shading inside the bar. Bars may be drawn in any line style. They support the .Ic color and .Ic fillcolor keywords described under .Ic circle . .Pp The second form of the command draws a box with the two points as corners. This can be used to draw boxes highlighting certain data as well as bar graphs. Note that filled bars will cover data drawn under them. .Ed .Ss Control Flow .Pp .Ic if Ar expr Ic then Ar block .Op Ic else Ar block .Bd -filled -offset indent The .Ic if statement provides simple conditional execution. If .Ar expr is non-zero, the .Ar block after the .Ic then statement is executed. If not the .Ar block after the .Ic else is executed, if present. See .Sx Macros for the definition of blocks. Early versions of this implementation of .Nm treated the blocks as macros that were defined and expanded in place. This led to unnecessary confusion because explicit separators were sometimes called for. Now, .Nm inserts a separator (;) after the last character in .Ar block , so constructs like .Bd -literal if (x == 3) { y = y + 1 } x = x + 1 .Ed behave as expected. A separator is also appended to the end of a .Ic for block. .Ed .Pp .Ic for Ar name Ic from Ar from_expr Ic to Ar to_expr .Oo .Ic by .Op No +\(or-\(or*\(or/ .Ar by_expr .Oc .Ic do .Ar block .Bd -filled -offset indent This command executes .Ar block iteratively. The variable .Ar name is set to .Ar from_expr and incremented by .Ar by_expr until it exceeds .Ar to_expr . The iteration has the semantics defined in the .Ic ticks command. The definition of .Ar block is discussed in .Sx Marcos . See also the note about implicit separators in the description of the .Ic if command. .Pp An .Ic = can be used in place of .Ic from . .Ed .Ss Expressions .Pp .Nm supports most standard arithmetic operators: + - / * ^. The carat (^) is exponentiation. In an .Ic if statement .Nm also supports the C logical operators ==, !=, &&, || and unary !. Also in an .Ic if , == and != are overloaded for the comparison of quoted strings. Parentheses are used for grouping. .Pp Assignment is not allowed in an expression in any context, except for simple cascading of assignments. .Li a = b = 35 works as expected; .Li a = 3.5 * (b = 10) does not execute. .Pp .Nm supports the following functions that take one argument: .Ic log , exp , int , sin , cos , sqrt , rand . The logarithms are base 10 and the trigonometric functions are in radians. .Ic eexp returns Euler's number to the given power and .Ic ln returns the natural logarithm. The natural log and exponentiation functions are extensions and are probably not available in other .Nm implementations. .Pp .Ic rand returns a random number uniformly distributed on [0,1). The following two-argument functions are supported: .Ic atan2 , min , max . .Ic atan2 works just like .Xr atan2 3 . The random number generator can be seeded by calling .Ic srand with a single parameter (converted internally to an integer). Because its return value is of no use, you must use .Ic srand as a separate statement, it is not part of a valid expression. .Ic srand is not portable. .Pp The .Ic getpid function takes no arguments and returns the process id. This may be used to seed the random number generator, but do not expect cryptographically random values to result. .Pp Other than string comparison, no expressions can use strings. One string valued function exists: .Ic sprintf ( Ar format , .Oo .Ar expr .Op Ar \&, expr .Oc ). It operates like .Xr sprintf 3 , except returning the value. It can be used anywhere a quoted string is used. If .Nm is run with .Fl S , the environment variable .Ev GRAP_SAFER is defined, or .Nm has been compiled for safer operation, the .Ic sprintf command will return the format string. This mode of operation is only intended to be used only if .Nm is being used as part of a super-user enabled print system. .Ss Macros .Nm has a simple but powerful macro facility. Macros are defined using the .Ic define command : .Pp .Ic define Ar name block .br .Ic undefine Ar name .Bd -filled -offset indent Every occurrence of .Ar name in the program text is replaced by the contents of .Ar block . .Ar block is defined by a series of statements in nested { }'s, or a series of statements surrounded by the same letter. An example of the latter is .Bd -literal -offset indent-two define foo X coord x 1,3 X .Ed Each time .Li foo appears in the text, it will be replaced by .Li coord x 1,3 . Macros are literal, and can contain newlines. If a macro does not span multiple lines, it should end in a semicolon to avoid parsing errors. .Pp Macros can take parameters, too. If a macro call is followed by a parenthesized, comma-separated list the values starting with $1 will be replaced in the macro with the elements of the list. A $ not followed by a digit is left unchanged. This parsing is very rudimentary; no nesting or parentheses or escaping of commas is allowed. Also, there is no way to say argument 1 followed by a digit (${1}0 in sh(1)). .Pp The following will draw a line with slope 1. .Bd -literal -offset indent-two define foo { next at $1, $2 } for i from 1 to 5 { foo(i,i) } .Ed Macros persist across graphs. The file .Pa /usr/local/share/grap/grap.defines contains simple macros for plotting common characters. The .Ic undefine command deletes a macro. .Pp See the directory .Pa /usr/local/share/examples/grap for more examples of macros. Confirm the location of the examples directory using the .Fl v flag. .Ed .Ss Number Lists .Pp A whitespace-separated list of numbers is treated specially. The list is taken to be points to be plotted using the default line style on the default coordinate system. If more than two numbers are given, the extra numbers are taken to be additional y values to plot at the first x value. Number lists in DWB .Nm can be comma-separated, and this .Nm supports that as well. More precisely, numbers in number lists can be separated by either whitespace, commas, or both. .Bd -literal -offset indent 1 2 3 4 5 6 .Ed .sp Will plot points using the default line style at (1,2), (1,3),(4,5) and (4,6). A simple way to plot a set of numbers in a file named .Pa ./data is: .Bd -literal -offset indent \&.G1 copy "./data" \&.G2 .Ed .Ss Pic Macros .Pp .Nm defines pic macros that can be used in embedded pic code to place elements in the graph. The macros are .Ic x_gg , .Ic y_gg , and .Ic xy_gg . These macros define pic distances that correspond to the given argument. They can be used to size boxes or to plot pic constructs on the graph. To place a given construct on the graph, you should add Frame.Origin to it. Other coordinate spaces can be used by replacing .Ic gg with the name of the coordinate space. A coordinate space named .Ic gg cannot be reliably accessed by these macros. .Pp The macros are emitted immediately before the frame is drawn. .Pp DWB .Nm may use these as part of its implementation. This .Nm provides them only for compatibility. Note that these are very simple macros, and may not do what you expect under complex conditions. .Sh ENVIRONMENT VARIABLES .Pp If the environment variable .Ev GRAP_DEFINES is defined, .Nm will look for its defines file there. If that value is a relative path name the path specified in the .Fl M option will be searched for it. .Ev GRAP_DEFINES overrides the compiled in location of the defines file, but may be overridden by the .Fl d or .Fl D flags. .Pp If .Ev GRAP_SAFER is set, .Ic sprintf is disabled to prevent forcing .Nm to core dump or smash the stack. .Sh FILES .Pa /usr/local/share/grap/grap.defines .Sh SEE ALSO .Xr atan2 3 , .Xr groff 1 , .Xr pic 1 , .Xr printf 3 , .Xr sh 1 , .Xr sprintf 3 , .Xr troff 1 .Pp If documentation and examples have been installed, .Nm .Fl -version or .Nm .Fl -help will display the locations. .Sh BUGS .Pp There are several small incompatibilities with K&R .Nm grap . They include the .Ic sh command not expanding variables and macros, and a more strict adherence to parameter order in the internal commands. .Pp Although much improved, the error reporting code can still be confused. Notably, an error in a macro is not detected until the macro is used, and it produces unusual output in the error message. .Pp Iterating many times over a macro with no newlines can run .Nm out of memory. .Sh AUTHOR This implementation was done by .An Ted Faber Ao faber@lunabase.org Ac Ns . .An Bruce Lilly Ao blilly@erols.com Ac contributed many bug fixes, including a considerable revamp of the error reporting code. If you can actually find an error in your .Nm code, you can probably thank him. .Nm was designed and specified by .An Brian Kernighan and .An Jon Bentley . grap-1.43/grap_draw.cc000640 004133 000000 00000011600 10531454716 015055 0ustar00faberwheel000000 000000 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "grap.h" #include "grap_data.h" #include "grap_draw.h" // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. void coord::newx(double x) { // Specific code to add the x value. If the axis is being autoscaled, // see if this point expands it. Otherwise, sanity check it. if ( xautoscale == 2) { xmax = (x > xmax ) ? x : xmax; xmin = (x < xmin ) ? x : xmin; } if ( xautoscale == 1 ) { // first point xmax = xmin = x; xautoscale = 2; } if ( (logscale & x_axis) ) { if ( xmin < min_double ) { cerr << "Logscale with non-positive value (within precision)" << endl; xmin = min_double; } if ( xmax < min_double ) { cerr << "Logscale with non-positive value (within precision)" << endl; xmax = min_double; } } } void coord::newy(double y) { // Specific code to add the x value. If the axis is being autoscaled, // see if this point expands it. Otherwise, sanity check it. if ( yautoscale == 2) { ymax = (y > ymax ) ? y : ymax; ymin = (y < ymin ) ? y : ymin; } if ( yautoscale == 1 ) { // first point ymax = ymin = y; yautoscale = 2; } if ( (logscale & y_axis) ) { if ( ymin < min_double ) { cerr << "Logscale with non-positive value (within precision)" << endl; ymin = min_double; } if ( ymax < min_double ) { cerr << "Logscale with non-positive value (within precision)" << endl; ymax = min_double; } } } void coord::addmargin(double mf) { // Add a margin to the coordinate system to center the plot better. // The margin factor(mf) is given as a multiplier to the current size // (0.07 is 7% on either size). If the axis is logarithmic, we have // to work in that space. double range; // The size of the axis we're working on // Log sale must be positive if ( (logscale & x_axis) ) { if ( xmin < min_double ) xmin = min_double; if ( xmax < min_double ) xmax = min_double; } if ( (logscale & y_axis) ) { if ( ymin < min_double ) ymin = min_double; if ( ymax < min_double ) ymax = min_double; } if ( xautoscale ) { if ( logscale & x_axis) { double b, t; // bottom and top of the logscale range // Solving the log mapping equation for 1+mf and -mf // Isn't math cool? b = pow(xmax,-mf) / pow(xmin,(-mf-1)); t = pow(xmax,1+mf) / pow(xmin,mf); xmin = b; xmax = t; } else { range = xmax - xmin; xmin = xmin - mf * range; xmax = xmax + mf * range; } } if ( yautoscale ) { if ( logscale & y_axis) { double b, t; // bottom and top of the logscale range // Solving the log mapping equation for 1+mf and -mf // Isn't math cool? b = pow(ymax,-mf) / pow(ymin,(-mf-1)); t = pow(ymax,1+mf) / pow(ymin,mf); ymin = b; ymax = t; } else { range = ymax - ymin; ymin = ymin - mf * range; ymax = ymax + mf * range; } } // If they're too close together, just punt. (Actually this is less a punt // than it looks like. Adding 1 works if no points have been added that // would define a grid - xmin == xmax == 0 and if you do almost nothing you // get a (0,1) x (0,1) frame). if ( xmax == xmin) xmax += 1.0; if ( ymax == ymin) ymax += 1.0; } double coord::map(double v, axis ax ) { // map the coordinate from data space to [0,1]. 1 is the top of the axis, // 0 the bottom. Do it right for logscale or cartesian coordinates switch ( ax ) { case x_axis: if (logscale & x_axis ) { if ( v > min_double ) return ((log(v) -log(xmin)) / (log(xmax)-log(xmin))); else throw range_error("Negative or zero logscale coordinate"); } else return ( (v - xmin) / (xmax - xmin ) ); break; case y_axis: if (logscale & y_axis ) { if ( v > min_double ) return ((log(v) -log(ymin)) / (log(ymax)-log(ymin))); else throw range_error("Negative or zero logscale coordinate"); } else return ( (v - ymin) / (ymax - ymin ) ); break; default: return -1; break; } } // Linesegment constructor. Too long for a header, but // straightforward. Connect this segment to the previous point in the // line. linesegment::linesegment(double xx, double yy, coord* cc, line *ll, DisplayString *s /* =0 */, linedesc *l /* =0 */, bool a /* =false */) : to(xx,yy,cc), from(0) { point *p; // The last point on line ll. // If a null linedesc is passed in, use the one in the line if ( l ) desc = *l; else desc = ll->desc; if ( s ) plotstr = new DisplayString(*s); else { if ( ll->plotstr ) plotstr = new DisplayString(*ll->plotstr); else plotstr = 0; } arrow = a; if ((p = ll->lastplotted())) from = new point(p); ll->lastplotted(&to); } grap-1.43/grap_draw.h000640 004133 000000 00000050150 10625650214 014715 0ustar00faberwheel000000 000000 // -*-c++-*- #ifndef GRAP_DRAW_H #define GRAP_DRAW_H // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. // Names for the sides of graphs (_side because of globals left(), right()) typedef enum { top_side=0, bottom_side ,left_side, right_side} sides; // Styles of drawing lines typedef enum { solid, dotted, dashed, invis, def } linetype; // The axes of graphs typedef enum { none = 0, x_axis = 1, y_axis = 2, both=3} axis; // Justifications for strings, powers of two so we con combine them typedef enum { ljust = 1, rjust = 2, above = 4, below = 8, aligned = 16, unaligned=32} just; typedef struct { axis which; double min; double max; } axisdesc; typedef struct { double size; int rel; int just; bool clip; string *color; } strmod; class linedesc { // Basic class features for line descriptions: constructors, // destructor, and assignment public: linetype ld; // The basic style double param; // Some styles have parameters e.g., dotted 0.3 double fill; // Used for drawing solids, e.g. box string *color; // The name of a color for the line string *fillcolor ; // The color to fill a solid double thick; // Linethickness linedesc(linetype l=def, double p=0, string *c=0, double f=0, string *fc=0, double ft=0) : ld(l), param(p), fill(f), color(0), fillcolor(0), thick(ft) { if ( c ) color = new string(*c); if ( fc ) fillcolor = new string(*fc); } linedesc(const linedesc *l) { if ( l) { ld = l->ld; param = l->param; fill = l->fill; thick = l->thick; if ( l->color ) color = new string(*l->color); else color = 0; if ( l->fillcolor ) fillcolor = new string(*l->fillcolor); else fillcolor = 0; } else { ld = def; param = 0; color = 0; fillcolor = 0; fill = 0; thick = 0; } } linedesc(const linedesc& ldc) : ld(ldc.ld), param(ldc.param), fill(ldc.fill), color(0), fillcolor(0), thick(ldc.thick) { if ( ldc.color ) color = new string(*ldc.color); if ( ldc.fillcolor ) fillcolor = new string(*ldc.fillcolor); } // Make a new linedescriptor that combines the properites in ld1 and // ld2. linedesc(const linedesc* ld1, const linedesc* ld2) : ld(def), param(0), fill(0), color(0), fillcolor(0), thick(0) { if ( ld1 ) *this = *ld1; if ( ld2 && ld2->ld != def ) { ld = ld2->ld; param = ld2->param; } if ( (thick == 0) && ld2 && ld2->thick ) thick = ld2->thick; if ( ld2 && ld2->color ) color = new string(*ld2->color); } ~linedesc() { if ( color ) { delete color; color = 0; } if ( fillcolor ) { delete fillcolor; fillcolor = 0; } } linedesc& operator=(const linedesc &l) { ld = l.ld; param= l.param; fill = l.fill; thick = l.thick; if ( color ) { delete color; color = 0;} if ( l.color ) color = new string(*l.color); if ( fillcolor ) { delete fillcolor; fillcolor = 0;} if ( l.fillcolor ) fillcolor = new string(*l.fillcolor); return *this; } } ; class shiftdesc { // Basic class features for shift descriptions: constructors, // destructor, and assignment public: sides dir; // Direction to shift this label double param; // Amount to shift shiftdesc(sides s=top_side, double p=0) : dir(s), param(p) { } shiftdesc(const shiftdesc *sh ) { if ( sh ) { dir = sh->dir; param = sh->param; } else { dir = top_side; param = 0; } } }; // This functor copies one shiftlist into another, making copies of // each shiftdesc on the list. It's used by various objects that have // shiftlists in them. Each element is inserted at the back class shiftcpy : public unary_function { protected: shiftlist *s; // The new shiftlist public: shiftcpy(shiftlist *ss) : s(ss) { } int operator() (shiftdesc *sd) { shiftdesc *sd2 = new shiftdesc(sd); s->push_back(sd2); return 1; } }; class frame; // An abstract class that means that an object is drawable, and // priovides a method with which to draw itself. Drawing is always // relative to a frame. Because drawable classes are managed by the // graph structure, drawable also supplies a smart allocation system. class drawable { public: virtual void draw(frame *) = 0; // So we get the right size to delete (ick) virtual ~drawable() { } }; typedef list objlist; class DisplayString : public string { // These are primarily used to keep track of the extended string // info. A drawable class is derived to display them. public: int j; // justification modifiers (should be just, // but int supports | and & double size; // Fontsize int relsz; // True if the fontsize is relative bool clip; // True if the string can only appear in the frame string *color; // color of the string DisplayString() : string(), j(none), size(0), relsz(0), clip(true), color(0) { } DisplayString(const char *s, int ju=0, double sz=0, int rsz=0, bool c=true, string *col=0) : string(s), j(ju), size(sz), relsz(rsz), clip(c), color(col) { } DisplayString(string s, int ju=0, double sz=0, int rsz=0, bool c=true, string *col=0) : string(s), j(ju), size(sz), relsz(rsz), clip(c), color(col) { } DisplayString(const DisplayString& ds) : string(ds), j(ds.j), size(ds.size), relsz(ds.relsz), clip(ds.clip), color(ds.color) { if ( color ) color = new string(*color); } DisplayString(double e, const DisplayString *fmt=0) : j(0), size(0), relsz(0), clip(true), color(0) { char *c = new char[64]; bool delf = false; if ( !fmt) { fmt = new DisplayString("%g"); delf = true; } snprintf(c,64,fmt->c_str(),e); // *this = c; assign(c); delete[] c; if ( delf ) delete fmt; else { j = fmt->j; size = fmt->size; relsz = fmt->relsz; clip = fmt->clip; if ( fmt->color ) color = new string(*fmt->color); else color = 0; } } ~DisplayString() { delete color; } }; // A grap coordinate system class coord { public: coord() : xmin(0), xmax(0),ymin(0), ymax(0), logscale(none), xautoscale(1), yautoscale(1), name() { } coord(const string& s) : xmin(0), xmax(0),ymin(0), ymax(0), logscale(none), xautoscale(1), yautoscale(1), name(s) { } coord(axis ls) : xmin(0), xmax(0),ymin(0), ymax(0), logscale(ls), xautoscale(1), yautoscale(1), name() { } coord(axis ls, const string& s) : xmin(0), xmax(0),ymin(0), ymax(0), logscale(ls), xautoscale(1), yautoscale(1), name(s) { } coord(double xi, double xa, double yi, double ya, axis ls) : xmin(xi), xmax(xa),ymin(yi), ymax(ya),logscale(ls), xautoscale(0), yautoscale(0), name() { } coord(double xi, double xa, double yi, double ya, axis ls, const string& s) : xmin(xi), xmax(xa),ymin(yi), ymax(ya),logscale(ls), xautoscale(0), yautoscale(0), name(s) { } coord(const coord& c) : xmin(c.xmin), xmax(c.xmax), ymin(c.ymin), ymax(c.ymax), logscale(c.logscale), xautoscale(c.xautoscale), yautoscale(c.yautoscale), name(c.name) { } double xmin, xmax; // x range double ymin, ymax; // y range axis logscale; // The axes that are logarithmic int xautoscale; // True if the user has not given an explicit x range int yautoscale; // True if the user has not given an explicit y range string name; // Name of the coordinate system, if any void newpt(double x, double y) { newx(x); newy(y); } void newx(double); void newy(double); // Add a margin to the system (0.07 is 7%) handles log scales void addmargin(double); // Convert to [0,1] double map(double, axis); }; class tick { public: double where; // x or y value of the tick double size; // how large a tick mark to make sides side; // Which side of the graph the mark is on DisplayString *prt; // The string to print next to the mark shiftlist shift; // Shift information, to fine tune position of prt coord *c; // The coordinate scale that the tick is in tick() : where(0), size(0), side(top_side), prt(0), shift(), c(0) { } tick(const tick& t) : where(t.where), size(t.size), side(t.side), shift(), c(t.c) { shiftcpy sc(&shift); if ( t.prt ) prt = new DisplayString(*t.prt); else prt =0; for_each(t.shift.begin(), t.shift.end(), sc); } tick(double w, double s, sides sd, DisplayString *p, shiftlist *sh, coord *co) : where(w), size(s), side(sd), shift(), c(co) { shiftcpy sc(&shift); if ( p ) prt = new DisplayString(*p); else prt =0; if ( sh ) for_each(sh->begin(), sh->end(), sc); } ~tick() { shiftdesc *s; if ( prt) { delete prt; prt = 0; } while ( !shift.empty() ) { s = shift.front(); shift.pop_front(); delete s; } } // Important safety tip: Don't byte-copy string pointers. tick& operator=(const tick& t) { shiftcpy sc(&shift); where = t.where; size = t.size; side = t.side; shift = t.shift; c = t.c; if ( prt ) { delete prt; } if ( t.prt ) prt = new DisplayString(*t.prt); else prt = 0; for_each(t.shift.begin(), t.shift.end(), sc); return *this; } }; class grid { public: double where; // x or y value of the grid line linedesc desc; // style of the grid line sides side; // Side of the graph where line labels are printed DisplayString *prt; // The label for this line shiftlist shift; // Shift info for the label coord *c; // Coordinate system for this line grid() : where(0), desc(dotted,0,0), side(top_side), prt(0), shift(), c(0) { } grid(double w, linedesc *l, sides sd, DisplayString *p, shiftlist *sh, coord *co) : where(w), desc(l), side(sd), prt(0), shift(), c(co) { shiftcpy sc(&shift); if ( p ) prt = new DisplayString(*p); if ( sh ) for_each(sh->begin(), sh->end(), sc); } // To allow ticks and grids to share parse rules grid(const tick *t) : where(t->where), desc(dotted,0,0), side(t->side), prt(0), shift(), c(t->c) { shiftcpy sc(&shift); if ( t->prt ) prt = new DisplayString(*t->prt); for_each(t->shift.begin(), t->shift.end(), sc); } grid(const grid& g) : where(g.where), desc(g.desc), side(g.side), prt(0), shift(), c(g.c) { shiftcpy sc(&shift); if ( g.prt ) prt = new DisplayString(*g.prt); for_each(g.shift.begin(), g.shift.end(), sc); } ~grid() { shiftdesc *s; if ( prt ) { delete prt; prt = 0; } while ( !shift.empty() ) { s = shift.front(); shift.pop_front(); delete s; } } // Important safety tip: Don't byte-copy string pointers. grid& operator=(const grid& g) { shiftcpy sc(&shift); where = g.where; desc = g.desc; side = g.side; shift = g.shift; c = g.c; if ( prt ) delete prt; if ( g.prt ) prt = new DisplayString(*g.prt); else prt = 0; for_each(g.shift.begin(), g.shift.end(), sc); return *this; } }; class point { public: double x,y; // Point coordinates coord *c; // system the coordinates are in point() : x(0), y(0), c(0) {} point(double xx, double yy, coord* cc) : x(xx), y(yy), c(cc) { if ( c ) c->newpt(x, y); } point(const point *p) : x(p->x), y(p->y), c(p->c) { if ( c ) c->newpt(x, y); } point(const point& p) : x(p.x), y(p.x), c(p.c) { } point& operator=(point &p) { x = p.x; y = p.y; c = p.c; return *this; } }; class frame { // The frame is the physical description of the graph axes. It's // height and width are used by all drawable classes. public: double ht; // height of the graph double wid; // width linedesc desc[4]; // The line styles for the axes stringlist *label[4]; // labels for the axes. These are // lists of DisplayStrings that must // be translated by the associated // drawable class shiftlist *lshift[4]; // positioning info for labels tick tickdef[4]; // default tick definitions grid griddef[4]; // default gridline definitions ticklist tks; // the ticks to draw (generated from // defaults if unspecified by the user) gridlist gds; // gridlines to draw frame() : ht(2), wid(3), tks(), gds() { DisplayString g = "%g"; for ( int i = 0 ; i < 4 ; i ++ ) { desc[i] = linedesc(def,0,0); label[i] = new stringlist; lshift[i] = new shiftlist; griddef[i] = grid(0.0, desc+i, top_side, &g, lshift[i], 0); tickdef[i] = tick(0.0,((i== bottom_side || i == left_side ) ? 0.125 : 0), (sides) i, &g, lshift[i], 0); } } virtual ~frame() { for ( int i = 0; i < 4; i++ ) { if ( label[i] ) { stringlist::iterator s; for (s = label[i]->begin(); s != label[i]->end(); s++) delete (*s); label[i]->erase(label[i]->begin(), label[i]->end()); delete label[i]; label[i] =0; } if ( lshift[i] ) { shiftlist::iterator s; for (s = lshift[i]->begin(); s != lshift[i]->end(); s++) delete (*s); lshift[i]->erase(lshift[i]->begin(), lshift[i]->end()); delete lshift[i]; lshift[i] =0; } } if ( !tks.empty() ) { ticklist::iterator t; for (t = tks.begin(); t != tks.end(); t++) delete (*t); tks.erase(tks.begin(), tks.end()); } if ( !gds.empty() ) { gridlist::iterator g; for (g = gds.begin(); g != gds.end(); g++) delete (*g); gds.erase(gds.begin(), gds.end()); } } }; // A class that describes each point on the line. Each can have a // different plotting symbol or drawing style. class linesegment { public: point to; // The end point of this segment point *from; // the point this segment started from (if any) linedesc desc; // style for the connection to this point DisplayString *plotstr; // string to plot bool arrow; // true if the connection ends with an arrow linesegment() : to(), from(0), desc(invis, 0.0, 0), plotstr(0), arrow(false) { } ; linesegment(double xx, double yy, coord* cc, line *ll, DisplayString *s=0, linedesc *l=0, bool a=0); linesegment(const linesegment& ls) : to(ls.to), desc(ls.desc), plotstr(0) , arrow(ls.arrow) { if ( ls.from ) from = new point(ls.from); if ( ls.plotstr ) plotstr = new DisplayString(*ls.plotstr); } ~linesegment() { delete plotstr; plotstr = 0; delete from; from = 0; } }; class line { public: DisplayString *plotstr; // default plotting string linedesc desc; // Default connection style point *lastpoint; // The last point plotted on the line line() : plotstr(0), desc(), lastpoint(0) {} line(linedesc *l, DisplayString *s=0 ) : plotstr(0), desc(l), lastpoint(0) { if (s) plotstr = new DisplayString(*s); } line(const line& l) : plotstr(0), desc(l.desc), lastpoint(0) { if ( l.plotstr ) { plotstr = new DisplayString(*l.plotstr); } } ~line() { delete plotstr; plotstr = 0; } // Access to the last point plotted on the line, if any. point *lastplotted() { return lastpoint; } point *lastplotted(point *p) { if (!p) { delete lastpoint; lastpoint = 0; } else { if ( !lastpoint ) lastpoint = new point(p); else *lastpoint = *p; } return lastpoint; } }; class plot { // A string or set of strings drawn on the graph public: stringlist *strs; // the strings to draw point* loc; // The location to put them at plot(stringlist *s = 0, point *p =0, bool clip=true) : strs(s), loc(p) { } // copy constructors have to copy ... plot(const plot& p ) : strs(0), loc(0) { if (p.loc) loc = new point(p.loc); if ( p.strs ) { stringlist::iterator dsi; strs = new stringlist(); for ( dsi = p.strs->begin(); dsi != p.strs->end(); dsi++ ) { DisplayString *ds = *dsi; DisplayString *nds = new DisplayString(*ds); strs->push_back(nds); } } } ~plot() { if ( strs ) { DisplayString *ds; while ( !strs->empty()) { ds = strs->front(); strs->pop_front(); delete ds; } delete strs; strs = 0; } if ( loc ) { delete loc ; loc = 0; } } }; class circle { public: point center; // center of the circle double rad; // radius linedesc ld; circle() : center(0,0,0), rad(0), ld(solid) { } circle(point *p, double r, linedesc *l=0) : center(p), rad(r), ld(solid) { if ( l ) ld = *l; } circle(const circle& c) : center(&c.center), rad(c.rad), ld(c.ld) { } }; class box { public: point p1; // upper left and point p2; // lower right points linedesc ld; // Line style for the box box() : p1(), p2(), ld() { } box(point *pp1, point *pp2, linedesc *l) : p1(pp1), p2(pp2), ld(l) { } box(const box &b) : p1(b.p1), p2(b.p2), ld(b.ld) { } }; class graph : public drawable { // Catchall data structure for each graph in progress. It will be // the base class for various subclasses for specific output // devices protected: // These are internal functors to delete and display lists. class displayer_f : unary_function { frame *base; public: displayer_f(frame *f) : base(f) {} ; int operator()(drawable *d) { d->draw(base); return 0;} }; class obj_freer_f : public unary_function { public: int operator()(drawable *d) { delete d; return 0; } } obj_freer; class coord_freer_f : public unary_function { public: int operator()(coordinateDictionary::value_type ci) { coord *c = ci.second; delete c; return 0; } } coord_freer; class line_freer_f : public unary_function { public: int operator()(lineDictionary::value_type li) { line *l = li.second; delete l; return 0; } } line_freer; class addmargin_f : public unary_function { public: int operator() (coordinateDictionary::value_type cp) { coord *c = cp.second; c->addmargin(0.07); return 0; } } addmargin; public: objlist objs; // The elements of the graph coordinateDictionary coords;// The coodrinate systems defined lineDictionary lines; // The lines being defined for this graph frame *base; // The frame surrounding this graph string *name; // The name of the graph bool visible; // is this graph visible? graph() : objs(), coords(), lines(), base(0), name(0), visible(false) { } virtual ~graph() { init(); } void setname(string *n=0) { if ( n ) name = new string(*n); else { delete name; name = 0; } } // This clears graph parameters virtual void init(string *n =0, string* =0 ) { objlist::iterator o; coordinateDictionary::iterator c; lineDictionary::iterator l; visible = false; for (o = objs.begin(); o != objs.end(); o++) delete (*o); objs.erase(objs.begin(), objs.end()); for (c = coords.begin(); c != coords.end(); c++) delete (*c).second; coords.erase(coords.begin(), coords.end()); for (l = lines.begin(); l != lines.end(); l++) delete (*l).second; lines.erase(lines.begin(), lines.end()); delete base; base =0; setname(n); } bool is_visible() { return visible; } bool is_visible(bool v) { return visible = v; } // Called when a .G1 is encountered virtual void begin_block(string *) { } // Called when a .G2 is encountered virtual void end_block() { } // Called when pic or troff strings are found virtual void passthru_string(const string& ) { } // Virtual functions to allocate the proper subclassed elements. // Each real function should allocate an element and place it on // the objs list of the graph. It returns the base class of the // object created. The returned element is a pointer to the // object on the list. Don't delete it, although you can modify // it. virtual linesegment *new_linesegment(double x, double y, coord* c, line *l, DisplayString *s=0, linedesc *ld=0, bool a=false) =0; virtual plot *new_plot(stringlist *s =0, point *p=0) =0; virtual circle *new_circle(point *p, double r, linedesc *l=0) =0; virtual box *new_box(point *p1, point *p2, linedesc *l) = 0; // put a drawable version of the frame on the object list. virtual void queue_frame() =0; }; #endif grap-1.43/grap.man000660 004133 000000 00000122644 11076255041 014236 0ustar00faberwheel000000 000000 GRAP(1) FreeBSD General Commands Manual GRAP(1) NNAAMMEE ggrraapp -- Kernighan and Bentley's language for typesetting graphs SSYYNNOOPPSSIISS ggrraapp [--dd _d_e_f_i_n_e_s___f_i_l_e] [--DD] [--ll] [--MM _i_n_c_l_u_d_e _p_a_t_h] [--RR] [--rr] [--vv] [--uu] [--CC] [--cc] [--hh] [_f_i_l_e_n_a_m_e _._._.] DDEESSCCRRIIPPTTIIOONN ggrraapp is an implementation of Kernighan and Bentley's language for type- setting graphs, as described in ``Grap-A Language for Typesetting Graphs, Tutorial and User Manual,'' by Jon L. Bentley and Brian W. Kernighan, revised May 1991, which is the primary source for information on how to use ggrraapp. As of this writing, it is available electronically at http://www.kohala.com/start/troff/cstr114.ps. Additional documentation and examples, packaged with ggrraapp, may have been installed locally as well. If available, paths to them can be displayed using ggrraapp --hh or ggrraapp --vv (or ggrraapp ----hheellpp / ggrraapp ----vveerrssiioonn) This version is a black box implementation of ggrraapp, and some inconsisten- cies are to be expected. The remainder of this manual page will briefly outline the ggrraapp language as implemented here. ggrraapp is a pic(1) pre-processor. It takes commands embedded in a troff(1) source file which are surrounded by ..GG11 and ..GG22 macros, and rewrites them into pic commands to display the graph. Other lines are copied. Output is always to the standard output, which is usually redirected. Input is from the given _f_i_l_e_n_a_m_es, which are read in order. A _f_i_l_e_n_a_m_e of -- is the standard input. If no _f_i_l_e_n_a_m_es are given, input is read from the standard input. Because ggrraapp is a pic preprocessor, and GNU pic will output TeX, it is possible to use ggrraapp with TeX. The --dd option specifies a file of macro definitions to be read at startup, and defaults to /usr/local/share/grap/grap.defines . The --DD option inhibits the reading of any initial macros file (the --ll flag is a synonym for --DD, though I do not remember why). The defines file can also be given using the GRAP_DEFINES environment variable. (See below). --vv prints the version information on the standard output and exits. ----vveerrssiioonn is a synonym for --vv. --uu makes labels unaligned by default. This version of ggrraapp uses new fea- tures of GNU pic to align the left and right labels with the axes, that is that the left and right labels run at right angles to the text of the paper. This may be useful in porting old ggrraapp programs. --cc makes plot strings unclipped by default. Some versions of ggrraapp allow users to place a string anywhere in the coordinate space, rather than only in the frame. By default this version of ggrraapp does not plot any string centered outside the frame. --cc allows strings to be placed anywhere. See also the cclliippppeedd and uunncclliippppeedd string modifiers described in the pplloott statement. --MM is followed by a colon-separated list of directories used to search for relative pathnames included via ccooppyy. The path is also used to locate the defines file, so if the --dd changes the defines file name to a relative name, it will be searched for in the path given by --MM. The search path always includes the current directory, and by default that directory is searched last. All numbers used internally by ggrraapp are double precision floating point values. Sometimes using floating point numbers has unintended conse- quences. To help avoid these problems, ggrraapp can use two thresholds for comparison of floating point numbers, set by --RR or --rr. The --RR flag sets coarse comparison mode, which is suitable for most applications. If you are plotting small values - less than 1e-6 or so - consider using --rr which uses very fine comparisons between numbers. You may also want to rescale your plotted values to be larger in magnitude. The coarse comarisons are used by default. To be precise, the value by which two numbers must differ for ggrraapp to consider them not equal is called the comparison limit and the smallest non-zero number is called the minimum value. The values a given version of ggrraapp uses for these are included in the output of --vv or --hh. All ggrraapp commands are included between ..GG11 and ..GG22 macros, which are con- sumed by ggrraapp. The output contains pic between ..PPSS and ..PPEE macros. Any arguments to the ..GG11 macro in the input are arguments to the ..PPSS macro in the output, so graphs can be scaled just like pic diagrams. If --CC is given, any macro beginning with .G1 or .G2 is treated as a .G1 or .G2 macro, for compatibility with old versions of troff. Using --CC also forces pure troff syntax on embedded font change commands when strings have the ssiizzee attribute, and all strings to be uunncclliippppeedd. The --hh flag prints a brief help message and exits. ----hheellpp is a synonym for --hh. It is possible for someone to cause ggrraapp to fail by passing a bad format string and data to the sspprriinnttff command. If ggrraapp is integrated as part of the printing system, this could conceivably provided a path to breaching security on the machine. If you choose to use ggrraapp as part of a printing system run by the super-user, you should disable sspprriinnttff commands. This can be done by calling ggrraapp with the --SS flag, setting the GRAP_SAFER environment variable, or compiling with the GRAP_SAFER preprocessor sym- bol defined. (The GNU configure script included with ggrraapp will define that preprocessor symbol if the ----wwiitthh--ggrraapp--ssaaffee option is given.) The ggrraapp commands are sketched below. Refer to Kernighan and Bentley's paper for the details. New versions of groff(1) will invoke ggrraapp if --GG is given. CCoommmmaannddss Commands are separated from one another by newlines or semicolons (;). ffrraammee [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] [hhtt _h_e_i_g_h_t | wwiidd _w_i_d_t_h] [[(ttoopp|bboottttoomm|lleefftt| rriigghhtt) _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] ...] ffrraammee [hhtt _h_e_i_g_h_t | wwiidd _w_i_d_t_h] [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] [[(ttoopp|bboottttoomm|lleefftt| rriigghhtt) _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] ...] This describes how the axes for the graph are drawn. A _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n is a pic line description, e.g., dashed 0.5, or the literal solid. It may also include a ccoolloorr keyword followed by the color to draw the string in double quotes. Any color under- stood by the underlying groff system can be used. Color can only be used under GNU pic, and is not available in compatibility mode. Similarly, for pic implementations that understand tthhiicckknneessss, that attribute may be used with a real valued parameter. TThhiicckknneessss is not available in compatibility mode. If the first _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n is given, the frame is drawn with that style. The default is solid. The height and width of the frame can also be specified in inches. The default line style can be over-ridden for sides of the frame by specifying additional parameters to ffrraammee. If no plotting commands have been given before the ffrraammee command is issued, the frame will be output at that point in the plotting stream relative to embedded troff or pic commands. Otherwise the frame is output before the first plotted object (even invisible ones). hhtt and wwiidd are in inches by default, but can be any groff unit. If omitted, the dimensions are 2 inches high by 3 inches wide. ccoooorrdd [_n_a_m_e] [xx _e_x_p_r, _e_x_p_r] [yy _e_x_p_r, _e_x_p_r] [lloogg xx | lloogg yy | lloogg lloogg] The ccoooorrdd command specifies a new coordinate system or sets limits on the default system. It defines the largest and smallest values that can be plotted, and therefore the scale of the data in the frame. The limits for the x and y coordinate systems can be given separately. If a _n_a_m_e is given, that coordinate system is defined, if not the default system is modified. A coordinate system created by one ccoooorrdd command may be modified by subsequent ccoooorrdd commands. A ggrraapp program may declare a coordinate space using ccoooorrdd, ccooppyy a file of data through a macro that plots the data and finds its maxima and minima, and then define the size of the coordinate system with a second ccoooorrdd statement. This command also determines if a scale is plotted logarithmically. lloogg lloogg means the same thing as lloogg xx lloogg yy. ddrraaww [_l_i_n_e___n_a_m_e] [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] [_p_l_o_t___s_t_r_i_n_g] The ddrraaww command defines the style with which a given line will be plotted. If _l_i_n_e___n_a_m_e is given, the style is associated with that name, otherwise the default style is set. _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n is a pic line description, and the optional _p_l_o_t___s_t_r_i_n_g is a string to be centered at each point. The default line description is invis, and the default plotting string is a centered bullet, so by default each point is a filled circle, and they are unconnected. If points are being connected, each ddrraaww command ends any current line and begins a new one. When defining a line style, that is the first ddrraaww command for a given line name, specifying no plot string means that there are to be no plot strings. Omitting the plot string on subsequent ddrraaww commands addressing the same named line means not to change the plot string. If a line has been defined with a plot string, and the format is changed by a subsequent ddrraaww statement, the plot string can be removed by specifying "" in the ddrraaww statement. The plot string can have its format changed through several string_modifiers. String_modifiers are described in the descrip- tion of the pplloott command. The standard defines file includes several macros useful as plot strings, including bbuulllleett, ssqquuaarree, and ddeellttaa. nneeww is a synonym for ddrraaww. nneexxtt [_l_i_n_e___n_a_m_e] aatt [_c_o_o_r_d_i_n_a_t_e_s___n_a_m_e] _e_x_p_r, _e_x_p_r [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] The nneexxtt command plots the given point using the line style given by _l_i_n_e___n_a_m_e, or the default if none is given. If _l_i_n_e___n_a_m_e is given, it should have been defined by an earlier ddrraaww command, if not a new line style with that name is created, initialized the same way as the default style. The two expressions give the point's x and y values, relative to the optional coordinate system. That system should have been defined by an earlier ccoooorrdd command, if not, grap will exit. If the optional _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n is given, it overrides the style's default line description. You cannot over-ride the plotting string. To use a different plotting string use the pplloott command. The coordinates may optionally be enclosed in parentheses: (_e_x_p_r, _e_x_p_r) _q_u_o_t_e_d___s_t_r_i_n_g [_s_t_r_i_n_g___m_o_d_i_f_i_e_r_s] [, _q_u_o_t_e_d___s_t_r_i_n_g [_s_t_r_i_n_g___m_o_d_i_f_i_e_r_s]] ... aatt [_c_o_o_r_d_i_n_a_t_e_s___n_a_m_e] _e_x_p_r, _e_x_p_r pplloott _e_x_p_r [_f_o_r_m_a_t___s_t_r_i_n_g] aatt [_c_o_o_r_d_i_n_a_t_e_s___n_a_m_e] _e_x_p_r, _e_x_p_r These commands both plot a string at the given point. In the first case the literal strings are stacked above each other. The string_modifiers include the pic justification modifiers (lljjuusstt, rrjjuusstt, aabboovvee, and bbeellooww), and absolute and relative size modifiers. See the pic documentation for the description of the justification modifiers. ggrraapp also supports the aalliiggnneedd and uunnaalliiggnneedd modifiers which are briefly noted in the description of the llaabbeell command. The standard defines file includes several macros useful as plot strings, including bbuulllleett, ssqquuaarree, and ddeellttaa. Strings placed by either format of the pplloott command are restricted to being within the frame. This can be overriden by using the uunncclliippppeedd attribute, which allows a string to be plotted in or out of the frame. The --cc and --CC flags set uunncclliippppeedd on all strings, and to prevent a string from being plotted outside the frame when those flags are active, the cclliippppeedd attribute can be used to retore clipping behavior. Though cclliippppeedd or uunncclliippppeedd can be applied to any string, it only has meaning for pplloott statements. size _e_x_p_r sets the string size to _e_x_p_r points. If _e_x_p_r is preceded by a + or -, the size is increased or decreased by that many points. If ccoolloorr and a color name in double quotes appears, the string will be rendered in that color under a version of GNU troff that sup- ports color. Color is not available in compatibility mode. In the second version, the _e_x_p_r is converted to a string and placed on the graph. _f_o_r_m_a_t___s_t_r_i_n_g is a printf(3) format string. Only formatting escapes for printing floating point numbers make sense. The format string is only respected if the sspprriinnttff command is also active. See the description of sspprriinnttff for the various ways to disable it. PPlloott and sspprriinnttff respond differently when ggrraapp is run- ning safely. SSpprriinnttff ignores any arguments, passing the format string through without substitution. pplloott ignores the format string completely, plotting _e_x_p_r using the "%g" format. Points are specified the same way as for nneexxtt commands, with the same consequences for undefined coordinate systems. The second form of this command is because the first form can be used with a ggrraapp sspprriinnttff expression (See _E_x_p_r_e_s_s_i_o_n_s). ttiicckkss (lleefftt|rriigghhtt|ttoopp|bboottttoomm)[ (iinn|oouutt) [_e_x_p_r]] [oonn||aauuttoo _c_o_o_r_d___n_a_m_e] ttiicckkss (lleefftt|rriigghhtt|ttoopp|bboottttoomm) (iinn|oouutt) [_e_x_p_r] [uupp _e_x_p_r | ddoowwnn _e_x_p_r | lleefftt _e_x_p_r | rriigghhtt _e_x_p_r] aatt [_c_o_o_r_d___n_a_m_e] _e_x_p_r [_f_o_r_m_a_t___s_t_r_i_n_g] [[, _e_x_p_r [_f_o_r_m_a_t___s_t_r_i_n_g]] ...] ttiicckkss (lleefftt|rriigghhtt|ttoopp|bboottttoomm) (iinn|oouutt) [_e_x_p_r] [uupp _e_x_p_r | ddoowwnn _e_x_p_r | lleefftt _e_x_p_r | rriigghhtt _e_x_p_r] ffrroomm [coord_name] _s_t_a_r_t___e_x_p_r ttoo _e_n_d___e_x_p_r [bbyy [+|-|*|/] _b_y___e_x_p_r] [format_string] ttiicckkss [lleefftt|rriigghhtt|ttoopp|bboottttoomm] ooffff This command controls the placement of ticks on the frame. By default, ticks are automatically generated on the left and bottom sides of the frame. The first version of this command turns on the automatic tick gen- eration for a given side. The iinn or oouutt parameter controls the direction and length of the ticks. If a _c_o_o_r_d___n_a_m_e is specified, the ticks are automatically generated using that coordinate system. If no system is specified, the default coordinate system is used. As with nneexxtt and pplloott, the coordinate system must be declared before the ttiicckkss statement that references it. This syntax for requesting automatically generated ticks is an extension, and will not port to older ggrraapp implementations. The second version of the ttiicckkss command overrides the automatic placement of the ticks by specifying a list of coordinates at which to place the ticks. If the ticks are not defined with respect to the default coordinate system, the _c_o_o_r_d___n_a_m_e parameter must be given. For each tick a printf(3) style format string can be given. The _f_o_r_m_a_t___s_t_r_i_n_g defaults to "%g". The format string can also take string modifiers as described in the pplloott command. To place ticks with no labels, specify _f_o_r_m_a_t___s_t_r_i_n_g as "". If sspprriinnttff is disabled, ttiicckkss behaves as pplloott with respect to the format string. The labels on the ticks may be shifted by specifying a direction and the distance in inches to offset the label. That is the optional direction and expression immediately preceding the aatt. The third format of the ttiicckkss command over-rides the default tick generation with a set of ticks ar regular intervals. The syntax is reminiscent of programming language for loops. Ticks are placed starting at _s_t_a_r_t___e_x_p_r ending at _e_n_d___e_x_p_r one unit apart. If the bbyy clause is specified, ticks are _b_y___e_x_p_r units apart. If an oper- ator appears before _b_y___e_x_p_r each tick is operated on by that opera- tor instead of +. For example ticks left out from 2 to 32 by *2 will put ticks at 2, 4, 8, 16, and 32. If _f_o_r_m_a_t___s_t_r_i_n_g is speci- fied, all ticks are formatted using it. The parameters preceding the ffrroomm act as described above. The aatt and ffoorr forms of tick command may both be issued on the same side of a frame. For example: ticks left out from 2 to 32 by *2 ticks left in 3, 5, 7 will put ticks on the left side of the frame pointing out at 2, 4, 8, 16, and 32 and in at 3, 5, and 7. The final form of ttiicckkss turns off ticks on a given side. If no side is given the ticks for all sides are cancelled. ttiicckk is a synonym for ttiicckkss. ggrriidd (lleefftt|rriigghhtt|ttoopp|bboottttoomm) [ticks off] [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] [uupp _e_x_p_r | ddoowwnn _e_x_p_r | lleefftt _e_x_p_r | rriigghhtt _e_x_p_r] [oonn||aauuttoo [_c_o_o_r_d___n_a_m_e]] ggrriidd (lleefftt|rriigghhtt|ttoopp|bboottttoomm) [ticks off] [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] [uupp _e_x_p_r | ddoowwnn _e_x_p_r | lleefftt _e_x_p_r | rriigghhtt _e_x_p_r] aatt [_c_o_o_r_d___n_a_m_e] _e_x_p_r [_f_o_r_m_a_t___s_t_r_i_n_g] [[, _e_x_p_r [_f_o_r_m_a_t___s_t_r_i_n_g]] ...] ggrriidd (lleefftt|rriigghhtt|ttoopp|bboottttoomm) [ticks off] [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] [uupp _e_x_p_r | ddoowwnn _e_x_p_r | lleefftt _e_x_p_r | rriigghhtt _e_x_p_r] ffrroomm [coord_name] _s_t_a_r_t___e_x_p_r ttoo _e_n_d___e_x_p_r [bbyy [+|-|*|/] _b_y___e_x_p_r] [format_string] The ggrriidd command is similar to the ttiicckkss command except that ggrriidd specifies the placement of lines in the frame. The syntax is simi- lar to ttiicckkss as well. By specifying ticks off in the command, no ticks are drawn on that side of the frame. If ticks appear on a side by default, or have been declared by an earlier ttiicckkss command, ggrriidd does not cancel them unless ticks off is specified. Instead of a direction for ticks, ggrriidd allows the user to pick a line description for the grid lines. The usual pic line descrip- tions are allowed. Grids are labelled by default. To omit labels, specify the format string as "". If sspprriinnttff is disabled, ggrriidd behaves as pplloott with respect to the format string. llaabbeell (lleefftt|rriigghhtt|ttoopp|bboottttoomm) _q_u_o_t_e_d___s_t_r_i_n_g [_s_t_r_i_n_g___m_o_d_i_f_i_e_r_s] [, _q_u_o_t_e_d___s_t_r_i_n_g [_s_t_r_i_n_g___m_o_d_i_f_i_e_r_s]] ... [uupp _e_x_p_r | ddoowwnn _e_x_p_r | lleefftt _e_x_p_r | rriigghhtt _e_x_p_r] The llaabbeell command places a label on the given axis. It is possible to specify several labels, which will be stacked over each other as in pic. The final argument, if present, specifies how many inches the label is shifted from the axis. By default the labels on the left and right labels run parallel to the frame. You can cancel this by specifying unaligned as a _s_t_r_i_n_g___m_o_d_i_f_i_e_r. cciirrccllee aatt [_c_o_o_r_d_i_n_a_t_e___n_a_m_e] _e_x_p_r, _e_x_p_r [rraaddiiuuss _e_x_p_r] [_l_i_n_e_d_e_s_c] This draws an circle at the point indicated. By default, the cir- cle is small, 0.025 inches. This can be over-ridden by specifying a radius. The coordinates of the point are relative to the named coordinate system, or the default system if none is specified. This command has been extended to take a line description, e.g., dotted. It also accepts the filling extensions described below in the bbaarr command. It will also accept a ccoolloorr keyword that gives the color of the outline of the circle in double quotes and a ffiillllccoolloorr command that sets the color to fill the circle with simi- larly. Colors are only available when compatibility mode is off, and using a version of GNU pic that supports color. lliinnee [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] ffrroomm [_c_o_o_r_d_i_n_a_t_e___n_a_m_e] _e_x_p_r, _e_x_p_r ttoo [_c_o_o_r_d_i_n_a_t_e___n_a_m_e] _e_x_p_r, _e_x_p_r [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] aarrrrooww [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] ffrroomm [_c_o_o_r_d_i_n_a_t_e___n_a_m_e] _e_x_p_r, _e_x_p_r ttoo [_c_o_o_r_d_i_n_a_t_e___n_a_m_e] _e_x_p_r, _e_x_p_r [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] This draws a line or arrow from the first point to the second using the given style. The default line style is solid. The _l_i_n_e___d_e_s_c_r_i_p_t_i_o_n can be given either before the ffrroomm or after the ttoo clause. If both are given the second is used. It is possible to specify one point in one coordinate system and one in another, note that if both points are in a named coordinate system (even if they are in the same named coordinate system), both points must have _c_o_o_r_d_i_n_a_t_e___n_a_m_e given. ccooppyy ["_f_i_l_e_n_a_m_e"] [uunnttiill "_s_t_r_i_n_g"] [tthhrruu _m_a_c_r_o] The ccooppyy command imports data from another file into the current graph. The form with only a filename given is a simple file inclu- sion; the included file is simply read into the input stream and can contain arbitrary ggrraapp commands. The more common case is that it is a number list; see _N_u_m_b_e_r _L_i_s_t_s below. The second form takes lines from the file, splits them into words delimited by one or more spaces, and calls the given macro with those words as parameters. The macro may either be defined here, or be a macro defined earlier. See _M_a_c_r_o_s for more information on macros. The _f_i_l_e_n_a_m_e may be omitted if the uunnttiill clause is present. If so the current file is treated as the input file until _s_t_r_i_n_g is encountered at the beginning of the line. ccooppyy is one of the workhorses of ggrraapp. Check out the paper and _/_u_s_r_/_l_o_c_a_l_/_s_h_a_r_e_/_e_x_a_m_p_l_e_s_/_g_r_a_p for more details. Confirm the loca- tion of the examples directory using the --vv flag. pprriinntt (_e_x_p_r_|_s_t_r_i_n_g) Prints its argument to the standard error. sshh _b_l_o_c_k This passes _b_l_o_c_k to sh(1). Unlike K&B ggrraapp no macro or variable expansion is done. I believe that this is also true for GNU pic version 1.10. See the _M_a_c_r_o_s section for information on defining blocks. ppiicc _p_i_c___s_t_a_t_e_m_e_n_t This issues the given pic statements in the enclosing ..PPSS and ..PPEE at the point where the command is issued. Statements that begin with a period are considered to be troff(statements) and are output in the enclosing ..PPSS and ..PPEE at the point where the command appears. For the purposes of relative placement of pic or troff commands, the frame is output immediately before the first plotted object, or the ffrraammee statement, if any. If the user specifies pic or troff commands and neither any plotable object nor a ffrraammee command, the commands will not be output. ggrraapphh _N_a_m_e _p_i_c___c_o_m_m_a_n_d_s This command is used to position graphs with respect to each other. The current graph is given the pic name _N_a_m_e (names used by pic begin with capital letters). Any pic commands following the graph are used to position the next graph. The frame of the graph is available for use with pic name Frame. The following places a sec- ond graph below the first: graph Linear [ graph description ] graph Exponential with .Frame.n at \ Linear.Frame.s - (0, .05) [ graph description ] _n_a_m_e _= _e_x_p_r This assigns _e_x_p_r to the variable _n_a_m_e. ggrraapp has only numeric (double) variables. Assignment creates a variable if it does not exist. Variables per- sist across graphs. Assignments can cascade; a = b = 35 assigns 35 to a and b. bbaarr (uupp|rriigghhtt) [_c_o_o_r_d_i_n_a_t_e_s___n_a_m_e] _o_f_f_s_e_t hhtt _h_e_i_g_h_t [wwiidd _w_i_d_t_h] [bbaassee _b_a_s_e___o_f_f_s_e_t] [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] bbaarr [_c_o_o_r_d_i_n_a_t_e_s___n_a_m_e] _e_x_p_r, _e_x_p_r, [_c_o_o_r_d_i_n_a_t_e_s___n_a_m_e] _e_x_p_r, _e_x_p_r, [_l_i_n_e___d_e_s_c_r_i_p_t_i_o_n] The bbaarr command facilitates drawing bar graphs. The first form of the command describes the bar somewhat generally and has ggrraapp place it. The bar may extend up or to the right, is centered on _o_f_f_s_e_t and extends up or right _h_e_i_g_h_t units (in the given coordinate sys- tem). For example bar up 3 ht 2 draws a 2 unit high bar sitting on the x axis, centered on x=3. By default bars are 1 unit wide, but this can be changed with the wwiidd keyword. By default bars sit on the base axis, i.e., bars directed up will extend from y=0. That may be overridden by the bbaassee key- word. (The bar described above has corners (2.5, 0) and (3.5, 2).) The line description has been extended to include a ffiillll _e_x_p_r key- word that specifies the shading inside the bar. Bars may be drawn in any line style. They support the ccoolloorr and ffiillllccoolloorr keywords described under cciirrccllee. The second form of the command draws a box with the two points as corners. This can be used to draw boxes highlighting certain data as well as bar graphs. Note that filled bars will cover data drawn under them. CCoonnttrrooll FFllooww iiff _e_x_p_r tthheenn _b_l_o_c_k [eellssee _b_l_o_c_k] The iiff statement provides simple conditional execution. If _e_x_p_r is non-zero, the _b_l_o_c_k after the tthheenn statement is executed. If not the _b_l_o_c_k after the eellssee is executed, if present. See _M_a_c_r_o_s for the definition of blocks. Early versions of this implementation of ggrraapp treated the blocks as macros that were defined and expanded in place. This led to unnecessary confusion because explicit separa- tors were sometimes called for. Now, ggrraapp inserts a separator (;) after the last character in _b_l_o_c_k, so constructs like if (x == 3) { y = y + 1 } x = x + 1 behave as expected. A separator is also appended to the end of a ffoorr block. ffoorr _n_a_m_e ffrroomm _f_r_o_m___e_x_p_r ttoo _t_o___e_x_p_r [bbyy [+|-|*|/] _b_y___e_x_p_r] ddoo _b_l_o_c_k This command executes _b_l_o_c_k iteratively. The variable _n_a_m_e is set to _f_r_o_m___e_x_p_r and incremented by _b_y___e_x_p_r until it exceeds _t_o___e_x_p_r. The iteration has the semantics defined in the ttiicckkss command. The definition of _b_l_o_c_k is discussed in _M_a_r_c_o_s. See also the note about implicit separators in the description of the iiff command. An == can be used in place of ffrroomm. EExxpprreessssiioonnss ggrraapp supports most standard arithmetic operators: + - / * ^. The carat (^) is exponentiation. In an iiff statement ggrraapp also supports the C logi- cal operators ==, !=, &&, || and unary !. Also in an iiff, == and != are overloaded for the comparison of quoted strings. Parentheses are used for grouping. Assignment is not allowed in an expression in any context, except for simple cascading of assignments. a = b = 35 works as expected; a = 3.5 * (b = 10) does not execute. ggrraapp supports the following functions that take one argument: lloogg, eexxpp, iinntt, ssiinn, ccooss, ssqqrrtt, rraanndd. The logarithms are base 10 and the trigono- metric functions are in radians. eeeexxpp returns Euler's number to the given power and llnn returns the natural logarithm. The natural log and exponentiation functions are extensions and are probably not available in other ggrraapp implementations. rraanndd returns a random number uniformly distributed on [0,1). The follow- ing two-argument functions are supported: aattaann22, mmiinn, mmaaxx. aattaann22 works just like atan2(3). The random number generator can be seeded by calling ssrraanndd with a single parameter (converted internally to an integer). Because its return value is of no use, you must use ssrraanndd as a separate statement, it is not part of a valid expression. ssrraanndd is not portable. The ggeettppiidd function takes no arguments and returns the process id. This may be used to seed the random number generator, but do not expect cryp- tographically random values to result. Other than string comparison, no expressions can use strings. One string valued function exists: sspprriinnttff (_f_o_r_m_a_t, [_e_x_p_r [_, _e_x_p_r]] ). It operates like sprintf(3), except returning the value. It can be used anywhere a quoted string is used. If ggrraapp is run with --SS, the environment variable GRAP_SAFER is defined, or ggrraapp has been compiled for safer operation, the sspprriinnttff command will return the format string. This mode of operation is only intended to be used only if ggrraapp is being used as part of a super- user enabled print system. MMaaccrrooss ggrraapp has a simple but powerful macro facility. Macros are defined using the ddeeffiinnee command : ddeeffiinnee _n_a_m_e _b_l_o_c_k uunnddeeffiinnee _n_a_m_e Every occurrence of _n_a_m_e in the program text is replaced by the contents of _b_l_o_c_k. _b_l_o_c_k is defined by a series of statements in nested { }'s, or a series of statements surrounded by the same let- ter. An example of the latter is define foo X coord x 1,3 X Each time foo appears in the text, it will be replaced by coord x 1,3. Macros are literal, and can contain newlines. If a macro does not span multiple lines, it should end in a semicolon to avoid parsing errors. Macros can take parameters, too. If a macro call is followed by a parenthesized, comma-separated list the values starting with $1 will be replaced in the macro with the elements of the list. A $ not followed by a digit is left unchanged. This parsing is very rudimentary; no nesting or parentheses or escaping of commas is allowed. Also, there is no way to say argument 1 followed by a digit (${1}0 in sh(1)). The following will draw a line with slope 1. define foo { next at $1, $2 } for i from 1 to 5 { foo(i,i) } Macros persist across graphs. The file _/_u_s_r_/_l_o_c_a_l_/_s_h_a_r_e_/_g_r_a_p_/_g_r_a_p_._d_e_f_i_n_e_s contains simple macros for plot- ting common characters. The uunnddeeffiinnee command deletes a macro. See the directory _/_u_s_r_/_l_o_c_a_l_/_s_h_a_r_e_/_e_x_a_m_p_l_e_s_/_g_r_a_p for more examples of macros. Confirm the location of the examples directory using the --vv flag. NNuummbbeerr LLiissttss A whitespace-separated list of numbers is treated specially. The list is taken to be points to be plotted using the default line style on the default coordinate system. If more than two numbers are given, the extra numbers are taken to be additional y values to plot at the first x value. Number lists in DWB ggrraapp can be comma-separated, and this ggrraapp supports that as well. More precisely, numbers in number lists can be separated by either whitespace, commas, or both. 1 2 3 4 5 6 Will plot points using the default line style at (1,2), (1,3),(4,5) and (4,6). A simple way to plot a set of numbers in a file named _._/_d_a_t_a is: .G1 copy "./data" .G2 PPiicc MMaaccrrooss ggrraapp defines pic macros that can be used in embedded pic code to place elements in the graph. The macros are xx__gggg, yy__gggg, and xxyy__gggg. These macros define pic distances that correspond to the given argument. They can be used to size boxes or to plot pic constructs on the graph. To place a given construct on the graph, you should add Frame.Origin to it. Other coordinate spaces can be used by replacing gggg with the name of the coordinate space. A coordinate space named gggg cannot be reliably accessed by these macros. The macros are emitted immediately before the frame is drawn. DWB ggrraapp may use these as part of its implementation. This ggrraapp provides them only for compatibility. Note that these are very simple macros, and may not do what you expect under complex conditions. EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS If the environment variable GRAP_DEFINES is defined, ggrraapp will look for its defines file there. If that value is a relative path name the path specified in the --MM option will be searched for it. GRAP_DEFINES over- rides the compiled in location of the defines file, but may be overridden by the --dd or --DD flags. If GRAP_SAFER is set, sspprriinnttff is disabled to prevent forcing ggrraapp to core dump or smash the stack. FFIILLEESS _/_u_s_r_/_l_o_c_a_l_/_s_h_a_r_e_/_g_r_a_p_/_g_r_a_p_._d_e_f_i_n_e_s SSEEEE AALLSSOO atan2(3), groff(1), pic(1), printf(3), sh(1), sprintf(3), troff(1) If documentation and examples have been installed, ggrraapp ----vveerrssiioonn or ggrraapp ----hheellpp will display the locations. BBUUGGSS There are several small incompatibilities with K&R ggrraapp. They include the sshh command not expanding variables and macros, and a more strict adherence to parameter order in the internal commands. Although much improved, the error reporting code can still be confused. Notably, an error in a macro is not detected until the macro is used, and it produces unusual output in the error message. Iterating many times over a macro with no newlines can run ggrraapp out of memory. AAUUTTHHOORR This implementation was done by Ted Faber . Bruce Lilly contributed many bug fixes, including a consid- erable revamp of the error reporting code. If you can actually find an error in your ggrraapp code, you can probably thank him. ggrraapp was designed and specified by Brian Kernighan and Jon Bentley. FreeBSD 8.0 March 11, 2006 FreeBSD 8.0 grap-1.43/README000640 004133 000000 00000010174 10410150604 013446 0ustar00faberwheel000000 000000 This is grap, an implementation of Kernighan and Bentley's grap language for typesetting graphs. I got sick of groff not having a version of grap, so I built one. The code is distributed under the FreeBSD-style copyright: Copyright 1998-2001 Ted Faber All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. That text is reproduced in the COPYRIGHT file, too. Changes are in CHANGES. The code was all written by me, based on K&B's _Grap-A Language for Typesetting Graphs, Tutorial and User Manual_ by Jon L. Bentley and Brian W. Kernighan, revised May 1991. That paper is available from http://www.kohala.com/start/troff/troff.html as http://www.kohala.com/start/troff/cstr114.ps . You should check out the paper for a complete understanding of grap's power. grap is a pic preprocessor, so any typesetting language that can use pic can use grap. I believe that TeX can use pic, but I wouldn't be surprised if grap.defines needs to be fooled with. If you use TeX and find a set of grap.defines that work, please let me know. Some people have used the given grap.tex.defines. Modifications always welcome. If you want to generate a GNU makefile when the system make command is not GNU make, use the --enable-force-gnu-make option to configure. configure does it's best to tell if you have GNU make and create an appropriate make file, but can be confused. The man page uses the BSD macros. If your system doesn't, there's an ASCII version in grap.man, and a postscript version in grap.ps. Check out the examples in the examples directory. So far I've compiled the code on Sunos 4.1.3, Solaris 5.5.1, FreeBSD 2.2.7-4.2, and an unknown RedHat Linux 6.1. It may run under other systems, and your c++ compiler and yacc/lex versions are probably more important than the type of Unix you run. Flex 2.5.4 and the yacc on FreeBSD 2.2.7 are known to work as well as later versions of bison. g++ 2.7.2.1, 2.8.1 2.95.1 and 2.95.2 have all worked. grap uses the standard template library, so that may also be a factor. The STL included with g++ works. grap has successfully compiled under UWIN (http://www.research.att.com/sw/tools/uwin/) under Windows NT with g++ 2.95.1. (Yeah, it surprised me, too.) The distribution uses GNU configure. ./configure should create a viable set of makefiles. After running configure, you should be able to use make directly (specifically, make depend && make). The resulting makefile should run under most versions of make, including GNU make and FreeBSD's pmake. If you try to compile grap on a new system and have problems, let me know and I'll try to help. If you succeed, let me know. Bug reports or other correspondance to faber@lunabase.org. This program is a hobby, so understand that bug reports will be handled as I have time. The most recent stable version should always be available at http://www.lunabase.org/~faber/Vault/software/grap/ . If you're having a problem, don't hesitate to mail, because I often have a slightly pre-release version with in-progress bug fixes too. grap-1.43/install-sh000750 004133 000000 00000012736 06676745357 014641 0ustar00faberwheel000000 000000 #!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 grap-1.43/grap.spec000600 004133 000000 00000001611 11074000500 014357 0ustar00faberwheel000000 000000 # -*-rpm-spec-*- %define prefix %{_prefix} %define version 1.43 Summary: grap, typesets graphs for groff Name: grap Version: %{version} Release: 1 License: BSD Group: Applications/Publishing Source: http://www.lunabase.org/~faber/Vault/software/grap/grap-%{version}.tar.gz BuildRoot: /var/tmp/grap-%{version} %description This is grap, an implementation of Kernighan and Bentley\'s grap language for typesetting graphs. %prep %setup %build ./configure --prefix=%{prefix} --mandir=%{prefix}/share/man make prefix=$RPM_BUILD_ROOT%{prefix} MANDIR=$RPM_BUILD_ROOT%{prefix}/share/man/man1 %install make prefix=$RPM_BUILD_ROOT%{prefix} MANDIR=$RPM_BUILD_ROOT%{prefix}/share/man/man1 install %files %defattr(-, root, root) %doc README %doc COPYRIGHT %doc CHANGES %{prefix}/bin/grap %{prefix}/share/man/man1/grap.1.gz %{prefix}/share/grap/ %{prefix}/share/examples/grap/ %{prefix}/share/doc/grap/ grap-1.43/grap.ps000660 004133 000000 00000214271 11076255042 014104 0ustar00faberwheel000000 000000 %!PS-Adobe-3.0 %%Creator: groff version 1.19.2 %%CreationDate: Fri Oct 17 20:38:10 2008 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%+ font Courier-Bold %%+ font Courier-Oblique %%+ font Courier %%+ font Symbol %%DocumentSuppliedResources: procset grops 1.19 2 %%Pages: 10 %%PageOrder: Ascend %%DocumentMedia: Default 612 792 0 () () %%Orientation: Portrait %%EndComments %%BeginDefaults %%PageMedia: Default %%EndDefaults %%BeginProlog %%BeginResource: procset grops 1.19 2 /setpacking where{ pop currentpacking true setpacking }if /grops 120 dict dup begin /SC 32 def /A/show load def /B{0 SC 3 -1 roll widthshow}bind def /C{0 exch ashow}bind def /D{0 exch 0 SC 5 2 roll awidthshow}bind def /E{0 rmoveto show}bind def /F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def /G{0 rmoveto 0 exch ashow}bind def /H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def /I{0 exch rmoveto show}bind def /J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def /K{0 exch rmoveto 0 exch ashow}bind def /L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def /M{rmoveto show}bind def /N{rmoveto 0 SC 3 -1 roll widthshow}bind def /O{rmoveto 0 exch ashow}bind def /P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def /Q{moveto show}bind def /R{moveto 0 SC 3 -1 roll widthshow}bind def /S{moveto 0 exch ashow}bind def /T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def /SF{ findfont exch [exch dup 0 exch 0 exch neg 0 0]makefont dup setfont [exch/setfont cvx]cvx bind def }bind def /MF{ findfont [5 2 roll 0 3 1 roll neg 0 0]makefont dup setfont [exch/setfont cvx]cvx bind def }bind def /level0 0 def /RES 0 def /PL 0 def /LS 0 def /MANUAL{ statusdict begin/manualfeed true store end }bind def /PLG{ gsave newpath clippath pathbbox grestore exch pop add exch pop }bind def /BP{ /level0 save def 1 setlinecap 1 setlinejoin 72 RES div dup scale LS{ 90 rotate }{ 0 PL translate }ifelse 1 -1 scale }bind def /EP{ level0 restore showpage }def /DA{ newpath arcn stroke }bind def /SN{ transform .25 sub exch .25 sub exch round .25 add exch round .25 add exch itransform }bind def /DL{ SN moveto SN lineto stroke }bind def /DC{ newpath 0 360 arc closepath }bind def /TM matrix def /DE{ TM currentmatrix pop translate scale newpath 0 0 .5 0 360 arc closepath TM setmatrix }bind def /RC/rcurveto load def /RL/rlineto load def /ST/stroke load def /MT/moveto load def /CL/closepath load def /Fr{ setrgbcolor fill }bind def /setcmykcolor where{ pop /Fk{ setcmykcolor fill }bind def }if /Fg{ setgray fill }bind def /FL/fill load def /LW/setlinewidth load def /Cr/setrgbcolor load def /setcmykcolor where{ pop /Ck/setcmykcolor load def }if /Cg/setgray load def /RE{ findfont dup maxlength 1 index/FontName known not{1 add}if dict begin { 1 index/FID ne{def}{pop pop}ifelse }forall /Encoding exch def dup/FontName exch def currentdict end definefont pop }bind def /DEFS 0 def /EBEGIN{ moveto DEFS begin }bind def /EEND/end load def /CNT 0 def /level1 0 def /PBEGIN{ /level1 save def translate div 3 1 roll div exch scale neg exch neg exch translate 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit []0 setdash /setstrokeadjust where{ pop false setstrokeadjust }if /setoverprint where{ pop false setoverprint }if newpath /CNT countdictstack def userdict begin /showpage{}def /setpagedevice{}def }bind def /PEND{ countdictstack CNT sub{end}repeat level1 restore }bind def end def /setpacking where{ pop setpacking }if %%EndResource %%BeginFeature: *PageSize Default << /PageSize [ 612 792 ] /ImagingBBox null >> setpagedevice %%EndFeature %%IncludeResource: font Times-Roman %%IncludeResource: font Times-Bold %%IncludeResource: font Courier-Bold %%IncludeResource: font Courier-Oblique %%IncludeResource: font Courier %%IncludeResource: font Symbol grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron /scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef /.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent /ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen /period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon /semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O /P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex /underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y /z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft /guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl /endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut /dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash /quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen /brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft /logicalnot/minus/registered/macron/degree/plusminus/twosuperior /threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior /ordmasculine/guilsinglright/onequarter/onehalf/threequarters /questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE /Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex /Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis /multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn /germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash /ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def /Courier@0 ENC0/Courier RE/Courier-Oblique@0 ENC0/Courier-Oblique RE /Courier-Bold@0 ENC0/Courier-Bold RE/Times-Bold@0 ENC0/Times-Bold RE /Times-Roman@0 ENC0/Times-Roman RE %%EndProlog %%Page: 1 1 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F/F1 10/Times-Bold@0 SF -.2(NA)72 96 S(ME).2 E/F2 10/Courier-Bold@0 SF(grap) 102 108 Q F0 2.5<8a4b>2.5 G(ernighan and Bentle)-2.75 E(y')-.15 E 2.5 (sl)-.55 G(anguage for typesetting graphs)-2.5 E F1(SYNOPSIS)72 132 Q F2 (grap)102 144 Q F0([)3.333 E F22.499 E/F3 10/Courier-Oblique@0 SF (defines_file)6 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F3(include path)6 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F0 3.333(][).833 G F2-.834 E F0(]) .833 E([)132.833 156 Q F22.499 E F0 3.333(][).833 G F3 1.666 (filename .)-2.5 F 1.666(..)1.666 G F0(])-.833 E F1(DESCRIPTION)72 180 Q F2(grap)102 192 Q F0 1.608(is an implementation of K)4.107 F 1.608 (ernighan and Bentle)-.25 F(y')-.15 E 4.108(sl)-.55 G 1.608 (anguage for typesetting graphs, as described in)-4.108 F -.74(``)102 204 S 1.377(Grap-A Language for T).74 F 1.377(ypesetting Graphs, T)-.8 F 1.377(utorial and User Manual,)-.45 F 2.857 -.74('' b)-.7 H 3.877(yJ).74 G 1.376(on L. Bentle)-3.877 F 3.876(ya)-.15 G 1.376(nd Brian W)-3.876 F (.)-.92 E -.25(Ke)102 216 S .452(rnighan, re).25 F .452 (vised May 1991, which is the primary source for information on ho)-.25 F 2.952(wt)-.25 G 2.952(ou)-2.952 G(se)-2.952 E F2(grap)2.953 E F0 5.453 (.A)C 2.953(so)-5.453 G 2.953(ft)-2.953 G(his)-2.953 E 2.597 (writing, it is a)102 228 R -.25(va)-.2 G 2.597 (ilable electronically at).25 F/F4 10/Courier@0 SF (http://www.kohala.com/start/troff/cstr114.ps)5.096 E F0(.)A .802 (Additional documentation and e)102 240 R .802(xamples, packaged with) -.15 F F2(grap)3.302 E F0 3.302(,m)C .802(ay ha)-3.302 F 1.102 -.15 (ve b)-.2 H .802(een installed locally as well.).15 F(If)5.803 E -.2(av) 102 252 S 2.434(ailable, paths to them can be displayed using)-.05 F F2 .6(grap \255h)4.934 F F0(or)4.934 E F2 .599(grap \255v)4.934 F F0(\(or) 4.933 E F2 .599(grap \255-help)4.933 F F0(/)4.933 E F2(grap)4.933 E (\255-version)103.666 264 Q F0(\))A 1.505(This v)102 282 R 1.505 (ersion is a black box implementation of)-.15 F F2(grap)4.005 E F0 4.005 (,a)C 1.505(nd some inconsistencies are to be e)-4.005 F 4.005 (xpected. The)-.15 F (remainder of this manual page will brie\215y outline the)102 294 Q F2 (grap)2.5 E F0(language as implemented here.)2.5 E F2(grap)102 312 Q F0 1.164(is a)3.664 F F4(pic)3.663 E F0 1.163(\(1\) pre-processor)B 6.163 (.I)-.55 G 3.663(tt)-6.163 G(ak)-3.663 E 1.163 (es commands embedded in a)-.1 F F4(troff)3.663 E F0 1.163 (\(1\) source \214le which are sur)B(-)-.2 E .547(rounded by)102 324 R F2(.G1)3.047 E F0(and)3.047 E F2(.G2)3.047 E F0 .547(macros, and re) 3.047 F .547(writes them into)-.25 F F4(pic)3.047 E F0 .547 (commands to display the graph.)3.047 F .548(Other lines)5.547 F 1.261 (are copied.)102 336 R 1.261(Output is al)6.261 F -.1(wa)-.1 G 1.261 (ys to the standard output, which is usually redirected.).1 F 1.26 (Input is from the gi)6.26 F -.15(ve)-.25 G(n).15 E F3(filename)102 348 Q F0 1.291(s, which are read in order)B 6.291(.A)-.55 G F3(filename)-2.5 E F0(of)3.791 E F25.457 E F0 1.291(is the standard input.)5.457 F 1.291(If no)6.291 F F3(filename)3.791 E F0 3.792(sa)C(re)-3.792 E(gi)102 360 Q -.15(ve)-.25 G(n, input is read from the standard input.).15 E (Because)102 378 Q F2(grap)2.5 E F0(is a)2.5 E F4(pic)2.5 E F0 (preprocessor)2.5 E 2.5(,a)-.4 G(nd GNU)-2.5 E F4(pic)2.5 E F0 (will output T)2.5 E(eX, it is possible to use)-.7 E F2(grap)2.5 E F0 (with T)2.5 E(eX.)-.7 E(The)102 396 Q F29.845 E F0 5.679(option s\ peci\214es a \214le of macro de\214nitions to be read at startup, and d\ ef)8.179 F 5.679(aults to)-.1 F .242 (/usr/local/share/grap/grap.de\214nes .)102 408 R(The)5.242 E F2 4.408 E F0 .242(option inhibits the reading of an)2.742 F 2.743(yi)-.15 G .243(nitial macros \214le \(the)-2.743 F F24.409 E F0(\215ag) 2.743 E 2.28(is a synon)102 420 R 2.28(ym for)-.15 F F26.446 E F0 4.78(,t)C 2.28(hough I do not remember wh)-4.78 F 4.78(y\). The)-.05 F 2.279(de\214nes \214le can also be gi)4.78 F -.15(ve)-.25 G 4.779(nu).15 G 2.279(sing the)-4.779 F F4(GRAP_DEFINES)102 432 Q F0(en)2.5 E (vironment v)-.4 E(ariable. \(See belo)-.25 E(w\).)-.25 E F2 103.666 450 Q F0(prints the v)2.5 E (ersion information on the standard output and e)-.15 E(xits.)-.15 E F2 (\255-version)6.666 E F0(is a synon)2.5 E(ym for)-.15 E F24.166 E F0(.)A F2103.666 468 Q F0(mak)3.376 E .876 (es labels unaligned by def)-.1 F 3.376(ault. This)-.1 F -.15(ve)3.376 G .876(rsion of).15 F F2(grap)3.376 E F0 .876(uses ne)3.376 F 3.376(wf) -.25 G .877(eatures of GNU)-3.376 F F4(pic)3.377 E F0 .877(to align the) 3.377 F .919(left and right labels with the ax)102 480 R .918(es, that \ is that the left and right labels run at right angles to the te)-.15 F .918(xt of the)-.15 F(paper)102 492 Q 6.58(.T)-.55 G 1.58 (his may be useful in porting old)-6.58 F F2(grap)4.08 E F0(programs.) 4.08 E F28.246 E F0(mak)4.08 E 1.581 (es plot strings unclipped by def)-.1 F(ault.)-.1 E .798(Some v)102 504 R .798(ersions of)-.15 F F2(grap)3.298 E F0(allo)3.298 E 3.297(wu)-.25 G .797(sers to place a string an)-3.297 F .797 (ywhere in the coordinate space, rather than only in)-.15 F .582 (the frame.)102 516 R .582(By def)5.582 F .582(ault this v)-.1 F .582 (ersion of)-.15 F F2(grap)3.082 E F0 .582(does not plot an)3.082 F 3.083 (ys)-.15 G .583(tring centered outside the frame.)-3.083 F F27.249 E F0(allo)3.083 E(ws)-.25 E .98(strings to be placed an)102 528 R 3.48 (ywhere. See)-.15 F .98(also the)3.48 F F2(clipped)3.48 E F0(and)3.48 E F2(unclipped)3.48 E F0 .98(string modi\214ers described in the)3.48 F F2 (plot)102 540 Q F0(statement.)2.5 E F2103.666 558 Q F0 1.219 (is follo)3.719 F 1.22 (wed by a colon-separated list of directories used to search for relati) -.25 F 1.52 -.15(ve p)-.25 H 1.22(athnames included via).15 F F2(copy) 102 570 Q F0 5.125(.T)C .124 (he path is also used to locate the de\214nes \214le, so if the)-5.125 F F24.29 E F0 .124(changes the de\214nes \214le name to a relati) 2.624 F -.15(ve)-.25 G .196 (name, it will be searched for in the path gi)102 582 R -.15(ve)-.25 G 2.697(nb).15 G(y)-2.697 E F24.363 E F0 5.197(.T)C .197 (he search path al)-5.197 F -.1(wa)-.1 G .197 (ys includes the current directory).1 F(,)-.65 E(and by def)102 594 Q (ault that directory is searched last.)-.1 E .781 (All numbers used internally by)102 612 R F2(grap)3.281 E F0 .781 (are double precision \215oating point v)3.281 F 3.28(alues. Sometimes) -.25 F .78(using \215oating)3.28 F .957 (point numbers has unintended consequences.)102 624 R 2.558 -.8(To h) 5.958 H .958(elp a).8 F -.2(vo)-.2 G .958(id these problems,).2 F F2 (grap)3.458 E F0 .958(can use tw)3.458 F 3.458(ot)-.1 G(hresholds)-3.458 E 1.346(for comparison of \215oating point numbers, set by)102 636 R F2 5.512 E F0(or)3.846 E F25.512 E F0 6.346(.T)C(he)-6.346 E F2 5.512 E F0 1.346(\215ag sets coarse comparison mode,)3.846 F 1.094 (which is suitable for most applications.)102 648 R 1.094 (If you are plotting small v)6.094 F 1.094 (alues \211 less than 1e-6 or so \211 consider)-.25 F(using)102 660 Q F2 5.081 E F0 .915(which uses v)3.415 F .915 (ery \214ne comparisons between numbers.)-.15 F -1.1(Yo)5.915 G 3.415 (um)1.1 G .914(ay also w)-3.415 F .914(ant to rescale your plotted)-.1 F -.25(va)102 672 S(lues to be lar).25 E (ger in magnitude. The coarse comarisons are used by def)-.18 E(ault.) -.1 E 1.804 -.8(To b)102 690 T 2.704(ep).8 G .204(recise, the v)-2.704 F .204(alue by which tw)-.25 F 2.704(on)-.1 G .204(umbers must dif)-2.704 F .204(fer for)-.25 F F2(grap)2.704 E F0 .204 (to consider them not equal is called the)2.704 F .152(comparison limit\ and the smallest non-zero number is called the minimum v)102 702 R 2.652(alue. The)-.25 F -.25(va)2.652 G .152(lues a gi).25 F -.15(ve)-.25 G 2.651(nv).15 G(ersion)-2.801 E(FreeBSD 8.0)72 750 Q(March 11, 2006) 149.98 E(1)197.2 E 0 Cg EP %%Page: 2 2 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F (of)102 96 Q/F1 10/Courier-Bold@0 SF(grap)2.5 E F0 (uses for these are included in the output of)2.5 E F14.166 E F0 (or)2.5 E F14.166 E F0(.)A(All)102 114 Q F1(grap)3.015 E F0 .515 (commands are included between)3.015 F F1(.G1)3.015 E F0(and)3.015 E F1 (.G2)3.015 E F0 .515(macros, which are consumed by)3.015 F F1(grap)3.015 E F0 5.515(.T)C .515(he out-)-5.515 F .89(put contains)102 126 R/F2 10 /Courier@0 SF(pic)3.39 E F0(between)3.39 E F1(.PS)3.39 E F0(and)3.39 E F1(.PE)3.39 E F0 3.39(macros. An)3.39 F 3.39(ya)-.15 G -.18(rg)-3.39 G .89(uments to the).18 F F1(.G1)3.39 E F0 .89(macro in the input are ar) 3.39 F(gu-)-.18 E .575(ments to the)102 138 R F1(.PS)3.075 E F0 .575 (macro in the output, so graphs can be scaled just lik)3.075 F(e)-.1 E F2(pic)3.076 E F0 3.076(diagrams. If)3.076 F F14.742 E F0 .576 (is gi)3.076 F -.15(ve)-.25 G .576(n, an).15 F(y)-.15 E 1.113(macro be) 102 150 R 1.112(ginning with .G1 or .G2 is treated as a .G1 or .G2 macr\ o, for compatibility with old v)-.15 F 1.112(ersions of)-.15 F(trof)102 162 Q 3.627(f. Using)-.25 F F15.293 E F0 1.128 (also forces pure trof)3.627 F 3.628(fs)-.25 G 1.128 (yntax on embedded font change commands when strings ha)-3.628 F 1.428 -.15(ve t)-.2 H(he).15 E F1(size)102 174 Q F0(attrib)2.5 E (ute, and all strings to be)-.2 E F1(unclipped)2.5 E F0(.)A(The)102 192 Q F14.166 E F0(\215ag prints a brief help message and e)2.5 E (xits.)-.15 E F1(\255-help)6.666 E F0(is a synon)2.5 E(ym for)-.15 E F1 4.166 E F0(.)A .941(It is possible for someone to cause)102 210 R F1(grap)3.441 E F0 .941(to f)3.441 F .94 (ail by passing a bad format string and data to the)-.1 F F1(sprintf) 3.44 E F0 3.569(command. If)102 222 R F1(grap)3.569 E F0 1.069(is inte) 3.569 F 1.069(grated as part of the printing system, this could concei) -.15 F -.25(va)-.25 G 1.07(bly pro).25 F 1.07(vided a path to)-.15 F .242(breaching security on the machine.)102 234 R .242 (If you choose to use)5.242 F F1(grap)2.742 E F0 .241 (as part of a printing system run by the super)2.741 F(-)-.2 E(user)102 246 Q 2.9(,y)-.4 G .4(ou should disable)-2.9 F F1(sprintf)2.901 E F0 2.901(commands. This)2.901 F .401(can be done by calling)2.901 F F1 (grap)2.901 E F0 .401(with the)2.901 F F14.567 E F0 .401 (\215ag, setting)2.901 F(the)102 258 Q F2(GRAP_SAFER)5.895 E F0(en)5.895 E 3.395(vironment v)-.4 F 3.395 (ariable, or compiling with the GRAP_SAFER preprocessor symbol)-.25 F 5.21(de\214ned. \(The)102 270 R 2.71 (GNU con\214gure script included with)5.21 F F1(grap)5.21 E F0 2.71 (will de\214ne that preprocessor symbol if the)5.21 F F1 (\255-with-grap-safe)103.666 282 Q F0(option is gi)2.5 E -.15(ve)-.25 G (n.\)).15 E(The)102 300 Q F1(grap)2.5 E F0(commands are sk)2.5 E (etched belo)-.1 E 3.8 -.65(w. R)-.25 H(efer to K).65 E (ernighan and Bentle)-.25 E(y')-.15 E 2.5(sp)-.55 G (aper for the details.)-2.5 E(Ne)102 318 Q 2.5(wv)-.25 G(ersions of) -2.65 E F2(groff)2.5 E F0(\(1\) will in)A -.2(vo)-.4 G -.1(ke).2 G F1 (grap)2.6 E F0(if)2.5 E F14.166 E F0(is gi)2.5 E -.15(ve)-.25 G (n.).15 E/F3 10/Times-Bold@0 SF(Commands)84 342 Q F0 (Commands are separated from one another by ne)102 354 Q (wlines or semicolons \(;\).)-.25 E F1(frame)102 372 Q F0([)13.424 E/F4 10/Courier-Oblique@0 SF(line_description).833 E F0 12.59(][).833 G F1 (ht)-12.59 E F4(height)6 E .4 LW 326.67 365.25 326.67 372 DL F1(wid) 330.17 372 Q F4(width)6 E F0 12.59(][)C([\()-12.59 E F1(top)A 429.08 365.25 429.08 372 DL(bottom)430.08 372 Q 467.08 365.25 467.08 372 DL (left)468.08 372 Q 493.08 365.25 493.08 372 DL(right)506.67 372 Q F0(\)) A F4(line_description)102 384 Q F0 2.5(].)C(..])-2.5 E F1(frame)102 408 Q F0([)12.59 E F1(ht)A F4(height)6 E 208.92 401.25 208.92 408 DL F1(wid) 212.42 408 Q F4(width)6 E F0 13.423(][)C F4(line_description)-12.59 E F0 12.59(][).833 G([\()-12.59 E F1(top)A 429.079 401.25 429.079 408 DL (bottom)430.079 408 Q 467.079 401.25 467.079 408 DL(left)468.079 408 Q 493.079 401.25 493.079 408 DL(right)506.67 408 Q F0(\))A F4 (line_description)102 420 Q F0 2.5(].)C(..])-2.5 E .029 (This describes ho)132 438 R 2.529(wt)-.25 G .029(he ax)-2.529 F .029 (es for the graph are dra)-.15 F .029(wn. A)-.15 F F4(line_description) 2.529 E F0 .028(is a)2.529 F F2(pic)2.528 E F0 .028(line descrip-)2.528 F .897(tion, e.g.,)132 450 R F2 -2.603(dashed 0.5)3.397 F F0 3.397(,o)C 3.397(rt)-3.397 G .897(he literal)-3.397 F F2(solid)3.397 E F0 5.897(.I) C 3.398(tm)-5.897 G .898(ay also include a)-3.398 F F1(color)3.398 E F0 -.1(ke)3.398 G(yw)-.05 E .898(ord follo)-.1 F .898(wed by)-.25 F .711 (the color to dra)132 462 R 3.211(wt)-.15 G .711 (he string in double quotes.)-3.211 F(An)5.711 E 3.211(yc)-.15 G .71 (olor understood by the underlying grof)-3.211 F 3.21(fs)-.25 G(ystem) -3.21 E 1.3(can be used.)132 474 R 1.301 (Color can only be used under GNU pic, and is not a)6.3 F -.25(va)-.2 G 1.301(ilable in compatibility mode.).25 F(Similarly)132 486 Q 3.666(,f) -.65 G 1.166(or pic implementations that understand)-3.666 F F1 (thickness)3.665 E F0 3.665(,t)C 1.165(hat attrib)-3.665 F 1.165 (ute may be used with a)-.2 F(real v)132 498 Q(alued parameter)-.25 E(.) -.55 E F1(Thickness)5 E F0(is not a)2.5 E -.25(va)-.2 G (ilable in compatibility mode.).25 E .028(If the \214rst)132 516 R F4 (line_description)2.528 E F0 .029(is gi)2.528 F -.15(ve)-.25 G .029 (n, the frame is dra).15 F .029(wn with that style.)-.15 F .029(The def) 5.029 F .029(ault is)-.1 F F2(solid)2.529 E F0(.)A .238 (The height and width of the frame can also be speci\214ed in inches.) 132 528 R .238(The def)5.238 F .238(ault line style can be o)-.1 F -.15 (ve)-.15 G -.2(r-).15 G (ridden for sides of the frame by specifying additional parameters to) 132 540 Q F1(frame)2.5 E F0(.)A .984(If no plotting commands ha)132 558 R 1.284 -.15(ve b)-.2 H .984(een gi).15 F -.15(ve)-.25 G 3.484(nb).15 G .984(efore the)-3.484 F F1(frame)3.484 E F0 .985 (command is issued, the frame will be)3.484 F .01 (output at that point in the plotting stream relati)132 570 R .31 -.15 (ve t)-.25 H 2.51(oe).15 G(mbedded)-2.51 E F2(troff)2.51 E F0(or)2.51 E F2(pic)2.51 E F0 2.51(commands. Otherwise)2.51 F (the frame is output before the \214rst plotted object \(e)132 582 Q -.15(ve)-.25 G 2.5(ni).15 G -.4(nv)-2.5 G(isible ones\).).4 E F1(ht)132 600 Q F0(and)3.283 E F1(wid)3.283 E F0 .783(are in inches by def)3.283 F .784(ault, b)-.1 F .784(ut can be an)-.2 F(y)-.15 E F2(groff)3.284 E F0 3.284(unit. If)3.284 F .784(omitted, the dimensions are 2)3.284 F (inches high by 3 inches wide.)132 612 Q F1(coord)102 630 Q F0([)3.333 E F4(name).833 E F0 3.333(][).833 G F1(x)-2.5 E F4(expr)6 E F0(,)A F4 (expr)6 E F0 3.333(][).833 G F1(y)-2.5 E F4(expr)6 E F0(,)A F4(expr)6 E F0 2.5(][).833 G F1(log x)-2.5 E 370.807 623.25 370.807 630 DL(log y) 374.307 630 Q 411.307 623.25 411.307 630 DL(log log)414.807 630 Q F0(])A (The)132 648 Q F1(coord)4.189 E F0 1.689(command speci\214es a ne)4.189 F 4.189(wc)-.25 G 1.689(oordinate system or sets limits on the def) -4.189 F 1.688(ault system.)-.1 F(It)6.688 E .827(de\214nes the lar)132 660 R .827(gest and smallest v)-.18 F .828 (alues that can be plotted, and therefore the scale of the data in the) -.25 F 2.528(frame. The)132 672 R .028 (limits for the x and y coordinate systems can be gi)2.528 F -.15(ve) -.25 G 2.527(ns).15 G(eparately)-2.527 E 5.027(.I)-.65 G 2.527(fa)-5.027 G F4(name)A F0 .027(is gi)2.527 F -.15(ve)-.25 G .027(n, that).15 F (coordinate system is de\214ned, if not the def)132 684 Q (ault system is modi\214ed.)-.1 E(FreeBSD 8.0)72 750 Q(March 11, 2006) 149.98 E(2)197.2 E 0 Cg EP %%Page: 3 3 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F 2.916(Ac)132 96 S .416(oordinate system created by one)-2.916 F/F1 10 /Courier-Bold@0 SF(coord)2.916 E F0 .417 (command may be modi\214ed by subsequent)2.916 F F1(coord)2.917 E F0 (com-)2.917 E 2.835(mands. A)132 108 R F1(grap)2.835 E F0 .335 (program may declare a coordinate space using)2.835 F F1(coord)2.834 E F0(,)A F1(copy)2.834 E F0 2.834<618c>2.834 G .334(le of data through) -2.834 F 3.098(am)132 120 S .599(acro that plots the data and \214nds i\ ts maxima and minima, and then de\214ne the size of the coordi-)-3.098 F (nate system with a second)132 132 Q F1(coord)2.5 E F0(statement.)2.5 E .301(This command also determines if a scale is plotted log)132 150 R (arithmically)-.05 E(.)-.65 E F1 .3(log log)5.301 F F0 .3 (means the same thing)2.8 F(as)132 162 Q F1(log x log y)2.5 E F0(.)A F1 (draw)102 180 Q F0([)3.333 E/F2 10/Courier-Oblique@0 SF(line_name).833 E F0 3.333(][).833 G F2(line_description)-2.5 E F0 3.333(][).833 G F2 (plot_string)-2.5 E F0(]).833 E(The)132 198 Q F1(draw)3.811 E F0 1.311 (command de\214nes the style with which a gi)3.811 F -.15(ve)-.25 G 3.811(nl).15 G 1.311(ine will be plotted.)-3.811 F(If)6.312 E F2 (line_name)3.812 E F0(is)3.812 E(gi)132 210 Q -.15(ve)-.25 G 7.494 (n, the style is associated with that name, otherwise the def).15 F 7.493(ault style is set.)-.1 F F2(line_description)132 222 Q F0 .671 (is a)3.171 F/F3 10/Courier@0 SF(pic)3.171 E F0 .671 (line description, and the optional)3.171 F F2(plot_string)3.172 E F0 .672(is a string to be)3.172 F .127(centered at each point.)132 234 R .127(The def)5.127 F .127(ault line description is)-.1 F F3(invis)2.626 E F0 2.626(,a)C .126(nd the def)-2.626 F .126 (ault plotting string is a cen-)-.1 F .628(tered b)132 246 R .628 (ullet, so by def)-.2 F .628 (ault each point is a \214lled circle, and the)-.1 F 3.129(ya)-.15 G .629(re unconnected.)-3.129 F .629(If points are being)5.629 F (connected, each)132 258 Q F1(draw)2.5 E F0(command ends an)2.5 E 2.5 (yc)-.15 G(urrent line and be)-2.5 E(gins a ne)-.15 E 2.5(wo)-.25 G(ne.) -2.5 E .463(When de\214ning a line style, that is the \214rst)132 276 R F1(draw)2.962 E F0 .462(command for a gi)2.962 F -.15(ve)-.25 G 2.962 (nl).15 G .462(ine name, specifying no plot)-2.962 F .579 (string means that there are to be no plot strings.)132 288 R .58 (Omitting the plot string on subsequent)5.579 F F1(draw)3.08 E F0(com-) 3.08 E .109(mands addressing the same named line means not to change th\ e plot string.)132 300 R .108(If a line has been de\214ned)5.108 F .502 (with a plot string, and the format is changed by a subsequent)132 312 R F1(draw)3.002 E F0 .503(statement, the plot string can be)3.002 F(remo) 132 324 Q -.15(ve)-.15 G 2.5(db).15 G 2.5(ys)-2.5 G(pecifying "" in the) -2.5 E F1(draw)2.5 E F0(statement.)2.5 E 1.104(The plot string can ha) 132 342 R 1.403 -.15(ve i)-.2 H 1.103(ts format changed through se).15 F -.15(ve)-.25 G 1.103(ral string_modi\214ers.).15 F 1.103 (String_modi\214ers are)6.103 F(described in the description of the)132 354 Q F1(plot)2.5 E F0(command.)2.5 E .196 (The standard de\214nes \214le includes se)132 372 R -.15(ve)-.25 G .196 (ral macros useful as plot strings, including).15 F F1(bullet)2.697 E F0 (,)A F1(square)2.697 E F0(,)A(and)132 384 Q F1(delta)2.5 E F0(.)A F1 (new)132 402 Q F0(is a synon)2.5 E(ym for)-.15 E F1(draw)2.5 E F0(.)A F1 (next)102 420 Q F0([)3.333 E F2(line_name).833 E F0(]).833 E F1(at)2.5 E F0([)3.333 E F2(coordinates_name).833 E F0(]).833 E F2(expr)2.5 E F0(,)A F2(expr)6 E F0([)3.333 E F2(line_description).833 E F0(]).833 E(The)132 438 Q F1(next)2.62 E F0 .12(command plots the gi)2.62 F -.15(ve)-.25 G 2.62(np).15 G .119(oint using the line style gi)-2.62 F -.15(ve)-.25 G 2.619(nb).15 G(y)-2.619 E F2(line_name)2.619 E F0 2.619(,o)C 2.619(rt) -2.619 G .119(he def)-2.619 F .119(ault if)-.1 F .282(none is gi)132 450 R -.15(ve)-.25 G 2.783(n. If).15 F F2(line_name)2.783 E F0 .283(is gi) 2.783 F -.15(ve)-.25 G .283(n, it should ha).15 F .583 -.15(ve b)-.2 H .283(een de\214ned by an earlier).15 F F1(draw)2.783 E F0 .283 (command, if)2.783 F .454(not a ne)132 462 R 2.954(wl)-.25 G .453 (ine style with that name is created, initialized the same w)-2.954 F .453(ay as the def)-.1 F .453(ault style.)-.1 F .453(The tw)5.453 F(o) -.1 E -.15(ex)132 474 S .8(pressions gi).15 F 1.1 -.15(ve t)-.25 H .8 (he point').15 F 3.3(sxa)-.55 G .801(nd y v)-3.3 F .801(alues, relati) -.25 F 1.101 -.15(ve t)-.25 H 3.301(ot).15 G .801 (he optional coordinate system.)-3.301 F .801(That system)5.801 F 1.959 (should ha)132 486 R 2.259 -.15(ve b)-.2 H 1.958 (een de\214ned by an earlier).15 F F1(coord)4.458 E F0 1.958 (command, if not, grap will e)4.458 F 4.458(xit. If)-.15 F 1.958 (the optional)4.458 F F2(line_description)132 498 Q F0 1.272(is gi)3.772 F -.15(ve)-.25 G 1.272(n, it o).15 F -.15(ve)-.15 G 1.272 (rrides the style').15 F 3.773(sd)-.55 G(ef)-3.773 E 1.273 (ault line description.)-.1 F -1.1(Yo)6.273 G 3.773(uc)1.1 G 1.273 (annot o)-3.773 F -.15(ve)-.15 G -.2(r-).15 G(ride the plotting string.) 132 510 Q 1.6 -.8(To u)5 H(se a dif).8 E(ferent plotting string use the) -.25 E F1(plot)2.5 E F0(command.)2.5 E (The coordinates may optionally be enclosed in parentheses: \()132 528 Q F2(expr)A F0(,)A F2(expr)6 E F0(\))A F2(quoted_string)102 546 Q F0([) 8.004 E F2(string_modifiers).833 E F0 7.17(][).833 G(,)-7.17 E F2 (quoted_string)7.17 E F0([)7.17 E F2(string_modifiers)A F0 4.67(]] ...)B F1(at)9.67 E F0([)102.833 558 Q F2(coordinates_name).833 E F0(]).833 E F2(expr)2.5 E F0(,)A F2(expr)6 E F1(plot)102 576 Q F2(expr)2.5 E F0([) 3.333 E F2(format_string).833 E F0(]).833 E F1(at)2.5 E F0([)3.333 E F2 (coordinates_name).833 E F0(]).833 E F2(expr)2.5 E F0(,)A F2(expr)6 E F0 .598(These commands both plot a string at the gi)132 594 R -.15(ve)-.25 G 3.098(np).15 G 3.098(oint. In)-3.098 F .599 (the \214rst case the literal strings are stack)3.098 F(ed)-.1 E(abo)132 606 Q 2.072 -.15(ve e)-.15 H 1.772(ach other).15 F 6.772(.T)-.55 G 1.772 (he string_modi\214ers include the)-6.772 F F3(pic)4.272 E F0 1.772 (justi\214cation modi\214ers \()4.272 F F1(ljust)A F0(,)A F1(rjust)4.271 E F0(,)A F1(above)132 618 Q F0 2.762(,a)C(nd)-2.762 E F1(below)2.762 E F0 .262(\), and absolute and relati)B -.15(ve)-.25 G F3(size)2.912 E F0 2.762(modi\214ers. See)2.762 F(the)2.762 E F3(pic)2.762 E F0 .263 (documentation for the)2.762 F .205 (description of the justi\214cation modi\214ers.)132 630 R F1(grap)5.204 E F0 .204(also supports the)2.704 F F1(aligned)2.704 E F0(and)2.704 E F1 (unaligned)2.704 E F0(modi-)2.704 E (\214ers which are brie\215y noted in the description of the)132 642 Q F1(label)2.5 E F0(command.)2.5 E .196 (The standard de\214nes \214le includes se)132 660 R -.15(ve)-.25 G .196 (ral macros useful as plot strings, including).15 F F1(bullet)2.697 E F0 (,)A F1(square)2.697 E F0(,)A(and)132 672 Q F1(delta)2.5 E F0(.)A .428 (Strings placed by either format of the)132 690 R F1(plot)2.928 E F0 .427(command are restricted to being within the frame.)2.928 F(This) 5.427 E .466(can be o)132 702 R -.15(ve)-.15 G .466(rriden by using the) .15 F F1(unclipped)2.966 E F0(attrib)2.967 E .467(ute, which allo)-.2 F .467(ws a string to be plotted in or out of)-.25 F(FreeBSD 8.0)72 750 Q (March 11, 2006)149.98 E(3)197.2 E 0 Cg EP %%Page: 4 4 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F .627(the frame.)132 96 R(The)5.627 E/F1 10/Courier-Bold@0 SF4.793 E F0(and)3.127 E F14.793 E F0 .627(\215ags set)3.127 F F1 (unclipped)3.127 E F0 .626(on all strings, and to pre)3.127 F -.15(ve) -.25 G .626(nt a string from being).15 F .99 (plotted outside the frame when those \215ags are acti)132 108 R -.15 (ve)-.25 G 3.49(,t).15 G(he)-3.49 E F1(clipped)3.49 E F0(attrib)3.49 E .99(ute can be used to retore)-.2 F .085(clipping beha)132 120 R(vior) -.2 E 5.085(.T)-.55 G(hough)-5.085 E F1(clipped)2.585 E F0(or)2.585 E F1 (unclipped)2.585 E F0 .085(can be applied to an)2.585 F 2.584(ys)-.15 G .084(tring, it only has mean-)-2.584 F(ing for)132 132 Q F1(plot)2.5 E F0(statements.)2.5 E/F2 10/Courier@0 SF(size)132 150 Q/F3 10 /Courier-Oblique@0 SF(expr)2.54 E F0 .041(sets the string size to)2.541 F F3(expr)2.541 E F0 2.541(points. If)2.541 F F3(expr)2.541 E F0 .041 (is preceded by a + or -, the size is increased)2.541 F (or decreased by that man)132 162 Q 2.5(yp)-.15 G(oints.)-2.5 E(If)132 180 Q F1(color)2.663 E F0 .162(and a color name in double quotes appear\ s, the string will be rendered in that color under a)2.663 F -.15(ve)132 192 S(rsion of GNU trof).15 E 2.5(ft)-.25 G(hat supports color)-2.5 E 5 (.C)-.55 G(olor is not a)-5 E -.25(va)-.2 G (ilable in compatibility mode.).25 E .161(In the second v)132 210 R .162 (ersion, the)-.15 F F3(expr)2.662 E F0 .162(is con)2.662 F -.15(ve)-.4 G .162(rted to a string and placed on the graph.).15 F F3(format_string) 5.162 E F0 1.468(is a)132 222 R F2(printf)3.968 E F0 1.468 (\(3\) format string.)B 1.468 (Only formatting escapes for printing \215oating point numbers mak)6.468 F(e)-.1 E 2.765(sense. The)132 234 R .265 (format string is only respected if the)2.765 F F1(sprintf)2.765 E F0 .265(command is also acti)2.765 F -.15(ve)-.25 G 5.265(.S).15 G .265 (ee the descrip-)-5.265 F .58(tion of)132 246 R F1(sprintf)3.08 E F0 .58 (for the v)3.08 F .58(arious w)-.25 F .58(ays to disable it.)-.1 F F1 (Plot)5.58 E F0(and)3.08 E F1(sprintf)3.08 E F0 .58(respond dif)3.08 F .58(ferently when)-.25 F F1(grap)132 258 Q F0 .188(is running safely) 2.688 F(.)-.65 E F1(Sprintf)5.188 E F0 .188(ignores an)2.688 F 2.688(ya) -.15 G -.18(rg)-2.688 G .189 (uments, passing the format string through without).18 F(substitution.) 132 270 Q F1(plot)5 E F0(ignores the format string completely)2.5 E 2.5 (,p)-.65 G(lotting)-2.5 E F3(expr)2.5 E F0(using the "%g" format.)2.5 E .13(Points are speci\214ed the same w)132 288 R .13(ay as for)-.1 F F1 (next)2.63 E F0 .13 (commands, with the same consequences for unde\214ned)2.63 F (coordinate systems.)132 300 Q 1.477(The second form of this command is\ because the \214rst form can be used with a)132 318 R F1 -2.022 (grap sprintf)3.977 F F0 -.15(ex)132 330 S(pression \(See).15 E/F4 10 /Times-Bold@0 SF(Expr)2.5 E(essions)-.18 E F0(\).)A F1(ticks)102 348 Q F0(\()2.5 E F1(left)A .4 LW 162.83 341.25 162.83 348 DL(right)163.83 348 Q 194.83 341.25 194.83 348 DL(top)195.83 348 Q 214.83 341.25 214.83 348 DL(bottom)215.83 348 Q F0(\)[ \()A F1(in)A 277.32 341.25 277.32 348 DL (out)278.32 348 Q F0 3.333(\)[)C F3(expr)-2.5 E F0(]] [).833 E F1(on)A 357.469 341.25 357.469 348 DL(auto)358.469 348 Q F3(coord_name)2.5 E F0 (])A F1(ticks)102 366 Q F0(\()4.433 E F1(left)A 164.763 359.25 164.763 366 DL(right)165.763 366 Q 196.763 359.25 196.763 366 DL(top)197.763 366 Q 216.763 359.25 216.763 366 DL(bottom)217.763 366 Q F0 4.433(\)\()C F1 (in)-4.433 E 277.856 359.25 277.856 366 DL(out)278.856 366 Q F0 5.266 (\)[)C F3(expr)-4.433 E F0 4.433(][).833 G F1(up)-4.433 E F3(expr)7.933 E 398.407 359.25 398.407 366 DL F1(down)403.84 366 Q F3(expr)7.932 E 468.704 359.25 468.704 366 DL F1(left)474.136 366 Q F3(expr)7.932 E 539 359.25 539 366 DL F1(right)102 378 Q F3(expr)6 E F0(])A F1(at)2.5 E F0 ([)3.333 E F3(coord_name).833 E F0(]).833 E F3(expr)2.5 E F0([)3.333 E F3(format_string).833 E F0 2.5(][).833 G([,)-2.5 E F3(expr)2.5 E F0([) 2.5 E F3(format_string)A F0 1.666(]] .)B 1.666(..)1.666 G(])-1.666 E F1 (ticks)102 396 Q F0(\()4.432 E F1(left)A 164.762 389.25 164.762 396 DL (right)165.762 396 Q 196.762 389.25 196.762 396 DL(top)197.762 396 Q 216.762 389.25 216.762 396 DL(bottom)217.762 396 Q F0 4.432(\)\()C F1 (in)-4.432 E 277.854 389.25 277.854 396 DL(out)278.854 396 Q F0 5.265 (\)[)C F3(expr)-4.432 E F0 4.432(][).833 G F1(up)-4.432 E F3(expr)7.932 E 398.402 389.25 398.402 396 DL F1(down)403.835 396 Q F3(expr)7.933 E 468.701 389.25 468.701 396 DL F1(left)474.134 396 Q F3(expr)7.933 E 539 389.25 539 396 DL F1(right)102 408 Q F3(expr)12.891 E F0(])A F1(from) 9.39 E F0 .833([c)10.223 G -1.667(oord_name ])-.833 F F3(start_expr)9.39 E F1(to)9.39 E F3(end_expr)9.39 E F0([)9.39 E F1(by)A F0([+)9.39 E 465.84 401.25 465.84 408 DL(-)466.84 408 Q 471.17 401.25 471.17 408 DL /F5 10/Symbol SF(*)472.17 408 Q 478.17 401.25 478.17 408 DL F0(/])479.17 408 Q F3(by_expr)9.39 E F0(])A .833([f)102.833 420 S -1.667 (ormat_string ])-.833 F F1(ticks)102 438 Q F0([)2.5 E F1(left)A 162.83 431.25 162.83 438 DL(right)163.83 438 Q 194.83 431.25 194.83 438 DL(top) 195.83 438 Q 214.83 431.25 214.83 438 DL(bottom)215.83 438 Q F0(])A F1 (off)2.5 E F0 .322 (This command controls the placement of ticks on the frame.)132 456 R .322(By def)5.322 F .322(ault, ticks are automatically gen-)-.1 F (erated on the left and bottom sides of the frame.)132 468 Q .367 (The \214rst v)132 486 R .367 (ersion of this command turns on the automatic tick generation for a gi) -.15 F -.15(ve)-.25 G 2.866(ns).15 G 2.866(ide. The)-2.866 F F1(in)2.866 E F0(or)2.866 E F1(out)132 498 Q F0 1.374 (parameter controls the direction and length of the ticks.)3.874 F 1.374 (If a)6.374 F F3(coord_name)3.874 E F0 1.374(is speci\214ed, the)3.874 F .563(ticks are automatically generated using that coordinate system.)132 510 R .563(If no system is speci\214ed, the def)5.563 F(ault)-.1 E .411 (coordinate system is used.)132 522 R .411(As with)5.411 F F1(next)2.911 E F0(and)2.911 E F1(plot)2.911 E F0 2.911(,t)C .412 (he coordinate system must be declared before)-2.911 F(the)132 534 Q F1 (ticks)2.521 E F0 .021(statement that references it.)2.521 F .021 (This syntax for requesting automatically generated ticks is an)5.021 F -.15(ex)132 546 S(tension, and will not port to older).15 E F1(grap)2.5 E F0(implementations.)2.5 E .327(The second v)132 564 R .327 (ersion of the)-.15 F F1(ticks)2.827 E F0 .327(command o)2.827 F -.15 (ve)-.15 G .328(rrides the automatic placement of the ticks by speci-) .15 F .542(fying a list of coordinates at which to place the ticks.)132 576 R .542(If the ticks are not de\214ned with respect to the)5.542 F (def)132 588 Q .636(ault coordinate system, the)-.1 F F3(coord_name) 3.136 E F0 .636(parameter must be gi)3.136 F -.15(ve)-.25 G 3.136(n. F) .15 F .636(or each tick a)-.15 F F2(printf)3.137 E F0(\(3\))A 1.163 (style format string can be gi)132 600 R -.15(ve)-.25 G 3.663(n. The).15 F F3(format_string)3.663 E F0(def)3.663 E 1.163(aults to "%g".)-.1 F 1.162(The format string can)6.163 F .43(also tak)132 612 R 2.93(es)-.1 G .43(tring modi\214ers as described in the)-2.93 F F1(plot)2.931 E F0 2.931(command. T)2.931 F 2.931(op)-.8 G .431 (lace ticks with no labels, specify)-2.931 F F3(format_string)132 624 Q F0(as "".)2.5 E(If)132 642 Q F1(sprintf)2.5 E F0(is disabled,)2.5 E F1 (ticks)2.5 E F0(beha)2.5 E -.15(ve)-.2 G 2.5(sa).15 G(s)-2.5 E F1(plot) 2.5 E F0(with respect to the format string.)2.5 E .801(The labels on th\ e ticks may be shifted by specifying a direction and the distance in in\ ches to of)132 660 R(fset)-.25 E(the label.)132 672 Q (That is the optional direction and e)5 E (xpression immediately preceding the)-.15 E F1(at)2.5 E F0(.)A .526 (The third format of the)132 690 R F1(ticks)3.026 E F0 .526(command o) 3.026 F -.15(ve)-.15 G -.2(r-).15 G .526(rides the def).2 F .527 (ault tick generation with a set of ticks ar)-.1 F(re)132 702 Q 1.214 (gular interv)-.15 F 3.713(als. The)-.25 F 1.213 (syntax is reminiscent of programming language for loops.)3.713 F -.35 (Ti)6.213 G 1.213(cks are placed).35 F(FreeBSD 8.0)72 750 Q (March 11, 2006)149.98 E(4)197.2 E 0 Cg EP %%Page: 5 5 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F .103(starting at)132 96 R/F1 10/Courier-Oblique@0 SF(start_expr)2.603 E F0 .103(ending at)2.603 F F1(end_expr)2.604 E F0 .104(one unit apart.) 2.604 F .104(If the)5.104 F/F2 10/Courier-Bold@0 SF(by)2.604 E F0 .104 (clause is speci\214ed, ticks are)2.604 F F1(by_expr)132 108 Q F0 .234 (units apart.)2.734 F .234(If an operator appears before)5.234 F F1 (by_expr)2.734 E F0 .233(each tick is operated on by that oper)2.734 F (-)-.2 E(ator instead of +.)132 120 Q -.15(Fo)5 G 2.5(re).15 G(xample) -2.65 E/F3 10/Courier@0 SF(ticks left out from 2 to 32 by)192 138 Q/F4 10/Symbol SF(*)6 E F3(2)A F0 .132 (will put ticks at 2, 4, 8, 16, and 32.)132 156 R(If)5.133 E F1 (format_string)2.633 E F0 .133 (is speci\214ed, all ticks are formatted using it.)2.633 F (The parameters preceding the)132 174 Q F2(from)2.5 E F0 (act as described abo)2.5 E -.15(ve)-.15 G(.).15 E(The)132 192 Q F2(at) 2.696 E F0(and)2.696 E F2(for)2.696 E F0 .196 (forms of tick command may both be issued on the same side of a frame.) 2.696 F -.15(Fo)5.196 G 2.696(re).15 G(xam-)-2.846 E(ple:)132 204 Q F3 (ticks left out from 2 to 32 by)192 222 Q F4(*)6 E F3(2)A (ticks left in 3, 5, 7)192 234 Q F0(will put ticks on the left side of \ the frame pointing out at 2, 4, 8, 16, and 32 and in at 3, 5, and 7.)132 252 Q .363(The \214nal form of)132 270 R F2(ticks)2.863 E F0 .363 (turns of)2.863 F 2.863(ft)-.25 G .363(icks on a gi)-2.863 F -.15(ve) -.25 G 2.863(ns).15 G 2.863(ide. If)-2.863 F .363(no side is gi)2.863 F -.15(ve)-.25 G 2.863(nt).15 G .364(he ticks for all sides are)-2.863 F (cancelled.)132 282 Q F2(tick)132 300 Q F0(is a synon)2.5 E(ym for)-.15 E F2(ticks)2.5 E F0(.)A F2(grid)102 318 Q F0(\()3.077 E F2(left)A .4 LW 157.407 311.25 157.407 318 DL(right)158.407 318 Q 189.407 311.25 189.407 318 DL(top)190.407 318 Q 209.407 311.25 209.407 318 DL(bottom)210.407 318 Q F0 3.91(\)[)C F3 .577(ticks off)-3.077 F F0 3.91(][).833 G F1 (line_description)-3.077 E F0 3.077(][).833 G F2(up)-3.077 E F1(expr) 6.577 E 481.347 311.25 481.347 318 DL F2(down)485.424 318 Q F1(expr) 6.576 E 103 323.25 103 330 DL F2(left)106.5 330 Q F1(expr)6 E 167.5 323.25 167.5 330 DL F2(right)171 330 Q F1(expr)6 E F0 2.5(][)C F2(on) -2.5 E 253.16 323.25 253.16 330 DL(auto)254.16 330 Q F0([)3.333 E F1 (coord_name).833 E F0(]]).833 E F2(grid)102 348 Q F0(\()3.076 E F2(left) A 157.406 341.25 157.406 348 DL(right)158.406 348 Q 189.406 341.25 189.406 348 DL(top)190.406 348 Q 209.406 341.25 209.406 348 DL(bottom) 210.406 348 Q F0 3.91(\)[)C F3 .577(ticks off)-3.077 F F0 3.91(][).833 G F1(line_description)-3.077 E F0 3.077(][).833 G F2(up)-3.077 E F1(expr) 6.577 E 481.346 341.25 481.346 348 DL F2(down)485.423 348 Q F1(expr) 6.577 E 103 353.25 103 360 DL F2(left)112.427 360 Q F1(expr)11.927 E 185.281 353.25 185.281 360 DL F2(right)194.708 360 Q F1(expr)11.927 E F0 (])A F2(at)8.427 E F0([)9.259 E F1(coord_name).833 E F0(]).833 E F1 (expr)8.426 E F0([)9.259 E F1(format_string).833 E F0 8.426(][).833 G ([,)-8.426 E F1(expr)8.426 E F0([)102 372 Q F1(format_string)A F0 1.666 (]] .)B 1.666(..)1.666 G(])-1.666 E F2(grid)102 390 Q F0(\()3.076 E F2 (left)A 157.406 383.25 157.406 390 DL(right)158.406 390 Q 189.406 383.25 189.406 390 DL(top)190.406 390 Q 209.406 383.25 209.406 390 DL(bottom) 210.406 390 Q F0 3.91(\)[)C F3 .577(ticks off)-3.077 F F0 3.91(][).833 G F1(line_description)-3.077 E F0 3.077(][).833 G F2(up)-3.077 E F1(expr) 6.577 E 481.346 383.25 481.346 390 DL F2(down)485.423 390 Q F1(expr) 6.577 E 103 395.25 103 402 DL F2(left)109.904 402 Q F1(expr)9.404 E 177.712 395.25 177.712 402 DL F2(right)184.616 402 Q F1(expr)9.404 E F0 (])A F2(from)5.903 E F0 .833([c)6.736 G -1.667(oord_name ])-.833 F F1 (start_expr)5.903 E F2(to)5.903 E F1(end_expr)5.903 E F0([)5.903 E F2 (by)A F0([+)5.903 E 520.56 395.25 520.56 402 DL(-)521.56 402 Q 525.89 395.25 525.89 402 DL F4(*)526.89 402 Q 532.89 395.25 532.89 402 DL F0 (/])533.89 402 Q F1(by_expr)102 414 Q F0 3.333(][)C -1.667 (format_string ])-2.5 F(The)132 432 Q F2(grid)2.938 E F0 .438 (command is similar to the)2.938 F F2(ticks)2.939 E F0 .439(command e) 2.939 F .439(xcept that)-.15 F F2(grid)2.939 E F0 .439 (speci\214es the placement of)2.939 F(lines in the frame.)132 444 Q (The syntax is similar to)5 E F2(ticks)2.5 E F0(as well.)2.5 E .82 (By specifying)132 462 R F3 .82(ticks off)3.32 F F0 .82 (in the command, no ticks are dra)3.32 F .82 (wn on that side of the frame.)-.15 F .82(If ticks)5.82 F .97 (appear on a side by def)132 474 R .97(ault, or ha)-.1 F 1.27 -.15(ve b) -.2 H .97(een declared by an earlier).15 F F2(ticks)3.47 E F0(command,) 3.47 E F2(grid)3.47 E F0 .97(does not)3.47 F(cancel them unless)132 486 Q F3(ticks off)2.5 E F0(is speci\214ed.)2.5 E .169 (Instead of a direction for ticks,)132 504 R F2(grid)2.669 E F0(allo) 2.669 E .168(ws the user to pick a line description for the grid lines.) -.25 F(The)5.168 E(usual)132 516 Q F3(pic)2.5 E F0 (line descriptions are allo)2.5 E(wed.)-.25 E(Grids are labelled by def) 132 534 Q 2.5(ault. T)-.1 F 2.5(oo)-.8 G (mit labels, specify the format string as "".)-2.5 E(If)132 552 Q F2 (sprintf)2.5 E F0(is disabled,)2.5 E F2(grid)2.5 E F0(beha)2.5 E -.15 (ve)-.2 G 2.5(sa).15 G(s)-2.5 E F2(plot)2.5 E F0 (with respect to the format string.)2.5 E F2(label)102 570 Q F0(\()4.07 E F2(left)A 164.4 563.25 164.4 570 DL(right)165.4 570 Q 196.4 563.25 196.4 570 DL(top)197.4 570 Q 216.4 563.25 216.4 570 DL(bottom)217.4 570 Q F0(\))A F1(quoted_string)4.07 E F0([)4.903 E F1(string_modifiers).833 E F0 4.07(][).833 G(,)-4.07 E F1(quoted_string)4.071 E F0([)102 582 Q F1 (string_modifiers)A F0(]] ...)A([)5 E F2(up)A F1(expr)6 E 275.32 575.25 275.32 582 DL F2(down)278.82 582 Q F1(expr)6 E 339.82 575.25 339.82 582 DL F2(left)343.32 582 Q F1(expr)6 E 404.32 575.25 404.32 582 DL F2 (right)407.82 582 Q F1(expr)6 E F0(])A(The)132 600 Q F2(label)2.858 E F0 .358(command places a label on the gi)2.858 F -.15(ve)-.25 G 2.858(na) .15 G 2.858(xis. It)-2.858 F .357(is possible to specify se)2.858 F -.15 (ve)-.25 G .357(ral labels, which).15 F .307(will be stack)132 612 R .307(ed o)-.1 F -.15(ve)-.15 G 2.807(re).15 G .307(ach other as in) -2.807 F F3(pic)2.807 E F0 5.307(.T)C .307(he \214nal ar)-5.307 F .307 (gument, if present, speci\214es ho)-.18 F 2.807(wm)-.25 G(an)-2.807 E 2.808(yi)-.15 G(nches)-2.808 E(the label is shifted from the axis.)132 624 Q 1.146(By def)132 642 R 1.146(ault the labels on the left and righ\ t labels run parallel to the frame.)-.1 F -1.1(Yo)6.146 G 3.645(uc)1.1 G 1.145(an cancel this by)-3.645 F(specifying)132 654 Q F3(unaligned)2.5 E F0(as a)2.5 E F1(string_modifier)2.5 E F0(.)A F2 -3.5(circle at)102 672 R F0([)3.333 E F1(coordinate_name).833 E F0(]).833 E F1(expr)2.5 E F0(,) A F1(expr)6 E F0([)3.333 E F2(radius).833 E F1(expr)6 E F0 3.333(][).833 G F1(linedesc)-2.5 E F0(]).833 E .384(This dra)132 690 R .384 (ws an circle at the point indicated.)-.15 F .384(By def)5.384 F .385 (ault, the circle is small, 0.025 inches.)-.1 F .385(This can be)5.385 F -.15(ove)132 702 S -.2(r-).15 G .359(ridden by specifying a radius.).2 F .359(The coordinates of the point are relati)5.359 F .658 -.15(ve t)-.25 H 2.858(ot).15 G .358(he named coordinate)-2.858 F(FreeBSD 8.0)72 750 Q (March 11, 2006)149.98 E(5)197.2 E 0 Cg EP %%Page: 6 6 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F (system, or the def)132 96 Q(ault system if none is speci\214ed.)-.1 E .386(This command has been e)132 114 R .387(xtended to tak)-.15 F 2.887 (eal)-.1 G .387(ine description, e.g.,)-2.887 F/F1 10/Courier@0 SF (dotted)2.887 E F0 5.387(.I)C 2.887(ta)-5.387 G .387 (lso accepts the \214lling)-2.887 F -.15(ex)132 126 S .041 (tensions described belo).15 F 2.541(wi)-.25 G 2.541(nt)-2.541 G(he) -2.541 E/F2 10/Courier-Bold@0 SF(bar)2.541 E F0 2.541(command. It)2.541 F .041(will also accept a)2.541 F F2(color)2.54 E F0 -.1(ke)2.54 G(yw) -.05 E .04(ord that gi)-.1 F -.15(ve)-.25 G 2.54(st).15 G(he)-2.54 E .41 (color of the outline of the circle in double quotes and a)132 138 R F2 (fillcolor)2.91 E F0 .41(command that sets the color to)2.91 F .882 (\214ll the circle with similarly)132 150 R 5.881(.C)-.65 G .881 (olors are only a)-5.881 F -.25(va)-.2 G .881 (ilable when compatibility mode is of).25 F .881(f, and using a)-.25 F -.15(ve)132 162 S(rsion of GNU pic that supports color).15 E(.)-.55 E F2 (line)102 180 Q F0([)3.764 E/F3 10/Courier-Oblique@0 SF (line_description).833 E F0(]).833 E F2(from)2.932 E F0([)3.765 E F3 (coordinate_name).833 E F0(]).833 E F3(expr)2.932 E F0(,)A F3(expr)6.432 E F2(to)2.932 E F0([)3.765 E F3(coordinate_name).833 E F0(]).833 E F3 (expr)102 192 Q F0(,)A F3(expr)6 E F0([)3.333 E F3(line_description).833 E F0(]).833 E F2(arrow)102 210 Q F0([)19.78 E F3(line_description).833 E F0(]).833 E F2(from)18.947 E F0([)19.78 E F3(coordinate_name).833 E F0 (]).833 E F3(expr)18.947 E F0(,)A F3(expr)22.447 E F2(to)18.947 E F0([) 102.833 222 Q F3(coordinate_name).833 E F0(]).833 E F3(expr)2.5 E F0(,)A F3(expr)6 E F0([)3.333 E F3(line_description).833 E F0(]).833 E .777 (This dra)132 240 R .778(ws a line or arro)-.15 F 3.278(wf)-.25 G .778 (rom the \214rst point to the second using the gi)-3.278 F -.15(ve)-.25 G 3.278(ns).15 G 3.278(tyle. The)-3.278 F(def)3.278 E .778(ault line)-.1 F 1.19(style is)132 252 R F1(solid)3.69 E F0 6.19(.T)C(he)-6.19 E F3 (line_description)3.69 E F0 1.19(can be gi)3.69 F -.15(ve)-.25 G 3.69 (ne).15 G 1.19(ither before the)-3.69 F F2(from)3.69 E F0 1.19 (or after the)3.69 F F2(to)3.69 E F0 2.725(clause. If)132 264 R .225 (both are gi)2.725 F -.15(ve)-.25 G 2.726(nt).15 G .226 (he second is used.)-2.726 F .226 (It is possible to specify one point in one coordinate sys-)5.226 F .382 (tem and one in another)132 276 R 2.882(,n)-.4 G .381 (ote that if both points are in a named coordinate system \(e)-2.882 F -.15(ve)-.25 G 2.881(ni).15 G 2.881(ft)-2.881 G(he)-2.881 E 2.881(ya) -.15 G .381(re in)-2.881 F (the same named coordinate system\), both points must ha)132 288 Q -.15 (ve)-.2 G F3(coordinate_name)2.65 E F0(gi)2.5 E -.15(ve)-.25 G(n.).15 E F2(copy)102 306 Q F0 .833([")3.333 G F3(filename)-.833 E F0 -.833 .833 ("] [)D F2(until)A F0(")6 E F3(string)A F0 -.833 .833("] [)D F2(thru)A F3(macro)6 E F0(]).833 E(The)132 324 Q F2(copy)2.624 E F0 .124 (command imports data from another \214le into the current graph.)2.624 F .124(The form with only a \214le-)5.124 F .869(name gi)132 336 R -.15 (ve)-.25 G 3.369(ni).15 G 3.369(sas)-3.369 G .869(imple \214le inclusio\ n; the included \214le is simply read into the input stream and can) -3.369 F .704(contain arbitrary)132 348 R F2(grap)3.204 E F0 3.204 (commands. The)3.204 F .704 (more common case is that it is a number list; see)3.204 F/F4 10 /Times-Bold@0 SF(Number)3.205 E(Lists)132 360 Q F0(belo)2.5 E -.65(w.) -.25 G .926(The second form tak)132 378 R .926 (es lines from the \214le, splits them into w)-.1 F .926 (ords delimited by one or more spaces,)-.1 F .342(and calls the gi)132 390 R -.15(ve)-.25 G 2.842(nm).15 G .342(acro with those w)-2.842 F .342 (ords as parameters.)-.1 F .343 (The macro may either be de\214ned here, or)5.342 F (be a macro de\214ned earlier)132 402 Q 5(.S)-.55 G(ee)-5 E F4(Macr)2.5 E(os)-.18 E F0(for more information on macros.)2.5 E(The)132 420 Q F3 (filename)2.635 E F0 .135(may be omitted if the)2.635 F F2(until)2.635 E F0 .135(clause is present.)2.635 F .134 (If so the current \214le is treated as the)5.135 F(input \214le until) 132 432 Q F3(string)2.5 E F0(is encountered at the be)2.5 E (ginning of the line.)-.15 E F2(copy)132 450 Q F0 11.817 (is one of the w)14.317 F 11.817(orkhorses of)-.1 F F2(grap)14.318 E F0 16.818(.C)C 11.818(heck out the paper and)-16.818 F F1 (/usr/local/share/examples/grap)132 462 Q F0 .693(for more details.) 3.193 F .692(Con\214rm the location of the e)5.692 F(xamples)-.15 E (directory using the)132 474 Q F24.166 E F0(\215ag.)2.5 E F2 (print)102 486 Q F0(\()2.5 E F3(expr)A .4 LW 162.83 479.25 162.83 486 DL (string)163.83 486 Q F0(\))A(Prints its ar)132 504 Q (gument to the standard error)-.18 E(.)-.55 E F2(sh)102 522 Q F3(block)6 E F0 .427(This passes)132 540 R F3(block)2.927 E F0(to)2.927 E F1(sh) 2.927 E F0 2.927(\(1\). Unlik)B 2.927(eK)-.1 G(&B)-2.927 E F2(grap)2.927 E F0 .428(no macro or v)2.927 F .428(ariable e)-.25 F .428 (xpansion is done.)-.15 F 2.928(Ib)5.428 G(elie)-2.928 E -.15(ve)-.25 G .349(that this is also true for GNU)132 552 R F1(pic)2.849 E F0 -.15(ve) 2.849 G .349(rsion 1.10.).15 F .349(See the)5.349 F F4(Macr)2.849 E(os) -.18 E F0 .348(section for information on de\214ning)2.849 F(blocks.)132 564 Q F2(pic)102 582 Q F3(pic_statement)6 E F0 .13(This issues the gi) 132 600 R -.15(ve)-.25 G(n).15 E F1(pic)2.63 E F0 2.63(statements in) 2.63 F .13(the enclosing)2.63 F F2(.PS)2.63 E F0(and)2.63 E F2(.PE)2.63 E F0 .13(at the point where the command)2.63 F(is issued.)132 612 Q 1.196(Statements that be)132 630 R 1.195 (gin with a period are considered to be)-.15 F F1(troff)3.695 E F0 1.195 (\(statements\) and are output in the)B(enclosing)132 642 Q F2(.PS)2.5 E F0(and)2.5 E F2(.PE)2.5 E F0(at the point where the command appears.)2.5 E -.15(Fo)132 660 S 2.614(rt).15 G .114(he purposes of relati)-2.614 F .414 -.15(ve p)-.25 H .114(lacement of).15 F F1(pic)2.614 E F0(or)2.614 E F1(troff)2.614 E F0 .114(commands, the frame is output immediately) 2.614 F .884(before the \214rst plotted object, or the)132 672 R F2 (frame)3.384 E F0 .884(statement, if an)3.384 F 4.683 -.65(y. I)-.15 H 3.383(ft).65 G .883(he user speci\214es)-3.383 F F1(pic)3.383 E F0(or) 3.383 E F1(troff)3.383 E F0 .194(commands and neither an)132 684 R 2.694 (yp)-.15 G .194(lotable object nor a)-2.694 F F2(frame)2.694 E F0 .194 (command, the commands will not be output.)2.694 F(FreeBSD 8.0)72 750 Q (March 11, 2006)149.98 E(6)197.2 E 0 Cg EP %%Page: 7 7 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F/F1 10/Courier-Bold@0 SF(graph)102 96 Q/F2 10/Courier-Oblique@0 SF (Name pic_commands)6 E F0 .71 (This command is used to position graphs with respect to each other)132 114 R 5.709(.T)-.55 G .709(he current graph is gi)-5.709 F -.15(ve)-.25 G 3.209(nt).15 G(he)-3.209 E/F3 10/Courier@0 SF(pic)132 126 Q F0(name) 2.706 E F2(Name)2.706 E F0 .206(\(names used by)2.706 F F3(pic)2.706 E F0(be)2.706 E .206(gin with capital letters\).)-.15 F(An)5.206 E(y)-.15 E F3(pic)2.706 E F0 .206(commands follo)2.706 F .206(wing the)-.25 F .168(graph are used to position the ne)132 138 R .168(xt graph.)-.15 F .167(The frame of the graph is a)5.167 F -.25(va)-.2 G .167 (ilable for use with).25 F F3(pic)2.667 E F0(name)2.667 E F3(Frame.)132 150 Q F0(The follo)2.5 E(wing places a second graph belo)-.25 E 2.5(wt) -.25 G(he \214rst:)-2.5 E F3(graph Linear)192 168 Q 6([g)192 180 S (raph description ])-6 E(graph Exponential with .Frame.n at \\)192 192 Q (Linear.Frame.s - \(0, .05\))237 204 Q 6([g)192 216 S (raph description ])-6 E F2(name = expr)102 234 Q F0(This assigns)132 252 Q F2(expr)2.5 E F0(to the v)2.5 E(ariable)-.25 E F2(name)2.5 E F0(.) A F1(grap)5 E F0(has only numeric \(double\) v)2.5 E(ariables.)-.25 E .644(Assignment creates a v)132 270 R .644(ariable if it does not e)-.25 F 3.144(xist. V)-.15 F .645(ariables persist across graphs.)-1.11 F .645 (Assignments can)5.645 F(cascade;)132 282 Q F3 6(a=b=3)2.5 G(5)-6 E F0 (assigns 35 to)2.5 E F3(a)2.5 E F0(and)2.5 E F3(b)2.5 E F0(.)A F1(bar) 102 300 Q F0(\()11.316 E F1(up)A .4 LW 147.646 293.25 147.646 300 DL (right)148.646 300 Q F0 12.149(\)[)C F2(coordinates_name)-11.316 E F0(]) .833 E F2(offset)11.316 E F1(ht)11.316 E F2(height)11.316 E F0([)12.149 E F1(wid).833 E F2(width)14.815 E F0 12.148(][).833 G F1(base)-11.315 E F2(base_offset)102 312 Q F0 3.333(][).833 G F2(line_description)-2.5 E F0(]).833 E F1(bar)102 330 Q F0([)16.946 E F2(coordinates_name).833 E F0 (]).833 E F2(expr)16.113 E F0(,)A F2(expr)19.614 E F0 16.947(,[)C F2 (coordinates_name)-16.114 E F0(]).833 E F2(expr)16.114 E F0(,)A F2(expr) 19.614 E F0(,)A([)102.833 342 Q F2(line_description).833 E F0(]).833 E (The)132 360 Q F1(bar)3.096 E F0 .596(command f)3.096 F .596 (acilitates dra)-.1 F .596(wing bar graphs.)-.15 F .596 (The \214rst form of the command describes the bar)5.596 F(some)132 372 Q 1.097(what generally and has)-.25 F F1(grap)3.597 E F0 1.097 (place it.)3.597 F 1.097(The bar may e)6.097 F 1.097 (xtend up or to the right, is centered on)-.15 F F2(offset)132 384 Q F0 (and e)2.5 E(xtends up or right)-.15 E F2(height)2.5 E F0 (units \(in the gi)2.5 E -.15(ve)-.25 G 2.5(nc).15 G (oordinate system\).)-2.5 E -.15(Fo)5 G 2.5(re).15 G(xample)-2.65 E F3 (bar up 3 ht 2)192 402 Q F0(dra)132 420 Q .029 (ws a 2 unit high bar sitting on the x axis, centered on x=3.)-.15 F .028(By def)5.029 F .028(ault bars are 1 unit wide, b)-.1 F .028 (ut this)-.2 F .159(can be changed with the)132 432 R F1(wid)2.659 E F0 -.1(ke)2.659 G(yw)-.05 E 2.659(ord. By)-.1 F(def)2.659 E .159 (ault bars sit on the base axis, i.e., bars directed up will)-.1 F -.15 (ex)132 444 S .298(tend from y=0.).15 F .298(That may be o)5.298 F -.15 (ve)-.15 G .298(rridden by the).15 F F1(base)2.797 E F0 -.1(ke)2.797 G (yw)-.05 E 2.797(ord. \(The)-.1 F .297(bar described abo)2.797 F .597 -.15(ve h)-.15 H .297(as cor).15 F(-)-.2 E (ners \(2.5, 0\) and \(3.5, 2\).\))132 456 Q .452 (The line description has been e)132 474 R .452(xtended to include a) -.15 F F1(fill)2.952 E F2(expr)6.452 E F0 -.1(ke)2.952 G(yw)-.05 E .452 (ord that speci\214es the shading)-.1 F 1.427(inside the bar)132 486 R 6.427(.B)-.55 G 1.426(ars may be dra)-6.427 F 1.426(wn in an)-.15 F 3.926(yl)-.15 G 1.426(ine style.)-3.926 F(The)6.426 E 3.926(ys)-.15 G 1.426(upport the)-3.926 F F1(color)3.926 E F0(and)3.926 E F1(fillcolor) 3.926 E F0 -.1(ke)132 498 S(yw)-.05 E(ords described under)-.1 E F1 (circle)2.5 E F0(.)A .803(The second form of the command dra)132 516 R .803(ws a box with the tw)-.15 F 3.303(op)-.1 G .803(oints as corners.) -3.303 F .804(This can be used to)5.803 F(dra)132 528 Q 2.546(wb)-.15 G (ox)-2.546 E .046(es highlighting certain data as well as bar graphs.) -.15 F .045(Note that \214lled bars will co)5.045 F -.15(ve)-.15 G 2.545 (rd).15 G .045(ata dra)-2.545 F(wn)-.15 E(under them.)132 540 Q/F4 10 /Times-Bold@0 SF(Contr)84 564 Q .625(ol Flo)-.18 F(w)-.1 E F1(if)102 576 Q F2(expr)6 E F1(then)6 E F2(block)6 E F0([)3.333 E F1(else).833 E F2 (block)6 E F0(]).833 E(The)132 594 Q F1(if)3.175 E F0 .675 (statement pro)3.175 F .675(vides simple conditional e)-.15 F -.15(xe) -.15 G 3.175(cution. If).15 F F2(expr)3.175 E F0 .675(is non-zero, the) 3.175 F F2(block)3.175 E F0 .675(after the)3.175 F F1(then)132 606 Q F0 .731(statement is e)3.231 F -.15(xe)-.15 G 3.231(cuted. If).15 F .731 (not the)3.231 F F2(block)3.231 E F0 .731(after the)3.231 F F1(else) 3.231 E F0 .73(is e)3.23 F -.15(xe)-.15 G .73(cuted, if present.).15 F (See)5.73 E F4(Macr)3.23 E(os)-.18 E F0 1.482 (for the de\214nition of blocks.)132 618 R 1.483(Early v)6.482 F 1.483 (ersions of this implementation of)-.15 F F1(grap)3.983 E F0 1.483 (treated the blocks as)3.983 F .441(macros that were de\214ned and e)132 630 R .441(xpanded in place.)-.15 F .44 (This led to unnecessary confusion because e)5.441 F(xplicit)-.15 E 1.148(separators were sometimes called for)132 642 R 6.148(.N)-.55 G -.25(ow)-6.148 G(,)-.4 E F1(grap)3.649 E F0 1.149 (inserts a separator \(;\) after the last character in)3.649 F F2(block) 132 654 Q F0 2.5(,s)C 2.5(oc)-2.5 G(onstructs lik)-2.5 E(e)-.1 E F3 (if \(x == 3\) { y = y + 1 })132 672 Q 6(x=x+1)132 684 S F0(beha)132 708 Q .3 -.15(ve a)-.2 H 2.5(se).15 G 2.5(xpected. A)-2.65 F (separator is also appended to the end of a)2.5 E F1(for)2.5 E F0 (block.)2.5 E(FreeBSD 8.0)72 756 Q(March 11, 2006)149.98 E(7)197.2 E 0 Cg EP %%Page: 8 8 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F/F1 10/Courier-Bold@0 SF(for)102 96 Q/F2 10/Courier-Oblique@0 SF(name)6 E F1 (from)6 E F2(from_expr)6 E F1(to)6 E F2(to_expr)6 E F0([)2.5 E F1(by)A F0 .833([+)3.333 G .4 LW 337.966 89.25 337.966 96 DL(-)338.966 96 Q 343.296 89.25 343.296 96 DL/F3 10/Symbol SF(*)344.296 96 Q 350.296 89.25 350.296 96 DL F0 .833(/])351.296 96 S F2(by_expr)1.667 E F0(])A F1(do) 2.5 E F2(block)2.5 E F0 1.602(This command e)132 114 R -.15(xe)-.15 G (cutes).15 E F2(block)4.102 E F0(iterati)4.102 E -.15(ve)-.25 G(ly).15 E 6.602(.T)-.65 G 1.602(he v)-6.602 F(ariable)-.25 E F2(name)4.102 E F0 1.601(is set to)4.101 F F2(from_expr)4.101 E F0 1.601(and incre-)4.101 F 1.846(mented by)132 126 R F2(by_expr)4.346 E F0 1.846(until it e)4.346 F (xceeds)-.15 E F2(to_expr)4.346 E F0 6.846(.T)C 1.847 (he iteration has the semantics de\214ned in the)-6.846 F F1(ticks)132 138 Q F0 2.547(command. The)2.547 F .047(de\214nition of)2.547 F F2 (block)2.547 E F0 .047(is discussed in)2.547 F/F4 10/Times-Bold@0 SF (Mar)2.547 E(cos)-.18 E F0 5.047(.S)C .046 (ee also the note about implicit)-5.047 F (separators in the description of the)132 150 Q F1(if)2.5 E F0(command.) 2.5 E(An)132 168 Q F1(=)2.5 E F0(can be used in place of)2.5 E F1(from) 2.5 E F0(.)A F4(Expr)84 192 Q(essions)-.18 E F1(grap)102 204 Q F0 .331 (supports most standard arithmetic operators: + - /)2.831 F F3(*)2.832 E F0 2.832(^. The)2.832 F .332(carat \(^\) is e)2.832 F 2.832 (xponentiation. In)-.15 F(an)2.832 E F1(if)2.832 E F0(state-)2.832 E (ment)102 216 Q F1(grap)3.197 E F0 .697 (also supports the C logical operators ==, !=, &&, || and unary !.)3.197 F .696(Also in an)5.696 F F1(if)3.196 E F0 3.196(,=)C 3.196(=a)-3.196 G .696(nd != are)-3.196 F -.15(ove)102 228 S (rloaded for the comparison of quoted strings.).15 E -.15(Pa)5 G (rentheses are used for grouping.).15 E .101(Assignment is not allo)102 246 R .102(wed in an e)-.25 F .102(xpression in an)-.15 F 2.602(yc)-.15 G(onte)-2.602 E .102(xt, e)-.15 F .102 (xcept for simple cascading of assignments.)-.15 F/F5 10/Courier@0 SF 6.102(a=)5.102 G 6(b=3)102 258 S(5)-6 E F0 -.1(wo)2.5 G(rks as e).1 E (xpected;)-.15 E F5 6(a=3)2.5 G(.5)-6 E F3(*)6 E F5(\(b = 10\))6 E F0 (does not e)2.5 E -.15(xe)-.15 G(cute.).15 E F1(grap)102 276 Q F0 1.726 (supports the follo)4.226 F 1.726(wing functions that tak)-.25 F 4.226 (eo)-.1 G 1.726(ne ar)-4.226 F(gument:)-.18 E F1(log)4.226 E F0(,)A F1 (exp)7.726 E F0(,)A F1(int)7.725 E F0(,)A F1(sin)7.725 E F0(,)A F1(cos) 7.725 E F0(,)A F1(sqrt)7.725 E F0(,)A F1(rand)102 288 Q F0 6.396(.T)C 1.396(he log)-6.396 F 1.397 (arithms are base 10 and the trigonometric functions are in radians.) -.05 F F1(eexp)6.397 E F0 1.397(returns Euler')3.897 F(s)-.55 E .745 (number to the gi)102 300 R -.15(ve)-.25 G 3.245(np).15 G -.25(ow)-3.245 G .745(er and).25 F F1(ln)3.245 E F0 .745(returns the natural log)3.245 F 3.245(arithm. The)-.05 F .745(natural log and e)3.245 F .745 (xponentiation func-)-.15 F(tions are e)102 312 Q (xtensions and are probably not a)-.15 E -.25(va)-.2 G(ilable in other) .25 E F1(grap)2.5 E F0(implementations.)2.5 E F1(rand)102 330 Q F0 .924 (returns a random number uniformly distrib)3.423 F .924(uted on [0,1\).) -.2 F .924(The follo)5.924 F .924(wing tw)-.25 F(o-ar)-.1 E .924 (gument functions are)-.18 F(supported:)102 342 Q F1(atan2)3.193 E F0(,) A F1(min)6.693 E F0(,)A F1(max)6.693 E F0(.)A F1(atan2)5.693 E F0 -.1 (wo)3.193 G .693(rks just lik).1 F(e)-.1 E F5(atan2)3.193 E F0 3.193 (\(3\). The)B .693(random number generator can be)3.193 F 1.308 (seeded by calling)102 354 R F1(srand)3.808 E F0 1.308 (with a single parameter \(con)3.808 F -.15(ve)-.4 G 1.308 (rted internally to an inte).15 F 3.808(ger\). Because)-.15 F 1.308 (its return)3.808 F -.25(va)102 366 S .401 (lue is of no use, you must use).25 F F1(srand)2.901 E F0 .401 (as a separate statement, it is not part of a v)2.901 F .401(alid e)-.25 F(xpression.)-.15 E F1(srand)5.4 E F0(is not portable.)102 378 Q(The)102 396 Q F1(getpid)2.938 E F0 .439(function tak)2.938 F .439(es no ar)-.1 F .439(guments and returns the process id.)-.18 F .439 (This may be used to seed the random)5.439 F(number generator)102 408 Q 2.5(,b)-.4 G(ut do not e)-2.7 E(xpect cryptographically random v)-.15 E (alues to result.)-.25 E .65(Other than string comparison, no e)102 426 R .649(xpressions can use strings.)-.15 F .649(One string v)5.649 F .649 (alued function e)-.25 F(xists:)-.15 E F1(sprintf)3.149 E F0(\()102 438 Q F2(format)A F0 3.439(,[)C F2(expr)-3.439 E F0([)4.272 E F2 6.939(,e) .833 G(xpr)-6.939 E F0 .939(]] \).).833 F .939(It operates lik)5.939 F (e)-.1 E F5(sprintf)3.439 E F0 .939(\(3\), e)B .94 (xcept returning the v)-.15 F 3.44(alue. It)-.25 F .94(can be used)3.44 F(an)102 450 Q 1.827(ywhere a quoted string is used.)-.15 F(If)6.827 E F1(grap)4.327 E F0 1.827(is run with)4.327 F F15.993 E F0 4.327 (,t)C 1.827(he en)-4.327 F 1.827(vironment v)-.4 F(ariable)-.25 E F5 (GRAP_SAFER)4.327 E F0(is)4.327 E 1.564(de\214ned, or)102 462 R F1(grap) 4.064 E F0 1.564(has been compiled for safer operation, the)4.064 F F1 (sprintf)4.064 E F0 1.564(command will return the format)4.064 F 2.69 (string. This)102 474 R .189 (mode of operation is only intended to be used only if)2.689 F F1(grap) 2.689 E F0 .189(is being used as part of a super)2.689 F(-user)-.2 E (enabled print system.)102 486 Q F4(Macr)84 510 Q(os)-.18 E F1(grap)102 522 Q F0(has a simple b)2.5 E(ut po)-.2 E(werful macro f)-.25 E(acility) -.1 E 5(.M)-.65 G(acros are de\214ned using the)-5 E F1(define)2.5 E F0 (command :)2.5 E F1(define)102 540 Q F2(name block)6 E F1(undefine)102 552 Q F2(name)6 E F0(Ev)132 570 Q 1.453(ery occurrence of)-.15 F F2 (name)3.953 E F0 1.454(in the program te)3.953 F 1.454 (xt is replaced by the contents of)-.15 F F2(block)3.954 E F0(.)A F2 (block)6.454 E F0(is)3.954 E .212 (de\214ned by a series of statements in nested { }')132 582 R .211 (s, or a series of statements surrounded by the same let-)-.55 F(ter)132 594 Q 5(.A)-.55 G 2.5(ne)-5 G(xample of the latter is)-2.65 E F5 (define foo)192 612 Q 6(Xc)12 G(oord x 1,3 X)-6 E F0 .003(Each time)132 624 R F5(foo)2.503 E F0 .003(appears in the te)2.503 F .003 (xt, it will be replaced by)-.15 F F5 .003(coord x 1,3)2.503 F F0 5.003 (.M)C .004(acros are literal, and can)-5.003 F .19(contain ne)132 636 R 2.69(wlines. If)-.25 F 2.69(am)2.69 G .189 (acro does not span multiple lines, it should end in a semicolon to a) -2.69 F -.2(vo)-.2 G .189(id pars-).2 F(ing errors.)132 648 Q .962 (Macros can tak)132 666 R 3.462(ep)-.1 G .962(arameters, too.)-3.462 F .962(If a macro call is follo)5.962 F .962 (wed by a parenthesized, comma-separated)-.25 F .064(list the v)132 678 R .064(alues starting with $1 will be replaced in the macro with the el\ ements of the list.)-.25 F 2.563(A$n)5.063 G .063(ot fol-)-2.563 F(lo) 132 690 Q 1.083(wed by a digit is left unchanged.)-.25 F 1.084 (This parsing is v)6.084 F 1.084 (ery rudimentary; no nesting or parentheses or)-.15 F .498 (escaping of commas is allo)132 702 R 2.997(wed. Also,)-.25 F .497 (there is no w)2.997 F .497(ay to say ar)-.1 F .497(gument 1 follo)-.18 F .497(wed by a digit \(${1}0)-.25 F(FreeBSD 8.0)72 750 Q (March 11, 2006)149.98 E(8)197.2 E 0 Cg EP %%Page: 9 9 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F (in sh\(1\)\).)132 96 Q(The follo)132 114 Q(wing will dra)-.25 E 2.5 (wal)-.15 G(ine with slope 1.)-2.5 E/F1 10/Courier@0 SF (define foo { next at $1, $2 })192 132 Q (for i from 1 to 5 { foo\(i,i\) })192 144 Q F0 1.727 (Macros persist across graphs.)132 156 R 1.727(The \214le)6.727 F F1 (/usr/local/share/grap/grap.defines)4.227 E F0(contains)4.228 E (simple macros for plotting common characters.)132 168 Q(The)5 E/F2 10 /Courier-Bold@0 SF(undefine)2.5 E F0(command deletes a macro.)2.5 E 1.189(See the directory)132 186 R F1(/usr/local/share/examples/grap) 3.689 E F0 1.189(for more e)3.689 F 1.189(xamples of macros.)-.15 F (Con-)6.188 E(\214rm the location of the e)132 198 Q (xamples directory using the)-.15 E F24.166 E F0(\215ag.)2.5 E/F3 10/Times-Bold@0 SF .625(Number Lists)84 222 R F0 2.896(Aw)102 234 S .396 (hitespace-separated list of numbers is treated specially)-2.896 F 5.396 (.T)-.65 G .396(he list is tak)-5.396 F .396 (en to be points to be plotted using)-.1 F .604(the def)102 246 R .604 (ault line style on the def)-.1 F .604(ault coordinate system.)-.1 F .604(If more than tw)5.604 F 3.104(on)-.1 G .604(umbers are gi)-3.104 F -.15(ve)-.25 G .604(n, the e).15 F .603(xtra num-)-.15 F 1.465 (bers are tak)102 258 R 1.465(en to be additional y v)-.1 F 1.466 (alues to plot at the \214rst x v)-.25 F 3.966(alue. Number)-.25 F 1.466 (lists in D)3.966 F(WB)-.3 E F2(grap)3.966 E F0 1.466(can be)3.966 F .26 (comma-separated, and this)102 270 R F2(grap)2.76 E F0 .26 (supports that as well.)2.76 F .26(More precisely)5.26 F 2.76(,n)-.65 G .26(umbers in number lists can be sep-)-2.76 F (arated by either whitespace, commas, or both.)102 282 Q F1 6(123)132 300 S 6(456)132 312 S F0 -.4(Wi)102 336 S .265 (ll plot points using the def).4 F .266 (ault line style at \(1,2\), \(1,3\),\(4,5\) and \(4,6\).)-.1 F 2.766 (As)5.266 G .266(imple w)-2.766 F .266(ay to plot a set of num-)-.1 F (bers in a \214le named)102 348 Q F1(./data)2.5 E F0(is:)2.5 E F1(.G1) 132 366 Q(copy "./data")132 378 Q(.G2)132 390 Q F3 .625(Pic Macr)84 414 R(os)-.18 E F2(grap)102 426 Q F0 .201(de\214nes pic macros that can be \ used in embedded pic code to place elements in the graph.)2.701 F .2 (The macros)5.2 F(are)102 438 Q F2(x_gg)3.728 E F0(,)A F2(y_gg)3.728 E F0 3.728(,a)C(nd)-3.728 E F2(xy_gg)3.728 E F0 6.228(.T)C 1.229 (hese macros de\214ne pic distances that correspond to the gi)-6.228 F -.15(ve)-.25 G 3.729(na).15 G -.18(rg)-3.729 G(ument.).18 E(The)102 450 Q 3.737(yc)-.15 G 1.237(an be used to size box)-3.737 F 1.236 (es or to plot pic constructs on the graph.)-.15 F 2.836 -.8(To p)6.236 H 1.236(lace a gi).8 F -.15(ve)-.25 G 3.736(nc).15 G 1.236 (onstruct on the)-3.736 F 1.157 (graph, you should add Frame.Origin to it.)102 462 R 1.158 (Other coordinate spaces can be used by replacing)6.158 F F2(gg)3.658 E F0 1.158(with the)3.658 F(name of the coordinate space.)102 474 Q 2.5 (Ac)5 G(oordinate space named)-2.5 E F2(gg)2.5 E F0 (cannot be reliably accessed by these macros.)2.5 E (The macros are emitted immediately before the frame is dra)102 492 Q (wn.)-.15 E -.3(DW)102 510 S(B).3 E F2(grap)3.109 E F0 .608 (may use these as part of its implementation.)3.109 F(This)5.608 E F2 (grap)3.108 E F0(pro)3.108 E .608(vides them only for compatibility)-.15 F(.)-.65 E(Note that these are v)102 522 Q (ery simple macros, and may not do what you e)-.15 E(xpect under comple) -.15 E 2.5(xc)-.15 G(onditions.)-2.5 E F3(ENVIR)72 546 Q 1.666(ONMENT V) -.3 F(ARIABLES)-1.35 E F0 1.261(If the en)102 558 R 1.262(vironment v) -.4 F(ariable)-.25 E F1(GRAP_DEFINES)3.762 E F0 1.262(is de\214ned,) 3.762 F F2(grap)3.762 E F0 1.262 (will look for its de\214nes \214le there.)3.762 F 1.262(If that)6.262 F -.25(va)102 570 S .756(lue is a relati).25 F 1.056 -.15(ve p)-.25 H .755 (ath name the path speci\214ed in the).15 F F24.921 E F0 .755 (option will be searched for it.)3.255 F F1(GRAP_DEFINES)5.755 E F0 -.15 (ove)102 582 S (rrides the compiled in location of the de\214nes \214le, b).15 E (ut may be o)-.2 E -.15(ve)-.15 G(rridden by the).15 E F24.166 E F0(or)2.5 E F24.166 E F0(\215ags.)2.5 E(If)102 600 Q F1 (GRAP_SAFER)2.5 E F0(is set,)2.5 E F2(sprintf)2.5 E F0 (is disabled to pre)2.5 E -.15(ve)-.25 G(nt forcing).15 E F2(grap)2.5 E F0(to core dump or smash the stack.)2.5 E F3(FILES)72 624 Q F1 (/usr/local/share/grap/grap.defines)102 636 Q F3 1.666(SEE ALSO)72 660 R F1(atan2)102 672 Q F0(\(3\),)A F1(groff)2.5 E F0(\(1\),)A F1(pic)2.5 E F0(\(1\),)A F1(printf)2.5 E F0(\(3\),)A F1(sh)2.5 E F0(\(1\),)A F1 (sprintf)2.5 E F0(\(3\),)A F1(troff)2.5 E F0(\(1\))A (If documentation and e)102 690 Q(xamples ha)-.15 E .3 -.15(ve b)-.2 H (een installed,).15 E F2 -1.834(grap \255-version)2.5 F F0(or)2.5 E F2 -1.834(grap \255-help)2.5 F F0(will display the)2.5 E(locations.)102 702 Q(FreeBSD 8.0)72 750 Q(March 11, 2006)149.98 E(9)197.2 E 0 Cg EP %%Page: 10 10 %%BeginPageSetup BP %%EndPageSetup /F0 10/Times-Roman@0 SF -.834(GRAP \(1\))72 48 R (FreeBSD General Commands Manual)117.764 E -.834(GRAP \(1\))117.764 F/F1 10/Times-Bold@0 SF -.1(BU)72 96 S(GS).1 E F0 1.03(There are se)102 108 R -.15(ve)-.25 G 1.03(ral small incompatibilities with K&R).15 F/F2 10 /Courier-Bold@0 SF(grap)3.529 E F0 6.029(.T)C(he)-6.029 E 3.529(yi)-.15 G 1.029(nclude the)-3.529 F F2(sh)3.529 E F0 1.029(command not e)3.529 F (xpanding)-.15 E -.25(va)102 120 S(riables and macros, and a more stric\ t adherence to parameter order in the internal commands.).25 E .347 (Although much impro)102 138 R -.15(ve)-.15 G .347 (d, the error reporting code can still be confused.).15 F(Notably)5.347 E 2.847(,a)-.65 G 2.847(ne)-2.847 G .348(rror in a macro is not)-2.847 F (detected until the macro is used, and it produces unusual output in th\ e error message.)102 150 Q(Iterating man)102 168 Q 2.5(yt)-.15 G(imes o) -2.5 E -.15(ve)-.15 G 2.5(ram).15 G(acro with no ne)-2.5 E (wlines can run)-.25 E F2(grap)2.5 E F0(out of memory)2.5 E(.)-.65 E F1 -.5(AU)72 192 S(THOR).5 E F0 .423(This implementation w)102 204 R .423 (as done by T)-.1 F .423(ed F)-.7 F(aber)-.15 E/F3 10/Symbol SF2.923 E F0 -.1(fa)C(ber@lunabase.or).1 E(g)-.18 E F3A F0 5.423(.B)C .422 (ruce Lilly)-5.423 F F32.922 E F0(blilly@erols.com)A F3A F0 (contrib-)2.922 E .15(uted man)102 216 R 2.65(yb)-.15 G .15(ug \214x) -2.85 F .15(es, including a considerable re)-.15 F -.25(va)-.25 G .15 (mp of the error reporting code.).25 F .15 (If you can actually \214nd an)5.15 F 2.667(error in your)102 228 R F2 (grap)5.167 E F0 2.666(code, you can probably thank him.)5.167 F F2 (grap)7.666 E F0 -.1(wa)5.166 G 5.166(sd).1 G 2.666 (esigned and speci\214ed by Brian)-5.166 F -.25(Ke)102 240 S (rnighan and Jon Bentle).25 E(y.)-.15 E(FreeBSD 8.0)72 750 Q (March 11, 2006)149.98 E(10)192.2 E 0 Cg EP %%Trailer end %%EOF grap-1.43/grap_lex.l000640 004133 000000 00000064332 11073546041 014563 0ustar00faberwheel000000 000000 /* -*-c++-*- */ %{ /* This code is (c) 1998-2001 Ted Faber see COPYRIGHT for the full copyright and limitations of liabilities. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef STDC_HEADERS #include #include #endif #if defined(STDC_HEADERS) | defined(HAVE_STDLIB_H) #include #else extern "C" { void free(void*); }; #endif #include #include #include #include #include "grap.h" #include "grap_data.h" #include "grap_draw.h" #include "y.tab.h" extern int errno; #ifndef STRERROR_DECLARED #if HAVE_STRERROR extern "C" { char *strerror(int errnum); } #else extern char *strerror(int errnum); #endif #endif // CGYWIN needs errno if we have it: #ifdef HAVE_ERRNO_H #include #endif int return_macro = 0; int slashcount = 0; int macro_end = 0; string *macrotext; int in_str = 0; int braces = 0; int stack_init =0; int copystate =0; int continuation =0; unsigned int tokenpos =0; bool print_lex_debug = false; bool lex_expand_macro = true; linelist *sl=0; string *copy_end, *copy_backstop; string linebuf; extern macroDictionary macros; extern doubleDictionary vars; extern graph *the_graph; extern stringSequence path; extern bool compat_mode; extern bool id_letter[]; // Templates for debugging. Print the parameters to cerr. //#define LEX_DEBUG template inline void debug(T p) { if ( print_lex_debug) cerr << p << endl; } template inline void debug(T p1, U p2) { if ( print_lex_debug) cerr << p1 << p2 << endl; } int include_string(string *, struct for_descriptor *f=0, grap_input i=GMACRO); void lex_begin_macro_text(); void lex_end_expr(); void macro_args(macro*); void expand_macro(macro*); bool is_macro(const string&); void newline(); #ifndef HAVE_STRDUP char *strdup(const char *); #endif const char *vf1names[NVF1] = { "srand" }; const char *f0names[NF0] = { "rand", "getpid" }; const char *f1names[NF1] = { "log", "exp", "int", "sin", "cos", "sqrt", "eexp","ln" }; const char *f2names[NF2] = { "atan2", "min", "max" }; #define ECHO /* */ // Set of currently active keywords set active; // Commonly used keyword sets extern vector grap_keys; extern keywordDictionary keywords; // There are a couple times when the possiblity of a COORD_NAME can be // ruled out. If this is set, this is one of those times. bool no_coord=false; %} %x GRAP %x REJECTED_COORD %x MACROTEXT %x COPYSTATE %x HUNTMACRO %x RESTOFLINE identifier [A-Za-z][A-Za-z0-9_]* keyword above|aligned|arrow|auto|bar|base|below|bot|bottom|by|circle|color|coord|copy|dashed|define|do|dotted|down|draw|else|fill|fillcolor|for|frame|from|graph|grid|ht|if|in|invis|label|left|line|ljust|new|next|off|on|out|pic|plot|print|rad|radius|right|rjust|sh|size|solid|sprintf|then|through|thru|tick|ticks|to|top|unaligned|until|up|wid|x|y|undefine|clipped|unclipped|thickness %% { ^.*$ { linebuf = yytext; tokenpos = 0; REJECT; } \n { debug(" newline"); newline(); tokenpos += yyleng; cout << yytext; } .G1.* { if ( yyleng > 3 && yytext[3] != '\t' && yytext[3] != ' ' ) if ( !compat_mode ) REJECT; if ( yyleng > 3) { // Some extra characters after the macro invocation (or an // extension of the macro under compat mode). char *c; for (c = yytext; *c != '\t' && *c != ' '&& *c != '\0'; c++ ) ; yylval.String = ( *c != '\0' ) ? new string(yytext+3) : 0; } else yylval.String = 0; tokenpos += yyleng; BEGIN(GRAP); debug("START"); active.clear(); active.insert(grap_keys.begin(), grap_keys.end()); return START; } .+ { tokenpos += yyleng; cout << yytext; } } { ^.*$ { linebuf = yytext; tokenpos = 0; REJECT; } \\\n { newline(); tokenpos = 0;} \n { tokenpos = 0; newline(); // Back to square 1 after a SEP active.clear(); active.insert(grap_keys.begin(), grap_keys.end()); debug("SEP"); BEGIN(GRAP); return SEP; } \#.*$ [ \t]+ tokenpos += yyleng; ([0-9]*\.?[0-9]+)|([0-9]*\.?[0-9]+[eE](\+|\-)?[0-9]+)|([0-9]+\.) { debug("Number: ",yytext); yylval.num = atof(yytext); tokenpos += yyleng; BEGIN(GRAP); return NUMBER; } {identifier}[ \t]*=/[^=] { if ( is_macro(yytext) ) REJECT; // in a for statement, identifier = is a // synonym for identifier FROM, so don't // identify it as a LHS. if ( active.count("do") && active.count("from")) REJECT; tokenpos += yyleng; for ( int i = 0; i < yyleng; i++ ) if ( yytext[i] == ' ' || yytext[i] == '\t' || yytext[i] == '=' ) { yytext[i] = '\0'; break; } yylval.String = new string(yytext); debug("LHS: ", yytext); BEGIN(GRAP); return LHS; } ; { tokenpos += yyleng; debug("SEP"); // Back to square 1 after a SEP active.clear(); active.insert(grap_keys.begin(), grap_keys.end()); BEGIN(GRAP); return SEP; } \( tokenpos += yyleng; debug("LPAREN"); return LPAREN; \) tokenpos += yyleng; debug("RPAREN"); return RPAREN; , tokenpos += yyleng; debug("COMMA"); return COMMA; \+ tokenpos += yyleng; debug("PLUS"); return PLUS; \- tokenpos += yyleng; debug("MINUS"); return MINUS; \* tokenpos += yyleng; debug("TIMES"); return TIMES; \/ tokenpos += yyleng; debug("DIV"); return DIV; \^ tokenpos += yyleng; debug("CARAT"); return CARAT; \= { tokenpos += yyleng; // if this is in a for statement, the EQUALS // has taken the place of the from, so // remove the from from active. if ( active.count("do") && active.count("from")) active.erase("from"); debug("EQUALS"); BEGIN(GRAP); return EQUALS; } \=\= tokenpos += yyleng; debug("EQ"); return EQ; \!\= tokenpos += yyleng; debug("NEQ"); return NEQ; \< tokenpos += yyleng; debug("LT"); return LT; \> tokenpos += yyleng; debug("GT"); return GT; \<\= tokenpos += yyleng; debug("LTE"); return LTE; \>\= tokenpos += yyleng; debug("GTE"); return GTE; \&\& tokenpos += yyleng; debug("AND"); return AND; \|\| tokenpos += yyleng; debug("OR"); return OR; \! tokenpos += yyleng; debug("NOT"); return NOT; log[ \t]+(x|y|log) { int rc = LOG_LOG; string ls(yytext); if (active.count("log") ) { tokenpos += yyleng; // LOG_whatever doesn't change the active // state. debug(yytext); BEGIN(GRAP); if ( ls.find('x') != string::npos ) rc = LOG_X; else if ( ls.find('y') != string::npos) rc = LOG_Y; return rc; } else { debug(yytext, " not active"); REJECT; } } } {identifier}[ \t][ \t]*{identifier} { // The yyless/YY_BREAK allows us to redo the // match under the new start condition. debug("starting ident white ident"); if ( is_macro(yytext) ) { BEGIN(REJECTED_COORD); yyless(0); YY_BREAK; } // Early rejection if a COORD_NAME is // illegal here. if ( no_coord ) { debug(""); BEGIN(REJECTED_COORD); yyless(0); YY_BREAK; } // Here we go - parse out the two // identifiers. If the first is an active // keyword, REJECT. If the second // identifier is not an active keyword, // then this is a coordinate name, so put // the whitespace and the second identifier // back into the input and return the // coordinate name. If no REJECT. string first(yytext); // first id string second; string::size_type f, l; coordinateDictionary::iterator ci; coord *c; for (f = 0;isalnum(first[f]) ||first[f] == '_'; f++) ; // Now f is on the first whitespace character; for (l = f; first[l] == ' '|| first[l] =='\t'; l++) ; // l is now the first character of the // second identifier. second = first.substr(l); first.erase(f); debug("Coord search"); debug(first, second); debug(active.count(first), active.count(second)); if (active.count(first) || active.count(second)) { debug(""); BEGIN(REJECTED_COORD); yyless(0); YY_BREAK; } ci = the_graph->coords.find(first); if ( ci != the_graph->coords.end()) { c = (*ci).second; yylval.coordptr = c; } else { yylval.coordptr = new coord(first); the_graph->coords[first] = yylval.coordptr; } yyless(first.length()); tokenpos += first.length(); debug("COORD_NAME"); return COORD_NAME; } { {identifier}/[ \t][ \t]*-[ \t]*[0123456789\.(] { // This is close to the case below, which is more // clearly a coordinate space modifying a number. // This case includes things like // ident -3 // It's often literally impossible to decide if that // means -3 in the ident coordinate space or the // variable ident minus 3. This code rules that if // ident is a keyword, macro, or initialized // variable, ident will be treated as one of those, // and this rule will be rejected. Otherwise it is // a coordinate space and, if neceaasry, a new space // will be allocated for it. // // I don't expect that this is the last piece of // pain to come from here. coordinateDictionary::iterator ci; coord *c; debug("testing (minus sign): ",yytext); debug("count ", active.count(yytext)); if ( is_macro(yytext) ) REJECT; if ( active.count(yytext) ) REJECT; if ( vars.count(yytext) ) REJECT; ci = the_graph->coords.find(yytext); if ( ci != the_graph->coords.end()) { c = (*ci).second; yylval.coordptr = c; } else { yylval.coordptr = new coord(yytext); the_graph->coords[yytext] = yylval.coordptr; } tokenpos += yyleng; debug("COORD_NAME: ",yytext); return COORD_NAME; } {identifier}/[ \t][ \t]*[0123456789\.(] { coordinateDictionary::iterator ci; coord *c; debug("testing: ",yytext); debug("count ", active.count(yytext)); if ( is_macro(yytext) ) REJECT; if ( active.count(yytext) ) REJECT; ci = the_graph->coords.find(yytext); if ( ci != the_graph->coords.end()) { c = (*ci).second; yylval.coordptr = c; } else { yylval.coordptr = new coord(yytext); the_graph->coords[yytext] = yylval.coordptr; } tokenpos += yyleng; debug("COORD_NAME: ",yytext); return COORD_NAME; } {keyword} { macroDictionary::iterator mi; if ( lex_expand_macro && ( mi = macros.find(yytext)) != macros.end() ) { expand_macro((*mi).second); tokenpos += yyleng; BEGIN(GRAP); } else { if (active.count(yytext) ) { keywordDictionary::iterator ki; unsigned int i; if ( (ki = keywords.find(yytext)) == keywords.end()) { cerr << "keyword not in map!?" << endl; return(0); } // The alias runs faster const keyword& k = (*ki).second; if ( k.clear ) active.clear(); for ( i = 0; i < k.add.size(); i++ ) active.insert(k.add[i]); for ( i = 0; i < k.remove.size(); i++) active.erase(k.remove[i]); debug("keyword: ", yytext); tokenpos += yyleng; BEGIN(GRAP); return(k.token); } else { debug(yytext, " not active"); REJECT; } } } at { if (active.count(yytext) ) { tokenpos += yyleng; // AT can be active for 2 reasons. It's // been found in an expression that // recognizes AT, or it's following an // implicit PLOT statement - "string" at // x, y. In the first case, no more // keywords need to be detected. In the // second just delete the AT from the // list. If COPY, which doesn't take an // AT, is in active, this is an implicit // PLOT because active is in the initial // state. if ( active.count("plot")) active.clear(); else active.erase("at"); debug("AT"); BEGIN(GRAP); return AT; } else { debug("AT not active"); REJECT; } } srand { debug("VFUNC1"); for ( int i = 0 ; i < NVF1; i++ ) if ( !strcmp(yytext,vf1names[i]) ) yylval.val = i; tokenpos += yyleng; BEGIN(GRAP); return VFUNC1; } rand|getpid { debug("FUNC0"); for ( int i = 0 ; i < NF0; i++ ) if ( !strcmp(yytext,f0names[i]) ) yylval.val = i; tokenpos += yyleng; BEGIN(GRAP); return FUNC0; } log|exp|int|sin|cos|sqrt|eexp|ln { debug("FUNC1"); for ( int i = 0 ; i < NF1; i++ ) if ( !strcmp(yytext,f1names[i]) ) yylval.val = i; tokenpos += yyleng; BEGIN(GRAP); return FUNC1; } atan2|min|max { debug("FUNC2"); for ( int i = 0 ; i < NF2; i++ ) if ( !strcmp(yytext,f2names[i]) ) yylval.val = i; tokenpos += yyleng; BEGIN(GRAP); return FUNC2; } [.\'][ \t]*[^\t 0-9].*$ { tokenpos += yyleng; if ( !strncmp(".G1", yytext, 3) ) { if ( lexstack.empty() || lexstack.front()->report_start == 1 ) { debug("Start: ", yytext); BEGIN(GRAP); return START; } else YY_BREAK; } if ( !strncmp(".G2", yytext, 3) ) { if ( lexstack.empty() || lexstack.front()->report_start == 1) { debug("End: ",yytext); BEGIN(INITIAL); // Eat the newline yyinput(); newline(); tokenpos = 0; return END; } else YY_BREAK; } yylval.String = new string(yytext); debug("Troff: ", yytext); BEGIN(GRAP); return TROFF; } \"([^\"\n]|\\\")*\" { debug("String: ", yytext); yylval.String = new string(yytext); tokenpos += yyleng; BEGIN(GRAP); return STRING; } {identifier} { macroDictionary::iterator mi; string *id; debug("ident: ", yytext); id = new string(yytext); if ( lex_expand_macro && ( mi = macros.find(*id)) != macros.end() ) { delete id; expand_macro((*mi).second); tokenpos += yyleng; } else { tokenpos += yyleng; yylval.String = id; BEGIN(GRAP); return IDENT; } } . tokenpos += yyleng; debug("unknown: ", yytext); return 0; } { ^.*$ { linebuf = yytext; REJECT; } [ \t]+ { slashcount = 0; tokenpos += yyleng; if ( macro_end != 0) *macrotext += yytext; } \\ { *macrotext += *yytext; tokenpos += yyleng; slashcount ++; } \" { *macrotext += *yytext; tokenpos += yyleng; if ( in_str ) { if ( slashcount % 2 == 0) in_str=0; } else { if ( slashcount % 2 == 0) in_str=1; } slashcount = 0; } \{ { if ( macro_end == 0 ) { macro_end = '}'; braces = 1; } else { if ( !in_str ) braces++; *macrotext += *yytext; slashcount =0; } tokenpos += yyleng; } \} { tokenpos += yyleng; if ( macro_end == 0 ) return 0; else { if ( !in_str ) braces--; if ( macro_end == '}' && !braces ) { BEGIN(GRAP); if ( !return_macro) { yylval.String = macrotext; debug("TEXT"); return TEXT; } else { macro *m = new macro(macrotext); yylval.macro_val = m; debug("MACRO: ",macrotext->c_str()); macrotext = 0; return MACRO; } } else { *macrotext += *yytext; slashcount =0; } } } \n { *macrotext += *yytext; slashcount =0; tokenpos = 0; newline(); // don't return SEP here } . { tokenpos += yyleng; if ( macro_end == 0 ) macro_end = *yytext; else { if ( *yytext == macro_end ) { BEGIN(GRAP); if ( !return_macro ) { yylval.String = macrotext; return TEXT; } else { macro *m = new macro(macrotext); yylval.macro_val = m; macrotext = 0; return MACRO; } } else { *macrotext += *yytext; slashcount =0; } } } } { ^.*$ { linebuf = yytext; REJECT; } \n { tokenpos = 0; newline(); } .+ { string *s; if ( *copy_end != yytext && *copy_backstop != yytext ) { s = new string(yytext); sl->push_back(s); } else { // If we're stopped by an END symbol, we have to put it back if ( !strncmp(".G2",yytext,3) ) { debug("End: ", yytext); yyless(0); unput('\n'); lexstack.front()->line--; tokenpos = 0; } else tokenpos += yyleng; BEGIN(GRAP); yylval.line_list = sl; sl = 0; copystate = 0; debug("COPYTEXT ", yylval.line_list->size()); return COPYTEXT; } } } { [ \t]+ tokenpos += yyleng; [A-Za-z0-9_]* { macro *m; macroDictionary::iterator mi; string *id = new string(yytext); if ( ( mi = macros.find(*id)) != macros.end()) { m = (*mi).second; delete id; tokenpos += yyleng; BEGIN(GRAP); yylval.macro_val = m; return MACRO; } else { char *c = strdup(yytext); delete id; lex_begin_macro_text(); return_macro =1; yyless(0); free(c); tokenpos += yyleng; } } . { debug(" ", yytext); unput(*yytext); lex_begin_macro_text(); return_macro = 1; } } { .*$ { BEGIN(GRAP); tokenpos += yyleng; debug("REST: ",yytext); if ( strcmp("\n",yytext) ) yylval.String = new string(yytext); else yylval.String = 0; no_coord = false; return REST; } } <> { debug("EOF"); if ( copystate && !lexstack.empty()) { copystate = 0; tokenpos = 0; BEGIN(GRAP); yylval.line_list = sl; sl = 0; debug("COPYTEXT(EOF)"); return COPYTEXT; } else yyterminate(); } %% // Most of these that begin with lex_ are an interface from the parser // (grap.y) // XXX: Store the line number info in the output text as a .lf. This isn't // quite right yet. It's nulled out because it was worse than "not right" it // was emitting text outside the PS/PE. void linenum() { } // Put the given file into the input stream. If rs is true, report // start tokens from that buffer. If usepath is true the grap path is // used to search for the file. bool include_file(string *s, bool rs /* =false */ , bool usepath /* =true*/) { FILE *f=0; struct grap_buffer_state *g = new grap_buffer_state(0, 0, 0, 1, rs, GFILE); grap_buffer_state *gg = lexstack.empty() ? 0 : lexstack.front(); if ( s ) { debug("include_file: ",s->c_str()); if ( gg ) { gg->tokenpos = tokenpos; tokenpos = 0; } if ( *s != "-" ) { if ( (*s)[0] != '/' && usepath ) { // use path to look up relative path for ( stringSequence::iterator i = path.begin(); i != path.end(); i++) { string str = *(*i); str += "/"; str += *s; if ( ( f = fopen(str.c_str(),"r"))) break; } } else f = fopen(s->c_str(),"r"); if ( !f ) { cerr << "Can't open " << *s << " " << strerror(errno) << endl; return 0; } g->yy = yy_create_buffer(f,YY_BUF_SIZE); g->name = new string(*s); } else { g->yy = yy_create_buffer(stdin,YY_BUF_SIZE); g->name = new string("-"); } lexstack.push_front(g); yy_switch_to_buffer(g->yy); return 1; } else return 0; } // Include the given string into the input stream. Additional // parameters are a for descriptor associated with the buffer (if its // part of a for loop) and an input type (that's usualy GMACRO) int include_string(string *s, struct for_descriptor *f /* =0 */, grap_input it /*=GMACRO */) { char *cbuf; int len; grap_buffer_state *g; grap_buffer_state *gg = lexstack.empty() ? 0 : lexstack.front(); debug("include string ",s->c_str()); if ( gg ) { gg->tokenpos = tokenpos; tokenpos = 0; } g = new grap_buffer_state(0, f, 0, 1, 1, it); cbuf = new char[len = s->length()+1]; strncpy(cbuf,s->c_str(),len-1); cbuf[len-1] = '\0'; lexstack.push_front(g); g->yy = yy_scan_string(cbuf); delete cbuf; return 1; } // Disable macro expansion of identifers (used in definingin new macros) void lex_no_macro_expansion() { lex_expand_macro = false; } // Disable macro expansion of identifers (used in definingin new macros) void lex_macro_expansion_ok() { lex_expand_macro = true; } // Begin parsing macro text. Set the lexer into the appropriate start // condition and initialize the appropriate internals. void lex_begin_macro_text() { BEGIN(MACROTEXT); debug(" lex_begin_macro_text()"); lex_expand_macro = true; slashcount = 0; macro_end = 0; return_macro=0; macrotext = new string; in_str = 0; braces = 0; } // Parse the arguments to a macro invocation and call macro::add_arg // on them. void macro_args(macro *m) { string *arg; int c; int parens = 0; int slashcount = 0; int in_str = 0; arg = new string; for ( c = yyinput(); c != EOF && ( c != ')' || parens ); c = yyinput()) { if ( c == ',' && !in_str && !parens) { // End of arg if ( m->add_arg(arg)) arg = new string; continue; } if ( c == '(' ) parens++; if ( c == ')' ) parens --; if ( c == '"' && (slashcount % 2 ) == 0 ) { if ( in_str ) in_str = 0; else in_str = 1; } if ( c == '\\' ) slashcount++; else slashcount = 0; *arg += (char) c; tokenpos++; } if ( c == ')' && arg->length() ) { if ( !m->add_arg(arg)) delete arg; } else if (arg) delete arg; tokenpos++; } // prepare to copy text from the input for a copy statement. Set the // start condition and the internal state. void lex_begin_copy(string *s /* =0 */) { debug("COPYSTATE (lex_begin_copy)"); BEGIN(COPYSTATE); copystate = 1; if ( !copy_backstop ) copy_backstop = new string(".G2"); if ( copy_end) delete copy_end; if ( s ) copy_end = s; else copy_end = new string(".G2"); if ( sl ) delete sl; sl = new linelist; } // Change start condition void lex_hunt_macro() { BEGIN(HUNTMACRO); } // Change start condition void lex_begin_rest_of_line() { BEGIN(RESTOFLINE); } // Tell if coordinate names are allowed here void lex_no_coord() { no_coord = true; } // Tell if coordinate names are allowed here void lex_coord_ok() { no_coord = false; } // This buffer is empty, go to the next one on the stack. If there is // an associated for descriptor, do the for processing and replace the // buffer on the stack if the loop is continuing. int yywrap() { struct grap_buffer_state *g; debug("(yywrap)"); if ( lexstack.empty() ) yyterminate(); else { g = lexstack.front(); lexstack.pop_front(); } if ( g->f ) { struct for_descriptor *f = g->f; // we're processing a for statement switch (f->by_op ) { case PLUS: default: *f->loop_var += f->by; break; case MINUS: *f->loop_var -= f->by; break; case TIMES: *f->loop_var *= f->by; break; case DIV: *f->loop_var /= f->by; break; } if ( (*f->loop_var - f->limit) * f->dir < epsilon ) { // still iterating redo this stack frame yy_delete_buffer(g->yy); // *do not delete g->f because include string will attach // it to the new grap_buffer_state that it allocates. g->f = 0; delete g; include_string(f->anything, f); return 0; } } // If we get here, we need to switch to the previous buffer yy_delete_buffer(g->yy); if ( lexstack.empty() ) { // groff line marker delete g; return 1; } else { grap_input closed = g->type; delete g; g = lexstack.front(); tokenpos = g->tokenpos; yy_switch_to_buffer(g->yy); } return copystate ? 1 : 0; } // Newline processing. Inrement the current line number void newline() { if ( !lexstack.empty() ) { grap_buffer_state *g = lexstack.front(); g->line++; } } // Error message printing. string pre_context(void) { if (!tokenpos) return ""; else return linebuf.substr(0,tokenpos-yyleng); } char *token_context(void) { return (yytext); } string post_context(void) { return (tokenpos < linebuf.size()) ? linebuf.substr(tokenpos) : "" ; } void expand_macro(macro *m) { char ch = yyinput(); string *exp; if ( ch == '(') { macro_args(m); tokenpos++; } else { // flex 2.3.51+ undefs yytext_ptr which breaks the unput macro outside the // first %% section. This is a kludge to expand the macro by hand if this bad // thing has happened. I think I'll try to convince them this is a bad idea. #ifndef yytext_ptr yyunput(ch, yytext); #else unput(ch); #endif } exp = m->invoke(); include_string(exp); delete exp; } bool is_macro(const string& s) { int i = (int) s.length()-1; string mname; while ( i >=0 && !id_letter[static_cast(s[i])]) i--; if ( i < 0 ) return false; mname = s.substr(0, i+1); return (macros.find(mname) != macros.end()); } grap-1.43/grap_parse.cc000640 004133 000000 00000063370 11073542122 015234 0ustar00faberwheel000000 000000 /* -*-c++-*- */ /* This code is (c) 1998-2001 Ted Faber (faber@lunabase.org) see the COPYRIGHT file for the full copyright and limitations of liabilities. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #if defined(STDC_HEADERS) | defined(HAVE_STDLIB_H) #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifndef HAVE_OPTARG extern "C" { extern char *optarg; extern int optind; int getopt(int, char * const [], const char *); }; #endif #include "grap.h" #include "grap_data.h" #include "grap_draw.h" #include "grap_pic.h" #include "y.tab.h" extern doubleDictionary vars; extern stringSequence path; extern graph *the_graph; extern bool unaligned_default; // Should strings be unaligned by default extern bool clip_default; // Should strings be clipped by default extern bool print_lex_debug; extern line* defline; extern coord *defcoord; bool compat_mode=false; // Compatibility mode #ifdef GRAP_SAFER bool do_sprintf = false; // Allow sprintf #else bool do_sprintf = true; // Allow sprintf #endif // defined in grap_lex.l extern int include_string(string *,struct for_descriptor *f=0, grap_input i=GMACRO); extern string pre_context(void); extern char *token_context(void); extern string post_context(void); extern bool include_file(string *, bool =false, bool=true); extern void init_keywords(); extern int yyparse(); extern int nlines; extern macroDictionary macros; const char *opts = "d:lDvuM:CVhScRr"; // Coarse defaults for double tolerances because these work best for common // cases - comparisons of fairly large values that don't differ by much. double epsilon = COARSE_EPSILON; double min_double = COARSE_MIN_DOUBLE; // Classes for various for_each calls // This collects the modifiers for other strings in // a string list to construct the modifiers for the next string class modaccumulator : public unary_function { public: int just; double size; int rel; bool clip; string *color; modaccumulator() : just(0), size(0), rel(0), clip(true), color(0) {}; int operator()(DisplayString* s) { just = s->j; size = s->size; rel = s->relsz; clip = s->clip; delete color; color = s->color; return 0; } }; // Add a tick to the graph class add_tick_f : public unary_function { sides side; double size; shiftlist shift; public: add_tick_f(sides sd, double sz, shiftlist *s) : side(sd), size(sz), shift() { shiftcpy sc(&shift); for_each(s->begin(), s->end(), sc); }; int operator()(tick *t) { shiftcpy sc(&t->shift); t->side = side; t->size = size; for_each(shift.begin(), shift.end(), sc); the_graph->base->tks.push_back(t); if ( t->side == top_side || t->side == bottom_side ) t->c->newx(t->where); else t->c->newy(t->where); return 0; } }; // Allocate a new graph (at this point always a Picgraph. This is // here so we don't have to include grap_pic in grap.y. graph *initial_graph() { return (graph *) new Picgraph; } // Combine a pair of line descriptions. Non-defaults in elem override // those features in desc. The function returns desc and frees elem, // so the programmer can treat it as freeing its parameters and // returning a new linedesc. (desc and elem should have been // allocated by new). linedesc* combine_linedesc(linedesc *desc, linedesc* elem) { if ( elem->ld != def ) { desc->ld = elem->ld; desc->param = elem->param; } if ( elem->fill ) desc->fill = elem->fill; if ( elem->thick ) desc->thick = elem->thick; if ( elem->color ) { if ( desc->color ) delete desc->color; desc->color = elem->color; // Don't let the destructor delete the color in desc. elem->color = 0; } if ( elem->fillcolor ) { if ( desc->fillcolor ) delete desc->fillcolor; desc->fillcolor = elem->fillcolor; // Don't let the destructor delete the fillcolor // in desc. elem->fillcolor = 0; } delete elem; return desc; } // Process a draw statement. Create a new line description if this is // a new name, assign the line description to it, and a plot string if // necessary. void draw_statement(string *ident, linedesc *ld, DisplayString *plot) { line *l; lineDictionary::iterator li; linedesc defld(invis,0,0); bool extant = false; // True if this line was already defined. if ( ident ) { li = the_graph->lines.find(*ident); if ( li == the_graph->lines.end() ) { if ( *ident == "grap_internal_default") defline = l = new line(); else l = new line(*defline); the_graph->lines[*ident] = l; } else { l = (*li).second; extant = true; } } else { l = defline; // This is a bit of a kludge. Don't reset any parameters of // the default line if new is given alone. if ( !ld && !plot ) extant = true; } // If a linedesc is specified, set the current line's description. if ( ld ) l->desc = *ld; if ( plot ) { if ( *plot != "" ) { delete l->plotstr; l->plotstr = new DisplayString(*plot); } else { // If the string is "", don't issue the pic commands to // print it. if (l->plotstr) { delete l->plotstr; l->plotstr = 0; } } } else { // Only delete the plot string if this is the line definition. // (This makes draw solid do what's expected.) To remove a // plot string, the user will have to explicitly specify an // empty plot string. if ( !extant ) { delete l->plotstr; l->plotstr = 0; } } l->lastplotted(0); delete ident; delete plot; delete ld; } // Process a line of a number list. dl is a list of numbers on this // line. If if at least an x and y are there, add those points to the // current line and coords. If only one number is given, use the // number of lines processed so far as the x value and the given // number as the y. void num_list(doublelist *dl) { double x, y; if ( dl->empty() ) exit(20); else { x = dl->front(); dl->pop_front(); } if ( dl->empty() ) { the_graph->new_linesegment(nlines, x, defcoord, defline); } else { while ( !dl->empty() ) { y = dl->front(); dl->pop_front(); the_graph->new_linesegment(x, y, defcoord, defline); } } delete dl; nlines++; } // Assign the double to the variable named by ident. If no such // variable exists, create it. double assignment_statement(string *ident, double val) { double *d; doubleDictionary::iterator di; if ( ( di = vars.find(*ident)) != vars.end() ) { d = (*di).second; *d = val; } else { d = new double(val); vars[*ident] = d; } // XXX: Again, shouldn't this go away? delete ident; return *d; } // This collects the modifiers for other strings in the list to // construct the modifiers for the current string. stringlist *combine_strings(stringlist *sl, string *st, strmod &sm) { modaccumulator last; DisplayString *s; last = for_each(sl->begin(), sl->end(), modaccumulator()); // If unaligned_default is set, then treat unaligned // strings as unmodified strings if ( sm.just != (unaligned_default ? unaligned : 0) ) last.just = sm.just; if ( sm.size != 0 ) { last.size = sm.size; last.rel = sm.rel; } // If there is a color in the string modifier, it will be used to create // the new display string, otherise if there is a color specified for an // earlier string use a copy of that string for the color to avoid freeing // that string twice. if ( sm.color ) last.color = sm.color; else if ( last.color ) last.color = new string(*last.color); s = new DisplayString(*st,last.just, last.size, last.rel, last.clip, last.color); delete st; sl->push_back(s); return sl; } // Create a new plot, that is a string created from a double, and add // it to the current graph. void plot_statement(double val, DisplayString *fmt, point *pt) { stringlist *seq = new stringlist; DisplayString *s; if ( fmt && do_sprintf ) { unquote(fmt); s = new DisplayString(val,fmt); } else s = new DisplayString(val); // Delete format whether or not we used it (delete on 0 is OK) delete fmt; quote(s); seq->push_back(s); the_graph->new_plot(seq,pt); } // Add a point to the current line (or the named line if ident is // non-0). It may also include a pointer to a linedesc, wich should be // passed on if non-0. void next_statement(string *ident, point *p, linedesc* ld) { line *l; lineDictionary::iterator li; if ( ident) { li = the_graph->lines.find(*ident); if ( li == the_graph->lines.end() ) { macroDictionary::iterator md; macro *m; DisplayString *s; // We need to create a new line with default perameters. // Initialize the line to be invisible with a bullet // plotting string. if ( ( md = macros.find("bullet")) != macros.end()) { m = (*md).second; string *ss = m->invoke(); s = new DisplayString(*ss); delete ss; } else s = new DisplayString("\"\\(bu\""); l = new line((linedesc *)0, s ); the_graph->lines[*ident] = l; delete s; } else { l = (*li).second; } } else l = defline; delete ident; if ( ld ) the_graph->new_linesegment(p->x, p->y, p->c, l, 0, ld); else the_graph->new_linesegment(p->x, p->y, p->c, l); delete p; delete ld; } // Create a new tick with the given format (if any) and add it to the // current ticklist (which we're creating as we go). If no such list // exists, create it. ticklist *ticklist_elem(double d, DisplayString *fmt, ticklist *tl) { tick *t = new tick(d,0,top_side,0, (shiftlist *) 0, 0); DisplayString *s; if ( fmt ) { unquote(fmt); s = new DisplayString(d, fmt); delete fmt; } else s = new DisplayString(d); t->prt = s; if ( !tl ) tl = new ticklist; tl->push_back(t); return tl; } // Convert a for description of a set of ticks into a list of ticks, // including the coordinate system to put the ticks in, the beginning // and ending ticks, a general increment descriptor (by) and a string // to format each tick value. Return the list. ticklist *tick_for(coord *c, double from, double to, bydesc by, DisplayString *rfmt) { tick *t; DisplayString *s; DisplayString *fmt; double idx; int dir; ticklist *tl; tl = new ticklist; if ( rfmt && do_sprintf) { unquote(rfmt); fmt = new DisplayString(*rfmt); delete rfmt; } else fmt = new DisplayString("%g"); if ( to - from >= 0 ) dir = 1; else dir = -1; idx = from; while ( (idx - to) *dir < epsilon ) { t = new tick(idx, 0, top_side, 0, (shiftlist *) 0, 0); t->c = c; s = new DisplayString(idx,fmt); t->prt = s; tl->push_back(t); switch (by.op ) { case PLUS: idx += by.expr; break; case MINUS: idx -= by.expr; break; case TIMES: idx *= by.expr; break; case DIV: idx /= by.expr; break; } } delete fmt; return tl; } // Process the most complicated form of tick description. Add a list // of ticks to the current graph. void ticks_statement(sides side, double dir, shiftlist *sl, ticklist *tl ) { shiftdesc *sd; shiftcpy sc(&the_graph->base->tickdef[side].shift); add_tick_f add_tick(side, dir, sl); the_graph->base->tickdef[side].side = side; for_each(sl->begin(), sl->end(), sc); if ( !tl || tl->empty() ) { the_graph->base->tickdef[side].size = dir; } else the_graph->base->tickdef[side].size = 0; if ( tl ) { for_each(tl->begin(), tl->end(), add_tick); delete tl; } while (!sl->empty()) { sd = sl->front(); sl->pop_front(); delete sd; } delete sl; } // Process a grid statement. This is similar to, but somewhat more // complex than the ticks statement above. void grid_statement(sides side, int ticks_off, linedesc *ld, shiftlist *sl, ticklist *tl) { tick *t; grid *g; linedesc defgrid(dotted, 0, 0); shiftcpy sc(&the_graph->base->griddef[side].shift); shiftdesc *sd; // Turning on a grid turns off default ticks on that side the_graph->base->tickdef[side].size = 0; // All grids have a linedesc, so create one if the user didn't // specify one. if ( !ld ) ld = new linedesc; // The default for grids is dotted if ( ld->ld == def ) ld->ld = dotted; the_graph->base->griddef[side].desc = *ld; for_each(sl->begin(), sl->end(), sc); if ( ticks_off ) { if ( the_graph->base->griddef[side].prt ) delete the_graph->base->griddef[side].prt; the_graph->base->griddef[side].prt = 0; } if ( tl ) { the_graph->base->griddef[side].desc.ld = def; while (!tl->empty() ) { t = tl->front(); tl->pop_front(); g = new grid(t); g->side = side; shiftcpy scy(&g->shift); if ( ld ) { // The default for grids is dotted if ( ld->ld == def ) ld->ld = dotted; g->desc = *ld; } for_each(sl->begin(), sl->end(), scy); if ( ticks_off ) { if ( g->prt ) delete g->prt; g->prt = 0; } the_graph->base->gds.push_back(g); if ( g->side == top_side || g->side == bottom_side ) g->c->newx(g->where); else g->c->newy(g->where); delete t; } delete tl; } while ( !sl->empty() ) { sd = sl->front(); sl->pop_front(); delete sd; } delete sl; delete ld; } // Draw a line from p1 to p2. If is_line is false, draw an arror // instead. Either ld1 or ld2 or both may be present. If only one is // non-default, it rules, otherwise ld2 counts. void line_statement(int is_line, linedesc *ld1, point *p1, point *p2, linedesc *ld2 ) { line *l; lineDictionary::iterator li; // This constructor combines the two linedescs linedesc des(ld1, ld2); // Basically this should never fail... li = the_graph->lines.find("grap.internal"); if ( li == the_graph->lines.end() ) { if ( des.ld == def ) des.ld = solid; l = new line(&des); the_graph->lines["grap.internal"] = l; } else { l = (*li).second; } l->lastplotted(0); if ( des.ld != def || des.color) { the_graph->new_linesegment(p1->x, p1->y, p1->c, l, 0, &des); if ( is_line ) the_graph->new_linesegment(p2->x, p2->y, p2->c, l, 0, &des); else the_graph->new_linesegment(p2->x, p2->y, p2->c, l, 0, &des, true); } else { the_graph->new_linesegment(p1->x, p1->y, p1->c, l, 0, &des); if (is_line) the_graph->new_linesegment(p2->x, p2->y, p2->c, l, 0, &des); else the_graph->new_linesegment(p2->x,p2->y,p2->c, l, 0, &des, true); } delete ld1; delete ld2; delete p1; delete p2; } // Create an axis description. That is, tell which axis it is and the // bounds. axisdesc axis_description(axis which, double d1, double d2) { axisdesc a; a.which = which; if (d1 < d2 ) { a.min = d1; a.max = d2; } else { a.min = d2; a.max = d1; } return a; } // Create a coordinate object. Assign the mins and maxes to the axes // and tell which if any are logarithmic. void coord_statement(string *ident, axisdesc& xa, axisdesc& ya, axis log) { coord *c; if (ident) { c = new coord(*ident); the_graph->coords[*ident] = c; } else c = defcoord; if ( xa.which != none ) { c->xmin = xa.min; c->xmax = xa.max; c->xautoscale = 0; } if ( ya.which != none ) { c->ymin = ya.min; c->ymax = ya.max; c->yautoscale = 0; } c->logscale = log; } // Assign to an old coordinate object. Assign the mins and maxes to // the axes and tell which if any are logarithmic. void coord_statement(coord *co, axisdesc& xa, axisdesc& ya, axis log) { coord *c; if (co) c = co; else c = defcoord; if ( xa.which != none ) { c->xmin = xa.min; c->xmax = xa.max; c->xautoscale = 0; } if ( ya.which != none ) { c->ymin = ya.min; c->ymax = ya.max; c->yautoscale = 0; } if ( log != none ) c->logscale = log; } // Initiate a for statement by generating a for descriptor and // including the string. The body is captured by changing lex state // in the middle of the for_statement yacc rule. void for_statement(string *ident, double from, double to, bydesc by, string *body) { // force body to end with a sep *body += ';'; if ( fabs(to - from) < epsilon ) { // Limits are essentially the same, include the string once. The // routine will discard body. include_string(body,0,GINTERNAL); } else { // Determine if the loop is advancing from -> to. If not, it's a null // loop. double lim1 = to -from; // Initial difference double lim2 = from; // Difference after an iteration int dir = ( lim1 > -epsilon ) ? 1 : -1; // Make the differences positive switch (by.op ) { case PLUS: default: lim2 += by.expr; break; case MINUS: lim2 -= by.expr; break; case TIMES: lim2 *= by.expr; break; case DIV: lim2 /= by.expr; break; } lim2 = (to - lim2) * dir; lim1 *= dir; // If the loop is advancing toward the limit include the string. // Create a for descriptor and insert the string. Otherwise throw away // body if ( lim1 > lim2 ) { for_descriptor *f = 0; doubleDictionary::iterator di = vars.find(*ident); double *d = 0; if ( di != vars.end() ) { d = (*di).second; *d = from; } else { d = new double(from); vars[*ident] = d; } f = new for_descriptor(d, dir, to, by.expr, by.op, body); // include_string is responsible for deleting body (actually the // for_descriptor destructor will do it. include_string(body, f, GINTERNAL); } else delete body; } } void process_frame(linedesc* d, frame *f, frame *s) { // it's inconvenient to write three forms of the frame statement // as one yacc rule, so I wrote the three rules explicitly and // extracted the action here. The three arugments are the default // frame linedesc (d), the size of the frame (f), and individual // descriptions of the linedescs (s) of the sides. Note that d, // f, and s are freed by this routine. int i; // Scratch if ( d ) { // If the default linedesc has a description, color or thickness, // propagate it. if ( d->ld != def || d->color || d->thick != 0.0 ) { for ( i = 0 ; i < 4; i++ ) { the_graph->base->desc[i] = *d; } } delete d; } if ( f ) { the_graph->base->ht = f->ht; the_graph->base->wid = f->wid; delete f; } if ( s ) { for ( i = 0 ; i < 4; i++ ) { // If the linedesc has a description, color or thickness, propagate // it. if ( s->desc[i].ld != def || s->desc[i].color || s->desc[i].thick != 0.0 ) the_graph->base->desc[i] = (linedesc) s->desc[i]; } delete s; } } // Combine two log descriptions in a log list. Old is the accumulated // log state so far, and n is the latest state to merge. Return the // new combined state. The new state is created by making the n axis // a log axis if it is not already in that list. axis combine_logs(axis old, axis n) { switch (old) { default: case none: return n; case x_axis: switch (n) { case x_axis: case none: return x_axis; case y_axis: case both: default: return both; } case y_axis: switch (n) { case y_axis: case none: return y_axis; case x_axis: case both: default: return both; } case both: return both; } } // If a macro with the given name is defined, redefine it to be text, // otherwise create a new macro and define it to be text. void define_macro(string *name, string *text) { macro *m; // The new macro macroDictionary::iterator mi; // To search defined macros if ( ( mi = macros.find(*name)) != macros.end() ) { m = (*mi).second; delete m->text; m->text = text; } else { m = new macro(text, name); macros[*name] = m; } } // Create a new bar with the given parameters and add it to the graph. void bar_statement(coord *c, sides dir, double offset, double ht, double wid, double base, linedesc *ld) { point *p1, *p2; // The defining points of the box switch (dir) { case right_side: p1 = new point(base, offset + wid/2, c); p2 = new point(base + ht, offset - wid/2, c); break; case top_side: default: p1 = new point(offset + wid/2, base, c); p2 = new point(offset - wid/2, base + ht, c); break; } c->newpt(p1->x,p1->y); c->newpt(p2->x,p2->y); the_graph->new_box(p1, p2, ld); delete p1; delete p2; delete ld; } // Perhaps a misnomer. Initialize the current frame default lines and // coordinate systems. The default line is initialized to be // invisible and have a plotting string defined by the bullet macro, // if it is defined or a bullet character if not. void init_dict() { // The plot string for the default line string s = (macros.find("bullet") != macros.end()) ? "bullet;" : "\"\\(bu\";\n"; s.insert(0,"new grap_internal_default invis "); include_string(&s, 0, GINTERNAL); defline = new line(); the_graph->lines["grap_internal_default"] = defline; defcoord = new coord; the_graph->coords["grap.internal.default"] = defcoord; for ( int i = 0 ; i < 4; i++) { the_graph->base->tickdef[i].c = defcoord; the_graph->base->griddef[i].c = defcoord; } nlines = 0; } int yyerror(const char *s) { grap_buffer_state *g = 0; int tp= 0; cerr << "grap: " << s << endl; while ( !lexstack.empty() ) { g = lexstack.front(); lexstack.pop_front(); switch ( g->type) { case GFILE: cerr << "Error near line " << g->line << ", " ; if ( g->name ) cerr << "file \"" << *g->name << "\"" << endl; break; case GMACRO: cerr << "Error near line " << g->line << " " ; cerr << "of macro" << endl; break; default: break; } tp = g->tokenpos; delete g; } cerr << " context is:" << endl << " " << pre_context(); cerr << " >>> " << token_context() << " <<< " << post_context() << endl; return 0; } void usage() { cerr << "Usage: grap [-d defines] [-h|-l|-D|-V|-v|-u|-C|-S] " << "[-M path] [files]" << endl; cerr << "\t-h\tprint this list and exit (also --help)" << endl; cerr << "\t-C\tcompatibility mode" << endl; cerr << "\t-c\tdefault to not clipping lines" << endl; cerr << "\t-d\tuse given defines file" << endl; cerr << "\t-D\tuse no defines file" << endl; cerr << "\t-l\tuse no defines file" << endl; cerr << "\t-R\tuse coarse numeric comparisons (default)" << endl; cerr << "\t-r\tuse fine numeric comparisons" << endl; cerr << "\t-v\tprint version and exit (also --version)" << endl; cerr << "\t-V\tprint parse debugging information" << endl; cerr << "\t-u\tforce graph labels to be unaligned by default" << endl; cerr << "\t-M\tspecify search path for files" << endl; cerr << "\t-S\tsafer mode, no internal user sprintf calls" << endl; cerr << endl; cerr << "Fine comparsion limit: " << FINE_EPSILON << endl; cerr << "Fine minimum value: " << FINE_MIN_DOUBLE << endl; cerr << "Coarse comparsion limit: " << COARSE_EPSILON << endl; cerr << "Coarse minimum value: " << COARSE_MIN_DOUBLE << endl; cerr << "Defines are in " << DEFINES << endl; cerr << "See the man page for more information." << endl; cerr << "Documentation in " << DOCS_DIR << endl; cerr << "Examples in " << EXAMPLES_DIR << endl; exit(5); } inline void version() { cout << "grap " << PACKAGE_VERSION << " compiled under " << OS_VERSION << endl; cerr << "Fine comparsion limit: " << FINE_EPSILON << endl; cerr << "Fine minimum value: " << FINE_MIN_DOUBLE << endl; cerr << "Coarse comparsion limit: " << COARSE_EPSILON << endl; cerr << "Coarse minimum value: " << COARSE_MIN_DOUBLE << endl; cout << "Report bugs to " << PACKAGE_BUGREPORT << endl; cout << "Documentation in " << DOCS_DIR << endl; cout << "Examples in " << EXAMPLES_DIR << endl; cout << "Defines are in " << DEFINES << endl; exit(5); } int main(int argc, char** argv) { string defines=DEFINES; string fname; string pathstring; bool use_defines = true; int c; if (getenv("GRAP_DEFINES")) defines = getenv("GRAP_DEFINES"); if ( getenv("GRAP_SAFER") ) do_sprintf = false; // Either of these long options are recognized to make the GNU folks // happier. for (int i = 1; i< argc; i++ ) { string av(argv[i]); if ( av == "--version" ) version(); else if ( av == "--help" ) usage(); } while ( ( c = getopt(argc,argv,opts)) != -1) switch (c) { case 'd': defines = optarg; use_defines = true; break; case 'l': case 'D': use_defines = false; break; case 'v': version(); break; case 'V': print_lex_debug = true; break; case 'u': unaligned_default = 1; break; case 'M': pathstring = (pathstring + ":") + optarg; break; case 'c': clip_default = false; break; case 'C': clip_default = false; compat_mode = true; break; case 'S': do_sprintf = false; break; case 'R': epsilon = COARSE_EPSILON; min_double = COARSE_MIN_DOUBLE; break; case 'r': epsilon = FINE_EPSILON; min_double = FINE_MIN_DOUBLE; break; case 'h': case '?': usage(); break; } pathstring += (pathstring.length() > 0) ? ":." : "."; // Convert the colon separated file path into a sequence while (pathstring.length()) { string::size_type p = pathstring.find(':'); string *s; if ( pathstring[p] == ':' ) { if ( p != 0 ) { s = new string(pathstring.substr(0,p)); pathstring.erase(0,p+1); } else { pathstring.erase(0,1); continue; } } else { s = new string(pathstring); pathstring.erase(0,string::npos); } path.push_back(s); } init_keywords(); if ( argc == optind ) { fname = "-"; include_file(&fname, true, false); } else { for ( int i = argc-1; i >= optind; i-- ) { fname = argv[i]; include_file(&fname, true, false); } } if ( use_defines) include_file(&defines, true); yyparse(); for (stringSequence::iterator ii = path.begin(); ii != path.end(); ii++) delete (*ii); path.erase(path.begin(),path.end()); } grap-1.43/grap_pic.cc000640 004133 000000 00000057323 11047721423 014702 0ustar00faberwheel000000 000000 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "grap.h" #include "grap_data.h" #include "grap_draw.h" #include "grap_pic.h" // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. // Convert the abstract types to Pictypes and draw them. These are // called from for_each. These are declared outside the pic classes // to keep g++ 2.7.3 happy. template class draw_f : public unary_function { frame *f; public: draw_f(frame *fr) : f(fr) { } int operator()(FROM *ds) { TO p(*ds); p.draw(f); return 0; } }; // Simpler declarations typedef draw_f draw_string_f; typedef draw_f draw_tick_f; typedef draw_f draw_grid_f; // A little helper function - tells if a DisplayString * points to a string // with the clipped attribute. In an anonymous namespace so no one else has to // see it. namespace { bool clipped(DisplayString *d) { return d->clip; } } extern bool compat_mode; void Picgraph::init(string *n /* =0 */, string* p /* =0 */ ) { // Start a new graph, but maybe not a new block. if ( frame_queued ) base = 0; graph::init(n, p); // clear the base classes parameters if ( !base ) base = pframe = new Picframe; if ( p ) pos = new string(*p); frame_queued = false; } void Picgraph::draw(frame *) { // Do the work of drawing the current graph. displayer_f displayer(pframe); // Call draw on the object. This is // an embedded class of graph. if ( visible ) { if ( !graphs++ ) { cout << ".PS"; if (ps_param ) { cout << *ps_param; delete ps_param; ps_param = 0; } cout << endl; } // if we have a name, use it if ( name ) cout << *name << ": "; // The graph itself cout << "[" << endl; for_each(coords.begin(), coords.end(), addmargin); // put out the xy_gg mpic macros for (coordinateDictionary::iterator ci = coords.begin(); ci != coords.end(); ci++) { Piccoord pc(*(*ci).second); displayer(&pc); } for_each(objs.begin(), objs.end(), displayer); cout << "]"; // Positioning info relative to another graph in this block if ( pos ) { cout << " " << *pos << endl; delete pos; pos = 0; } else cout << endl; } } void PicDisplayString::draw(frame *) { // Draw a display string. Basically just a straight translation into // pic/troff idioms. cout << '"'; if ( size ) { if ( relsz ) { char relchar = ( size > 0 ) ? '+' : '-'; size = fabs(size); if ( compat_mode ) { cout << "\\s" << relchar; cout << ((size > 9) ? "(" : "") << size; } else { cout << "\\s[" << relchar << size << "]"; } } else { // double digit size changes need the ( using classic troff. Groff // allows a general [] syntax, that we use if available ). if ( compat_mode ) cout << "\\s" << ((size > 9) ? "(" : "") << size; else cout << "\\s[" << size << "]"; } } if ( color && !compat_mode ) { unquote(color); cout << "\\m[" << *color << "]"; } unquote(this); cout << *(string*)this; if ( color && !compat_mode ) cout << "\\m[]"; if ( size ) cout << "\\s" << 0 ; cout << "\" "; if ( j & (int) ljust ) cout << "ljust "; if ( j & (int) rjust ) cout << "rjust "; if ( j & (int) above ) cout << "above "; if ( j & (int) below ) cout << "below "; if ( j & (int) aligned ) cout << "aligned "; } void Picframe::frame_line(double x2, double y2, sides s) { // straightforward line drawing of one frame line switch (s) { case left_side: cout << "Left: "; break; case right_side: cout << "Right: "; break; case top_side: cout << "Top: "; break; case bottom_side: cout << "Bottom: "; break; } cout << "line "; switch (desc[s].ld) { case invis: cout << "invis "; break; case solid: default: break; case dotted: cout << "dotted "; if ( desc[s].param ) cout << desc[s].param << " "; break; case dashed: cout << "dashed "; if ( desc[s].param ) cout << desc[s].param << " "; break; } if ( !compat_mode ) { if ( desc[s].color ) cout << " color " << *desc[s].color << " " ; if ( desc[s].thick ) cout << " thickness " << desc[s].thick << " " ; } cout << "right " << x2 << " up " << y2 << endl; } void Picframe::label_line(sides s) { // Label a graph side. We rely heavily on pic tricks here. The C++ // is straightforward. // Functor to convert a DisplayString to a PicdisplayString and print it draw_string_f draw_string(this); double dx, dy; // Used to place the alignment line relative to the axis shiftlist::const_iterator csi; switch (s) { case left_side: dx = -0.4; dy = 0; break; case right_side: dx = 0.4; dy = 0; break; case top_side: dx = 0; dy = 0.4; break; case bottom_side: dx = 0; dy = -0.4; break; default: // to keep the compiler quiet dx = dy = 0; break; } for (csi = lshift[s]->begin(); csi != lshift[s]->end(); csi++) { switch ((*csi)->dir) { case left_side: dx -= (*csi)->param; break; case right_side: dx += (*csi)->param; break; case top_side: dy += (*csi)->param; break; case bottom_side: dy -= (*csi)->param; break; } } // DWB grap did not put the whitespace around for unlabelled sizes of the // graph, so omit that space if in compatibility mode. if ( compat_mode && label[s]->empty() ) return; cout << "line invis "; // draw all the labels for_each(label[s]->begin(), label[s]->end(), draw_string); switch (s) { case left_side: cout << "from Frame.Left.start + (" << dx << ", " << dy << ") " ; cout << "to Frame.Left.end + (" << dx << ", " << dy << ") " ; break; case right_side: cout << "from Frame.Right.start + (" << dx << ", " << dy << ") " ; cout << "to Frame.Right.end + (" << dx << ", " << dy << ") " ; break; case bottom_side: cout << "from Frame.Bottom.end + (" << dx << ", " << dy << ") " ; cout << "to Frame.Bottom.start + (" << dx << ", " << dy << ") " ; break; case top_side: cout << "from Frame.Top.start + (" << dx << ", " << dy << ") " ; cout << "to Frame.Top.end + (" << dx << ", " << dy << ") " ; break; default: break; } cout << endl; } void Picframe::autoguess(sides sd, double &idx, double& dir, double& lim, double &ts, int& ls, coord *c) { // Calculate a reasonable placement of tickmarks if the user has not // specified one. We aim for 5. The algorithm is heuristic. double lo, hi; // Low and high tickmarks double range; // the range of the coordinate system // determine the range of the axes if ( sd == bottom_side || sd == top_side ) { lo = c->xmin; hi = c->xmax; ls = (c->logscale & x_axis); } else { lo = c->ymin; hi = c->ymax; ls = (c->logscale & y_axis); } // Make our ticksize guess if ( !ls ) { range = fabs(hi - lo); ts = pow(10,floor(log10(range))); while ( range/ts > 4 ) ts *= 2; while ( range/ts < 3 ) ts /=2; idx = ts * ceil(lo/ts); } else { idx = pow(10,floor(log10(lo))); } // On machines with signed 0 representations, this ensures that // tickmarks have a 0 label (not a -0). See math(3). if ( idx == -0.0 ) idx = 0.0; // Are ticks increasing or decreasing? if ( hi - lo < 0 ) dir = -1; else dir = 1; lim = hi; } void Picframe::addautoticks(sides sd) { // Place ticks in accordance with the parameters returned by autoguess double ts; // The tick size (for linear axes) double dir, idx; // The direction of ticks and an index value double hi; // the tick limit int ls; // is this a logscale axis? tick *t; // Temporary tick value if ( tickdef[sd].size == 0 ) return; autoguess(sd, idx, dir, hi, ts, ls, tickdef[sd].c); // This changed to match the code in grap_parse (all the computations on // one side of the comparison) while ( (idx - hi)* dir < epsilon ) { t = new tick(idx,tickdef[sd].size,sd,0, &tickdef[sd].shift, tickdef[sd].c); if ( tickdef[sd].prt) t->prt = new DisplayString(idx,tickdef[sd].prt); //t->prt = dblString(idx,tickdef[sd].prt); tks.push_back(t); if ( ls ) idx *= 10; else idx += ts; } } void Picframe::addautogrids(sides sd) { // Place grids in accordance with the parameters returned by autoguess double ts; double dir, idx; double hi; int ls; grid *g; if ( griddef[sd].desc.ld == def ) return; autoguess(sd, idx, dir, hi, ts, ls, griddef[sd].c); while ( (idx - hi)*dir < epsilon ) { g = new grid(idx,&griddef[sd].desc,sd,0, &griddef[sd].shift, griddef[sd].c); if ( griddef[sd].prt) // g->prt = dblString(idx,griddef[sd].prt); g->prt = new DisplayString(idx,griddef[sd].prt); gds.push_back(g); if ( ls ) idx *= 10; else idx += ts; } } void Picframe::draw(frame *) { // Draw the frame. Autotick if necessary and draw the axes and // tickmarks. Straightforward application of the helpers above. The // result is a frame that is labelled for pic placement of other // graphs in the same block. // functors to draw ticks and grids out of the lists. draw_tick_f draw_tick(this); draw_grid_f draw_grid(this); cout << "Frame: [" << endl; cout << "Origin: " << endl; frame_line(0,ht,left_side); frame_line(wid,0,top_side); frame_line(0,-ht,right_side); frame_line(-wid,0,bottom_side); cout << "]" << endl; for ( int i = 0; i < 4 ; i++ ) { if ( label[(sides)i] ) label_line((sides)i); addautoticks((sides)i); addautogrids((sides)i); } for_each(tks.begin(), tks.end(), draw_tick); for_each(gds.begin(), gds.end(), draw_grid); } bool Piclinesegment::clipx(double& x1, double& y1, double& x2, double& y2) { // Clip the line to x = 0 and x = 1. We use the parametric // representation of the line for simplicity of calculation. This // gets called with the coordinates reversed to do the y-axis clip. // the line is p + tv where x1, y1 is t==0 and x2, y2 is t==1 double px = x1; // Point coordinate double py = y1; // Point coordinate double vx = x2 - x1; // vector component double vy = y2 - y1; // vector component double t; // The parameter // The line is parallel to the x axis. It's either all valid or // all invalid. We use epsilon again here to be conservative. if ( vx > -epsilon && vx < epsilon ) { if ( inbox(px) ) return true; else return false; } // Do the x = 0 intercept t = -px / vx; // The semantics of inbox here mean that the line has been // clipped. The intersection with x = 0 is between x1, y1 (t==0) // and x2, y2 (t==1). if ( inbox(t) ) { // This is the zero intercept, and one point has been clipped, // so if the first hasn't been clipped, the second must have. // We recalculate the parametric representation so we can // repeat the clip for x == 1. We use epsilon here because we have to // use it by definition in the t==1 half. if ( px < epsilon ) { x1 = px + t * vx; y1 = py + t * vy; px = x1; py = y1; } else { x2 = px + t * vx; y2 = py + t * vy; } vx = x2 - x1; vy = y2 - y1; } // repeat for 1 t = (1 - px) / vx; // The semantics of inbox here mean that the line has been // clipped. if ( inbox(t) ) { // This is the 1 intercept, and one point has been clipped, // so if the first hasn't been clipped, the second must have. if ( px > 1 - epsilon ) { x1 = px + t * vx; y1 = py + t * vy; } else { x2 = px + t * vx; y2 = py + t * vy; } } // If both x points are clipped to inside the box, we have a line, // otherwise, the whole line is invalid. return inbox(x1) && inbox(x2); } bool Piclinesegment::clip(double& x1, double& y1, double& x2, double& y2) { // If all 4 points are in the frame, return true. If not call // clip twice to clip the lines, and return true only if both // clips return valid lines. There is a little sleight of hand // there: the && guarantees that we only keep clipping while there // is a line to clip. if ( inbox(x1) && inbox(x2) && inbox(y1) && inbox(y2) ) return true; else return clipx(x1, y1, x2, y2) && clipx(y1, x1, y2, x2); } void Piclinesegment::draw(frame *f) { // Draw this line segment. Clip the line segment according to the // point's coordinates, then put them into the graph. There are some // details to laying out the styles and poltting strings correctly. double lastx, lasty; // The last point plotted (if any) double x,y; // The current point's coordinates double lastcx, lastcy; // The last point plotted post clipping double cx,cy; // The current point post clipping try { x = to.c->map(to.x,x_axis); y = to.c->map(to.y,y_axis); } catch (range_error &e) { cerr << "Unable to map point: (" << to.x << ", " << to.y << ") : " << e.what() << endl; return; } if ( from ) { try { lastcx = from->c->map(from->x, x_axis); lastcy = from->c->map(from->y, y_axis); } catch (range_error &e) { cerr << "Unable to map point: (" << to.x << ", " << to.y << ") : " << e.what() << endl; return; } } else { lastx = lasty = 0.0; } cx = x; cy = y; if ( !from || clip(lastcx, lastcy, cx, cy) ) { // If clipping has left us a (partial) line to draw, do // so. This also is invoked on the first point of a line. if ( !from ) { if ( inbox(x) && inbox(y) ) cout << "move to Frame.Origin + (" << x * f->wid << ", " << y * f->ht << ")" << endl; } else { // Chop off the arrowhead if the line is clipped if ( arrow && inbox(x) && inbox(y) ) cout << "arrow "; else cout << "line "; switch (desc.ld) { case invis: cout << "invis "; break; case solid: default: break; case dotted: cout << "dotted "; if ( desc.param ) cout << desc.param << " "; break; case dashed: cout << "dashed "; if ( desc.param ) cout << desc.param << " "; break; } if ( !compat_mode ) { if ( desc.color ) cout << " color " << *desc.color << " " ; if ( desc.thick ) cout << " thickness " << desc.thick << " " ; } cout << "from Frame.Origin + (" << lastcx * f->wid << ", " << lastcy * f->ht << ") "; cout << "to Frame.Origin + (" << cx * f->wid << ", " << cy * f->ht << ")" << endl; } // if a plot string has been specified and the point has // not been clipped, put the plotstring out. if ( plotstr && inbox(x) && inbox(y) ) { PicDisplayString pstr(*plotstr); pstr.draw(f); if ( !from ) cout << " at Frame.Origin + (" << x * f->wid << ", " << y * f->ht << ")" << endl; else cout << " at last line.end" << endl; } } } void Pictick::draw(frame *f) { // Actually draw a tick mark. Map it into the appropriate coordinate // space and draw and label the line. The translation from data // structure to pic is straightforward. double a,b; // x and y offsets from the origin string dir; // Direction of the tick mark string just; // placement of the label relative to the end of the tick Picshiftdraw sd(cout); // Functor to put out multiple tick shifts try { switch (side) { default: case left_side: a = 0; b = c->map(where,y_axis); dir = "left"; just = "rjust"; break; case right_side: a = 1; b = c->map(where,y_axis); dir = "right"; just = "ljust"; break; case top_side: a = c->map(where,x_axis); b = 1; dir = "up"; just = "above"; break; case bottom_side: a = c->map(where,x_axis); b = 0; dir = "down"; just = "below"; break; } } catch (range_error& e) { cerr << "failed to map tick value: " << where << ": " << e.what() << endl; return; } // epsilons for floating point weirdness if ( a < -epsilon || a > 1+epsilon ) return; else a *= f->wid; if ( b < -epsilon || b > 1+epsilon ) return; else b *= f->ht; cout << "move to Frame.Origin + (" << a << ", " << b << ")" << endl; cout << "line " << dir << " " << size << endl; if ( prt ) { double dist; if ( size > 0 ) dist = 1.2 * size; else dist = 0; cout << "move to Frame.Origin + (" << a << ", " << b << ")" << endl; cout << "move " << dir << " " << dist << endl; for_each(shift.begin(), shift.end(), sd); quote(prt); PicDisplayString pprt(*prt); pprt.draw(f); cout << " " << just << " at Here" << endl; } } void Picgrid::draw(frame *f) { // Draw a grid line. As usual very similar to a tick. double a,b; double len; string dir; Picshiftdraw sd(cout); // Functor to put out multiple tick shifts try { switch (side) { default: case left_side: a = 0; b = c->map(where,y_axis); dir = "right"; len = f->wid; break; case right_side: a = 1; b = c->map(where,y_axis); dir = "left"; len = f->wid; break; case top_side: a = c->map(where,x_axis); b = 1; dir = "down"; len = f->ht; break; case bottom_side: a = c->map(where,x_axis); b = 0; dir = "up"; len = f->ht; break; } } catch (range_error& e) { cerr << "failed to map grid value: " << where << ": " << e.what() << endl; return; } if ( a < 0 || a > 1 ) return; else a *= f->wid; if ( b < 0 || b > 1 ) return; else b *= f->ht; cout << "move to Frame.Origin + (" << a << ", " << b << ")" << endl; cout << "line "; switch (desc.ld) { case invis: cout << "invis "; break; case solid: default: break; case dotted: cout << "dotted "; if ( desc.param ) cout << desc.param << " "; break; case dashed: cout << "dashed "; if ( desc.param ) cout << desc.param << " "; break; } if ( !compat_mode ) { if ( desc.color ) cout << " color " << *desc.color << " "; if ( desc.thick ) cout << " thickness " << desc.thick << " "; } cout << dir << " " << len << endl; if ( prt ) { cout << "move to Frame.Origin + (" << a << ", " << b << ")" << endl; cout << "move " << dir << " -0.125" << endl; for_each(shift.begin(), shift.end(), sd); quote(prt); PicDisplayString pprt(*prt); pprt.draw(f); cout << " at Here" << endl; } } void Piccircle::draw(frame *f) { // Plot a circle. Strightforward. double x,y; // To transform the point into device coordinates try { x = center.c->map(center.x,x_axis); y = center.c->map(center.y,y_axis); } catch (range_error& e) { cerr << "Unable to map circle at (" << center.x << ", " << center.y << ") into " << "log coordinates: " << e.what() << endl; return; } // Again, epsilon is correct because it's needed for the 1+ and symmetry. if ( x > 1+epsilon || x < 0-epsilon ) { cerr << "Circle outside coordinates:" << center.x << ", "; cerr << center.y << endl; return; } if ( y > 1+epsilon || y < 0-epsilon ) { cerr << "Circle outside coordinates:" << center.x << ", "; cerr << center.y << endl; return; } x *= f->wid; y *= f->ht; cout << "circle at Frame.Origin + (" << x << ", " << y << ")"; cout << " rad " << rad ; switch (ld.ld) { case invis: cout << " invis "; break; case solid: default: break; case dotted: cout << " dotted "; if ( ld.param ) cout << ld.param << " "; break; case dashed: cout << " dashed "; if ( ld.param ) cout << ld.param << " "; break; } if ( !compat_mode ) { if ( ld.fillcolor ) { // fillcolor takes precedence over fill - if fillcolor is not // null, we draw one box filled with that color, and then a // second unfilled one in color (black is none specified) ld.fill = 0; cout << " shaded " << *ld.fillcolor << " "; } // Draw the circle with appropriate line style, fill, and color if ( ld.color ) cout << " outline " << *ld.color << " "; if ( ld.thick ) cout << " thick " << ld.thick << " " ; } if ( ld.fill ) cout << " fill " << ld.fill; cout << endl; } void Picbox::draw(frame *f) { // Plot the box. If there is a fill color, plot it twice so that // the box and edge can be different colors double x1,y1, x2,y2; // The box edges in device coords. double ht, wid; // height and width in device units (inches) try { x1 = p1.c->map(p1.x,x_axis); y1 = p1.c->map(p1.y,y_axis); x2 = p2.c->map(p2.x,x_axis); y2 = p2.c->map(p2.y,y_axis); } catch (range_error& e) { cerr << "Unable to map box [(" << p1.x << ", " << p1.y << "), (" << p2.x << ", " << p2.y << ")] into logscale : " << e.what() << endl; return; } // make (x1,y1) upper right and (x2,y2) lower left if ( x1 < x2 ) swap(x1,x2); if ( y1 < y2) swap(y1,y2); // Clip the box // If the box is entirely out of frame, ignore it. epsilon for 1+ and // symmetry. if ( (x1 > 1+epsilon && x2 > 1+epsilon) || (x1 <-epsilon && x2 < -epsilon ) ) return; if ( (y1 > 1+epsilon && y2 > 1+epsilon) || (y1 <-epsilon && y2 < -epsilon ) ) return; // Box is at least partially in frame - clip it if ( x1 > 1+epsilon) x1 = 1; if ( y1 > 1+epsilon) y1 = 1; if ( x2 < -epsilon) x2 = 0; if ( y2 < -epsilon) y2 = 0; x1 *= f->wid; y1 *= f->ht; x2 *= f->wid; y2 *= f->ht; wid = fabs(x1-x2); ht = fabs(y1-y2); cout << "box ht " << ht << " wid " << wid ; cout << " with .ne at Frame.Origin + (" << x1 << ", " << y1 << ")"; switch (ld.ld) { case invis: cout << " invis "; break; case solid: default: break; case dotted: cout << " dotted "; if ( ld.param ) cout << ld.param << " "; break; case dashed: cout << " dashed "; if ( ld.param ) cout << ld.param << " "; break; } if ( !compat_mode ) { if ( ld.fillcolor ) { // fillcolor takes precedence over fill - if fillcolor is not // null, we draw one box filled with that color, and then a // second unfilled one in color (black is none specified) ld.fill = 0; cout << " shaded " << *ld.fillcolor << " "; } if ( ld.color ) cout << " outline " << *ld.color << " " ; if ( ld.thick ) cout << " thickness " << ld.thick << " " ; } if ( ld.fill ) cout << " fill " << ld.fill; cout << endl; } void Picplot::draw(frame *f) { // Slightly trickier than the circle because we have to output a list // of strings instead of one. A functor to convert the DisplayStrings // to PicDisplayStrings and plot them simplifies matters. double x, y; // To transform the point into device coordinates bool in_frame = true; // To print a set of strings draw_string_f draw_string(f); if ( !strs || !loc ) return; try { x = f->wid * loc->c->map(loc->x,x_axis); y = f->ht * loc->c->map(loc->y,y_axis); } catch (range_error& e) { cerr << "Unable to place string at (" << loc->x << ", " << loc->y << "): " << e.what() << endl; return; } // Clip strings to lie in the graph (if requested) if ( x < -epsilon || x > f->wid + epsilon ) in_frame = false; if ( y < -epsilon || y > f->ht + epsilon ) in_frame = false; // Make a copy of all the DisplayStrings that are really displayed - either // all of them, if the plot is in the graph, or the unclipped ones if the // plot is off the graph. stringlist v; if ( in_frame ) copy(strs->begin(), strs->end(), back_inserter(v)); else remove_copy_if(strs->begin(), strs->end(), back_inserter(v), clipped); // If there are strings to show, show them. if ( v.size() ) { for_each(v.begin(), v.end(), draw_string); cout << "at Frame.Origin + (" << x << ", " << y << ")" << endl; } // Now v will go out of scope and disappear, leaving the object itself // alone. } grap-1.43/config.h.in000660 004133 000000 00000001514 11073757372 014636 0ustar00faberwheel000000 000000 #ifndef CONFIG_H #define CONFIG_H // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. // The following are set by configure #undef STDC_HEADERS #undef HAVE_STDLIB_H #undef HAVE_UNISTD_H #undef HAVE_HASH_MAP #undef HAVE_EXT_HASH_MAP #undef HAVE_UNORDERED_MAP #undef HASH_SPACE #undef HAVE_LIMITS #undef HAVE_SNPRINTF #undef HAVE_RANDOM #undef HAVE_RAND #undef HAVE_STRDUP #undef HAVE_STRERROR #undef HAVE_ERRNO_H #undef SNPRINTF_DECLARED #undef STRERROR_DECLARED #undef RANDOM_DECLARED #undef RANDOM_IN_MATH #undef RAND_DECLARED #undef RAND_IN_MATH #undef OPTARG_DEFINED #undef SPRINTF_NOT_INT #undef GRAP_SAFER #undef PACKAGE_VERSION #undef PACKAGE_BUGREPORT #undef OS_VERSION #undef LEX_HAS_YYUNPUT #undef DEFINES #undef EXAMPLES_DIR #undef DOCS_DIR #endif grap-1.43/CHANGES000640 004133 000000 00000056663 11076025607 013613 0ustar00faberwheel000000 000000 Change log 1.43 Bruce Lilly pointed out that g++ 4.3.1 was emitting all sorts of dire warnings about the hash_map data structure and associated support being pulled from g++ in the future. SuSe seems to ship with this and there's no point scaring people (or letting a time bomb tick). Grap now detects and uses unordered_map if it's present on your system, which stops the wailing and gnashing of teeth from g++ 4.3.1 . That g++ version also requires a compiler option to support that include file, which we also autodetect and use. (This is essentially autodetecting the flags described in the changes to grap 1.41 below, along with some code changes to make that actually function correctly.) A fellow named Fergus had a Cygwin compilation problem as well. His system apparently had rand but not random (a very rare configuration these days). This led me to find a corner of the autoconf code that I apparently hadn't checked sufficiently. If rand was found and a declaration made in the system files, the grap config stuff failed to note the declaration and made its own incompatible one. This should be gone now. Fergus's system also seemed to be lacking snprintf - which again is very odd. I hadn't reflected the change to grap sprintf in version 1.23 into the code that emulates snprintf on systems without it. That code has been added. Changed the examples to include a brief tutorial on string matching in grap. Suggested by John Heidemann. 1.42 There's been a long standing bug with how different versions of pic interpret the "line from (x,y) then down 5" construct. There was once a bug report at http://lists.gnu.org/archive/html/groff/2008-03/msg00003.html about this. As of version 1.42 grap no longer outputs this pic construct. Dan Lasley pointed out that the key was incomplete for the bar graph example. His fix to restore the key is included. John Heidemann points out that bars in coordinate systems other than the default just didn't work. This was a bug in my yacc grammer - for heaven's sake. It's corrected to match the manual page. For loops were strange in that .G1 for xx from 15 to 13 do { print "YYY" } print "ZZZZ" .G2 would loop infinitely. xx never passes 13. Added a test to make that a null loop as well as making .G1 for xx from 13 to 13 do { print "YYY" } print "ZZZZ" .G2 print one "YYY". You can still confuse loops, using strange by clauses - for example "by 0" or "by * -1" but common cases should be covered. Spotted by a fellow named Yuval. Found a lurking initializer bug while fixing the for loop thing. I added references to standard plot strings in a couple places to make them somewhat easier to find. 1.41 Small changes to compile without warnings under g++ 4.2.0 and to find and use ext/hash_map under g++ versions that include it. Incorporated Tobias Toedter's patch to the grap.spec. I'd found another place to misspell "Kernighan" and Tobias fixed it. Got rid of an ambiguous else construct in grap_pic.cc Support g++4.3.0 by either compiling under compatibility headers (with a warning) or using the c++0x standard header if you set CXXFLAGS=-std=c++0x CPPFLAGS=-std=c++0x in the environment (during configure and compile). Using unordered_set avoids the warnings, but is experimental. 1.40 Man, here's a weird one, care of Bruce Lilly: in previous versions doing something like this: coord temp x -2,2 y 3,4 ticks left out from temp -1 to 1 would interpret the ticks as starting from the value of the uninitialized variable temp with one subtracted from it to 1 in the default coordinate space rather than (correctly) interpreting that as ticks from -1 to 1 in the temp coordinate space. This is a two character fix to a regular expression, but a weird bug. I believe it's fixed. Bruce also discovered that the changes I put into version 1.38 to address issues raised by Hartmut Henkel affected large number comparisions in unpleasently non-intuitive ways. Specifically doing this: coord pressure x -2.400000, 27.000000 y 1035.124000, 1039.000000 ticks right in left 0.6 from pressure 1035.200 to 1039.000000 by 0.200 Results in the top tick - the one at 1039 - being clipped because the 19 additions in the tick loop introduce enough floating point error that the limit (1039) and the index (1039+epsilon) differ by a large enough value that the loop terminates one iteration early. Essentially the <= at the top of the tick loop fails because the error induced by the 19 additions accumulates to be detectable. I've reverted the default comparison thresholds back to their pre-1.38 levels; numbers must differ by more than 1e-6 to be considered different by grap. For people who explicitly want to work with very small quantities directly - a decision I still disagree with - the -r flag has been added to make grap use the system's idea of what the smallest comparable numbers are (the 1.38 and 1.39 behavior). The output of -v or -h lists these two values and the manual page documents the flags. I've updated the grap.spec to one donated by John Heidemann. Linux guys should have it easier. 1.39 Martin Michlmayr noticed a typo that upsets gcc 4.1, though earlier versions don't even generate a warning (Grrrr). (Original report at .) This is fixed. I didn't issue a new FreeBSD port, because it doesn't change anything functionally. I also cleaned up the man page a bit, and Tobias Toedter fixed a couple typos in the man page and the README file. Always troubling to misspell the inventor's name. 1.38 Michail Vidiassov suggests that a DESTDIR variable be added to the Makefile to allow staged installs or temporary installs or other stuff. Setting DESTDIR when making install or deinstall will create a tree under DESTDIR that contains the full grap install. E.g., make DESTDIR=/usr/tmp install Does something like: /usr/bin/install -c -d /usr/tmp/usr/local/share/doc/grap || true /usr/bin/install -c -m 644 README CHANGES COPYRIGHT grap.man /usr/tmp/usr/local/share/doc/grap strip grap || true /usr/bin/install -c -d /usr/tmp/usr/local/bin || true /usr/bin/install -c -d /usr/tmp/usr/local/man/man1 || true /usr/bin/install -c -d /usr/tmp/usr/local/share/grap || true /usr/bin/install -c -d /usr/tmp/usr/local/share/examples/grap || true /usr/bin/install -c grap /usr/tmp/usr/local/bin /usr/bin/install -c -m 644 grap.1 /usr/tmp/usr/local/man/man1 /usr/bin/install -c -m 644 grap*.defines /usr/tmp/usr/local/share/grap /usr/bin/install -c -m 644 examples/*.d examples/example.ms \ examples/*.result examples/Makefile \ /usr/tmp/usr/local/share/examples/grap There is a possibility of munging the manpage by doing this, but that's actually pretty difficult, and the modifications below to print install locations will still print the original (that is DESTDIR-free) install locations. Warner Lemberg found a bunch of bad typesetting in the examples, and I hope much of that is fixed. He also pointed out that configure should allow installers to place documentation and examples where their system likes them. I've altered the configuration script to accept these locations as --with arguments (--help lists them). grap -v or grap -h (or the long versions: grap --version/grap --help) prints out the examples/documentation locations and that new behavior is documented in the manual page. (The locations aren't directly given in the man page, because the ASCII and postscript versions of the manual are created before the source tar file is so that grap man pages can be installed places that don't have doc manual pages). Fixed a bug where lines acquired the lindescription of the last drawn line. This was a typo level error that just never got exercised. Thanks to Steve Blinkhorn for finding it. Steve also points out that thickness attributes on frames were being ignored. They're not anymore, but they're of limited usefulness and they don't thicken the ticks. The easiest way to draw a thick frame with thick ticks is: .G1 pic linethick=5 frame .\" ticks statement here pic linethick=1 draw solid bullet next at 1,2 next at 3,4 .G2 That draws a thick frame and thin line. I integrated some changes suggested by Hartmut Henkel to better handle graphing small numbers. I didn't include his patch exactly, but I think that most of the functionality has been added. His test cases look the same. If you're graphing things in the 1e-30 range, you should see autoscaling and not have your graph stop at 1e-6, assuming that your compiler has . I really think it's a bad idea to graph in that domain, as the math with numbers that small can be really hairy, and grap isn't exactly tuned for numerical analysis. But I think we do better now. 1.37 Fixed an error handling bug where an error at end of file/line could cause a core dump. Yuk. 1.36 Joel M. Cook pointed out that plot "\(bu" at 0, -306 didn't work. grap was requiring a numeric expression before the format string. I think I've had that discussion before, but I decided to support the behavior this time. Now both the expression and the format string are optional. plot at x,y will plot a 0 at x,y. plot "x" at x,y is exactly equivalent to "x" at x,y in output, but slightly slower. plot 3 at x,y works as before as does plot 2 "%g of clubs" at x,y I also modified the grammar to accept the base and wid paramaters to bar in any order. 1.35 Changes to lex code to compiler under newer versions of lex and configure code to activate them. Several people pointed out the problem and I like Bruce Lilly's solution best. Configure bugs are all mine. Bruce Lilly also noticed that copy statements with a macro and neither an until nor a filename didn't work as they should. He provided the fix for that. Bill Ward pointed out that grap should support gpic's "thickness" just like the color attributes. So now it does. And an apology to R. Clayton who sent patches for this very thing that I lost until after I'd implemented. 1.32: Whoops. Color modifiers were mis parsed in implicit plot statements. Now things like : bullet color "blue" at 1, 3 work. Minor code tweaks to make grap compile under g++ 3.4.2 1.31: In compatibility mode grap will no longer add whitespace around graphs. I like it, but Yuval Tamir rightly complained. 1.30: Made the undocumented color commands support GNU pic color commands. In other words added color to grap. Probably the easiest place to see the syntax is the new example added to the examples file. The changes are on the manual page, too, but the example sets basically everything that can be set, so it's a good example. 1.27: A couple compilation bugs reported under later g++ versions by a couple people have been fixed. Brian Mays caught a clipping bug, and Bruce Lilly also caught a couple compiler dependencies. 1.26: .lf was appearing outside the PS/PE pairs, so I disabled generation of those lines. 1.25: Fixed a bug parsing draw/new with no line descriptions. Thanks to Robert W. Numrich for spotting it. Cygwin seems to need errno.h to declare errno in grap_lex.l. I added the machinery to look for it and use it if it's there. I also added a couple missing semi-colons to grap.y to shut bison up. Added the clipped and unclipped attributes to allow plot statements to place strings outside the frame. Tuned the makefile so you can use pmake in parallel. 1.23: made it possible to disable sprintf and other calls to sprintf(3) with a user given format string, which is a potential security hole. Fixed a plot bug I found while disabling that. 1.22: John Heidemann caught a bug with respect to large sizes and size changes in titles. Those large size changes are now supported. Generally the groff [] syntax is now used for the embedded \s commans that size generates. This can be turned off by using -C. John also wanted to be able to specify string modifiers like size, etc. on ticks. Now ticks, grids, and plot strings (e.g. in a new or draw statement) all take string modifiers. grap.defines has been changed to support and encourage this usage. A bug where a null graph was output when only a draw statement was given has been corrected. sprintf processing has been revamped to more directly follow sprintf syntax. As a result, a limitation on the number of parameters (10) has been introduced. As a result of using string attributes on plotting strings, the name of the default line has become user-visible. Changing grap_internal_default via new will change the default lines for the rest of the graph. It's not encouraged. 1.21: Allow redefinition of keywords as macros. In the process, I added an undefine keyword to do the obvious: remove a macro. Added xy_gg macros, too. Fixed a bug where giving a coordinate name before a parenthesized point caused a syntax error. Thanks to Kees Zeelenberg for spotting this. Added an srand function to seed the random number generator, though there's none documented in Kernighan and Bentley's grap, and a getpid function to get a (sort of) random number. Don't use this for key generation. W. Robert Daasc caught this omission. While I was in there, I discovered that rand was not returning its full range from [0,1). It does now. Some keywords that accept strings weren't accepting sprintf, some of them have been fixed. Lee Ji Hwan found a bug with large files being read thru macros causing a core dump. That has been fixed. It was a really embarrassing coding style error, too... John Aycock discovered a bug where a line style was ignored on the first line command executed. It's not ignored anymore. I also found a bug in the execution order of copy through macros, although I'm uncertain if a version was ever released with the bug intact. I think this may have been related to Lee Ji Hwan's bug, which means it probably hasn't seen the light of day. -h prints a usage summary. --help is a synonym for -h and --version is a synonym for -v. 1.20: The big jump reflects both internal changes and visible feature changes. The class structure in the code has been substantially revamped, and the code brought into better conformance with the current state of the C++ world. As of version 1.20, grap no longer attempts to compile under g++ 2.7.2. grap 1.11 source will remain available from http://www.lunabase.org/~faber/Vault/software/grap for those who need it. One feature change is that troff and pic commands are now placed correctly in their relative order rather than being collected before and after the graph. This required specifying more carefully where the frame generation is placed. Frames are output either immediately before the first plotted object or after the frame statement, if any. This change motivated much of the class changes and actually cleaned them up somewhat. grap is now *much* more tolerant of variables with the keword names. Things like from=1; to = 10 for i from from to to do { ... } now work. This is due to a sizable rewrite of the tokenizer. In fact, variables and coordinate spaces can share names. Things like: for next = 0 to 10 do { next at next next, next } now work (you have to add a couple ticks statements to really see that example). I'd say we're to the point where obfuscated grap programs are a possibility. The only change this necessitated was that if you specify a coordinate system in an automatic ticks statement, you have to use the on or auto keyword. See the examples document for an example. I recoded macros to remove an antiquated construct that was confusing some non-g++ compilers. A static array was recoded as an STL vector, with the result that an artificial constraint on the number of arguments in a macro went away. Part of the recoding of the tokenizer encoded a large data structure in a file called grap_tokenizer.cc. The code is striaght-ahead initialization, but it drives the g++ optimizer stone crazy. (Optimizing this function is very memory intensive.) By default, optimization is specifically disabled under g++. You can override that behavior by specifying --enable-optimize-grap_tokenizer to ./configure. On the machines I use, optimizing this module has absolutely no effect on performance, and I suggest you don't bother spending the time optimizing it. The autoconf and make stuff has been revamped to use GNU make's automatic makefile generation or BSD pmake's automatic .depend inclusion, as well as simplifying the distribution creation and caching all configuration values. Added some GNU standard Makefile targets to the Makefile. Fixed some bugs in the manual page. Ran spell again on the examples. Misspelling Brian Kernighan's name is bad. Many additional compatibility changes suggested by Bruce Lilly. 1.11: Strings are now clipped, thanks to John Heidemann for finding the error. 1.10: Cleaned up the automatic tick generation and fixed a bug in there, too. Allow reassignment of coordinate system parameters, e.g., .G1 coord test copy "examples/cy_fatal.d" coord test x 1980,2000 .G2 Default line format now uses the bullet macro if it's defined. The coord statement now will accept multiple log scale modifiers. The statement coord x 1,1000 log x log y is now legal. x and y are now legal variable names. They used to be language tokens, and in fact still are, although their scope as tokens is now limited to coord statements. Tried to streamline the use of for_each and functors by removing trivial calls to for_each. Still trying to move code out of grap.y to make it shorter to compile. Simplified expression grammar by disallowing logical expressions outside if statements. I also caught another memory leak here. Signifying a line break by using new (or draw) now works. So code like .G1 draw solid next at 2,4 next at 3,5 new next at 4,6 next at 5,7 .G2 produces 2 solid line segments. This forced a little rethinking of the syntax for changing the properties of a line using new/draw. The implementation is on the man page. If it breaks existing grap scripts, I'd love to hear about it. Grids support similar syntax to that of ticks for explicitly requesting automatic grid generation. Automatic tock or grid generation can now be requested relative to a named coordinate system, formerly automatic ticks/grid lines were only generated for the default coordinate system. Added the ln function. Why did that take me so long? Revised and (finally) spell-checked the man page. I also stopped including the auto-generated manual page in an macros. A text version of the man page is now installed, but the manual uses the doc macros exclusively. Line clipping was added in here, too. 1.06: Added an anonymous donor's TeX defines. Also added the -C compatibility option for groff and fixed some manpage formatting bugs. 1.05: kromJx@crosswinds.net noticed that numbers like 1. weren't accepted. They are now. While I was fixing that I noticed that copy until commands without a macro weren't supported. They are now. Made a minor change to the examples to test the fixes. 1.03: Added the -M path option to make groff handle grap better. I also added the GRAP_DEFINES environment variable to change the defines file. I also added a new source file, grap_parse.cc in an attempt to break up the monolithic and gigantic grap.y. I had some small success. In the course of creating grap_parse.cc I think I caught some memory leaks, too. 1.02: Bruce's error handling code produced a few inconsistencies (eating the last newline of a file, and adding one befor ethe file. I think it no longer does that. In addition I took care of a error placement bug when the error was in a line containing a macro expansion, and changed the error handling from using char * to using Strings, like the rest of grap. Got rid of an error on SunOS (and presumably other architectures) where -0 labels were printed on auto-generated labels. Fixed bugs in sprintf when compiled using standard strings. Fixed a memory leak and general bug with the undocumented color commands. (There, that'll tell me if anyone reads this!) 1.01: Fixed a compilation bug under RedHat 6.1. Cleaned up autoconf and tweaked the makefile. 1.0: Incorporated Bruce Lilly's error reporting code. Cleaned up the documents (including a menton for Bruce in the man page) for v1.0 release. Cleared up a file reading bug. 0.98b: Bruce Lilly reported some bugs and DWP incompatibilities, mainly with negative numbers in number lists and comma separations in them. He also compiles in UWIN under NT, which broke autoconf in some weird ways. The most important of these necessitated adding a check to ensure that install supports -d. His test case is in the example file now. He also found some spelling errors. The README file now reflects the real state of the world, too. More kudos to Bruce. While tinkering with those autoconf changes I found that grap didn't compile under g++ 2.7.2.1 any more. Good thing that 0.97b wasn't really released. All is well again. More fun from Bruce: he's given me patches to make cascding assignments work and to remove a bug with comments not acting as separators. I've also make the order of copy commands more flexible (the until can go before or after an inline macro, for example) and fixed a bug in the grammar that made it difficult to put general expressions in places like the frame size. Expressions can go anywhere now, at the expense that string comparisons can only appear in if statements. Those bugs were also spotted by Bruce. 0.97b: Finally have a copy of egcs, so grap will now compile under it using both the stl and the standard string class. What do you know, compiling under egcs halves the run time. This is roughly half due to better egcs compilation and half due to the better performance of the standard string class. Moved to a config.h-style grap.h. Smoothed out the header files to confine as much conditional compilation as possible to grap.h. The code now uses hash_maps if they're available. 0.95b: bug fix: deleting grap_buffer_state contents twice on error, allow more than one shift description on ticks, grids, and labels. Thanks to Anindo Banerjea at ISI for spotting my misimplementation. Another couple of Bannerjea catches: through is now recognized as a synonym for thru. "For," "then" and "else" clauses were previously treated as macros but now have a terminating separator added to them. The result is that things like if (x == 3) { y = y + 1 } x = x + 1 work now. (If the { } is treated as a macro defined and expanded on the spot, the grap parser sees y = y + 1x = x + 1 and cannot parse the expression y+1x). The new behavior is both more intuitive and more in line with previous grap implementations. More from Anindo: expansion of macro arguments assumed that the only possible character following a dollar sign was a single digit. This caused problems both when a non-digit followed and the $ was literal, and when the intent was to access an argument with an index greater than 9. Argument expansion now only expands when a $ is followed by 1 or more digits, and includes all the digits in the index. The frame statement will now accept the default line style before or after the frame size. I still don't accept things like frame ht 3 solid wid 3 - the specifications of the size must be contiguous. 0.92a: bug fix - string equality check. Small change to Makefile.in to support default Solaris behavior. Added -v for version info. Some general internals fiddling (I'd like to call it cleanup, but I think that's generous). 0.91a: small changes for the RPM 0.9a: Added commands for making bars. Error reporting is much closer to the correct line now. Generalized line descriptions for fillable objects. Circles now take a line description. Added new examples of fillable objects. Now using the BSD copyright notice instead of my own half-baked one. 0.8a: alpha release grap-1.43/COPYRIGHT000640 004133 000000 00000002361 07314131142 014065 0ustar00faberwheel000000 000000 Copyright 1998-2001 Ted Faber All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. grap-1.43/grap_pic.h000640 004133 000000 00000012741 10531454621 014537 0ustar00faberwheel000000 000000 // -*-c++-*- #ifndef GRAP_PIC_H #define GRAP_PIC_H // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. extern void linenum(); // This is used by Pictick and Picgrid to iterate across their shifts class Picshiftdraw : unary_function { protected: ostream &f; // The output ostream public: Picshiftdraw(ostream& ff) : f(ff) { } int operator()(shiftdesc *sd) { if ( sd->param != 0 ) { f << "move " ; switch (sd->dir) { case left_side: f << "left "; break; case right_side: f << "right "; break; case top_side: f << "up "; break; case bottom_side: f << "down "; break; } f << sd->param << endl; } return 1; } }; class PicDisplayString : public DisplayString, public drawable { public: PicDisplayString(DisplayString& ds) : DisplayString(ds) { } void draw(frame *); ~PicDisplayString() { }; }; class Pictick : public tick, public drawable { public: Pictick(tick& t) : tick(t) { }; void draw(frame *); ~Pictick() { } }; class Picgrid: public grid, public drawable { public: Picgrid(grid &g) : grid(g) { } void draw(frame *); ~Picgrid() { } }; class Picframe: public frame, public drawable { public: void draw(frame *) ; ~Picframe() { } protected: void autoguess(sides, double &, double&, double&, double &, int&, coord *); void addautoticks(sides); void addautogrids(sides); void frame_line(double, double, sides); void label_line(sides); }; class Piclinesegment : public linesegment, public drawable { protected: // Returns true if the coordinate is between 0 and 1 (withing tolerance). inline bool inbox(double a) { return ( a < 1+epsilon && a > 0-epsilon ); } bool clipx( double &, double &, double &, double &); bool clip( double &, double &, double &, double &); public: Piclinesegment(linesegment &ls) : linesegment(ls) { } Piclinesegment(double x, double y, coord* c, line *l, DisplayString *s=0, linedesc *ld=0, bool a=false) : linesegment(x, y, c, l, s, ld, a) { } ~Piclinesegment() { } void draw(frame *); }; // Sequence is defined in grap_data.h class Picplot: public plot, public drawable { public: Picplot(plot& p) : plot(p) { } Picplot(stringlist *s =0, point *p=0) : plot(s, p) { } ~Picplot() { } void draw(frame *); }; class Piccircle: public circle, public drawable { public: Piccircle(circle& c) : circle(c) { } Piccircle(point *p, double r, linedesc *l=0) : circle(p, r, l) { } ~Piccircle() { } void draw(frame *); }; class Picbox: public box, public drawable { protected: void swap(double &a, double &b) { double h = a; a =b ; b =h; } public: Picbox(box& b) : box(b) { } Picbox(point *p1, point *p2, linedesc *l) : box(p1, p2, l) { } ~Picbox() { } void draw(frame *); }; class Picthrustring : public string, public drawable { public: Picthrustring(const string &s) : string(s) { } ~Picthrustring() { } void draw(frame *) { cout << *this << endl; } }; class Picgraph : public graph { string *ps_param; // The params to .G1 string *pos; // the position of the graph (in pic) int graphs; // the number of graphs drawn this block bool frame_queued; // The frame is on the object list Picframe *pframe; // The pic frame for deallocation public: // regular member functions Picgraph() : graph(), ps_param(0), pos(0), graphs(0), pframe(0) { } ~Picgraph() { // pframe should always be a copy of base, so don't delete it. // It will be deallocated by graph::init. delete ps_param; ps_param = 0; delete pos; pos = 0; } // overload the virtual functions in graph void init(string * =0, string* =0); void begin_block(string *param) { graphs = 0; ps_param = param; } void end_block() { if ( graphs ) { cout << ".PE" << endl; linenum(); } } void passthru_string(const string& s) { Picthrustring *t = new Picthrustring(s); if ( t ) objs.push_back(t); } virtual linesegment *new_linesegment(double x, double y, coord* c, line *l, DisplayString *s=0, linedesc *ld=0, bool a=false) { Piclinesegment *pls = new Piclinesegment(x, y, c, l, s, ld, a); queue_frame(); if (pls) objs.push_back(pls); return pls; } virtual plot *new_plot(stringlist *s =0, point *p=0) { Picplot *pl = new Picplot(s, p); queue_frame(); if ( pl ) objs.push_back(pl); return pl; } virtual circle *new_circle(point *p, double r, linedesc *l=0) { Piccircle *c = new Piccircle(p, r, l); queue_frame(); if ( c ) objs.push_back(c); return c; } virtual box *new_box(point *p1, point *p2, linedesc *l) { Picbox *b = new Picbox(p1, p2, l); queue_frame(); if ( b ) objs.push_back(b); return b; } virtual void queue_frame() { if ( !frame_queued ) { objs.push_back(pframe); frame_queued = true; } } void draw(frame *); }; class Piccoord: public coord, public drawable { public: Piccoord(const coord& c) : coord(c) { } ~Piccoord() { } void draw(frame *f) { const string& nm = (name != "") ? name : "gg"; cout << "define x_"<< nm << " { ((( $1 - " << xmin << ") / " << xmax-xmin << ") * " << f->wid << " ) }" << endl; cout << "define y_"<< nm << " { ((( $1 - " << ymin << ") / " << ymax-ymin << ") * " << f->ht << " ) }" << endl; cout << "define xy_" << nm << " { x_" << nm << "($1), " << "y_"<< nm << "($2) }" << endl; } }; #endif grap-1.43/strerror.cc000640 004133 000000 00000000210 07300141416 014752 0ustar00faberwheel000000 000000 #include char *strerror(int errnum) { static char rv[100]; sprintf(rv, "error number %d", errnum); return rv; } grap-1.43/grap_string.h000640 004133 000000 00000010545 07404051125 015267 0ustar00faberwheel000000 000000 #ifndef GRAP_STRING_H #define GRAP_STRING_H // These should be replaced by the standard string library, but under // g++ 2.7.2.1 that library is incompatible with the STL static const int strchunk = 256; class String { public: typedef size_t size_type; static const size_type npos = ~0; String() : str(0), len(0) { } String(const char *c) : str(0), len(0) { resize(::strlen(c)+1); strcpy(str,c); }; String(const int i) : str(0), len(0) { resize(strchunk); snprintf(str,len,"%d",i); }; String(const double d, const String *fmt = 0) : str(0), len(0) { resize(strchunk); if ( fmt ) snprintf(str,len,fmt->str,d); else snprintf(str,len,"%g",d); }; String(const String* x) : str(0), len(0) { resize(x->len); if ( len ) strcpy(str,x->str); }; String(const String& x) : str(0), len(0) { resize(x.len); if ( len) strcpy(str,x.str); }; ~String() { if ( str) { delete str; str = 0; } len = 0; }; char& operator[](const int i) { if ( i < len ) return str[i]; else { resize(i+1); return str[i]; } }; String& operator=(const String &s) { if ( len < s.len) resize(s.len); if ( len )strcpy(str,s.str); return *this; }; String& operator+=(const String& s) { int nlen = s.strlen() + strlen()+ 1; if ( len < nlen ) resize(nlen); if ( len ) strcat(str,s.str); return *this; } String& operator+=(const char *s) { int nlen = ::strlen(s) + strlen() + 1; if ( len < nlen ) resize(nlen); if ( len ) strcat(str,s); return *this; } String& operator+=(const char c) { int last = strlen(); if ( len < last +2 ) resize(last+2); last=strlen(); str[last] = c; str[last+1] = '\0'; return *this; } String operator+(const String& s) { String rc = *this; rc+= s; return rc; } String operator+(const char *c) { String rc = *this; rc+= c; return rc; } size_type find(char c) const { size_type len = length(); for ( size_type i = 0; i < len; i++ ) if ( str[i] == c ) return i; return npos; } void erase(size_type start, size_type end) { size_type lim = length(); if ( end == npos ) end = lim-1; if ( len ) { strcpy(str+start,str+end); str[(lim-1)-end-start] = '\0'; } } int operator==(const String &s) const { return !strcmp(str,s.str); } int operator<(const String &s) const { return ( strcmp(str,s.str) < 0) ; } int operator==(const char *s) const { return !strcmp(str,s); } int operator!=(const String &s) const { return strcmp(str,s.str); } int operator!=(const char *s) const { return strcmp(str,s); } int operator<(String& s) { return strcmp(str,s.str) < 0; } void quote() { int l; if ( len < strlen()+3 ) resize(len+3); for ( int i = len-1; i >=1; i-- ) str[i] = str[i-1]; l = strlen(); if ( l == 0 ) l = 1; str[0] = '"'; str[l] = '"'; str[l+1] = '\0'; } void unquote() { int i; if ( str[0] == '"' ) { for ( i = 0; i < len-2; i++ ) str[i] = str[i+1]; str[strlen()-1] = '\0'; } i = strlen(); if ( str[i-1] == '"' ) str[i-1] = '\0'; } void strncpy(char *s, int l) { ::strncpy(s,str,l); } int strlen() const { return ( (str) ? ::strlen(str) : 0 ); } const char *c_str() const { return str;} int length() const { return strlen();} ostream& print(ostream& f) const { return f << str; } String substr(int i, int n=0) { String s; s.resize(strlen()); if ( n == 0 || n > strlen()-i ) n = strlen() - i; for ( int j = 0; j < n; j++ ) s.str[j] = str[i+j]; s.str[n] = '\0'; return s; } protected: char *str; int len; void resize(int ns) { char *c; int s; s =( ns/strchunk + (( ns % strchunk ) ? 1 : 0 )) * strchunk; c = new char[s]; if ( len ) for ( int j = 0; j < len; j++) c[j] = str[j]; else c[0] = '\0'; if ( str ) delete str; str = c; len = s; } }; inline ostream& operator<<(ostream& f, const String& s) { return s.print(f); } // These functions and classes are all duplicated for standard strings // in grap_data.h. The choice is to either support 2 versions of // these functions or to make the emulation of standard strings better // and support that. Because this code was already written, I chose // this. inline void unquote(String *s) { s->unquote(); } inline void quote(String *s) { s->quote(); } #endif grap-1.43/strdup.cc000640 004133 000000 00000000453 06750427334 014440 0ustar00faberwheel000000 000000 #ifdef STDC_HEADERS #include #endif extern "C" { void * malloc(size_t size); }; char *strdup(const char *s) { int len = strlen(s)+1; char *t; int i; if ( !(t = (char *) malloc(len)) ) return 0; else for ( i = 0; i < len; i++ ) t[i] = s[i]; return t; } grap-1.43/default_depend000640 004133 000000 00000000413 07060374604 015466 0ustar00faberwheel000000 000000 grap.o: grap.cc grap.h grap_data.h grap_draw.h grap_pic.h grap_lex.o: grap_lex.cc grap.h y.tab.h grap_data.h grap_draw.h grap_pic.h grap_draw.o: grap_draw.cc grap.h grap_data.h grap_draw.h grap_pic.h grap_pic.o: grap_pic.cc grap_pic.h grap.h grap_data.h grap_draw.h grap-1.43/grap.tex.defines000640 004133 000000 00000002010 07105461240 015653 0ustar00faberwheel000000 000000 .G1 # This file adds support for TeX to grap # (assuming that your 'pic' implementation allows that. Eg. the pic program # that comes with the GNU groff package does so) # # # All symbols defined here come standard with LaTeX2e, # with the exception of square and box # # If you want to use these two symbols, you must load the 'amssym' package, # ie. put \usepackage{amssymb} in the preamble of your document. # define delta {"\textrm{\fontsize{8}{0}\selectfont{$\triangle$}}"} define bullet {"\textrm{\fontsize{9}{0}\selectfont{$\bullet$}}"} define vtick {"\textrm{\fontsize{8}{0}\selectfont{$\mid$}}"} define square {"\textrm{\fontsize{8}{0}\selectfont{$\square$}}"} define box {"\textrm{\fontsize{8}{0}\selectfont{$\blacksquare$}}"} define times {"\textrm{\fontsize{8}{0}\selectfont$\times$}"} define htick {"\textrm{\fontsize{8}{0}\selectfont{--}}"} define plus {"\textrm{\fontsize{8}{0}\selectfont{+}}"} define star {"\textrm{\fontsize{8}{0}\selectfont$\star$}"} define dot {"\textrm{\fontsize{8}{0}\selectfont$\cdot$}"} .G2 grap-1.43/grap_tokenizer.cc000640 004133 000000 00000023442 10242304067 016131 0ustar00faberwheel000000 000000 /* This code is (c) 1998-2001 Ted Faber see COPYRIGHT for the full copyright and limitations of liabilities. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef STDC_HEADERS #include #include #include #endif #if defined(STDC_HEADERS) | defined(HAVE_STDLIB_H) #include #endif #include #include #include #include "grap.h" #include "grap_data.h" #include "grap_draw.h" #include "y.tab.h" // Keywords recognized in the initial GRAP state (AT, SPRINTF and all // the string modifiers are there for implicit PLOT statements). string gk[] = { "copy", "next", "draw", "new", "line", "define", "arrow", "circle", "plot", "at", "frame", "graph", "coord", "for", "if", "print", "sprintf", "ticks", "tick", "label", "grid", "pic", "sh", "bar", "ljust", "rjust", "above", "below", "aligned", "unaligned", "size", "undefine", "clipped", "unclipped", "color" }; // These are the keywords recognized by any keyword that takes a line // descriptor: string lk[] = { "invis", "solid", "dotted", "dashed", "fill", "fillcolor", "color", "thickness" }; // Keywords recognized for sting modifiers string sk[] = { "ljust", "rjust", "above", "below", "aligned", "unaligned", "size", "clipped", "unclipped", "color" }; // Keywords recognized by ticks and graph string tk[] = { "left", "right", "up", "down", "bottom", "bot", "top", "in", "out", "from", "to", "by", "at", "off", "on", "auto", "sprintf", "color" }; // Vector versions of these vector grap_keys(gk, gk+sizeof(gk)/sizeof(string)); vector linedesc_keys(lk, lk+sizeof(lk)/sizeof(string)); vector strmod_keys(sk, sk+sizeof(sk)/sizeof(string)); vector tick_keys(tk, tk+sizeof(tk)/sizeof(string)); // The data structure encapsulating the keyword handling algorithms keywordDictionary keywords; // This builds a large hash table encapsulating the actions to take // when a keyword is parsed. This is one big static data structure, // and should just be statically initialized, but is complex enough // that building it is easier to maintain. It's split into // subfunctions primarily because the gcc optimizer has a terrible // time with the one big function, and partially to make it easier to // maintain. // All these can appear multiple times in a command void init_multiples() { vector empty; keywords["above"] = keyword(empty, empty, false, ABOVE); keywords["top"] = keyword(empty, empty, false, TOP); keywords["bot"] = keywords["bottom"] = keyword(empty, empty, false, BOTTOM); keywords["left"] = keyword(empty, empty, false, LEFT); keywords["right"] = keyword(empty, empty, false, RIGHT); keywords["up"] = keyword(empty, empty, false, UP); keywords["down"] = keyword(empty, empty, false, DOWN); keywords["ljust"] = keyword(empty, empty, false, LJUST); keywords["rjust"] = keyword(empty, empty, false, RJUST); keywords["below"] = keyword(empty, empty, false, BELOW); keywords["aligned"] = keyword(empty, empty, false, ALIGNED); keywords["unaligned"] = keyword(empty, empty, false, UNALIGNED); keywords["clipped"] = keyword(empty, empty, false, CLIPPED); keywords["unclipped"] = keyword(empty, empty, false, UNCLIPPED); keywords["size"] = keyword(empty, empty, false, SIZE); keywords["in"] = keyword(empty, empty, false, IN); keywords["out"] = keyword(empty, empty, false, OUT); keywords["off"] = keyword(empty, empty, false, OFF); keywords["on"] = keywords["auto"] = keyword(empty, empty, false, ON); keywords["fill"] = keyword(empty, empty, false, FILL); keywords["invis"] = keyword(empty, empty, false, INVIS); keywords["solid"] = keyword(empty, empty, false, SOLID); keywords["dotted"] = keyword(empty, empty, false, DOTTED); keywords["dashed"] = keyword(empty, empty, false, DASHED); keywords["fillcolor"] = keyword(empty, empty, false, FILLCOLOR); keywords["color"] = keyword(empty, empty, false, COLOR); keywords["thickness"] = keyword(empty, empty, false, THICKNESS); } // These are all one time command modifiers void init_only_once() { vector empty; vector temp; // temp.clear(); temp.push_back("radius"); temp.push_back("rad"); keywords["radius"] = keywords["rad"] = keyword(empty, temp, false, RADIUS); temp.clear(); temp.push_back("from"); keywords["from"] = keyword(empty, temp, false, FROM); temp.clear(); temp.push_back("thru"); temp.push_back("through"); keywords["thru"] = keywords["through"] = keyword(empty, temp, false, THRU); temp.clear(); temp.push_back("to"); keywords["to"] = keyword(empty, temp, false, TO); temp.clear(); temp.push_back("by"); keywords["by"] = keyword(empty, temp, false, BY); temp.clear(); temp.push_back("until"); keywords["until"] = keyword(empty, temp, false, UNTIL); temp.clear(); temp.push_back("do"); keywords["do"] = keyword(empty, temp, false, DO); temp.clear(); temp.push_back("x"); keywords["x"] = keyword(empty, temp, false, XDIM); temp.clear(); temp.push_back("y"); keywords["y"] = keyword(empty, temp, false, YDIM); temp.clear(); temp.push_back("base"); keywords["base"] = keyword(empty, temp, false, BASE); temp.clear(); temp.push_back("ht"); keywords["ht"] = keyword(empty, temp, false, HT); temp.clear(); temp.push_back("wid"); keywords["wid"] = keyword(empty, temp, false, WID); temp.clear(); temp.push_back("at"); keywords["plot"] = keyword(temp, empty, true, PLOT); } // These all signal the start of a command void init_line_starters() { vector empty; vector temp; temp.clear(); temp.push_back("thru"); temp.push_back("through"); temp.push_back("until"); keywords["copy"] = keyword(temp, empty, true, COPY); temp = linedesc_keys; temp.push_back("at"); temp.push_back("sprintf"); keywords["next"] = keyword(temp, empty, true, NEXT); temp = linedesc_keys; temp.insert(temp.end(), strmod_keys.begin(), strmod_keys.end()); temp.push_back("sprintf"); keywords["draw"] = keywords["new"] = keyword(temp, empty, true, DRAW); temp = linedesc_keys; temp.push_back("from"); temp.push_back("to"); keywords["line"] = keyword(temp, empty, true, LINE); temp = linedesc_keys; temp.push_back("from"); temp.push_back("to"); keywords["arrow"] = keyword(temp, empty, true, ARROW); temp = linedesc_keys; temp.push_back("at"); temp.push_back("radius"); temp.push_back("rad"); keywords["circle"] = keyword(temp, empty, true, CIRCLE); temp = linedesc_keys; temp.push_back("top"); temp.push_back("bottom"); temp.push_back("bot"); temp.push_back("left"); temp.push_back("right"); temp.push_back("ht"); temp.push_back("wid"); keywords["frame"] = keyword(temp, empty, true, FRAME); temp.clear(); temp.push_back("x"); temp.push_back("y"); temp.push_back("log"); keywords["coord"] = keyword(temp, empty, true, COORD); temp.clear(); temp.push_back("from"); temp.push_back("to"); temp.push_back("by"); temp.push_back("do"); keywords["for"] = keyword(temp, empty, true, FOR); temp.clear(); temp.push_back("then"); keywords["if"] = keyword(temp, empty, true, IF); temp.clear(); temp.push_back("else"); keywords["then"] = keyword(temp, empty, true, THEN); temp = tick_keys; temp.insert(temp.end(), strmod_keys.begin(), strmod_keys.end()); keywords["tick"] = keywords["ticks"] = keyword(temp, empty, true, TICKS); temp = strmod_keys; temp.push_back("left"); temp.push_back("right"); temp.push_back("up"); temp.push_back("down"); temp.push_back("bottom"); temp.push_back("bot"); temp.push_back("top"); temp.push_back("sprintf"); keywords["label"] = keyword(temp, empty, true, LABEL); temp = linedesc_keys; temp.insert(temp.end(), tick_keys.begin(), tick_keys.end()); temp.insert(temp.end(), strmod_keys.begin(), strmod_keys.end()); temp.push_back("ticks"); temp.push_back("tick"); keywords["grid"] = keyword(temp, empty, true, GRID); temp = linedesc_keys; temp.push_back("ht"); temp.push_back("wid"); temp.push_back("up"); temp.push_back("right"); temp.push_back("base"); keywords["bar"] = keyword(temp, empty, true, BAR); } // These have special parsing rules. They clear the active commands. void init_wipers() { vector empty; keywords["define"] = keyword(empty, empty, true, DEFINE); keywords["undefine"] = keyword(empty, empty, true, UNDEFINE); keywords["graph"] = keyword(empty, empty, true, GRAPH); keywords["else"] = keyword(empty, empty, true, ELSE); keywords["print"] = keyword(empty, empty, true, PRINT); keywords["pic"] = keyword(empty, empty, true, PIC); keywords["sh"] = keyword(empty, empty, true, SH); } // This are used in parsing multi-element matches for macros. bool id_letter[256]; // set up the table to scan for embedded macros void init_id() { int i; // Scratch for (i = 0; i < 256; i++ ) id_letter[i] = false; // assumes letters are contiugous. Is there still any character set // for this which doesn't hold? for ( i = 'a'; i <= 'z' ; i++ ) id_letter[i] = true; for ( i = 'A'; i <= 'Z' ; i++ ) id_letter[i] = true; for ( i = '0'; i <= '9' ; i++ ) id_letter[i] = true; id_letter[static_cast('_')] = true; } // Initialize the table of keywords. void init_keywords() { vector empty; init_multiples(); init_only_once(); init_line_starters(); init_wipers(); // Sprintf is unusual in that it doesn't alter the parse state at // all. keywords["sprintf"] = keyword(empty, empty, false, SPRINTF); // init the table init_id(); } grap-1.43/Makefile.common000640 004133 004133 00000005702 10470234206 015513 0ustar00faberfaber000000 000000 # -*-makefile-*- # This file is (c) 2001 Ted Faber (faber@lunabase.org) see COPYRIGHT # for the full copyright and limitations of liabilities. # Some standard targets are defined below. The parameters that need # to be defined for these to work are: # PROGS programs to make # DISTDIR the name of the directory in which tarred files appear # RM the file deletion command. rm -f is usual. # OBJS object files. Can be null, removed on make clean # MAKE make should set it. # MKDEP make depend program # MKDEPFLAGS arguments to mkdep # LD program to link .o -> executables # CLEANFILES files to remove on make clean beyond the defaults # VERYCLEANFILES files to remove on make veryclean beyond the defaults # SPOTLESSFILES files to remove on make spotless beyond the defaults # solaris make uses these as defaults: CCC=$(CXX) CCFLAGS=$(CXXFLAGS) COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) -c PREMKDEP?=@true POSTMKDEP?=@true ALL?=${PROGS} .SUFFIXES: .doc .an all: .depend ${ALL} manifest: manifest.in sed 's/^/${DISTDIR}\//;' < manifest.in > manifest dist: manifest ${RM} -r /tmp/${DISTDIR} && mkdir /tmp/${DISTDIR} tar cf - . | (cd /tmp/${DISTDIR} && tar xf - ) cd /tmp && tar --create --gzip --file ${DISTDIR}.tar.gz \ --files-from ${DISTDIR}/manifest --dereference mv /tmp/${DISTDIR}.tar.gz . ${RM} -r /tmp/${DISTDIR} clean: ${MAKE} cleancore ${RM} ${PROGS} ${OBJS} ${DISTDIR}.tar.gz *.core core ${CLEANFILES} cleancore: ${RM} *.core core cleanconfig: ${RM} config.log config.status config.cache cleandepend: cat < /dev/null > .depend touch -t 9912311000 .depend > /dev/null 2>&1 || ( sleep 1; touch Makefile) cleanautoconf: ${RM} -r autom4te.cache veryclean: ${MAKE} clean cleantags ${RM} ${VERYCLEANFILES} distclean: ${MAKE} veryclean ${MAKE} cleanconfig ${RM} Makefile .depend config.h manifest ${SPOTLESSFILES} spotless: ${MAKE} veryclean ${MAKE} cleanconfig ${MAKE} cleanautoconf ${RM} Makefile .depend configure config.h manifest ${SPOTLESSFILES} depend: .depend newdepend: cleandepend depend .depend: Makefile ${PREMKDEP} ${MKDEP} ${MKDEPFLAGS} ${POSTMKDEP} tags: ${TAGFILES} ${CTAGS} ${CTAGSFLAGS} ${TAGFILES} cleantags: ${RM} tags # pattern rules for c++ compilation and linking. The *.o -> # executable rules are for times when c++ generated .o files are made # into executables. The linker muse be overlaid with a C++ aware # linker (usually the C++ complier). # pmake .NULL: .out .cc.out: ${CXX} ${CXXFLAGS} ${LDFLAGS} -o $@ ${.IMPSRC} ${LDLIBS} .o.out: ${LD} ${LDFLAGS} -o $@ ${.ALLSRC} ${LDLIBS} #GNU Make .cc: ${CXX} ${CXXFLAGS} ${LDFLAGS} -o $@ $< ${LDLIBS} .o: ${LD} ${LDFLAGS} -o $@ $^ ${LDLIBS} # create a -man macro formatted manpage. This only works if rosetta man # is available, and should be done on my system prior to dist. .doc.an: groff -Tascii -mdoc $< | rman -f roff > $@ # Some of the standard GNU targets to make some people's lives easier mostlyclean: clean maintainer-clean: veryclean grap-1.43/aclocal.m4000664 004133 004133 00000025016 11073761023 014434 0ustar00faberfaber000000 000000 dnl a lower case to upper case utility function define(tvf_upper,[translit($1,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ)]) dnl set the variable in the first argument to the value in the second if dnl the c++ compiler is a GNU compiler. Export the variable as a substitution AC_DEFUN(TVF_PROG_GXX_SUBST,[ AC_REQUIRE([AC_PROG_CXX]) # Set g++ specific compiler options if test "$GXX" = "yes" ; then $1="$2" else $1="" fi AC_SUBST($1) ]) dnl set the variable in the first argument to the value in the second if dnl the C compiler is a GNU compiler AC_DEFUN(TVF_PROG_GCC_SUBST,[ AC_REQUIRE([AC_PROG_CC]) # Set g++ specific compiler options if test "$GCC" = "yes" ; then $1="$2" else $1="" fi AC_SUBST($1) ]) dnl if the install doesn't handle -d properly, fall back to the install script AC_DEFUN(TVF_PROG_INSTALL_D,[ AC_REQUIRE([AC_PROG_INSTALL]) AC_CACHE_CHECK(whether $INSTALL supports -d, tvf_cv_prog_install_d, if $INSTALL -d /tmp/test$$ && test -d /tmp/test$$ ; then tvf_cv_prog_install_d="yes" else tvf_cv_prog_install_d="no" fi rm -rf /tmp/test$$ ) if test "$tvf_cv_prog_install_d" = "no" ; then INSTALL=$ac_install_sh fi ]) dnl check for various methods of making dependencies, from the mkdep dnl script to copying precomputed defaults. Both MKDEP and MKDEPFLAGS are dnl set and seported via AC_SUBST AC_DEFUN(TVF_PROG_MKDEP,[ AC_CHECK_PROGS(MKDEP,mkdep gcc, cp) define(tvf_extra_flags,$1) # depending on which mkdep method has been found, the args are # slightly different. -f is redundant on FreeBSD, but needed other places. # The test for that is completely superfluous. if test $ac_ext = "C" || test $ac_ext = "cc" ; then tvf_compflags='${CXXFLAGS}' tvf_mk_gcc=g++ tvf_mk_include="" else tvf_compflags='${CFLAGS}' tvf_mk_gcc=gcc tvf_mk_include="" fi # make sure that mkdep plays well with others. Be careful. Bad mkdep # implementations are very cranky about parameter order. if test "$MKDEP" = mkdep; then tvf_here=`pwd` cd /tmp mkdir test.$$ cd test.$$ # solaris mkdep wants a .depend there already touch .depend touch test.h cat > test.$ac_ext << END #include $tvf_mk_include #include "test.h" int main(int argc, char **argv) { } END $MKDEP -f .depend tvf_extra_flags -MM test.$ac_ext 2> /dev/null > /dev/null grep test.h .depend > /dev/null 2>&1 if test "$?" != "0"; then # MKDEP does not play well with us, use gcc or cp cd $tvf_here unset ac_cv_prog_MKDEP unset MKDEP AC_CHECK_PROGS(MKDEP,gcc, cp) else cd $tvf_here fi rm -rf /tmp/test.$$ fi case "$MKDEP" in mkdep) if test `uname` = 'FreeBSD'; then MKDEPFLAGS="tvf_extra_flags -MM $tvf_compflags \${SOURCES}" else MKDEPFLAGS="-f .depend tvf_extra_flags -MM $tvf_compflags \${SOURCES}" fi ;; gcc) MKDEP=$tvf_mk_gcc MKDEPFLAGS="-MM $tvf_compflags \${SOURCES} >> .depend" ;; cp) MKDEPFLAGS='default_depend .depend' ;; esac undefine([tvf_extra_flags]) AC_SUBST(MKDEPFLAGS) ]) dnl See if the given function is both present and declared. The first dnl argument is the function to check, the second is a space spearated dnl list of headers to check and the last is an optional CHECK or REPLACE dnl that determines whether AC_CHECK_FUNCS or AC_REPLACE_FUNCS is called dnl internally. Both the usual HAVE_function and function_DECLARED are dnl AC_DEFINEd. AC_DEFUN(TVF_FUNC_DECL,[ define(tvf_call,[AC_]ifelse($3,,CHECK,$3)[_FUNCS(]$1[)]) tvf_call if test "$ac_cv_func_$1" = "yes" ; then AC_CACHE_CHECK(for declaration of $1,tvf_cv_decl_$1, for f in $2; do AC_EGREP_HEADER($1,$f,tvf_cv_decl_$1="yes", tvf_cv_decl_$1="no") if test $tvf_cv_decl_$1 = "yes"; then break; fi done ) if test "$tvf_cv_decl_$1" = "yes"; then AC_DEFINE(tvf_upper($1)_DECLARED) fi fi undefine([tvf_call]) ]) dnl determine if one of rand or random is present (preferring random) dnl and if they are declared. HAVE_RANDOM and RANDOM_DECLARED (or their dnl RAND analogs) are set. stdlib.h and math.h are checked. If the function dnl is declated in math.h RANDOM_IN_MATH or the analog is defined AC_DEFUN(TVF_DECL_RANDOM, [ if test "x$ac_cv_header_stdc" = "x" -a "x$ac_cv_header_stdlib_h" = "x"; then AC_HEADER_STDC if test $ac_cv_header_stdc = "no"; then AC_CHECK_HEADERS(stdlib.h) fi fi AC_CHECK_FUNCS(random) if test $ac_cv_func_random = "no"; then AC_CHECK_FUNCS(rand) else # not really, but we never need it if we have random ac_cv_func_rand="no" fi if test "$ac_cv_func_random" = "no" -a "$ac_cv_func_rand" = "no"; then # It's possible to get here because the above tests failed due to # autoconf freakiness. These tests are more portable. Look for random # with either a long or int return type, and try rand with an int. If # none of these show up, punt. AC_TRY_LINK([ extern "C" { long random(); } ], [ long x = random(); ], AC_DEFINE(HAVE_RANDOM) ac_cv_func_random="yes", AC_TRY_LINK([ extern "C" { int random(); } ], [ int x = random(); ], AC_DEFINE(HAVE_RANDOM) ac_cv_func_random="yes")) AC_TRY_LINK([ extern "C" { int rand(); } ], [ int x = rand(); ], AC_DEFINE(HAVE_RAND) ac_cv_func_random="yes") if test "$ac_cv_func_random" = "no" -a $ac_cv_func_rand = "no"; then AC_MSG_ERROR(requires either random or rand) fi fi if test "$ac_cv_func_random" = "yes" ; then AC_CACHE_CHECK(for location of random() declaration,tvf_cv_header_random_declared,[ if test "$ac_cv_header_stdc" = "yes" -o "x$ac_cv_header_stdlib_h" = "xyes"; then AC_EGREP_HEADER(srandom,stdlib.h,tvf_cv_header_random_declared="stdlib.h",tvf_cv_header_random_declared="none") else tvf_cv_header_random_declared="none" fi if test "$tvf_cv_header_random_declared" = "none"; then #check math.h AC_EGREP_HEADER(srandom,math.h,tvf_cv_header_random_declared="math.h",tvf_cv_header_random_declared="none") fi ] ) case "$tvf_cv_header_random_declared" in "stdlib.h" ) AC_DEFINE(RANDOM_DECLARED) ;; "math.h" ) AC_DEFINE(RANDOM_DECLARED) AC_DEFINE(RANDOM_IN_MATH) ;; esac else AC_CACHE_CHECK(for location of rand() declaration,tvf_cv_header_rand_declared,[ if test "$ac_cv_header_stdc" = "yes"; then AC_EGREP_HEADER(srand,stdlib.h,tvf_cv_header_rand_declared="stdlib.h",tvf_cv_header_rand_declared="none") else tvf_cv_header_rand_declared="none" fi if test "$tvf_cv_header_rand_declared" = "none"; then #check math.h AC_EGREP_HEADER(srand,math.h,tvf_cv_header_rand_declared="math.h",tvf_cv_header_rand_declared="none") fi ] ) case "$tvf_cv_header_rand_declared" in "stdlib.h" ) AC_DEFINE(RAND_DECLARED) ;; "math.h" ) AC_DEFINE(RAND_DECLARED) AC_DEFINE(RAND_IN_MATH) ;; esac fi ]) dnl see if optarg is defined in unistd.h and cache the result. dnl OPTARG_DEFINED is set if optarg is found. AC_DEFUN(TVF_DECL_OPTARG,[ if test "$ac_cv_header_unistd_h" = "yes" ; then AC_CACHE_CHECK(for optarg in unistd.h,tvf_cv_header_optarg, AC_EGREP_HEADER(optarg,unistd.h,tvf_cv_header_optarg="yes"; ,tvf_cv_header_optarg="no")) if test "$tvf_cv_header_optarg" = "yes"; then AC_DEFINE(OPTARG_DEFINED) fi fi ]) dnl see the sh comment AC_DEFUN(TVF_CREATE_DOT_DEPEND,[ AC_MSG_RESULT(creating default depend file) # Create an empty .depend that is older than Makefile # if touch will take a time, set the time explicitly, # if not wait a bit so that the created Makefile is newer if test "$MKDEP" = "cp" ; then cp default_depend .depend else cat < /dev/null > .depend touch -t 9912311000 .depend > /dev/null 2>&1 || sleep 1 fi ]) dnl get the OS version. Export it as OS_VERSION in an AC_SUBST AC_DEFUN(TVF_OS_VERSION,[ AC_CACHE_CHECK(for OS version,tvf_cv_os_version, tvf_cv_os_version=`uname -sr` ) OS_VERSION=$tvf_cv_os_version AC_SUBST(OS_VERSION) AC_DEFINE_UNQUOTED(OS_VERSION,"$OS_VERSION") ]) dnl determine if $MAKE uses .ifdef or ifdef . If one of these choices dnl works, the output variables MAKE_IFDEF, MAKE_IFNDEF, MAKE_ELSE, dnl and MAKE_ENDIF are set to appropriate values. If the routine dnl can't tell which ones to use, the output variables are defined as dnl comment characters. Can be onverriden with --enable-make-ifdef=. AC_DEFUN(TVF_MAKE_IFDEF, [ AC_ARG_ENABLE(make-ifdef, [ --enable-make-ifdef=X set the string format used for ifdef in Makefiles either .ifdef, ifdef or no ], [ AC_MSG_CHECKING([make ifdef directive]) tvf_cv_make_ifdef=$enableval AC_MSG_RESULT($tvf_cv_make_ifdef (arg)) ], AC_CACHE_CHECK([make ifdef directive],tvf_cv_make_ifdef, tvf_cv_make_ifdef="no" tvf_here=`pwd` cd /tmp mkdir make.$$ cd make.$$ cat > Makefile < /dev/null 2> /dev/null && \ test -e ./test ; then tvf_cv_make_ifdef="ifdef" else rm -f test cat > Makefile < /dev/null 2>/dev/null \ && test -e ./test ; then tvf_cv_make_ifdef=".ifdef" fi fi cd /tmp rm -rf make.$$ cd $tvf_here )) case $tvf_cv_make_ifdef in no) MAKE_IFDEF='# ifdef' MAKE_IFNDEF='# ifndef' MAKE_ELSE='# else' MAKE_ENDIF='# endif' ;; .ifdef) MAKE_IFDEF='.ifdef' MAKE_IFNDEF='.ifndef' MAKE_ELSE='.else' MAKE_ENDIF='.endif' ;; ifdef) MAKE_IFDEF='ifdef' MAKE_IFNDEF='ifndef' MAKE_ELSE='else' MAKE_ENDIF='endif' ;; esac AC_SUBST(MAKE_IFDEF) AC_SUBST(MAKE_IFNDEF) AC_SUBST(MAKE_ELSE) AC_SUBST(MAKE_ENDIF) ]) dnl determine if the -mdoc macros are available. Export them into MAN_MACROS. AC_DEFUN(TVF_MAN_MACROS,[ AC_CACHE_CHECK(for manpage macros, tvf_cv_man_macros,[ if troff -mdoc < /dev/null > /dev/null 2> /dev/null; then tvf_cv_man_macros=doc else tvf_cv_man_macros=an fi ]) MAN_MACROS=$tvf_cv_man_macros AC_SUBST(MAN_MACROS) ]) dnl test a 3-place version number. The first is the actual version, dnl the second the limit. The third is the program name AC_DEFUN(TVF_CHECK_VERSION_THREE,[ changequote(<<,>>) tvf_lim_major=`echo "$2" | sed 's/\..*//'` tvf_lim_minor=`echo "$2" | sed 's/[^\.]*\.\([^.]*\)\..*/\1/'` tvf_lim_three=`echo "$2" | sed 's/[^\.]*\.[^.]*\.\(.*\)/\1/'` tvf_act_major=`echo "$1" | sed 's/\..*//'` tvf_act_minor=`echo "$1" | sed 's/[^\.]*\.\([^.]*\)\..*/\1/'` tvf_act_three=`echo "$1" | sed 's/[^\.]*\.[^.]*\.\(.*\)/\1/'` changequote([,]) define([tvf_ok],ifelse("$3","",[true],$3)) define([tvf_bad],ifelse("$4","",[true],$4)) if test $tvf_act_major -lt $tvf_lim_major ; then tvf_bad else if test $tvf_act_major -eq $tvf_lim_major && \ test $tvf_act_minor -lt $tvf_lim_minor ; then tvf_bad else if test $tvf_act_major -eq $tvf_lim_major && \ test $tvf_act_minor -eq $tvf_lim_minor &&\ test $tvf_act_three -lt $tvf_lim_three; then tvf_bad else tvf_ok fi fi fi undefine([tvf_ok]) undefine([tvf_bad]) ]) grap-1.43/snprintf.h000660 004133 000000 00000014776 11076025241 014627 0ustar00faberwheel000000 000000 // -*-c++-*- #ifndef SNPRINTF_H #define SNPRINTF_H // This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT // for the full copyright and limitations of liabilities. #ifndef HAVE_SNPRINTF // Snprintf is only called with the following 11 signatures. Enumerating them // is ugly, but probably more portable than varargs. And very few systems have // no snprintf. It's concievable that someone could smash the stack here, but // there's not much privlege to gain, and I'd be impressed enough if you could // print a float that caused a stack overflow and error that you can break the // code. inline int snprintf(char *s, int lim, const char *fmt) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt); tot = lim; #else if ( (tot = sprintf(s,fmt)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d); tot = lim; #else if ( (tot = sprintf(s,fmt,d)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4, double d5) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4, d5); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4, d5)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4, double d5, double d6) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4, d5, d6); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4, d5, d6)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4, double d5, double d6, double d7) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7, d8); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7, d8)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7, d8, d9); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7, d8, d9)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } inline int snprintf(char *s, int lim, const char *fmt, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) { int tot; #ifdef SPRINTF_NOT_INT // For some reason some old versions of SunOS have an sprintf that // doesn't return an int. In this case, we can't bounds check at all. sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7, d8, d9, d10); tot = lim; #else if ( (tot = sprintf(s,fmt,d1, d2, d3, d4, d5, d6, d7, d8, d9, d10)) > lim ) { std::cerr << "Bad format to internal sprintf crashed the stack" << std::endl; abort(); } #endif return tot; } #endif #endif