rivet-3.3.1/doc/examples.rvt000664 001750 001751 00000006762 15245054302 016555 0ustar00manghimanghi000000 000000 Rivet examples
Rivet examples

These are some examples, rather limited ones, of what can be done with Rivet.

\n" for {set j 1} {$j <= 8} {incr j} { set num [ expr {$i * $j * 4 - 1} ] puts [ format "\n" $num $num $num ] } incr i puts "\n" } puts "

Hello world

<?
cookie "foo" "bar" # we have to put this before any 'puts' statements

puts "Hello world"
?>

Produces:


Conditionals:

<? if { 1 } { ?>

<h2> True </h2>

<? }  ?>

Produces:

True


Loops:

<? 
set x 0 
while { $x < 5 } { 
 puts "\$x = $x<br>"
 incr x
?>

LOOP<br>

<? }  ?>

Produces:

" incr x ?> LOOP


Variables (environmental as well as those passed to the script)


<? 
 hgetvars
if { [ array exists VARS ] } {
    puts "< ul>"
    foreach { vr } [ array names VARS ]  {
        puts "<li>(VARS) $vr = $VARS($vr)"
    }
    puts "</ul>"
}

if { [ array exists ENVS ] } {
    
    puts "<ul>"
    foreach { vr } [ array names ENVS ]  {
        puts "<li>(ENVS) $vr = $ENVS($vr)"
    }
    puts "</ul>"
}

if { [ array exists COOKIES ] } {
    
    puts "<ul>"
    foreach { vr } [ array names COOKIES ]  {
        puts "<li>(COOKIES) $vr = $COOKIES($vr)"
    }
    puts "</ul>"
}

?>

Produces:

" foreach { vr } [ array names VARS ] { puts "

  • (VARS) $vr = $VARS($vr)" } puts "" } if { [ array exists ENVS ] } { puts "
      " foreach { vr } [ array names ENVS ] { puts "
    • (ENVS) $vr = $ENVS($vr)" } puts "
    " } if { [ array exists COOKIES ] } { puts "
      " foreach { vr } [ array names COOKIES ] { puts "
    • (COOKIES) $vr = $COOKIES($vr)" } puts "
    " } ?>

  • Create a table on the fly

    
    <?
    set i 1
    puts "<table>\n"
    
    while { $i <= 8 } {
        puts "<tr>\n"
        for {set j 1} {$j <= 8} {incr j} {
    	set num [ expr $i * $j * 4 - 1]
    	puts [ format "<td bgcolor=%2x%2x%2x > $num $num $num </td>\n" $num $num $num ]
        }
        incr i
        puts "</tr>\n"
    }
    
    puts "</table>\n"
    ?>
    
    Produces:

    \n" while { $i <= 8 } { puts "

    $num $num $num
    \n" ?>


    In addition
    There are many, many other things you can do with Rivet. You can, if everything is compiled right, load tcl modules, like libpgtcl.so (the Postgresql interface), so that you can interact with a database!

    Return to the Rivet homepage

    rivet-3.3.1/doc/html/escape_sgml_chars.html000664 001750 001751 00000005255 15245054474 021504 0ustar00manghimanghi000000 000000 escape_sgml_chars

    Name

    escape_sgml_chars — escape special SGML characters in a string.

    Synopsis

    ::rivet::escape_sgml_chars ?string?

    Description

    Scans through each character in the specified string looking for any special (with respect to SGML, and hence HTML) characters from the specified string, and returns the result. For example, the right angle bracket is escaped to the corrected ampersand gt symbol.

    rivet-3.3.1/doc/html/entities.html000664 001750 001751 00000004555 15245054474 017670 0ustar00manghimanghi000000 000000 RivetEntities

    RivetEntities

    Introduction

    The RivetEntities package was kindly provided by Harald Oehlmann and is largely taken from a simple yet clever encoder/decoder of HTML entities starting from a utf-8 character string. The original code writted by Andy Goth is at http://wiki.tcl.tk/26403. Package entities extends the functionality in the original code combining it with Tcl's 'encoding' command to encode/decode from any supported encoding

    rivet-3.3.1/tests/access.conf000664 001750 001751 00000000000 15245054302 016662 0ustar00manghimanghi000000 000000 rivet-3.3.1/doc/xml/formbroker.xml000664 001750 001751 00000045362 15245054302 017673 0ustar00manghimanghi000000 000000
    The Form Broker
    Introduction The FormBroker package creates instances of form data description objects. These objects instances have a simple set of methods to validate and control data as typically posted by HTML forms, thus data represented as the map of form variables to their values. In Rivet this association can be obtained either calling ::rivet::load_response or ::rivet::var (form variables can be selectively read also calling ::rivet::var_post or ::rivet::var_qs) The FormBroker package is still experimental. Basic functionalities and interface are not likely to change but internal details and implementation could be redesigned in future releases. More specifically the external validator mechanism will likely need design improvements.
    FormBroker Form broker object creator ::FormBroker create ... Description The command returns a reference to a form broker object by creating a representation of the form data using the list of variable descriptors passed to method create. Each descriptor is a list of parameter or parameter-value pairs that must begin with the {variable_name variable_type} pair as only requirement. A formbroker object provide native support for integer, unsigned integer, string, boolean and email data types. The programmer can defined new data types and provide in the descriptor a reference to a validation procedure for that type. The optional -quoting quoting_procedure switch defines an external procedure to quote or reformat the response values. The quoting procedure is any procedure accepting a single string argument and returning its quoted value. A most basic example is the FormBroker default quoting procedure proc force_quote {str} { return "'$str'" } Other parameters of a descriptors are type: the data type of the variable bounds: limits of a variable value. The meanining of bounds depends on the variable type. For an integer is the maximum absolute value for that variable (for an unsigned the lower limit is invariably 0), for a string is the maximum length of the string. The parameter bounds has no effect on an email data type constrain: boolean value telling the variable has to be forced to fulfill the constrain imposed by bounds. This field is bidirectional in that it can be used by the validator to force the variable value rewriting validator: name of the specialized validator for this variable default: default value of the variable if not set in a response array. When a variable is given a default value the form validation will not fail on the fact that this variable may be missing from the form response array quote: the variable value has to be quoted when written back in the response array validator: name of the validator procedure. The procedure can be any Tcl procedure accepting as argument the name of a dictionary holding the variable internal representation. An example of a form accepting four variable, one for each native type of a form broker object % set fbroker [::FormBroker create {var1 integer} {var2 unsigned} {var3 string} {var4 integer bounds {-10 100}}] ::FormBroker::form0 Form broker object methods The central method of a form broker object is validate formBroker_object validate response response copy The method validate takes as argument the name of an array of variables in the way this is produced by command ::rivet::load_response returning a form response. The optional argument -forcequote causes the variable values to be rewritten and quoted. If the optional argument response copy is present the validated response is copied in this array instead of the input response array. If the form data have been validated the method validate returns true Example of form data validation (assuming ::rivet::load_response is loading the array response with data taken from a form non displayed here) % package require formbroker % set fbroker [::FormBroker create {var1 integer} {var2 unsigned} {var3 string} {var4 integer bounds {-10 100}}] ::FormBroker::form0 % ::rivet::load_response % parray response response(var1) = -10 response(var2) = 20 response(var3) = a string response(var4) = 50 # let's keep a copy of the response % array set response_copy [array get response] # form data validation % $fbroker validate response true % $fbroker validate -forcequote response % parray response response(var1) = '-10' response(var2) = '20' response(var3) = 'a string' response(var4) = '50' # restore response original value % array set response [array get response_copy] % $fbroker validate -forcequote response response_copy true % parray response response(var1) = -10 response(var2) = 20 response(var3) = a string response(var4) = 50 % parray response_copy response_copy(var1) = '-10' response_copy(var2) = '20' response_copy(var3) = 'a string' response_copy(var4) = '50' # a form object has to be destroyed if it's not needed anymore % $fbroker destroy formBroker_object failing In case the validation fails method failing returns a list of variable_name - error_condition pairs for each variable whose value failed to validate and was impossible to fix. This list is suitable to populate an array or used directly as a dictionary % package require formbroker 1.0 % set fbroker [::FormBroker create {var1 integer} \ {var2 unsigned} \ {var3 string} \ {var4 integer}] ::FormBroker::form0 % ::rivet::load_response # let's suppose we have an incomplete response % parray response response(var1) = '100' response(var2) = '20' response(var3) = 'a string' % $fbroker validate response false $fbroker failing var4 MISSING_VAR # this can be prevented by assigning a variable a default value % set fbroker [::FormBroker create {var1 integer} \ {var2 unsigned} \ {var3 string} \ {var4 integer default 0}] ::FormBroker::form1 % $fbroker validate response true % parray response response(var1) = 100 response(var2) = 20 response(var3) = a string response(var4) = 0 % set fbroker [::FormBroker create {var1 integer} \ {var2 unsigned} \ {var3 string length 10 constrain} \ {var4 integer bounds {-10 100}}] ::FormBroker::form2 % ::rivet::load_response # this time the response has invalid data % parray response response(var1) = 'aaaaa' response(var2) = '-20' response(var3) = 'a longer string that breaks the 10 chars max limit imposed' response(var4) = '150' % $fbroker validate response false % $fbroker failing var1 NOT_INTEGER var2 FB_OUT_OF_BOUNDS var4 FB_OUT_OF_BOUNDS Notice that even though $response(var3) exceeds the 10 characters max length imposed to variable var3 this variable is not in the list returned by failing because the 'constrain' attribute forced the truncation of the string. In fact this applies also to the integer and unsigned values % package require formbroker % set fbroker [::FormBroker create {var1 integer bounds 10 constrain} \ {var2 unsigned constrain} \ {var3 string length 10 constrain} \ {var4 integer bounds {-10 100} constrain}] ::FormBroker::form0 % ::rivet::load_response % parray response response(var1) = abcdef response(var2) = -20 response(var3) = a longer string that breaks the 10 chars max limit imposed response(var4) = 150 % $fbroker validate response response_copy false % $fbroker failing var1 NOT_INTEGER % parray response_copy response_copy(var2) = 0 response_copy(var3) = a longer s response_copy(var4) = 100 The variable var1 could not be constrained because the input value "abcdef" is fundamentally incompatible formBroker_object response The response method fills the array whose name is passed as optional argument with the last response processing. If this argument is omitted the method creates an array named response. This method can be called also if no form response validation has taken place: it simply populates the array with the default values assigned to the form variables. As such is a way to create form default arrays to initialize forms created with the form package. set fbroker [::FormBroker create {var1 integer default 0} \ {var2 unsigned default 1} \ {var3 string} \ {var4 integer default 0}] % $fbroker response a % parray a a(var1) = 0 a(var2) = 1 a(var4) = 0 formBroker_object reset The method resets the object to its initial defaults Validator Error codes Variable type validators returned specific code string: FB_EMPTY_STRING if the variable descriptor has the 'nonempty' flag set and the trimmed string is empty FB_STRING_TOO_LONG if the string length exceeds the max string length set with the maxlength option. This error is not returned if maxlength was not set integer: FB_OUT_OF_BOUNDS if bounds were assigned to the variable but it's value lies outside of them. This error is not returned if bounds were not set or the variable was defined with the flag constrain which forces its value to be the closest boundary value unsigned: FB_OUT_OF_BOUNDS the variable value is either negative or outside the bounds assigned to the variable descriptor. The error is not returned if the variable was defined with the flag constrain which forces its value to be the closest boundary value or set to zero if the value was negative email: FB_INVALID_EMAIL the variable is an invalid email address representation Writing a custom variable validator The form broker is by no means restricted to work only with its native data types: you may define your own form variable types and have them validated with their own variable validator. A validator is a function accepting a dictionary as single argument and must return either FB_OK, if the variable value is valid, or any other used defined error code. The dictionary argument stores the variable descriptor used internally by the form broker. Suppose you're writing a form text entry that demands as input a network interface MAC address. A MAC address is represented by 6 hexadecimal octets separated by either a - (Windows convention) or : (Unix, Mac convention). The procedure validate_mac checks the validity of the mac address and if validation is successful it transforms its representation into the Unix form. By setting the key constrain in the dictionary mac_address_d the procedure is telling the form broker to copy the transformed value back in the input response array proc validate_mac {_mac_address_d} { upvar $_mac_address_d mac_address_d dict with mac_address_d { set var [string trim $var] if {[regexp {^[[:xdigit:]]{2}([:-][[:xdigit:]]{2}){5}$} $var]} { set var [string tolower $var] # we normalize the mac address to the Unix form. # The dash '-' characters in the windows representation # are replaced by columns ':' set var [regsub -all -- {-} $var :] # the 'constrain' field is bidirectional: # it tells the validator to curb/change the value # within bonds/forms/representation. By setting it the # validator tells the FormBroker to copy the value # back in the response array set constrain 1 return FB_OK } else { return FB_WRONG_MAC } } } % set fbroker [::FormBroker create {mac mac_address validator validate_mac}] % ::rivet::load_response r % parray r r(mac) = 00-A1-B2-C3-D4-C5 % $fbroker validate r true % parray r r(mac) = 00:a1:b2:c3:d4:c5
    rivet-3.3.1/doc/html/load_env.html000664 001750 001751 00000005431 15245054474 017625 0ustar00manghimanghi000000 000000 load_env

    Name

    load_env — get the request's environment variables.

    Synopsis

    ::rivet::load_env ?array_name?

    Description

    Load the array of environment variables into the specified array name. Uses array ::request::env by default.

    As Rivet pages are run in the ::request namespace, it isn't necessary to qualify the array name for most uses - it's ok to access it as env.

    rivet-3.3.1/doc/images/table.png000664 001750 001751 00000006430 15245054302 017234 0ustar00manghimanghi000000 000000 ‰PNG  IHDR,ž4�b ßIDATxœí�AkcGÇÿZò ð‚²ñ‚÷æ½)à š9yo^Pë“c¼÷‰`�÷¦Ñm-8¹¯Qæä=ݾeNá1Ä·øÃ� ‚ ÄŸA{è~ê÷^·ž«ë•,͸~`ZþרI袺^¿rue E¡ñ»yÿ(ê, u…Œ:‹BF�E!£Î¢�QgQÈ|â>V_/ü·¦Lõ©ÔT¿á÷RSýŠÏ¤¦úËRS½s5²(dÔY2ŸÜÿO>ZîªpTc”ï�%7P• # Œ FW‚ �: ë1J�×YîìPM<‚¤y¿¼_JªdTF5Ô`��¦Ö�aÃ8¥ˆÇ» U½Õ§(A–2U â"ŨFW‚ØXQ¯G)E<ÞÈ"‹‰ïSÎ@Q‚ø@QB ‘wŠ2�Gï,Õ;Ž’Çî,Kn‹¡(A¬Œ¼øQ¨©{©E™Î£wT'©IŒ’Å_~ŠD.®ÈóxsA’6N "è+~ÖJQŠxôÎâG Š2s2À<úm¨ê�¡P”ï,a){ªr¯d„üá E Q"—¼R”"*®wÑßòè»!:únH™3ê, u…LEÿnH¡¢‘E!3§J9Îį’þ¥¦ú’šê'|.5Õ�x*5Õ÷Q#‹BF�E!3¿\^u™`õ×5°æª2…«uà ÖcŸKh$U 3šn *ÌÍYxÕe‚Õ_×kÀõZ2P•)L|à*F ÑÈ T%Ä  šÉ@UŠ˜Û6Ä«.¬þòŸ¢„¹Zç|xš^Ä (Ó˜ç‹DVu™`õ×µç eÆ\šˆqéE 30^0pÎ@Q¦3GgáU— V­áz kבJÁÀÒpÙHªÆî/hN¶ŠRÀ\¹ê²R¬×ñJù)ÊìñWŸ¢0·œ…W]&Xýå¯>E ruu•ËZ)J�ËÌ@Uа” �¾øÉÊ¡(Öa#Ç$|P”�¹ž³ÄW— V­™Ã“5w†BQfMÃd­ —¼R” MsxÒtg(¥ˆ9UÊ黡únHùxPgQȨ³(d´RN!£‘E!SºRŽ÷\óÆ·þ'ùÜñ…ÔToñg©©~À—RS}�¯¤¦úÎ}ÔÈ¢�QgQÈHœàòjÞn€UàVéŠ\MÚlÀ] ò6¼ÞŒPœ-7P• ¯€àìЕœ…Wóv³j~&N@R$kÒÌò_l˜ªbÀkët%ÈI 8i%U òjÇüìD)ElC¼š·´Е…­I{½ lnÆ*Sñ}€¢Ì™‰¬š·¬"ÙièŠþÞBQfL+Ù[Ng (…¼òE !â,¼š·Uܬ_X%+‚�eÀÅ6.¢”)ø‰E 0Ù[Z¹M§P ²óÊ 0; Q)B$Á}°š·YÔ¤mØ<6NùH2×8¥�œ…Wóv“¨Š`Mš¿úå�8a)A|_ (A>¬s–õõõud+ÐJ!">#¶ I"è%¡s–øš·U“µ®ºä•¢²a’× —ÃR”Yc“×–;C¡(AvLÖºã’WŠRDéJ9}7¤ï†ÅC�E!£Î¢�ÑJ9…ŒF…LéJ¹eÆ·Þ±žk~’ü[˜¿HMõ_É环¥¦ú/¤¦JM¤‘E!£Î¢�‘8ÁåöyãÔ¼ÉõI;€-àØ¢+a$kÒ¾}x†nº@è@‡m â,Ü>oœš7Á>i[N�Ó-óCT‚Ö¤}x†®:@·ƒNJ‰6X¶!+bû¼±KSšb}Ò| (3åùóÀÀ3tLTp±¡Ûá,"ÅOÒ·|!Ý'M¹š4YrkÎ6ˆ8 §Ï3°HöI;ݰu©�¯IÅ®¼ï±†y5óáÖ¼ù«OQŠØ²ylœ’E¼&M©¸"’³ðú¼•ªyì“&ˆ|µ‘r¾2·s–Ô¼ÅbRWoϹG ±˜^’CÀi¶!ù[>§#ß'mË;C¡(YäkÒ$é"w\Â6”®”[f|Kß ÑwCÊǃ:‹BF�E!£•r �, ™Ô£ó§Œ¯ÿÆjUý3ëÏvÞJ>ÂüMjªãRSýÿ’šêïé?÷)ÇWî£F…Œ:‹B&w‚{W€; ¡°®1åµt“,o;öÜ@U¼¶�qœR¢ Ïìp<;K~ã,™mˆw�*»;œð�¥‘–·¦£„‹Ãñ±û ÃY&.¤~‹7Xò/Y÷¨><‹Ú½ÍÐN/?Ó°�ãà¿dÄÈ9 çÕ2�%ËýÊ̺·I”·%iÝG¦ÛÇ&Blç Úpæo'\C.ÁeÜ£:‹Q§3³îmåËÛÚS¢ÀéA"Þp†@úÁ2drÞ=ª‚7¢RY̾\ívíTòZ°˜”¯îŸ4}s½à óÆR_¡(^«’¢ ‡˜+â ¼Í&Þ�þ-aðÎYâïQ}HfÖ½M¢¼ÍrØF8��0oOÙWâ gÉ©IyCê­³¾â ï†%€:‹BF�E!£•r �, ™Ô£ógŒ¯ÿ‚Ïßú_2¾õ½djÁ¿Ð|„y+5Õx'5Õ²û¨‘E!£Î¢�ÉžàŽ€0€Y¹€F2Pœ-7PÉËI»· –·=9€'À9ðι†àÖxCÆYF5`TC ÖhJ²ú 7A9i'­d *‚—“ vo,o{b‡só“øǰr ¬ÜæžÁ’Ù†j“O£])E+N¼œT°{›`yÛ¹[ì,ñ†ÛÐÀ3Xòo�}¸_¹4ãÒ‚ÒJö–“Ä(Ê,�ëÞ&_Þö$*â ©ˆ¬¤–?ÞxÎbý`äÅ�¥಑ Te²·´r›N¡2 ĺ· –·�›ÍåIFÂ2dV·nS‰7ð\F\ùH�èÞ&XÞv>IFø†ìÊ—229 ÏW.3U±œ°A;qÉv ¢!»ò+e –à9Ë# 0’>#PÞVÊKf†w΂Z¬Ò0YkÃ%¯Å&¯-w†BQäìÞ&XÞvnòÔs/��1¬¸M†ÛìqJ¤Á�zë¬ï†8è»!E  Î¢�QgQÈh¥œBF#‹B&õè¼Ìøú»ôŸ•�yÃú  ïð‚ñ­ /$P¿‘šêéLaÑÈ¢�QgQÈdOp‡@†õe4Ý@U˜Ýáºè  ¶AðrR¹îm‚åm` T`œ Lƒ!ã,Ã:0¬c§ šÀ ™ T…×®k‡Ðí “R¢ »vJ³à¥.'ìÞ&XÞV›»ÞnÙã –Ì6dcE½¥@ÓEŒ%žŽ‰ �‰Ðíp ‚—“ vo» <ƒ·Ö|ƒ%Wü4Lœ!J/8g (nw¸dÍ=b »±w�N7È XÞV#Ù[’�kdecode

    Name

    decode — decode an SGML encoded string replacing every entity with the corresponding character

    Synopsis

    ::rivet::decode string ?-encoding <encoding>?

    Description

    ::rivet::decode implements the inverse function of ::rivet::encode. The input string is scanned searching and replacing every SGML entity with its corresponding character. By default the command assumes the output string has to be encoded in UTF-8. Other encodings are supported by passing the -encoding <encoding> argument.

    rivet-3.3.1/rivet/packages/session/session-purge-mysql.sql000664 001750 001751 00000001622 15245054302 024504 0ustar00manghimanghi000000 000000 -- -- Note for Mysql 4.x and 5.0 users -- -- Though Mysql<5.1 supports the specification 'ON CASCADE DELETE' for CREATE TABLE -- this is only for sql code portability: deleting a row in rivet_session doesn't -- imply Mysql remove the rows in rivet_session_cache matching the same session_id. -- This table gets progressively cluttered with rows referring to sessions that are long dead. -- This command can be used to clean up 'rivet_session_cache' delete rivet_session_cache from rivet_session_cache left join rivet_session as t2 using(session_id) where t2.session_id is null; -- You may subclass 'Session' in order to specialize the method do_garbage_collection and -- exec this command after the superclass method has run. -- Starting with version 5.1 the 'on delete cascade' should be working (but I haven't tried) -- and also triggers can be used to achive the same goal -- 2 Oct 2006 rivet-3.3.1/rivet/packages/entities/entities.tcl000664 001750 001751 00000017440 15245054302 022513 0ustar00manghimanghi000000 000000 # -- package RivetEntities # # The code is largely taken from a simple yet clever encoder/decoder of HTML entities # starting from a utf-8 character string. The original code writted by Andy Goth is # at http://wiki.tcl.tk/26403. Package entities extends the functionality in the # original code combining it with Tcl's 'encoding' command to encode/decode from # any supported encoding # package provide RivetEntities 1.0.1 namespace eval ::rivet { # namespace ensemble create -subcommands {encode decode} namespace export encode decode variable utf8_entities_map { \u00a0  \; \u00a1 ¡\; \u00a2 ¢\; \u00a3 £\; \u00a4 ¤\; \u00a5 ¥\; \u00a6 ¦\; \u00a7 §\; \u00a8 ¨\; \u00a9 ©\; \u00aa ª\; \u00ab «\; \u00ac ¬\; \u00ad ­\; \u00ae ®\; \u00af ¯\; \u00b0 °\; \u00b1 ±\; \u00b2 ²\; \u00b3 ³\; \u00b4 ´\; \u00b5 µ\; \u00b6 ¶\; \u00b7 ·\; \u00b8 ¸\; \u00b9 ¹\; \u00ba º\; \u00bb »\; \u00bc ¼\; \u00bd ½\; \u00be ¾\; \u00bf ¿\; \u00c0 À\; \u00c1 Á\; \u00c2 Â\; \u00c3 Ã\; \u00c4 Ä\; \u00c5 Å\; \u00c6 Æ\; \u00c7 Ç\; \u00c8 È\; \u00c9 É\; \u00ca Ê\; \u00cb Ë\; \u00cc Ì\; \u00cd Í\; \u00ce Î\; \u00cf Ï\; \u00d0 Ð\; \u00d1 Ñ\; \u00d2 Ò\; \u00d3 Ó\; \u00d4 Ô\; \u00d5 Õ\; \u00d6 Ö\; \u00d7 ×\; \u00d8 Ø\; \u00d9 Ù\; \u00da Ú\; \u00db Û\; \u00dc Ü\; \u00dd Ý\; \u00de Þ\; \u00df ß\; \u00e0 à\; \u00e1 á\; \u00e2 â\; \u00e3 ã\; \u00e4 ä\; \u00e5 å\; \u00e6 æ\; \u00e7 ç\; \u00e8 è\; \u00e9 é\; \u00ea ê\; \u00eb ë\; \u00ec ì\; \u00ed í\; \u00ee î\; \u00ef ï\; \u00f0 ð\; \u00f1 ñ\; \u00f2 ò\; \u00f3 ó\; \u00f4 ô\; \u00f5 õ\; \u00f6 ö\; \u00f7 ÷\; \u00f8 ø\; \u00f9 ù\; \u00fa ú\; \u00fb û\; \u00fc ü\; \u00fd ý\; \u00fe þ\; \u00ff ÿ\; \u0192 &fnof\; \u0391 &Alpha\; \u0392 &Beta\; \u0393 &Gamma\; \u0394 &Delta\; \u0395 &Epsilon\; \u0396 &Zeta\; \u0397 &Eta\; \u0398 &Theta\; \u0399 &Iota\; \u039a &Kappa\; \u039b &Lambda\; \u039c &Mu\; \u039d &Nu\; \u039e &Xi\; \u039f &Omicron\; \u03a0 &Pi\; \u03a1 &Rho\; \u03a3 &Sigma\; \u03a4 &Tau\; \u03a5 &Upsilon\; \u03a6 &Phi\; \u03a7 &Chi\; \u03a8 &Psi\; \u03a9 &Omega\; \u03b1 &alpha\; \u03b2 &beta\; \u03b3 &gamma\; \u03b4 &delta\; \u03b5 &epsilon\; \u03b6 &zeta\; \u03b7 &eta\; \u03b8 &theta\; \u03b9 &iota\; \u03ba &kappa\; \u03bb &lambda\; \u03bc &mu\; \u03bd &nu\; \u03be &xi\; \u03bf &omicron\; \u03c0 &pi\; \u03c1 &rho\; \u03c2 &sigmaf\; \u03c3 &sigma\; \u03c4 &tau\; \u03c5 &upsilon\; \u03c6 &phi\; \u03c7 &chi\; \u03c8 &psi\; \u03c9 &omega\; \u03d1 &thetasym\; \u03d2 &upsih\; \u03d6 &piv\; \u2022 &bull\; \u2026 &hellip\; \u2032 &prime\; \u2033 &Prime\; \u203e &oline\; \u2044 &frasl\; \u2118 &weierp\; \u2111 &image\; \u211c &real\; \u2122 &trade\; \u2135 &alefsym\; \u2190 &larr\; \u2191 &uarr\; \u2192 &rarr\; \u2193 &darr\; \u2194 &harr\; \u21b5 &crarr\; \u21d0 &lArr\; \u21d1 &uArr\; \u21d2 &rArr\; \u21d3 &dArr\; \u21d4 &hArr\; \u2200 &forall\; \u2202 &part\; \u2203 &exist\; \u2205 &empty\; \u2207 &nabla\; \u2208 &isin\; \u2209 ¬in\; \u220b &ni\; \u220f &prod\; \u2211 &sum\; \u2212 &minus\; \u2217 &lowast\; \u221a &radic\; \u221d &prop\; \u221e &infin\; \u2220 &ang\; \u2227 &and\; \u2228 &or\; \u2229 &cap\; \u222a &cup\; \u222b &int\; \u2234 &there4\; \u223c &sim\; \u2245 &cong\; \u2248 &asymp\; \u2260 &ne\; \u2261 &equiv\; \u2264 &le\; \u2265 &ge\; \u2282 &sub\; \u2283 &sup\; \u2284 &nsub\; \u2286 &sube\; \u2287 &supe\; \u2295 &oplus\; \u2297 &otimes\; \u22a5 &perp\; \u22c5 &sdot\; \u2308 &lceil\; \u2309 &rceil\; \u230a &lfloor\; \u230b &rfloor\; \u2329 &lang\; \u232a &rang\; \u25ca &loz\; \u2660 &spades\; \u2663 &clubs\; \u2665 &hearts\; \u2666 &diams\; \u0022 "\; \u0026 &\; \u003c <\; \u003e >\; \u0152 &OElig\; \u0153 &oelig\; \u0160 &Scaron\; \u0161 &scaron\; \u0178 &Yuml\; \u02c6 &circ\; \u02dc &tilde\; \u2002 &ensp\; \u2003 &emsp\; \u2009 &thinsp\; \u200c &zwnj\; \u200d &zwj\; \u200e &lrm\; \u200f &rlm\; \u2013 &ndash\; \u2014 &mdash\; \u2018 &lsquo\; \u2019 &rsquo\; \u201a &sbquo\; \u201c &ldquo\; \u201d &rdquo\; \u201e &bdquo\; \u2020 &dagger\; \u2021 &Dagger\; \u2030 &permil\; \u2039 &lsaquo\; \u203a &rsaquo\; \u20ac &euro\; } variable entitities_utf8_map [lreverse $utf8_entities_map] proc args_processing {string mode arglist} { if {[dict exists $arglist -encoding] && [dict get $arglist -encoding] ne "utf-8"} { return [encoding $mode [dict get $arglist -encoding] $string] } else { return $string } } # -- encode # # input string is processed and its characters suitable to be transformed # into entities are replaced with their corrisponding HTML (SGML?) entity # # if the input string encoding is diffrent from utf-8 the string is # transformed into utf-8 and then processed for entity substitution # # ::rivet::encode ?-encoding ? # # Arguments: # # * : string whose characted must go through HTML # entities expansion # * : input string character encoding (utf-8 when omitted) # # Returned value: # # - expanded string # # proc encode {string args} { variable utf8_entities_map return [string map $utf8_entities_map [args_processing $string convertfrom $args]] } # -- decode # # input string is converted into utf-8 and in case the final string # has to be in some other encoding Tcl's command 'enconding' is # invoked for final conversion # # ::rivet::decode ?-encoding ? # # Arguments: # # * : string whose HTML entities have to be reconverted # in characters # * : output string character encoding (utf-8 when omitted) # # Returned value: # # - converted string # proc decode {string args} { variable entitities_utf8_map return [args_processing [string map $entitities_utf8_map $string] convertto $args] } } rivet-3.3.1/doc/html/shorthand.html000664 001750 001751 00000006155 15245054474 020034 0ustar00manghimanghi000000 000000 <?= ... ?>

    Name

    <?= ... ?> — Shorthand construct for single strings output

    Synopsis

    <?= $string ?>

    Description

    This construct is a simplified form to print a single string wherever needed in a ?.rvt? template. The contruct is equivalent to writing the following line of Tcl code

    puts -nonewline $string

    The ?string? argument to the shorthand construct can be any Tcl command returning a value

    See Example 1, “Hello World� or Example 3, “Variable Access�

    rivet-3.3.1/src/librivet/rivetPkgInit.c000664 001750 001751 00000007170 15245054302 020621 0ustar00manghimanghi000000 000000 /* * rivetPkgInit.c - Initialize all of the Rivet commands into a Tcl interp. */ /* Copyright 2002-2004 The Apache Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Rivet config */ #ifdef HAVE_CONFIG_H #include #endif #include /* Function prototypes are defined with EXTERN. Since we are in the same DLL, * no need to keep this extern... */ #ifdef EXTERN # undef EXTERN # define EXTERN #endif /* EXTERN */ #include "rivet.h" //#include "mod_rivet.h" /*----------------------------------------------------------------------------- * Rivet_GetNamespace -- * * Get the rivet namespace pointer. The procedure attempts to retrieve a * pointer to the Tcl_Namespace structure for the ::rivet namespace. This * pointer is stored in the interpreter's associated data (pointing to a * rivet_interp_globals structure) if the interpreter is passed by mod_rivet. * Otherwise a new ::rivet namespace is created and its Tcl_Namespace * pointer is returned * * Parameters: * * o interp - Interpreter to add commands to. * * Returned value: * * o rivet_ns - Tcl_Namespace* pointer to the RIVET_NS (::rivet) namespace * *----------------------------------------------------------------------------- */ #if RIVET_NAMESPACE_EXPORT == 1 Tcl_Namespace* Rivet_GetNamespace( Tcl_Interp* interp) { Tcl_Namespace *rivet_ns; rivet_ns = Tcl_FindNamespace(interp,RIVET_NS,NULL,TCL_GLOBAL_ONLY); if (rivet_ns == NULL) { rivet_ns = Tcl_CreateNamespace (interp,RIVET_NS,NULL, (Tcl_NamespaceDeleteProc *)NULL); } return rivet_ns; } #endif /*----------------------------------------------------------------------------- * Rivetlib_Init -- * * Install the commands provided by librivet into an interpreter. * * Parameters: * * o interp - Interpreter to add commands to. * *----------------------------------------------------------------------------- */ DLLEXPORT int Rivetlib_Init( Tcl_Interp *interp ) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) { #else if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) { #endif return TCL_ERROR; } Rivet_InitList (interp); Rivet_InitCrypt(interp); Rivet_InitWWW (interp); return Tcl_PkgProvide( interp, RIVETLIB_TCL_PACKAGE, RIVET_VERSION ); } /*----------------------------------------------------------------------------- * Rivetlib_SafeInit -- * * Install the commands provided by librivet that are believed to be * safe for use in safe interpreters, into a safe interpreter. * * Parameters: * * o interp - Interpreter to add commands to. * *----------------------------------------------------------------------------- */ DLLEXPORT int Rivetlib_SafeInit( Tcl_Interp *interp ) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) { #else if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) { #endif return TCL_ERROR; } Rivet_InitList(interp); Rivet_InitCrypt(interp); Rivet_InitWWW(interp); return Tcl_PkgProvide( interp, RIVETLIB_TCL_PACKAGE, RIVET_VERSION ); } rivet-3.3.1/tests/failtest.test000664 001750 001751 00000001605 15245054302 017302 0ustar00manghimanghi000000 000000 # This test is for those commands that must not run outside of a request processing # and return an error if called outside of that context (child process/thread initialization or # termination). Command ::rivet::inspect can be called various forms and depending # on its arguments ::tcltest::test failtest-1.1 {commands that must refuse to run in child init or exit} { apachetest::start { -c "RivetServerConf ChildInitScript \" source checkfails.tcl \"" } {} { catch { set inspect_page [::http::geturl "${urlbase}failtest.tcl"] set match [::http::data $inspect_page] ::http::cleanup $inspect_page } } set match } {apache_table->1 env->1 headers->1 include->1 inspect0->1 inspect1->0 inspect2->1 inspect3->0 inspect4->0 load_env->1 load_headers->1 makeurl->1 no_body->1 parse->1 raw_post->1 var->1 virtual_filename->1 } rivet-3.3.1/src/mod_rivet_ng/worker_prefork_common.c000664 001750 001751 00000031446 15245054302 023452 0ustar00manghimanghi000000 000000 /* worker_prefork_common.c: function common to both the prefork and worker bridges */ /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include #include #include #include "mod_rivet.h" /* Function prototypes are defined with EXTERN. Since we are in the same DLL, * no need to keep this extern... */ #ifdef EXTERN # undef EXTERN # define EXTERN #endif /* EXTERN */ #include "mod_rivet_common.h" #include "mod_rivet_cache.h" #include "worker_prefork_common.h" extern DLLIMPORT mod_rivet_globals* module_globals; extern DLLIMPORT apr_threadkey_t* rivet_thread_key; extern DLLIMPORT module rivet_module; extern rivet_thread_interp* MPM_MasterInterp(server_rec* s); /* * Rivet_DuplicateVhostInterp * * */ static rivet_thread_interp* Rivet_DuplicateVHostInterp(apr_pool_t* pool, rivet_thread_interp* source_obj) { rivet_thread_interp* interp_obj = apr_pcalloc(pool,sizeof(rivet_thread_interp)); interp_obj->interp = source_obj->interp; interp_obj->channel = source_obj->channel; interp_obj->cache_free = source_obj->cache_free; interp_obj->cache_size = source_obj->cache_size; /* An intepreter must have its own cache */ if (interp_obj->cache_size) { RivetCache_Create(pool,interp_obj); } interp_obj->pool = source_obj->pool; interp_obj->scripts = (running_scripts *) apr_pcalloc(pool,sizeof(running_scripts)); interp_obj->per_dir_scripts = apr_hash_make(pool); interp_obj->flags = source_obj->flags; return interp_obj; } /* -- Rivet_RunChildScripts * * */ void Rivet_RunChildScripts (rivet_thread_private* private,bool init) { server_rec* vhost_server; server_rec* root_server; rivet_server_conf* root_server_conf; void* parentfunction; /* this is topmost initialization script */ void* function; root_server = module_globals->server; root_server_conf = RIVET_SERVER_CONF (root_server->module_config); parentfunction = (init ? root_server_conf->rivet_child_init_script : root_server_conf->rivet_child_exit_script); for (vhost_server = root_server; vhost_server != NULL; vhost_server = vhost_server->next) { rivet_thread_interp* rivet_interp; rivet_server_conf* myrsc; rivet_interp_globals* globals = NULL; myrsc = RIVET_SERVER_CONF(vhost_server->module_config); rivet_interp = RIVET_PEEK_INTERP(private,myrsc); function = (init ? myrsc->rivet_child_init_script : myrsc->rivet_child_exit_script); if (function && (vhost_server == root_server || module_globals->separate_virtual_interps || function != parentfunction)) { char* errmsg = MODNAME ": Error in Child init script: %s"; Tcl_Obj* tcl_script_obj = Tcl_NewStringObj(function,-1); Tcl_IncrRefCount(tcl_script_obj); Tcl_Preserve (rivet_interp->interp); /* before we run a script we have to store the pointer to the * running configuration in the thread private data. The design has * to improve and running a script must have everything sanely * prepared TODO */ globals = Tcl_GetAssocData(rivet_interp->interp, "rivet", NULL); /* * The current server record is stored to enable ::rivet::apache_log_error and * other commands to log error messages in the virtual host's designated log file */ globals->server = vhost_server; private->running_conf = myrsc; if (Tcl_EvalObjEx(rivet_interp->interp,tcl_script_obj,0) != TCL_OK) { ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,vhost_server,errmsg, function); ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,vhost_server, "errorCode: %s", Tcl_GetVar(rivet_interp->interp,"errorCode",0)); ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,vhost_server, "errorInfo: %s", Tcl_GetVar(rivet_interp->interp,"errorInfo",0)); } Tcl_Release (rivet_interp->interp); Tcl_DecrRefCount(tcl_script_obj); } } } /* -- Rivet_VirtualHostsInterps * * The server_rec chain is walked through and server configurations are read to * set up the thread private configuration and interpreters database * * Arguments: * * rivet_thread_private* private; * * Returned value: * * a new rivet_thread_private object * * Side effects: * * GlobalInitScript and ChildInitScript are run at this stage * */ rivet_thread_private* Rivet_VirtualHostsInterps (rivet_thread_private* private) { server_rec* vhost_server; server_rec* root_server = module_globals->server; rivet_server_conf* root_server_conf; rivet_server_conf* myrsc; rivet_thread_interp* root_interp; root_server_conf = RIVET_SERVER_CONF (root_server->module_config); root_interp = MPM_MasterInterp(module_globals->server); /* we must assume the module was able to create the root interprter */ ap_assert (root_interp != NULL); /* The inherited interpreter has an empty cache since * evalutating a server_init_script does not require * parsing templates that need to be stored in it. * We need to create it */ if (root_server_conf->default_cache_size > 0) { root_interp->cache_size = root_server_conf->default_cache_size; } else if (root_server_conf->default_cache_size < 0) { root_interp->cache_size = RivetCache_DefaultSize(); } RivetCache_Create(root_interp->pool,root_interp); /* Using the root interpreter we evaluate the global initialization script, if any */ if (root_server_conf->rivet_global_init_script != NULL) { Tcl_Obj* global_tcl_script; global_tcl_script = Tcl_NewStringObj(root_server_conf->rivet_global_init_script,-1); Tcl_IncrRefCount(global_tcl_script); if (Tcl_EvalObjEx(root_interp->interp, global_tcl_script, 0) != TCL_OK) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, module_globals->server, MODNAME ": Error running GlobalInitScript '%s': %s", root_server_conf->rivet_global_init_script, Tcl_GetVar(root_interp->interp, "errorInfo", 0)); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, MODNAME ": GlobalInitScript '%s' successful", root_server_conf->rivet_global_init_script); } Tcl_DecrRefCount(global_tcl_script); } /* then we proceed assigning/creating the interpreters for each virtual host */ // parentfunction = root_server_conf->rivet_child_init_script; for (vhost_server = root_server; vhost_server != NULL; vhost_server = vhost_server->next) { rivet_thread_interp* rivet_interp; myrsc = RIVET_SERVER_CONF(vhost_server->module_config); /* by default we assign the root_interpreter as * interpreter of the virtual host. In case of separate * virtual interpreters we create new ones for each * virtual host */ rivet_interp = root_interp; if (vhost_server == root_server) { Tcl_RegisterChannel(rivet_interp->interp,*rivet_interp->channel); } else { if (module_globals->separate_virtual_interps) { rivet_interp = Rivet_NewVHostInterp(private->pool,myrsc->default_cache_size); if (module_globals->separate_channels) { rivet_interp->channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key); Tcl_RegisterChannel(rivet_interp->interp,*rivet_interp->channel); } else { rivet_interp->channel = private->channel; } } else { rivet_interp = Rivet_DuplicateVHostInterp(private->pool,root_interp); } } /* interpreter base running scripts definition and initialization */ rivet_interp->scripts = Rivet_RunningScripts (private->pool,rivet_interp->scripts,myrsc); RIVET_POKE_INTERP(private,myrsc,rivet_interp); /* Basic Rivet packages and libraries are loaded here */ if ((rivet_interp->flags & RIVET_INTERP_INITIALIZED) == 0) { Rivet_PerInterpInit(rivet_interp,private,vhost_server,private->pool); } /* It seems that allocating from a shared APR memory pool is not thread safe, * but it's not very well documented actually. In any case we protect this * memory allocation with a mutex */ /* this stuff must be allocated from the module global pool which * has the child process' same lifespan */ apr_thread_mutex_lock(module_globals->pool_mutex); myrsc->server_name = (char*) apr_pstrdup (private->pool,vhost_server->server_hostname); apr_thread_mutex_unlock(module_globals->pool_mutex); } /* the child init scripts get evaluated */ Rivet_RunChildScripts(private,true); return private; } /* * -- Rivet_ProcessorCleanup * * Thread private data cleanup. This function was meant to be * called by the worker and prefork MPM bridges to release resources * owned by thread private data and pointed in the array of rivet_thread_interp * objects. It has to be called just before an agent, either thread or * process, exits. We aren't calling this function anymore as we rely entirely * on the child process termination * * Arguments: * * data: pointer to a rivet_thread_private data structure. * * Returned value: * * none * * Side effects: * * resources stored in the array of rivet_thread_interp objects are released * and interpreters are deleted. * */ void Rivet_ProcessorCleanup (void *data) { int i; rivet_thread_private* private = (rivet_thread_private *) data; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, "Thread exiting after %d requests served (%d vhosts)", private->req_cnt,module_globals->vhosts_count); /* We are about to delete the interpreters and release the thread channel. * Rivet channel is set as stdout channel of Tcl and as such is treated * by Tcl_UnregisterChannel is a special way. When its refCount reaches 1 * the channel is released immediately by forcing the refCount to 0 * (see Tcl source code: generic/TclIO.c). Unregistering for each interpreter * causes the process to segfault at least for certain Tcl versions. * We unset the channel as stdout to avoid this */ Tcl_SetStdChannel(NULL,TCL_STDOUT); /* there must be always a root interpreter in the slot 0 of private->interps, * so we always need to run this cycle at least once */ i = 0; do { RivetCache_Cleanup(private,private->ext->interps[i]); if ((i > 0) && module_globals->separate_channels) Rivet_ReleaseRivetChannel(private->ext->interps[i]->interp,private->channel); /* if separate_virtual_interps == 0 we are running * the same interpreter instance for each vhost, * thus we need to delete only the first occurrence of * the interpreter but we need to release the scripts * stored in Tcl_Obj instances */ if ((i == 0) || module_globals->separate_virtual_interps) { Tcl_DeleteInterp(private->ext->interps[i]->interp); } /* Release interpreter scripts */ Rivet_ReleaseRunningScripts(private->ext->interps[i]->scripts); /* Release scripts defined within conf blocks */ Rivet_ReleasePerDirScripts(private->ext->interps[i]); } while (++i < module_globals->vhosts_count); } rivet-3.3.1/tests/binary.rvt000664 001750 001751 00000000704 15245054302 016606 0ustar00manghimanghi000000 000000 rivet-3.3.1/tests/tclfile.test000664 001750 001751 00000000332 15245054302 017105 0ustar00manghimanghi000000 000000 # $Id$ ::tcltest::test tclfile-1.1 {Plain .tcl file} { set page [ ::http::geturl "${urlbase}tclfile.tcl" ] set pgdata [string trim [ ::http::data $page ] ] } "¡ À È Ì Ò Ù - El Burro Sabe Más Que Tú!" rivet-3.3.1/doc/html/directives.html000664 001750 001751 00000103652 15245054474 020203 0ustar00manghimanghi000000 000000 Apache Rivet 3.3 Configuration

    Apache Rivet 3.3 Configuration

    Apache Rivet Configuration lines

    Rivet directives are used within the Apache httpd server configuration to set up the environment where Rivet script will be run.

    Rivet has 3 general “scope� directives

    • RivetDirConf: for configuration directives meant to apply to a directory tree
    • RivetUserConf: for directives specific to a user private space
    • RivetServerConf: for any directive meant to apply globally (either to the whole Rivet installation or a single virtual host)

    These directives are applied so that RivetDirConf will override RivetUserConf, which in turn overrides any RivetServerConf directives. Not every configuration directory is meaningful to a scope directive, as shown in the table below. The scope of application of a configuration line is matched also with the context where it appears. Virtual hosts definitions are contexts where rivet configuration lines can appear in many adding further customization to a given virtual host server.

    Example of configuration of a web server having independent interpreters for each virtual host, a larger default cache and a specific script to be executed before any templates/scripts located in /var/www/myrivetapp

    <IfModule rivet_module>
        AddType application/x-httpd-rivet .rvt
        AddType application/x-rivet-tcl   .tcl
    
        RivetServerConf CacheSize              100
        RivetServerConf SeparateVirtualInterps On
    </IfModule>
    
    <Directory /var/www/myrivetapp>
        RivetDirConf BeforeScript "source /var/www/myrivetapp/before_script.tcl"
    </Directory>

    Configuration Directives

    Configuration DirectivesDirConfUserConfServerConfVirtual HostNotes
    AbortScriptXXXX This directive is meaningful with the default request handler. In order to have this triggered by calling ::rivet::abort_page or ::rivet::exit any special request handler should explicitly read this script from the configuration using ::rivet::inspect and evaluate it (see the section called “Apache Child Processes Lifecycle and Request Processing�)
    AfterScriptXXXXSpecial request handler scripts should read it from the configuration calling ::rivet::inspect and evaluate it
    AfterEveryScriptXXXXSee notes for the AfterScript directive
    BeforeScriptXXXX See notes for the AfterScript directive
    CacheSizeXX
    ChildExitScriptXX
    ChildInitScriptXX
    ErrorScriptXXXX Rivet provides a default error handler. In case you are writing your own request handling procedure you need to call this error handler yourself or develop your application specific error handler to be integrated into the RequestHandler script. See also the notes for the AbortScript and AfterScript directives
    ExportRivetNSXXIt can be set in a virtual host configuration if SeparateVirtualInterps is On, otherwise this directive can be safely used at the global level only
    GlobalInitScriptX effective only when SeparateVirtualInterps is Off (default)
    ImportRivetNSXXIt can be set in a virtual host configuration if SeparateVirtualInterps is On, otherwise this directive can be safely used at the global level only
    HonorHeadRequestsXXReplaces HonorHeaderOnlyReqs, which is still supported but DEPRECATED
    MpmBridgeXglobal only
    RequestHandlerXX
    SeparateChannelsXglobal only (DEPRECATED: will be replaced in future versions of Rivet)
    SeparateVirtualInterpsXglobal only
    ServerInitScriptXglobal only
    SingleThreadExitXglobal only
    UploadDirectoryXXXX
    UploadFilesToVarXX
    UploadMaxSizeXX
    AbortScript ?script?
    If an AbortScript is defined control is passed to it as soon as the command abort_page is called. AbortScript is the right place where specific actions can be taken to catch resources left dangling by the sudden interruption.
    AfterScript ?script?
    Script to be called after each parsed .rvt template or .tcl script is executed
    In virtual hosts, this option overrides any AfterScript definitions at the global level.
    AfterEveryScript ?script?
    AfterEveryScript is a script that is to be run anyway before requests processing ends. This script is therefore run both when the content generation script completes successfully and when its execution is interrupted by abort_page. The code in this script can understand whether it's running after the page was interrupted by calling abort_page with the argument ?-aborting?. The command will return 1 if an abort_page call took place earlier in the request processing.
    BeforeScript ?script?
    Script to be evaluated before each server parsed (.rvt) page. This can be used to create a standard header, for instance. It could also be used to load code that you need for every page, if you don't want to put it in a GlobalInitScript ChildInitScript when you are first developing a web site.
    [Note]Note
    This code is evaluated at the global level, not inside the request namespace where pages are evaluated.
    In virtual hosts, this option takes precedence over the global setting.
    CacheSize ?size?
    Sets the size of the internal page cache, where size is the number of byte-compiled pages to be cached for future use. Default is MaxRequestsPerChild / 5, or 50, if MaxRequestsPerChild is 0.
    This option is completely global, even when using separate per-virtual host interpreters.
    ChildExitScript ?script?
    Script to be evaluated when each Apache child process exits. This is the logical place to clean up resources created in ChildInitScript, if necessary.
    In virtual hosts, this script is run in addition to any global childexitscript. When SeparateVirtualInterp any ChildExitScript placed within a <VirtualHost ...>....</VirtualHost> will be that Virtual Host specific exit handler
    ChildInitScript ?script?
    Script to be evaluated when each Apache child process is initialized. This is the recommended place to load modules, create global variables, open connections to other facilities (such as databases) and so on.
    In virtual hosts, this script is run in addition to any global childinitscript. When SeparateVirtualInterp any ChildInitScript placed within a <VirtualHost ...>....</VirtualHost> will be that Virtual Host specific ininitalization
    ErrorScript ?script?
    When Rivet encounters an error in a script, it constructs an HTML page with some information about the error, and the script that was being evaluated. If an ErrorScript is specified, it is possible to create custom error pages. This may be useful if you want to make sure that users never view your source code.
    In virtual hosts, this option takes precedence over the global setting.
    ExportRivetNS (yes | no)
    Rivet commands are created within the ::rivet namespace. Setting this option mod_rivet places the whole command set on the export list of the ::rivet namespace, enabling your scripts to import them in a different namespace.
    This option is, by nature, only available at the global level
    HonorHeadRequests (yes | no)
    If a HEAD requests is issued by the client Rivet detects this case and sends back to the client a standard header response. If the real header has to be examined (e.g. for debugging) you can turn this options on.
    This option is only available at the global level
    ImportRivetNS (yes | no)
    Rivet commands are created within the ::rivet namespace. Setting this option mod_rivet is told to place the whole command set on the export list of the ::rivet namespace (implicitly forcing also ExportRivetNS) and then importing the commands into the global namespace
    [Note]Note
    This option is provided only for compatibility with existing code that assumes mod_rivet commands to reside in the global namespace it could be removed in future versions of Rivet. This option is only available at the global level
    MpmBridge ?string?
    This global only option tells mod_rivet which MPM bridge has to be loaded. The module attempt to interpolate the argument value
    bridge = apr_pstrcat(pool,RIVET_DIR,"/mpm/rivet_",rsc->mpm_bridge,"_mpm.so",NULL);
    Where RIVET_DIR is the location of the rivet libraries whose definition is controlled by the configure switch --with-rivet-target-dir=DIR. For example
    RivetServerConf MpmBridge lazy
    will cause the rivet_lazy_mpm.so library module to be loaded.
    If such library does not exists mod_rivet tries to check if such definition is actually the fully qualified path to such MPM bridge. If this fails the module causes the web server to stop with an error.
    RequestHandler ?request_handler_filename?
    Filename of the request handler script. Overrides the default request handler. Can be virtual host specific
    [Note]Note
    Note that changing this scripts requires the programmer to understand mod_rivet request processing model. See the request processing manual page
    SeparateChannels (yes | no)
    Internally mod_rivet creates a new Tcl channel (Rivet channel) which is configured as stdout and registered to each existing interpreter. There is no need of multiple channels in a single thread as each thread can serve only one request at a time. But if you are deploying mod_rivet in a complex environment running unrelated applications developed by different teams, it could be the case to have SeparateVirtualInterps set. If you want to enhance the environment separation you may also set SeparateChannels to force mod_rivet to create a channel per each Tcl interpreter thus enabling single application code to change the Rivet channel parameters without affecting other applications (even though changing the Tcl channel parameters is a rare necessity). Setting this options increases the system overheads as each Rivet channel needs to allocate its own control structures and internal buffers.
    [Note]Note
    This option is implemented in order to have fine-grained control over mod_rivet. In nearly all practical cases you won't need to change Rivet Channel (stdout) settings for different applications by calling fconfigure stdout ..... This option is, by nature, only available at the global level and has effect only if also SeparateVirtualInterps is set
    SeparateVirtualInterps (yes | no)
    If on, Rivet will create a separate Tcl interpreter for each Apache virtual host. This is useful in an ISP type situation where it is desirable to separate clients into separate interpreters, so that they don't accidentally interfere with one another.
    [Note]Note
    This option is, by nature, only available at the global level. By enabling SeparateVirtualInterps you must rely only on ChildInitScript to initialize the interpreters. Don't expect the initialization done in ServerInitScript and GlobalInitScript to be handed down to the slave interpreters that are private to each configured virtual host.
    ServerInitScript ?script?
    The directive ServerInitScript plays a special role since the script runs within the master interpreter, an interpreter created when the Apache web server is setting up for answering requests and before worker processes/threads are started. During this stage Apache is still running as a single process, so this is the right place for doing initialization of systems such as any IPC systems.
    On systems with the capability of forking child processes the Apache web server can run the prefork MPM. By default rivet selects the prefork brigde which makes mod_rivet work the way mod_rivet 2.x work. In a web server with this set up child processes inherit a copy of the address space from the parent processes and therefore Tcl interpreters too are replicated into the child address space. If SeparateVirtualInteprs is Off child processes run with a copy of the Tcl master interpreter and ServerInitScipt thus provides a way to initialize only once any subsequent Tcl interpreters created by fork calls as each of them are clones of the master interpreter.
    SingleThreadExit (yes | no)
    The Tcl exit command has a simple implementation that eventually calls Tcl_Exit (which in turn calls stdlib's exit) that forces the immediate deletion of all threads in a process. This behavior would be unacceptable with the worker MPM and worker bridge which are fundamentally threaded. Therefore Rivet shadows the Tcl exit command with ::rivet::exit which calls a designated function in the running bridge. The prefork bridge simply prepares the child process to terminate, whereas the worker bridge is behavior controlled by this option.
    1. If SingleThreadExit is set (default) each thread behaves individually and terminates after running the ChildExitScript and deleting its Tcl interpreters
    2. If SingleThreadExit is No the worker bridge notifies all threads to exit and then calls Tcl_Exit
    The latter option might be useful in cases where an application is using an improperly developed Tcl extension which might cause a child process to crash when calling Tcl_DeleteInterp.
    [Note]Note
    The default is No for the prefork bridge (loaded by default if the server runs the prefork MPM) and true for the worker and lazy bridges
    UploadDirectory ?directory?
    Directory to place uploaded files.
    In virtual hosts, this option takes precedence over the global setting.
    UploadFilesToVar (yes | no)
    This option controls whether it is possible to upload files to a Tcl variable. If you have a size limit, and don't have to deal with large files, this might be more convenient than sending the data to a file on disk.
    UploadMaxSize ?size?
    Maximum size for uploaded files.
    In virtual hosts, this option takes precedence over the global setting.
    rivet-3.3.1/doc/style.css000664 001750 001751 00000001325 15245054302 016042 0ustar00manghimanghi000000 000000 body { font-family: Arial, sans-serif; font-style: normal; color: #000000; background-color: #FFFFFF; font-size: smaller; } A:link { color: #cc3300 } A:visited { color : #003399; } A:hover { color : #000000 ; background-color : #aaaaaa } h1 { font-size: xx-large; font-family: Arial, sans-serif; color: #000000; } h2 { font-size: larger; font-family: Arial, sans-serif; } h3 { font-family: Arial, sans-serif; } b { font-weight: bold; } td { font-family: Arial, sans-serif; color: #000000; padding: 0.25em; } code { font-size: larger; color: #006600; } div.box { border-width: medium; padding: 0.25em; background-color: #dddddd; } li { } rivet-3.3.1/doc/html/images/note.png000644 001750 001751 00000000752 15245054474 020067 0ustar00manghimanghi000000 000000 ‰PNG  IHDRÅb$bKGDª�#2IDATxÚe’!’Ã0 E}¾……K C ÿtAQCACQAÁ+g“4m¥ÉŒãçoKß.ã Ÿqþ•c ¢üô D«Ô="¼ú²s ˆÇ%‚äd¼ÇœH ô1Ÿ›à²ÿy%ØM8ÓöfÈK ¢wª¬Öµ>i6g-NpÖ‹˜Y‡tL#÷ßŸÛ a–Žb;�UÍ#2ÇØV} °Ô£rßVŠx¬]ÛzTîT÷1ú�ºÜO HËè4Ý]o žíÕzÌÎ§Ïæ™gç"Ó’NþåHl¶ó§‹U÷‹Äuýœß¯–Ñä9¾<†t‘,�×tÓß_‰)2Håž•÷d úkBCtEXtSoftware@(#)ImageMagick 4.2.8 99/08/01 cristy@mystic.es.dupont.com‘º!¸*tEXtSignature3bd747c5e45807006b090dd3e7a26c44Ó“útEXtPage24x24+0+0r[ 1IEND®B`‚rivet-3.3.1/tests/docroot2/vhost2.rvt000664 001750 001751 00000000370 15245054302 020301 0ustar00manghimanghi000000 000000 " puts "::childinit2 exists
    " } elseif {[info exists ::beforescript2]} { ?>Virtual Host2 Test" } ?> rivet-3.3.1/doc/html/commands.html000664 001750 001751 00000006072 15245054474 017641 0ustar00manghimanghi000000 000000 Rivet Tcl Commands and Variables

    Rivet Tcl Commands and Variables

    Starting with version 2.1.0 the Rivet command set moved into the ::rivet namespace.

    In order to preserve out of the box compatibility with existing scripts, Rivet exports commands by default and makes them available for import into any namespace (global namespace included). Rivet's build system can be told not to export the command set by passing the switch --disable-rivet-commands-export to 'configure'. In the future we may change this option's default.

    Commands must be imported into another namespace with the command:

    namespace import -force ::rivet::*

    Whenever a new application is being developed and compatibility issues can be confined within specific files, it is recommended that commands be specified with their fully qualified names.

    rivet-3.3.1/STATUS000664 001750 001751 00000001103 15245054302 014363 0ustar00manghimanghi000000 000000 tcl-rivet STATUS: Committers: ========== Massimo Manghi George Petasis Brice Hamon Work in progress: ================ *) Rivet 3.2: *) Rivet 'quattuor' branch (to become Rivet 4.0) *) Installation Min Required Platform Tcl Version Ok? -------- ----------- --- Debian Tcl 8.6 Yes Ubuntu Tcl 8.6 Yes CentOS Tcl 8.6 Yes Suse Tcl 8.6 Yes FreeBSD Tcl 8.6 Yes Windows 10 Tcl 8.6 Yes rivet-3.3.1/doc/000775 001750 001751 00000000000 15245055664 014203 5ustar00manghimanghi000000 000000 rivet-3.3.1/doc/html/write_binary.html000664 001750 001751 00000007076 15245054474 020543 0ustar00manghimanghi000000 000000 write_binary

    Name

    write_binary — write one binary value to the response channel.

    Synopsis

    ::rivet::write_binary data

    Description

    Writes data to stdout without newline translation or character encoding, and without appending a newline. The previous response-channel configuration is restored before the command returns. This command is equivalent to:

    ::rivet::with_binary_output {
        puts -nonewline stdout $data
    }

    The value must be byte-oriented and contain only characters in the range U+0000 through U+00FF. Use ::rivet::with_binary_output when several consecutive binary output operations need to be grouped.

    [Note]Note
    This command is not placed in the export list of the ::rivet namespace
    rivet-3.3.1/m4/ltoptions.m4000664 001750 001751 00000034262 15245054302 016246 0ustar00manghimanghi000000 000000 # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) rivet-3.3.1/rivet/rivet-tcl/cookie.tcl000664 001750 001751 00000007636 15245054302 020455 0ustar00manghimanghi000000 000000 ## ## cookie [set|get] and supporting functions ## ## $Id$ ## namespace eval ::rivet { ## clock_to_rfc850_gmt seconds -- Convert an integer-seconds-since-1970 ## click value to RFC850 format, with the additional requirement that it ## be GMT only. ## proc clock_to_rfc850_gmt {seconds} { return [clock format $seconds -format "%a, %d-%b-%y %T GMT" -gmt 1] } ## make_cookie_attributes paramsArray -- Build up cookie parameters. ## ## If an expires element appears in the array, it's appended to the ## result as "; expires=value" ## ## If an element is present named "days", "hours", or "minutes", the ## corresponding value is converted to seconds, added to the current ## time, converted to RFC850 time format, and appended to the result ## as, for example, "; expires=Sun, 25-Sep-05 23:09:52 GMT" ## ## If any other elements named "path", "domain", or "secure" are present, ## they too are appended to the result. ## ## The resut is returned. ## proc make_cookie_attributes {paramsArray} { upvar 1 $paramsArray params set cookieParams "" set expiresIn 0 if { [info exists params(expires)] } { append cookieParams "; expires=$params(expires)" } else { foreach {time num} [list days 86400 hours 3600 minutes 60] { if {[info exists params($time)]} { incr expiresIn [expr {$params($time) * $num}] } } if {$expiresIn != 0} { set secs [expr [clock seconds] + $expiresIn] append cookieParams "; expires=[clock_to_rfc850_gmt $secs]" } } if {[info exists params(path)]} { append cookieParams "; path=$params(path)" } if {[info exists params(domain)]} { append cookieParams "; domain=$params(domain)" } if {[info exists params(secure)] && $params(secure) == 1} { append cookieParams "; secure" } if {[info exists params(HttpOnly)] && $params(HttpOnly)} { append cookieParams "; HttpOnly" } return $cookieParams } ## cookie [set|get] cookieName ?cookieValue? [-days expireInDays] ## [-hours expireInHours] [-minutes expireInMinutes] ## [-expires Wdy, DD-Mon-YYYY HH:MM:SS GMT] ## [-path uriPathCookieAppliesTo] ## [-secure 1|0] ## proc cookie {cmd name args} { set badchars "\[ \t;\]" switch -- $cmd { "set" { set value [lindex $args 0] set args [lrange $args 1 end] import_keyvalue_pairs params $args if {[regexp $badchars $name]} { return -code error \ "name may not contain semicolons, spaces, or tabs" } if {[regexp $badchars $value]} { return -code error \ "value may not contain semicolons, spaces, or tabs" } set cookieKey "Set-Cookie" set cookieValue "$name=$value" append cookieValue [make_cookie_attributes params] headers add $cookieKey $cookieValue } "get" { ::request::global RivetCookies if {![array exists RivetCookies]} { load_cookies RivetCookies } if {![info exists RivetCookies($name)]} { return } return $RivetCookies($name) } "delete" { ## In order to delete a cookie, we just need to set a cookie ## with a time that has already expired. cookie set $name "" -minutes -1 } "unset" { ::request::global RivetCookies if {![array exists RivetCookies]} { load_cookies RivetCookies } if {![info exists RivetCookies($name)]} { return } unset RivetCookies($name) } } } } rivet-3.3.1/.gitignore000664 001750 001751 00000001111 15245054302 015404 0ustar00manghimanghi000000 000000 Makefile.in doc/Makefile.in src/Makefile.in aclocal.m4 autom4te.cache/ configure Makefile _configs.sed config.h config.h.in config.log config.status rivet_config.h doc/Makefile doc/convert_examples.tcl doc/graphics doc/html/ libtool src/Makefile src/librivet/.deps/ src/mod_rivet_ng/.deps/ src/parser/.deps/ src/request/.deps/ stamp-h1 *~ *.libs/ *.dirstamp *.lo *.la *.swp tags tests/access_log tests/apachelog.txt tests/error_log tests/htaccess2 tests/httpd.pid tests/redirect_code.txt tests/rivet/ tests/server.conf tests/test.conf tests/uploadedjpeg.jpg Session.vim rivet/init.tcl rivet-3.3.1/doc/examples-sgml/colortable.rvt000664 001750 001751 00000002571 15245054302 021635 0ustar00manghimanghi000000 000000 <html><head> <style> td { font-size: 12px; font-family: monospace; text-align: center; padding-left: 3px; padding-right: 3px } td.bright { color: #eee; } td.dark { color: #222; } </style> </head> <body> <table> <? # we create a 9x9 table selecting a different background for each cell for {set i 0} { $i < 9 } {incr i} { puts "<tr>" for {set j 0} {$j < 9} {incr j} { set r [expr int(255 * ($i + $j) / 16)] set g [expr int(255 * (8 + $j - $i) / 16)] set b [expr int(255 * (abs (4 - $i) + abs(4 - $j)) / 8)] # determining the background luminosity (YIQ space of NTSC) and choosing # the foreground color accordingly in order maintain maximum contrast if { [expr ($r*0.29894)+($g*0.58704)+($b*0.11402)] > 148.0} { set cssclass "dark" } else { set cssclass "bright" } set cell [format "%3d %3d %3d" $r $g $b] puts [format \ "<td bgcolor=\"%02x%02x%02x\" class=\"%s\">%s</td>" \ $r $g $b $cssclass $cell] } puts "</tr>" } ?> </table> </body></html> rivet-3.3.1/doc/html/images/important.png000644 001750 001751 00000001322 15245054474 021131 0ustar00manghimanghi000000 000000 ‰PNG  IHDRשÍÊäPLTE)))999BB1ZZ)ccBBBRRRkkBccRssRccckkk{{{ŒŒŒŒ9½½­­!­­9œœZŒŒ{œœcœœ{µµJµµR½½Z¥¥c­­k­­{ÞÞÖÖÞÞ!ÞÞ1ÞÞ9ççïïïïÿÿÿÿÿÿçç)çç1ïï1ÿÿ!ÆÆZÖÖRÎÎsÖÖcÖÖkïïBççcçç{„„„ŒŒŒ”””¥¥„­­Œ¥¥”¥¥œ½½„½½œ¥¥¥­­¥­­­µµµ½½½ÆÆÆÎÎÎÖÖÖÞÞÞçççïïï÷÷÷ÿÿÿ­ÒÃÞbKGDCgÐ bIDATxÚm’ SÂ0 Ç3Eñ1•¡ÀÔÉKÜPT”•‰F'�µûþßÇ®�Qïö¿ë]’_iÈK±B¥&ºF‚(å6àßñrúðcºŒ/‘Ñ´…\NÞÃh£°›* â2pã¹=…:©ôJí÷v•?°•¾ÿ 6Ôï| @}÷`ÿ^Û>ƒ¯µs P¿ÕvB�¡É¨é@Ãd6"èo;g•`PsÎ+ÁÝÞÖs%˜Çǯ%@ÈS�{4ñܾ•Už-µs"þ1чßÄ?øjª<`g ­ñeZÔ* Ô+½ƒÃ¦Ú2Ã_Yvì*ÿÁ¤è•lv¬~Œg Z¶[�s“ôY[Ã�a; =ùí/öoJĘ!¤f€þ�cl¯RmÌRCtEXtSoftware@(#)ImageMagick 4.2.8 99/08/01 cristy@mystic.es.dupont.com‘º!¸*tEXtSignaturec3ecc1fc5135d1e959695e569d213122riðIEND®B`‚rivet-3.3.1/src/mod_rivet_ng/rivetInspect.c000664 001750 001751 00000030672 15245054302 021520 0ustar00manghimanghi000000 000000 /* * rivetConf.c - Functions for accessing Rivet configuration variables * * Functions in this file implement core function to be called mainly * by the Rivet_InspectCmd function, which implments command 'inspect' * */ /* Copyright 2002-2004 The Apache Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include #include #include #include #include "httpd.h" #include "http_config.h" #include "http_request.h" #include "http_core.h" #include "http_main.h" #include "util_script.h" #include "http_config.h" #include "http_log.h" #include "mod_rivet.h" static const char* loglevel_defs[] = { "emerg", "alert", "crit", "err", "warning", "notice", "info", "debug", }; /* These arrays must be kept aligned. confDirectives must be NULL terminated */ static const char* confDirectives[] = { "ServerInitScript", "GlobalInitScript", "ChildInitScript", "ChildExitScript", "BeforeScript", "AfterScript", "AfterEveryScript", "AbortScript", "ErrorScript", "UploadMaxSize", "UploadDirectory", "UploadFilesToVar", "SeparateVirtualInterps", "SeparateChannels", "HonorHeaderOnlyRequests", "MpmBridge", "RequestHandler", "ExportRivetNS", "ImportRivetNS", NULL }; enum confIndices { server_init_script, global_init_script, child_init_script, child_exit_script, before_script, after_script, after_every_script, abort_script, error_script, upload_max, upload_directory, upload_files_to_var, separate_virtual_interps, separate_channels, honor_head_requests, mpm_bridge, request_handler, export_rivet_ns, import_rivet_ns, conf_index_terminator }; extern mod_rivet_globals* module_globals; /* * -- Rivet_ReadConfParameter * * This procedure reads a single field named par_name from * rivet_server_conf structure and returns a Tcl_Obj pointer * containing the field value. See confDirectives for a list * of possible names. If the procedure is queried for a non * existing field a NULL is returned. * * Arguments: * * - interp: pointer to the current Tcl interpreter structure * - rsc: a pointer to a rivet_server_conf structure * - par_name: parameter name (as listed in confDirectives) * * Returned value: * * - A Tcl_Obj pointer to the parameter value. A NULL * pointer works as a signal for an error (invalid parameter) * - If the parameter value in the configuration is undefined * then the procedure returns an empty string * */ Tcl_Obj* Rivet_ReadConfParameter ( Tcl_Interp* interp, rivet_server_conf* rsc, Tcl_Obj* par_name) { int parameter_i; Tcl_Obj* int_value = NULL; char* string_value = NULL; if (Tcl_GetIndexFromObj(interp, par_name, confDirectives, "", 0, ¶meter_i) == TCL_ERROR) { return NULL; } switch (parameter_i) { case server_init_script: string_value = (char *)module_globals->rivet_server_init_script; break; case global_init_script: string_value = rsc->rivet_global_init_script; break; case child_init_script: string_value = rsc->rivet_child_init_script; break; case child_exit_script: string_value = rsc->rivet_child_exit_script; break; case request_handler: string_value = rsc->request_handler; break; case before_script: string_value = rsc->rivet_before_script; break; case after_script: string_value = rsc->rivet_after_script; break; case after_every_script: string_value = rsc->after_every_script; break; case abort_script: string_value = rsc->rivet_abort_script; break; case error_script: string_value = rsc->rivet_error_script; break; case upload_directory: string_value = (char *)rsc->upload_dir; break; case mpm_bridge: string_value = (char *)module_globals->mpm_bridge; break; case upload_max: int_value = Tcl_NewIntObj(rsc->upload_max); break; case upload_files_to_var: int_value = Tcl_NewIntObj(rsc->upload_files_to_var); break; case separate_virtual_interps: int_value = Tcl_NewIntObj(module_globals->separate_virtual_interps); break; case separate_channels: int_value = Tcl_NewIntObj(module_globals->separate_channels); break; case honor_head_requests: int_value = Tcl_NewIntObj(rsc->honor_head_requests); break; case export_rivet_ns: int_value = Tcl_NewIntObj(rsc->export_rivet_ns); break; case import_rivet_ns: int_value = Tcl_NewIntObj(rsc->import_rivet_ns); break; default: return NULL; } /* * In the configuration record any integer valued parameter has a defined integer default, whereas * string parameters have NULL as default. If we got here but both the these pointers are NULL * it means a valid string valued configuration parameter was inspected but since it's NULL we * return an empty string */ if ((string_value == NULL) && (int_value == NULL)) { return Tcl_NewStringObj("",-1); } else if (string_value != NULL) { /* otherwise if string_value is defined we return it as Tcl_Obj*/ return Tcl_NewStringObj(string_value,-1); } else { /* there is no other possible case: int_value must be returned */ return int_value; } } /* * Rivet_ReadConfTable: * * This procedure builds a key-value list from an apr table * It's called by Rivet_BuildConfDictionary to read theRivet * configuration tables but it can work for every apr table * * Arguments: * * - interp: Tcl_Interp pointer * - table: an apr_table_t pointer * */ static Tcl_Obj* Rivet_ReadConfTable (Tcl_Interp* interp, apr_table_t* table) { Tcl_Obj* key; Tcl_Obj* val; apr_array_header_t *arr; apr_table_entry_t *elts; int nelts,i; int tcl_status = TCL_OK; Tcl_Obj* keyval_list = Tcl_NewObj(); //Tcl_IncrRefCount(keyval_list); arr = (apr_array_header_t*) apr_table_elts( table ); elts = (apr_table_entry_t *) arr->elts; nelts = arr->nelts; for (i = 0; i < nelts; i++) { key = Tcl_NewStringObj( elts[i].key, -1); val = Tcl_NewStringObj( elts[i].val, -1); Tcl_IncrRefCount(key); Tcl_IncrRefCount(val); tcl_status = Tcl_ListObjAppendElement (interp,keyval_list,key); if (tcl_status == TCL_ERROR) { Tcl_DecrRefCount(keyval_list); Tcl_DecrRefCount(key); Tcl_DecrRefCount(val); return NULL; } tcl_status = Tcl_ListObjAppendElement (interp,keyval_list,val); if (tcl_status == TCL_ERROR) { Tcl_DecrRefCount(keyval_list); Tcl_DecrRefCount(key); Tcl_DecrRefCount(val); return NULL; } Tcl_DecrRefCount(key); Tcl_DecrRefCount(val); } return keyval_list; } /* * -- Rivet_BuildConfDictionary * * Parameters set in the configuration files are collected in three * APR tables by Rivet_ServerConf,Rivet_DirConf and Rivet_UserConf. * * Arguments: * * - interp: Tcl_Interp pointer * - rivet_conf: pointer to a rivet_server_conf structure as * returned by Rivet_GetConf * * Returned value: * * - Tcl dictionary storing the dir/user/server configuration. The * dictionary refCount is incremented * */ Tcl_Obj* Rivet_BuildConfDictionary ( Tcl_Interp* interp, rivet_server_conf* rivet_conf) { apr_table_t* conf_tables[3]; Tcl_Obj* keyval_list = NULL; Tcl_Obj* key_list[2]; int it; Tcl_Obj* conf_dict = Tcl_NewObj(); static const char* section_names[] = { "dir", "user", "server" }; enum { dir_conf_section, user_conf_section, server_conf_section }; conf_tables[0] = rivet_conf->rivet_dir_vars; conf_tables[1] = rivet_conf->rivet_user_vars; conf_tables[2] = rivet_conf->rivet_server_vars; // Tcl_IncrRefCount(conf_dict); for (it=0; it < 3; it++) { keyval_list = Rivet_ReadConfTable(interp,conf_tables[it]); if (keyval_list != NULL) { int i; Tcl_Obj** objArrayPnt; Tcl_Size objArrayCnt; Tcl_Obj* val; Tcl_IncrRefCount(keyval_list); key_list[0] = Tcl_NewStringObj(section_names[it],-1); Tcl_IncrRefCount(key_list[0]); Tcl_ListObjGetElements(interp,keyval_list,&objArrayCnt,&objArrayPnt); for (i=0; i < objArrayCnt; i+=2) { key_list[1] = objArrayPnt[i]; val = objArrayPnt[i+1]; Tcl_IncrRefCount(key_list[1]); Tcl_IncrRefCount(val); Tcl_DictObjPutKeyList(interp,conf_dict,2,key_list,val); Tcl_DecrRefCount(key_list[1]); Tcl_DecrRefCount(val); } Tcl_DecrRefCount(key_list[0]); Tcl_DecrRefCount(keyval_list); } else { return NULL; } } return conf_dict; } /* * Rivet_CurrentConfDict * * This function is called by Rivet_InspectCmd which implements command * '::rivet::inspect -all'. The function returns a dictionary where every * parameter name (confDirectives) is associated to its value stored in * the rivet_server_conf as returned by Rivet_GetConf * * Arguments: * * - interp: Tcl interpreter pointer * - rivet_conf: a pointer to a rivet_server_conf structure * * Returned value_ * * - a Tcl_Obj* pointer to a dictionary. The function is guaranteed to * return a Tcl_Obj pointer * */ Tcl_Obj* Rivet_CurrentConfDict ( Tcl_Interp* interp, rivet_server_conf* rivet_conf) { Tcl_Obj* dictObj = Tcl_NewObj(); Tcl_Obj* par_name; const char** p; for (p = confDirectives; (*p) != NULL; p++) { Tcl_Obj* par_value; par_name = Tcl_NewStringObj(*p,-1); Tcl_IncrRefCount(par_name); par_value = Rivet_ReadConfParameter(interp,rivet_conf,par_name); ap_assert(par_value != NULL); Tcl_IncrRefCount(par_value); Tcl_DictObjPut(interp,dictObj,par_name,par_value); Tcl_DecrRefCount(par_value); Tcl_DecrRefCount(par_name); } return dictObj; } /* * -- Rivet_CurrentServerRec * * ::rivet::inspect provides also some basic access to * fields of the server_rec object. * * */ Tcl_Obj* Rivet_CurrentServerRec (Tcl_Interp* interp, server_rec* s ) { Tcl_Obj* dictObj; Tcl_Obj* field_name; Tcl_Obj* field_value; dictObj = Tcl_NewObj(); field_value = Tcl_NewStringObj(s->server_hostname,-1); field_name = Tcl_NewStringObj("hostname",-1); Tcl_DictObjPut(interp,dictObj,field_name,field_value); field_value = Tcl_NewStringObj(s->error_fname,-1); field_name = Tcl_NewStringObj("errorlog",-1); Tcl_DictObjPut(interp,dictObj,field_name,field_value); field_value = Tcl_NewStringObj(s->server_admin,-1); field_name = Tcl_NewStringObj("admin",-1); Tcl_DictObjPut(interp,dictObj,field_name,field_value); field_value = Tcl_NewStringObj(s->path,-1); field_name = Tcl_NewStringObj("server_path",-1); Tcl_DictObjPut(interp,dictObj,field_name,field_value); field_value = Tcl_NewIntObj(s->is_virtual); field_name = Tcl_NewStringObj("virtual",-1); Tcl_DictObjPut(interp,dictObj,field_name,field_value); field_value = Tcl_NewStringObj(loglevel_defs[s->log.level],-1); field_name = Tcl_NewStringObj("loglevel",-1); Tcl_DictObjPut(interp,dictObj,field_name,field_value); return dictObj; } rivet-3.3.1/tclconfig/tcl.m4000664 001750 001751 00000406411 15245054302 016424 0ustar00manghimanghi000000 000000 # tcl.m4 -- # # This file provides a set of autoconf macros to help TEA-enable # a Tcl extension. # # Copyright (c) 1999-2000 Ajuba Solutions. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. AC_PREREQ([2.69]) # Possible values for key variables defined: # # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem') # TEA_PLATFORM - windows unix # TEA_TK_EXTENSION - True if this is a Tk extension # #------------------------------------------------------------------------ # TEA_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TCLCONFIG], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl], [directory containing tcl configuration (tclConfig.sh)]), [with_tclconfig="${withval}"]) AC_ARG_WITH(tcl8, AS_HELP_STRING([--with-tcl8], [Compile for Tcl8 in Tcl9 environment]), [with_tcl8="${withval}"]) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case "${with_tclconfig}" in */tclConfig.sh ) if test -f "${with_tclconfig}"; then AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ `ls -d /usr/lib/tcl9.1 2>/dev/null` \ `ls -d /usr/lib/tcl9.0 2>/dev/null` \ `ls -d /usr/lib/tcl8.6 2>/dev/null` \ `ls -d /usr/lib/tcl8.5 2>/dev/null` \ `ls -d /usr/local/lib/tcl9.1 2>/dev/null` \ `ls -d /usr/local/lib/tcl9.0 2>/dev/null` \ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl9.1 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl9.0 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) else no_tcl= TCL_BIN_DIR="${ac_cv_c_tclconfig}" AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_PATH_TKCONFIG -- # # Locate the tkConfig.sh file # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tk=... # # Defines the following vars: # TK_BIN_DIR Full path to the directory containing # the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TKCONFIG], [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, AS_HELP_STRING([--with-tk], [directory containing tk configuration (tkConfig.sh)]), [with_tkconfig="${withval}"]) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case "${with_tkconfig}" in */tkConfig.sh ) if test -f "${with_tkconfig}"; then AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib/tk9.1 2>/dev/null` \ `ls -d /usr/lib/tk9.0 2>/dev/null` \ `ls -d /usr/lib/tk8.6 2>/dev/null` \ `ls -d /usr/lib/tk8.5 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ `ls -d /usr/local/lib/tk9.1 2>/dev/null` \ `ls -d /usr/local/lib/tk9.0 2>/dev/null` \ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk9.1 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk9.0 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) else no_tk= TK_BIN_DIR="${ac_cv_c_tkconfig}" AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Substitutes the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE # TCL_ZIP_FILE # TCL_ZIPFS_SUPPORT #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TCLCONFIG], [ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TCL_BIN_DIR}/tclConfig.sh" else AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) fi # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitrary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi AC_SUBST(TCL_VERSION) AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_MSG_CHECKING([platform]) hold_cc=$CC; CC="$TCL_CC" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ #ifdef _WIN32 #error win32 #endif ]])],[ # first test we've already retrieved platform (cross-compile), fallback to unix otherwise: TEA_PLATFORM="${TEA_PLATFORM-unix}" CYGPATH=echo ],[ TEA_PLATFORM="windows" AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]) CC=$hold_cc AC_MSG_RESULT($TEA_PLATFORM) # The BUILD_$pkg is to define the correct extern storage class # handling when making this package # To be able to sefely use the package name in a #define, it must not # contain anything other than alphanumeric characters and underscores SAFE_PKG_NAME=patsubst(AC_PACKAGE_NAME, [[^A-Za-z0-9_]], [_]) AC_DEFINE_UNQUOTED(BUILD_${SAFE_PKG_NAME}, [], [Building extension source?]) # Do this here as we have fully defined TEA_PLATFORM now if test "${TEA_PLATFORM}" = "windows" ; then EXEEXT=".exe" CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp" fi # TEA specific: AC_SUBST(CLEANFILES) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_EXTRA_CFLAGS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_SHLIB_LD_LIBS) ]) #------------------------------------------------------------------------ # TEA_LOAD_TKCONFIG -- # # Load the tkConfig.sh file # # Arguments: # # Requires the following vars to be set: # TK_BIN_DIR # # Results: # # Sets the following vars that should be in tkConfig.sh: # TK_BIN_DIR #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TKCONFIG], [ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TK_BIN_DIR}/tkConfig.sh" else AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TK_BIN_DIR}/Makefile" ; then TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tk.framework installed in an arbitrary location. case ${TK_DEFS} in *TK_FRAMEWORK*) if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then for i in "`cd "${TK_BIN_DIR}"; pwd`" \ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" break fi done fi if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" fi ;; esac fi # TEA specific: Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?]) TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi AC_SUBST(TK_VERSION) AC_SUBST(TK_BIN_DIR) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_LIB_FILE) AC_SUBST(TK_LIB_FLAG) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_STUB_LIB_FILE) AC_SUBST(TK_STUB_LIB_FLAG) AC_SUBST(TK_STUB_LIB_SPEC) # TEA specific: AC_SUBST(TK_LIBS) AC_SUBST(TK_XINCLUDES) ]) #------------------------------------------------------------------------ # TEA_PROG_TCLSH # Determine the fully qualified path name of the tclsh executable # in the Tcl build directory or the tclsh installed in a bin # directory. This macro will correctly determine the name # of the tclsh executable even if tclsh has not yet been # built in the build directory. The tclsh found is always # associated with a tclConfig.sh file. This tclsh should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments: # none # # Results: # Substitutes the following vars: # TCLSH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_TCLSH], [ AC_MSG_CHECKING([for tclsh]) if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}" elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}" elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}" fi else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}" fi list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" fi AC_MSG_RESULT([${TCLSH_PROG}]) AC_SUBST(TCLSH_PROG) ]) #------------------------------------------------------------------------ # TEA_PROG_WISH # Determine the fully qualified path name of the wish executable # in the Tk build directory or the wish installed in a bin # directory. This macro will correctly determine the name # of the wish executable even if wish has not yet been # built in the build directory. The wish found is always # associated with a tkConfig.sh file. This wish should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments: # none # # Results: # Substitutes the following vars: # WISH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_WISH], [ AC_MSG_CHECKING([for wish]) if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}s${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}$s{EXEEXT}" elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}" elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}" fi else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}" fi list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TK_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`/" break fi done WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}" fi AC_MSG_RESULT([${WISH_PROG}]) AC_SUBST(WISH_PROG) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SHARED -- # # Allows the building of shared libraries # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-shared=yes|no # --enable-stubs=yes|no # # Defines the following vars: # STATIC_BUILD Used for building import/export libraries # on Windows. # # Sets the following vars: # SHARED_BUILD Value of 1 or 0 # STUBS_BUILD Value if 1 or 0 # USE_TCL_STUBS Value true: if SHARED_BUILD or --enable-stubs # USE_TCLOO_STUBS Value true: if SHARED_BUILD or --enable-stubs # USE_TK_STUBS Value true: if SHARED_BUILD or --enable-stubs # AND TEA_WINDOWING_SYSTEM != "" #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, AS_HELP_STRING([--enable-shared], [build and link with shared libraries (default: on)]), [shared_ok=$enableval], [shared_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" shared_ok=$enableval else shared_ok=yes fi AC_ARG_ENABLE(stubs, AS_HELP_STRING([--enable-stubs], [build and link with stub libraries. Always true for shared builds (default: on)]), [stubs_ok=$enableval], [stubs_ok=yes]) if test "${enable_stubs+set}" = set; then enableval="$enable_stubs" stubs_ok=$enableval else stubs_ok=yes fi # Stubs are always enabled for shared builds if test "$shared_ok" = "yes" ; then AC_MSG_RESULT([shared]) SHARED_BUILD=1 STUBS_BUILD=1 else AC_MSG_RESULT([static]) SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [This a static build]) if test "$stubs_ok" = "yes" ; then STUBS_BUILD=1 else STUBS_BUILD=0 fi fi if test "${STUBS_BUILD}" = "1" ; then AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs]) if test "${TEA_WINDOWINGSYSTEM}" != ""; then AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) fi fi AC_SUBST(SHARED_BUILD) AC_SUBST(STUBS_BUILD) ]) #------------------------------------------------------------------------ # TEA_ENABLE_THREADS -- # # Specify if thread support should be enabled. If "yes" is specified # as an arg (optional), threads are enabled by default, "no" means # threads are disabled. "yes" is the default. # # TCL_THREADS is checked so that if you are compiling an extension # against a threaded core, your extension must be compiled threaded # as well. # # Note that it is legal to have a thread enabled extension run in a # threaded or non-threaded Tcl core, but a non-threaded extension may # only run in a non-threaded Tcl core. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # _THREAD_SAFE #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_THREADS], [ AC_ARG_ENABLE(threads, AS_HELP_STRING([--enable-threads], [build with threads (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants: # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention AC_DEFINE(USE_THREAD_ALLOC, 1, [Do we want to use the threaded memory allocator?]) AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) if test "`uname -s`" = "SunOS" ; then AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) fi AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the same # library, as some systems hide it there until pthread.h is # defined. We could alternatively do an AC_TRY_COMPILE with # pthread.h, but that will work with libpthread really doesn't # exist, like AIX 4.2. [Bug: 4359] AC_CHECK_LIB(pthread, __pthread_mutex_init, tcl_ok=yes, tcl_ok=no) fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else AC_CHECK_LIB(pthreads, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else AC_CHECK_LIB(c, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "no"; then AC_CHECK_LIB(c_r, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled]) fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with threads]) if test "${TCL_THREADS}" = 1; then AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) AC_MSG_RESULT([yes (default)]) else AC_MSG_RESULT([no]) fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then AC_MSG_WARN([ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads.]) fi ;; esac AC_SUBST(TCL_THREADS) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SYMBOLS -- # # Specify if debugging symbols should be used. # Memory (TCL_MEM_DEBUG) debugging can also be enabled. # # Arguments: # none # # TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives # the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted. # Requires the following vars to be set in the Makefile: # CFLAGS_DEFAULT # LDFLAGS_DEFAULT # # Results: # # Adds the following arguments to configure: # --enable-symbols # # Defines the following vars: # CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true # Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false # LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true # Sets to $(LDFLAGS_OPTIMIZE) if false #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_CONFIG_CFLAGS]) AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, AS_HELP_STRING([--enable-symbols], [build with debugging symbols (default: off)]), [tcl_ok=$enableval], [tcl_ok=no]) if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" AC_MSG_RESULT([no]) AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?]) else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (standard debugging)]) fi fi AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEFAULT) if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then AC_MSG_RESULT([enabled symbols mem debugging]) else AC_MSG_RESULT([enabled $tcl_ok debugging]) fi fi ]) #------------------------------------------------------------------------ # TEA_ENABLE_LANGINFO -- # # Allows use of modern nl_langinfo check for better l10n. # This is only relevant for Unix. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-langinfo=yes|no (default is yes) # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_LANGINFO], [ AC_ARG_ENABLE(langinfo, AS_HELP_STRING([--enable-langinfo], [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]), [langinfo_ok=$enableval], [langinfo_ok=yes]) HAVE_LANGINFO=0 if test "$langinfo_ok" = "yes"; then AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) fi AC_MSG_CHECKING([whether to use nl_langinfo]) if test "$langinfo_ok" = "yes"; then AC_CACHE_VAL(tcl_cv_langinfo_h, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[nl_langinfo(CODESET);]])], [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])]) AC_MSG_RESULT([$tcl_cv_langinfo_h]) if test $tcl_cv_langinfo_h = yes; then AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) fi else AC_MSG_RESULT([$langinfo_ok]) fi ]) #-------------------------------------------------------------------- # TEA_CONFIG_SYSTEM # # Determine what the system is (some things cannot be easily checked # on a feature-driven basis, alas). This can usually be done via the # "uname" command. # # Arguments: # none # # Results: # Defines the following var: # # system - System/platform/version identification code. # #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_SYSTEM], [ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ # TEA specific: if test "${TEA_PLATFORM}" = "windows" ; then tcl_cv_sys_version=windows else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_WARN([can't find uname command]) tcl_cv_sys_version=unknown else if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi if test "`uname -s`" = "NetBSD" -a -f /etc/debian_version ; then tcl_cv_sys_version=NetBSD-Debian fi fi fi ]) system=$tcl_cv_sys_version ]) #-------------------------------------------------------------------- # TEA_CONFIG_CFLAGS # # Try to determine the proper flags to pass to the compiler # for building shared libraries and other such nonsense. # # Arguments: # none # # Results: # # Defines and substitutes the following vars: # # DL_OBJS, DL_LIBS - removed for TEA, only needed by core. # LDFLAGS - Flags to pass to the compiler when linking object # files into an executable application binary such # as tclsh. # LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. Could # be the same as CC_SEARCH_FLAGS if ${CC} is used to link. # CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. # SHLIB_CFLAGS - Flags to pass to cc when compiling the components # of a shared library (may request position-independent # code, among other things). # SHLIB_LD - Base command to use for combining object files # into a shared library. # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build # shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on # SunOS 4.x, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. # SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable # extensions. An empty string means we don't know how # to use shared libraries on this platform. # LIB_SUFFIX - Specifies everything that comes after the "libfoo" # in a static or shared library name, using the $PACKAGE_VERSION variable # to put the version in the right place. This is used # by platforms that need non-standard library names. # Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs # to have a version after the .so, and ${PACKAGE_VERSION}.a # on AIX, since a shared library needs to have # a .a extension whereas shared objects for loadable # extensions have a .so extension. Defaults to # ${PACKAGE_VERSION}${SHLIB_SUFFIX}. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_CFLAGS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # Step 0.a: Enable 64 bit support? AC_MSG_CHECKING([if 64bit support is requested]) AC_ARG_ENABLE(64bit, AS_HELP_STRING([--enable-64bit], [enable 64bit support (default: off)]), [do64bit=$enableval], [do64bit=no]) AC_MSG_RESULT([$do64bit]) # Step 0.b: Enable Solaris 64 bit VIS support? AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) AC_ARG_ENABLE(64bit-vis, AS_HELP_STRING([--enable-64bit-vis], [enable 64bit Sparc VIS support (default: off)]), [do64bitVIS=$enableval], [do64bitVIS=no]) AC_MSG_RESULT([$do64bitVIS]) # Force 64bit on with VIS AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes]) # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. AC_CACHE_CHECK([if compiler supports visibility "hidden"], tcl_cv_cc_visibility_hidden, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ extern __attribute__((__visibility__("hidden"))) void f(void); void f(void) {}]], [[f();]])],[tcl_cv_cc_visibility_hidden=yes], [tcl_cv_cc_visibility_hidden=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [ AC_DEFINE(MODULE_SCOPE, [extern __attribute__((__visibility__("hidden")))], [Compiler support for module scope symbols]) AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols]) ]) # Step 0.d: Disable -rpath support? AC_MSG_CHECKING([if rpath support is requested]) AC_ARG_ENABLE(rpath, AS_HELP_STRING([--disable-rpath], [disable rpath support (default: on)]), [doRpath=$enableval], [doRpath=yes]) AC_MSG_RESULT([$doRpath]) # Set the variable "system" to hold the name and version number # for the system. TEA_CONFIG_SYSTEM # Require ranlib early so we can override it in special cases below. AC_REQUIRE([AC_PROG_RANLIB]) # Set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and removed some core-only vars. do64bit_ok=no # default to '{$LIBS}' and set to "" on per-platform necessary basis SHLIB_LD_LIBS='${LIBS}' # When ld needs options to work in 64-bit mode, put them in # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] # is disabled by the user. [Bug 1016796] LDFLAGS_ARCH="" UNSHARED_LIB_SUFFIX="" # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall" ], [ CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" ]) AC_CHECK_TOOL(AR, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"]) case $system in # TEA specific: windows) MACHINE="X86" if test "$do64bit" != "no" ; then case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build ;; arm64|aarch64) MACHINE="ARM64" ;; ia64) MACHINE="IA64" ;; esac do64bit_ok=yes fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi case "x`echo \${VisualStudioVersion}`" in x1[[4-9]]*) lflags="${lflags} -nodefaultlib:ucrt.lib" TEA_ADD_LIBS([ucrt.lib]) ;; *) ;; esac if test "$do64bit" != "no" ; then CC="cl.exe" RC="rc.exe" lflags="${lflags} -nologo -MACHINE:${MACHINE} " LINKBIN="link.exe" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 TEA_ADD_LIBS([bufferoverflowU.lib]) else RC="rc" lflags="${lflags} -nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode AC_CHECK_TOOL(RC, windres) CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" SHLIB_LD='${CC} -shared' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" AC_CACHE_CHECK(for cross-compile version of gcc, ac_cv_cross, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef _WIN32 #error cross-compiler #endif ]], [[]])], [ac_cv_cross=yes], [ac_cv_cross=no]) ) if test "$ac_cv_cross" = "yes"; then case "$do64bit" in amd64|x64|yes) CC="x86_64-w64-mingw32-${CC}" LD="x86_64-w64-mingw32-ld" AR="x86_64-w64-mingw32-ar" RANLIB="x86_64-w64-mingw32-ranlib" RC="x86_64-w64-mingw32-windres" ;; arm64|aarch64) CC="aarch64-w64-mingw32-clang" LD="aarch64-w64-mingw32-ld" AR="aarch64-w64-mingw32-ar" RANLIB="aarch64-w64-mingw32-ranlib" RC="aarch64-w64-mingw32-windres" ;; *) CC="i686-w64-mingw32-${CC}" LD="i686-w64-mingw32-ld" AR="i686-w64-mingw32-ar" RANLIB="i686-w64-mingw32-ranlib" RC="i686-w64-mingw32-windres" ;; esac fi else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # and also # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx # This essentially turns it all on. LDFLAGS_DEBUG="-debug -debugtype:cv" LDFLAGS_OPTIMIZE="-release" LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots ;; AIX-*) AS_IF([test "$GCC" != "yes"], [ # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r|*_r\ *) # ok ... ;; *) # Make sure only first arg gets _r CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'` ;; esac AC_MSG_RESULT([Using $CC for compiling with threads]) ]) LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" LD_LIBRARY_PATH_VAR="LIBPATH" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported with GCC on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS_ARCH="-q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" ]) ]) AS_IF([test "`uname -m`" = ia64], [ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" AS_IF([test "$GCC" = yes], [ CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' ], [ CC_SEARCH_FLAGS='"-R${LIB_RUNTIME_DIR}"' ]) LD_SEARCH_FLAGS='-R "${LIB_RUNTIME_DIR}"' ], [ AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared -Wl,-bexpall' ], [ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry" LDFLAGS="$LDFLAGS -brtl" ]) SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" CC_SEARCH_FLAGS='"-L${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -nostart' SHLIB_SUFFIX=".so" #----------------------------------------------------------- # Check for inet_ntoa in -lbind, for BeOS (which also needs # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"]) ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".so" LDFLAGS="$LDFLAGS -export-dynamic" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; CYGWIN_*|MINGW32_*|MINGW64_*|MSYS_*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" if test "${TEA_PLATFORM}" = "unix" -a "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$(patsubst cyg%.dll,lib%.dll,\$[@]).a" else SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a" fi EXEEXT=".exe" do64bit_ok=yes CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; Haiku*) LDFLAGS="$LDFLAGS -Wl,--export-dynamic" SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"]) ;; HP-UX-*.11.*) # Use updated header definitions where possible AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) # TEA specific: Needed by Tcl, but not most extensions #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) #LIBS="$LIBS -lxnet" # Use the XOPEN network library AS_IF([test "`uname -m`" = ia64], [ SHLIB_SUFFIX=".so" ], [ SHLIB_SUFFIX=".sl" ]) AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='"-Wl,+s,+b,${LIB_RUNTIME_DIR}:."' LD_SEARCH_FLAGS='+s +b "${LIB_RUNTIME_DIR}:."' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ CFLAGS="$CFLAGS -z" ]) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = "yes"], [ AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]) ;; esac ], [ do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS_ARCH="+DD64" ]) ]) ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='"-Wl,+s,+b,${LIB_RUNTIME_DIR}:."' LD_SEARCH_FLAGS='+s +b "${LIB_RUNTIME_DIR}:."' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath "${LIB_RUNTIME_DIR}"']) ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath "${LIB_RUNTIME_DIR}"']) AS_IF([test "$GCC" = yes], [ CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" ], [ case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" ]) ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath "${LIB_RUNTIME_DIR}"']) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported by gcc]) ], [ do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS_ARCH="-64" ]) ]) ;; Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" # TEA specific: CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared' LDFLAGS="$LDFLAGS -Wl,--export-dynamic" case $system in DragonFly-*|FreeBSD-*) AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) ;; esac AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) AS_IF([test $do64bit = yes], [ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_m64=yes],[tcl_cv_cc_m64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_m64 = yes], [ CFLAGS="$CFLAGS -m64" do64bit_ok=yes ]) ]) # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) ;; OpenBSD-*) arch=`arch -s` case "$arch" in alpha|sparc64) SHLIB_CFLAGS="-fPIC" ;; *) SHLIB_CFLAGS="-fpic" ;; esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="$LDFLAGS -Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" # On OpenBSD: Compile with -pthread # Don't link with -lpthread LIBS=`echo $LIBS | sed s/-lpthread//` CFLAGS="$CFLAGS -pthread" # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; NetBSD-*) # NetBSD has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" # To avoid discrepancies between what headers configure sees during # preprocessing tests and compiling tests, move any -isysroot and # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`" CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`" AS_IF([test $do64bit = yes], [ case `arch` in ppc) AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag], tcl_cv_cc_arch_ppc64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_ppc64=yes],[tcl_cv_cc_arch_ppc64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes ]);; i386) AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag], tcl_cv_cc_arch_x86_64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_x86_64=yes],[tcl_cv_cc_arch_x86_64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [ CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes ]);; *) AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);; esac ], [ # Check for combined 32-bit and 64-bit fat build AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [ fat_32_64=yes]) ]) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' # TEA specific: link shlib with current and compatibility version flags vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" SHLIB_SUFFIX=".dylib" LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])], [tcl_cv_ld_search_paths_first=yes],[tcl_cv_ld_search_paths_first=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_search_paths_first = yes], [ LDFLAGS="$LDFLAGS -Wl,-search_paths_first" ]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [__private_extern__], [Compiler support for module scope symbols]) tcl_cv_cc_visibility_hidden=yes ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" # TEA specific: for combined 32 & 64 bit fat builds of Tk # extensions, verify that 64-bit build is possible. AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[XrmInitialize();]])], [tcl_cv_lib_x11_64=yes],[tcl_cv_lib_x11_64=no]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}" LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[Tk_InitStubs(NULL, "", 0);]])], [tcl_cv_lib_tk_64=yes],[tcl_cv_lib_tk_64=no]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) # remove 64-bit arch flags from CFLAGS et al. if configuration # does not support 64-bit. AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done]) ]) ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" AS_IF([test "$SHARED_BUILD" = 1], [ SHLIB_LD='ld -shared -expect_unresolved "*"' ], [ SHLIB_LD='ld -non_shared -expect_unresolved "*"' ]) SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) # see pthread_intro(3) for pthread support on osf1, k.furukawa CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` AS_IF([test "$GCC" = yes], [ LIBS="$LIBS -lpthread -lmach -lexc" ], [ CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SCO_SV-3.2*) AS_IF([test "$GCC" = yes], [ SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" ], [ SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" ]) SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" SHLIB_SUFFIX=".so" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ SHLIB_LD="/usr/ccs/bin/ld -G -z text" CC_SEARCH_FLAGS='-R "${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ arch=`isainfo` AS_IF([test "$arch" = "sparcv9 sparc"], [ AS_IF([test "$GCC" = yes], [ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" SHLIB_CFLAGS="-fPIC" ]) ], [ do64bit_ok=yes AS_IF([test "$do64bitVIS" = yes], [ CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" ], [ CFLAGS="$CFLAGS -xarch=v9" LDFLAGS_ARCH="-xarch=v9" ]) # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" ]) ], [AS_IF([test "$arch" = "amd64 i386"], [ AS_IF([test "$GCC" = yes], [ case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) do64bit_ok=yes CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]);; esac ], [ do64bit_ok=yes case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64";; esac ]) ], [AC_MSG_WARN([64bit mode not supported for $arch])])]) ]) SHLIB_SUFFIX=".so" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "$do64bit_ok" = yes], [ AS_IF([test "$arch" = "sparcv9 sparc"], [ # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" ], [AS_IF([test "$arch" = "amd64 i386"], [ # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" ])]) ]) ], [ case $system in SunOS-5.[[1-9]][[0-9]]*) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';; *) SHLIB_LD='/usr/ccs/bin/ld -G -z text';; esac CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-R "${LIB_RUNTIME_DIR}"' ]) ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])], [tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_Bexport = yes], [ LDFLAGS="$LDFLAGS -Wl,-Bexport" ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) ]) dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so dnl # until the end of configure, as configure's compile and link tests use dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's dnl # preprocessing tests use only CPPFLAGS. AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""]) # Add in the arch flags late to ensure it wasn't removed. # Not necessary in TEA, but this is aligned with core LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. AS_IF([test "$GCC" = yes], [ case $system in AIX-*) ;; BSD/OS*) ;; CYGWIN_*|MINGW32_*|MINGW64_*|MSYS_*) ;; IRIX*) ;; NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; SCO_SV-3.2*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [extern], [No Compiler support for module scope symbols]) ]) AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then AC_CACHE_CHECK(for SEH support in compiler, tcl_cv_seh, AC_RUN_IFELSE([AC_LANG_SOURCE([[ #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN int main(int argc, char** argv) { int a, b = 0; __try { a = 666 / b; } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } return 1; } ]])], [tcl_cv_seh=yes], [tcl_cv_seh=no], [tcl_cv_seh=no]) ) if test "$tcl_cv_seh" = "no" ; then AC_DEFINE(HAVE_NO_SEH, 1, [Defined when mingw does not support SEH]) fi # # Check to see if the excpt.h include file provided contains the # definition for EXCEPTION_DISPOSITION; if not, which is the case # with Cygwin's version as of 2002-04-10, define it to be int, # sufficient for getting the current code to work. # AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files, tcl_cv_eh_disposition, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN ]], [[ EXCEPTION_DISPOSITION x; ]])], [tcl_cv_eh_disposition=yes], [tcl_cv_eh_disposition=no]) ) if test "$tcl_cv_eh_disposition" = "no" ; then AC_DEFINE(EXCEPTION_DISPOSITION, int, [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION]) fi # Check to see if winnt.h defines CHAR, SHORT, and LONG # even if VOID has already been #defined. The win32api # used by mingw and cygwin is known to do this. AC_CACHE_CHECK(for winnt.h that ignores VOID define, tcl_cv_winnt_ignore_void, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define VOID void #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN ]], [[ CHAR c; SHORT s; LONG l; ]])], [tcl_cv_winnt_ignore_void=yes], [tcl_cv_winnt_ignore_void=no]) ) if test "$tcl_cv_winnt_ignore_void" = "yes" ; then AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1, [Defined when cygwin/mingw ignores VOID define in winnt.h]) fi fi # See if the compiler supports casting to a union type. # This is used to stop gcc from printing a compiler # warning when initializing a union member. AC_CACHE_CHECK(for cast to union support, tcl_cv_cast_to_union, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ union foo { int i; double d; }; union foo f = (union foo) (int) 0; ]])], [tcl_cv_cast_to_union=yes], [tcl_cv_cast_to_union=no]) ) if test "$tcl_cv_cast_to_union" = "yes"; then AC_DEFINE(HAVE_CAST_TO_UNION, 1, [Defined when compiler supports casting to union type.]) fi AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have ?])],) AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) AC_SUBST(CFLAGS_WARNING) AC_SUBST(LDFLAGS_DEBUG) AC_SUBST(LDFLAGS_OPTIMIZE) AC_SUBST(STLIB_LD) AC_SUBST(SHLIB_LD) AC_SUBST(SHLIB_LD_LIBS) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(LD_LIBRARY_PATH_VAR) # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary TEA_TCL_EARLY_FLAGS TEA_TCL_64BIT_FLAGS ]) #-------------------------------------------------------------------- # TEA_SERIAL_PORT # # Determine which interface to use to talk to the serial port. # Note that #include lines must begin in leftmost column for # some compilers to recognize them as preprocessor directives, # and some build environments have stdin not pointing at a # pseudo-terminal (usually /dev/null instead.) # # Arguments: # none # # Results: # # Defines only one of the following vars: # HAVE_SYS_MODEM_H # USE_TERMIOS # USE_TERMIO # USE_SGTTY #-------------------------------------------------------------------- AC_DEFUN([TEA_SERIAL_PORT], [ AC_CHECK_HEADERS(sys/modem.h) AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { struct termios t; if (tcgetattr(0, &t) == 0) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termios],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) if test $tcl_cv_api_serial = no ; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termio],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no ; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }]])],[tcl_cv_api_serial=sgtty],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no ; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main() { struct termios t; if (tcgetattr(0, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termios],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termio],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }]])],[tcl_cv_api_serial=sgtty],[tcl_cv_api_serial=none],[tcl_cv_api_serial=none]) fi]) case $tcl_cv_api_serial in termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; esac ]) #-------------------------------------------------------------------- # TEA_PATH_X # # Locate the X11 header files and the X11 library archive. Try # the ac_path_x macro first, but if it doesn't find the X stuff # (e.g. because there's no xmkmf program) then check through # a list of possible directories. Under some conditions the # autoconf macro will return an include directory that contains # no include files, so double-check its result just to be safe. # # This should be called after TEA_CONFIG_CFLAGS as setting the # LIBS line can confuse some configure macro magic. # # Arguments: # none # # Results: # # Sets the following vars: # XINCLUDES # XLIBSW # PKG_LIBS (appends to) #-------------------------------------------------------------------- AC_DEFUN([TEA_PATH_X], [ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then TEA_PATH_UNIX_X fi ]) AC_DEFUN([TEA_PATH_UNIX_X], [ AC_PATH_X not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])],[],[not_really_there="yes"]) else if test ! -r $x_includes/X11/Xlib.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) found_xincludes="no" AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])],[found_xincludes="yes"],[found_xincludes="no"]) if test "$found_xincludes" = "no"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Xlib.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" found_xincludes="yes" break fi done fi else if test "$x_includes" != ""; then XINCLUDES="-I$x_includes" found_xincludes="yes" fi fi if test "$found_xincludes" = "no"; then AC_MSG_RESULT([couldn't find any!]) fi if test "$no_x" = yes; then AC_MSG_CHECKING([for X11 libraries]) XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then AC_MSG_RESULT([$i]) XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test "$XLIBSW" = nope ; then AC_MSG_RESULT([could not find any! Using -lX11.]) XLIBSW=-lX11 fi # TEA specific: if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi ]) #-------------------------------------------------------------------- # TEA_BLOCKING_STYLE # # The statements below check for systems where POSIX-style # non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. # On these systems (mostly older ones), use the old BSD-style # FIONBIO approach instead. # # Arguments: # none # # Results: # # Defines some of the following vars: # HAVE_SYS_IOCTL_H # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK #-------------------------------------------------------------------- AC_DEFUN([TEA_BLOCKING_STYLE], [ AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/filio.h) TEA_CONFIG_SYSTEM AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) case $system in OSF*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; esac ]) #-------------------------------------------------------------------- # TEA_TIME_HANDLER # # Checks how the system deals with time.h, what time structures # are used on the system, and what fields the structures have. # # Arguments: # none # # Results: # # Defines some of the following vars: # USE_DELTA_FOR_TZ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR # #-------------------------------------------------------------------- AC_DEFUN([TEA_TIME_HANDLER], [ AC_CHECK_HEADERS(sys/time.h) AC_HEADER_TIME AC_STRUCT_TIMEZONE AC_CHECK_FUNCS(gmtime_r localtime_r mktime) AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct tm tm; (void)tm.tm_tzadj;]])], [tcl_cv_member_tm_tzadj=yes], [tcl_cv_member_tm_tzadj=no])]) if test $tcl_cv_member_tm_tzadj = yes ; then AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) fi AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct tm tm; (void)tm.tm_gmtoff;]])], [tcl_cv_member_tm_gmtoff=yes], [tcl_cv_member_tm_gmtoff=no])]) if test $tcl_cv_member_tm_gmtoff = yes ; then AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) fi # # Its important to include time.h in this check, as some systems # (like convex) have timezone functions, etc. # AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern long timezone; timezone += 1; exit (0);]])], [tcl_cv_timezone_long=yes], [tcl_cv_timezone_long=no])]) if test $tcl_cv_timezone_long = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) else # # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. # AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern time_t timezone; timezone += 1; exit (0);]])], [tcl_cv_timezone_time=yes], [tcl_cv_timezone_time=no])]) if test $tcl_cv_timezone_time = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) fi fi ]) #-------------------------------------------------------------------- # TEA_BUGGY_STRTOD # # Under Solaris 2.4, strtod returns the wrong value for the # terminating character under some conditions. Check for this # and if the problem exists use a substitute procedure # "fixstrtod" (provided by Tcl) that corrects the error. # Also, on Compaq's Tru64 Unix 5.0, # strtod(" ") returns 0.0 instead of a failure to convert. # # Arguments: # none # # Results: # # Might defines some of the following vars: # strtod (=fixstrtod) #-------------------------------------------------------------------- AC_DEFUN([TEA_BUGGY_STRTOD], [ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) if test "$tcl_strtod" = 1; then AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include extern double strtod(); int main() { char *infString="Inf", *nanString="NaN", *spaceString=" "; char *term; double value; value = strtod(infString, &term); if ((term != infString) && (term[-1] == 0)) { exit(1); } value = strtod(nanString, &term); if ((term != nanString) && (term[-1] == 0)) { exit(1); } value = strtod(spaceString, &term); if (term == (spaceString+1)) { exit(1); } exit(0); }]])], [tcl_cv_strtod_buggy=ok], [tcl_cv_strtod_buggy=buggy], [tcl_cv_strtod_buggy=buggy])]) if test "$tcl_cv_strtod_buggy" = buggy; then AC_LIBOBJ([fixstrtod]) USE_COMPAT=1 AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) fi fi ]) #-------------------------------------------------------------------- # TEA_TCL_LINK_LIBS # # Search for the libraries needed to link the Tcl shell. # Things like the math library (-lm), socket stuff (-lsocket vs. # -lnsl), zlib (-lz) and libtommath (-ltommath) are dealt with here. # # Arguments: # None. # # Results: # # Might append to the following vars: # LIBS # MATH_LIBS # # Might define the following vars: # HAVE_NET_ERRNO_H # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_LINK_LIBS], [ #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. #-------------------------------------------------------------------- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) AC_CHECK_HEADER(net/errno.h, [ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) if test "$tcl_checkSocket" = 1; then AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs]) fi AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBS="$LIBS -lnsl"])]) AC_CHECK_FUNC(mp_log_u32, , [AC_CHECK_LIB(tommath, mp_log_u32, [LIBS="$LIBS -ltommath"])]) AC_CHECK_FUNC(deflateSetHeader, , [AC_CHECK_LIB(z, deflateSetHeader, [LIBS="$LIBS -lz"])]) ]) #-------------------------------------------------------------------- # TEA_TCL_EARLY_FLAGS # # Check for what flags are needed to be passed so the correct OS # features are available. # # Arguments: # None # # Results: # # Might define the following vars: # _ISOC99_SOURCE # _FILE_OFFSET_BITS # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[ ]$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)])) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) AC_DEFUN([TEA_TCL_EARLY_FLAGS],[ AC_MSG_CHECKING([for required early compiler flags]) tcl_flags="" TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) if test "${TCL_MAJOR_VERSION}" -ne 8 ; then TEA_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include ], [switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64) fi if test "x${tcl_flags}" = "x" ; then AC_MSG_RESULT([none]) else AC_MSG_RESULT([${tcl_flags}]) fi ]) #-------------------------------------------------------------------- # TEA_TCL_64BIT_FLAGS # # Check for what is defined in the way of 64-bit features. # # Arguments: # None # # Results: # # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE # HAVE_STRUCT_DIRENT64, HAVE_DIR64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T # _TIME_BITS # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ AC_MSG_CHECKING([for 64-bit integer type]) AC_CACHE_VAL(tcl_cv_type_64bit,[ tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[__int64 value = (__int64) 0;]])], [tcl_type_64bit=__int64],[tcl_type_64bit="long long"]) # See if we could use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; }]])],[tcl_cv_type_64bit=${tcl_type_64bit}],[])]) if test "${tcl_cv_type_64bit}" = none ; then AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Do 'long' and 'long long' have the same size (64-bit)?]) AC_MSG_RESULT([yes]) elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # TEA specific: We actually want to use the default tcl.h checks in # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* AC_MSG_RESULT([using Tcl header defaults]) else AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, [What type should be used to define wide integers?]) AC_MSG_RESULT([${tcl_cv_type_64bit}]) # Now check for auxiliary declarations if test "${TCL_MAJOR_VERSION}" -ne 8 ; then AC_CACHE_CHECK([for 64-bit time_t], tcl_cv_time_t_64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])], [tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])]) if test "x${tcl_cv_time_t_64}" = "xno" ; then # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64 # which SC_TCL_EARLY_FLAGS has defined if necessary. AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64 #include ]], [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])], [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])]) if test "x${tcl_cv__time_bits}" = "xyes" ; then AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.]) fi fi fi AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct dirent64 p;]])], [tcl_cv_struct_dirent64=yes],[tcl_cv_struct_dirent64=no])]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) fi AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct dirent64 *p; DIR64 d = opendir64("."); p = readdir64(d); rewinddir64(d); closedir64(d);]])], [tcl_cv_DIR64=yes], [tcl_cv_DIR64=no])]) if test "x${tcl_cv_DIR64}" = "xyes" ; then AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in ?]) fi AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct stat64 p; ]])], [tcl_cv_struct_stat64=yes], [tcl_cv_struct_stat64=no])]) if test "x${tcl_cv_struct_stat64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?]) fi AC_CHECK_FUNCS(open64 lseek64) AC_MSG_CHECKING([for off64_t]) AC_CACHE_VAL(tcl_cv_type_off64_t,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[off64_t offset; ]])], [tcl_cv_type_off64_t=yes], [tcl_cv_type_off64_t=no])]) dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the dnl functions lseek64 and open64 are defined. if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi ]) ## ## Here ends the standard Tcl configuration bits and starts the ## TEA specific functions ## #------------------------------------------------------------------------ # TEA_INIT -- # # Init various Tcl Extension Architecture (TEA) variables. # This should be the first called TEA_* macro. # # Arguments: # none # # Results: # # Defines and substs the following vars: # CYGPATH # EXEEXT # Defines only: # TEA_VERSION # TEA_INITED # TEA_PLATFORM (windows or unix) # # "cygpath" is used on windows to generate native path names for include # files. These variables should only be used with the compiler and linker # since they generate native path names. # # EXEEXT # Select the executable extension based on the host type. This # is a lightweight replacement for AC_EXEEXT that doesn't require # a compiler. #------------------------------------------------------------------------ AC_DEFUN([TEA_INIT], [ TEA_VERSION="3.13" AC_MSG_CHECKING([TEA configuration]) if test x"${PACKAGE_NAME}" = x ; then AC_MSG_ERROR([ The PACKAGE_NAME variable must be defined by your TEA configure.ac]) fi AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) # If the user did not set CFLAGS, set it now to keep macros # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi case "`uname -s`" in *win32*|*WIN32*|*MINGW32_*|*MINGW64_*|*MSYS_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *CYGWIN_*) EXEEXT=".exe" # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG ;; *) CYGPATH=echo # Maybe we are cross-compiling.... case ${host_alias} in *mingw32*) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) EXEEXT="" TEA_PLATFORM="unix" ;; esac ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}]) AC_SUBST(EXEEXT) AC_SUBST(CYGPATH) # This package name must be replaced statically for AC_SUBST to work AC_SUBST(PKG_LIB_FILE) AC_SUBST(PKG_LIB_FILE8) AC_SUBST(PKG_LIB_FILE9) # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) AC_SUBST(PKG_TCL_SOURCES) AC_SUBST(PKG_HEADERS) AC_SUBST(PKG_INCLUDES) AC_SUBST(PKG_LIBS) AC_SUBST(PKG_CFLAGS) # Configure the installer. TEA_INSTALLER ]) #------------------------------------------------------------------------ # TEA_ADD_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_SOURCES # PKG_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_SOURCES], [ vars="$@" for i in $vars; do case $i in [\$]*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ -a ! -f "${srcdir}/macosx/$i" \ ; then AC_MSG_ERROR([could not find source file '$i']) fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done AC_SUBST(PKG_SOURCES) AC_SUBST(PKG_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_STUB_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_STUB_SOURCES # PKG_STUB_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_STUB_SOURCES], [ vars="$@" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ -a ! -f "${srcdir}/macosx/$i" \ ; then AC_MSG_ERROR([could not find stub source file '$i']) fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_TCL_SOURCES -- # # Specify one or more Tcl source files. These should be platform # independent runtime files. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_TCL_SOURCES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_TCL_SOURCES], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i']) fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done AC_SUBST(PKG_TCL_SOURCES) ]) #------------------------------------------------------------------------ # TEA_ADD_HEADERS -- # # Specify one or more source headers. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_HEADERS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_HEADERS], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find header file '${srcdir}/$i']) fi PKG_HEADERS="$PKG_HEADERS $i" done AC_SUBST(PKG_HEADERS) ]) #------------------------------------------------------------------------ # TEA_ADD_INCLUDES -- # # Specify one or more include dirs. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_INCLUDES], [ vars="$@" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done AC_SUBST(PKG_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_ADD_LIBS -- # # Specify one or more libraries. Users should check for # the right platform before adding to their list. For Windows, # libraries provided in "foo.lib" format will be converted to # "-lfoo" when using GCC (mingw). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_LIBS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_LIBS], [ vars="$@" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.[[lL]][[iI]][[bB]][$]/-l\1/'` fi PKG_LIBS="$PKG_LIBS $i" done AC_SUBST(PKG_LIBS) ]) #------------------------------------------------------------------------ # TEA_ADD_CFLAGS -- # # Specify one or more CFLAGS. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_CFLAGS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CFLAGS], [ PKG_CFLAGS="$PKG_CFLAGS $@" AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_ADD_CLEANFILES -- # # Specify one or more CLEANFILES. # # Arguments: # one or more file names to clean target # # Results: # # Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CLEANFILES], [ CLEANFILES="$CLEANFILES $@" ]) #------------------------------------------------------------------------ # TEA_PREFIX -- # # Handle the --prefix=... option by defaulting to what Tcl gave # # Arguments: # none # # Results: # # If --prefix or --exec-prefix was not specified, $prefix and # $exec_prefix will be set to the values given to Tcl when it was # configured. #------------------------------------------------------------------------ AC_DEFUN([TEA_PREFIX], [ if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}]) prefix=${TCL_PREFIX} else AC_MSG_NOTICE([--prefix defaulting to /usr/local]) prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then if test x"${TCL_EXEC_PREFIX}" != x; then AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) exec_prefix=${TCL_EXEC_PREFIX} else AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}]) exec_prefix=$prefix fi fi ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER_CC -- # # Do compiler checks the way we want. This is just a replacement # for AC_PROG_CC in TEA configure.ac files to make them cleaner. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER_CC], [ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. AC_PROG_CC AC_PROG_CPP #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- AC_PROG_MAKE_SET #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- AC_CHECK_TOOL(RANLIB, ranlib) #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- AC_OBJEXT AC_EXEEXT ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER -- # # Do compiler checks that use the compiler. This must go after # TEA_SETUP_COMPILER_CC, which does the actual compiler check. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER], [ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. AC_REQUIRE([TEA_SETUP_COMPILER_CC]) #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then AC_CACHE_CHECK([if the compiler understands -pipe], tcl_cv_cc_pipe, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_pipe=yes],[tcl_cv_cc_pipe=no]) CFLAGS=$hold_cflags]) if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi if test "${TCL_MAJOR_VERSION}" -lt 9 -a "${TCL_MINOR_VERSION}" -lt 7; then AC_DEFINE(Tcl_Size, int, [Is 'Tcl_Size' in ?]) fi #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- AC_C_BIGENDIAN(,,,[#]) ]) #------------------------------------------------------------------------ # TEA_MAKE_LIB -- # # Generate a line that can be used to build a shared/unshared library # in a platform independent manner. # # Arguments: # none # # Requires: # # Results: # # Defines the following vars: # CFLAGS - Done late here to note disturb other AC macros # MAKE_LIB - Command to execute to build the Tcl library; # differs depending on whether or not Tcl is being # compiled as a shared library. # MAKE_SHARED_LIB Makefile rule for building a shared library # MAKE_STATIC_LIB Makefile rule for building a static library # MAKE_STUB_LIB Makefile rule for building a stub library # VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL # VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE #------------------------------------------------------------------------ AC_DEFUN([TEA_MAKE_LIB], [ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${LDFLAGS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" AC_EGREP_CPP([manifest needed], [ #if defined(_MSC_VER) && _MSC_VER >= 1400 print("manifest needed") #endif ], [ # Could do a CHECK_PROG for mt, but should always be with MSVC8+ VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi" VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi" MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}" TEA_ADD_CLEANFILES([*.manifest]) ]) MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${LDFLAGS} \${LDFLAGS_DEFAULT} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "$TEA_PLATFORM" = "unix"; then PACKAGE_LIB_PREFIX8="lib" if test "$EXEEXT" = ".exe" -a "$SHARED_BUILD" != "0"; then PACKAGE_LIB_PREFIX9="cygtcl9" else PACKAGE_LIB_PREFIX9="libtcl9" fi else PACKAGE_LIB_PREFIX8="" PACKAGE_LIB_PREFIX9="tcl9" fi if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then PACKAGE_LIB_PREFIX="${PACKAGE_LIB_PREFIX9}" else PACKAGE_LIB_PREFIX="${PACKAGE_LIB_PREFIX8}" AC_DEFINE(TCL_MAJOR_VERSION, 8, [Compile for Tcl8?]) AC_DEFINE(TK_MAJOR_VERSION, 8, [Compile for Tk8?]) fi if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" fi SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" if test "$GCC" = "yes"; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc" fi AC_CACHE_CHECK([if the linker understands --disable-high-entropy-va], tcl_cv_ld_high_entropy, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--disable-high-entropy-va" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_ld_high_entropy=yes],[tcl_cv_ld_high_entropy=no]) CFLAGS=$hold_cflags]) if test $tcl_cv_ld_high_entropy = yes; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--disable-high-entropy-va" fi eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else if test "$GCC" = "yes"; then PACKAGE_LIB_PREFIX=lib${PACKAGE_LIB_PREFIX} fi eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub.a" else eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi if test "$GCC" = "yes"; then PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} fi # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" fi eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub.a" else eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi AC_SUBST(MAKE_LIB) AC_SUBST(MAKE_SHARED_LIB) AC_SUBST(MAKE_STATIC_LIB) AC_SUBST(MAKE_STUB_LIB) # Substitute STUB_LIB_FILE in case package creates a stub library too. AC_SUBST(PKG_STUB_LIB_FILE) AC_SUBST(RANLIB_STUB) AC_SUBST(VC_MANIFEST_EMBED_DLL) AC_SUBST(VC_MANIFEST_EMBED_EXE) ]) #------------------------------------------------------------------------ # TEA_LIB_SPEC -- # # Compute the name of an existing object library located in libdir # from the given base name and produce the appropriate linker flags. # # Arguments: # basename The base name of the library without version # numbers, extensions, or "lib" prefixes. # extra_dir Extra directory in which to search for the # library. This location is used first, then # $prefix/$exec-prefix, then some defaults. # # Requires: # TEA_INIT and TEA_PREFIX must be called first. # # Results: # # Defines the following vars: # ${basename}_LIB_NAME The computed library name. # ${basename}_LIB_SPEC The computed linker flags. #------------------------------------------------------------------------ AC_DEFUN([TEA_LIB_SPEC], [ AC_MSG_CHECKING([for $1 library]) # Look in exec-prefix for the library (defined by TEA_PREFIX). tea_lib_name_dir="${exec_prefix}/lib" # Or in a user-specified location. if test x"$2" != x ; then tea_extra_lib_dir=$2 else tea_extra_lib_dir=NONE fi for i in \ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do if test -f "$i" ; then tea_lib_name_dir=`dirname $i` $1_LIB_NAME=`basename $i` $1_LIB_PATH_NAME=$i break fi done if test "${TEA_PLATFORM}" = "windows"; then $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\" else # Strip off the leading "lib" and trailing ".a" or ".so" tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'` $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}" fi if test "x${$1_LIB_NAME}" = x ; then AC_MSG_ERROR([not found]) else AC_MSG_RESULT([${$1_LIB_SPEC}]) fi ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TCL_HEADERS -- # # Locate the private Tcl include files # # Arguments: # # Requires: # TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has # already been called. # # Results: # # Substitutes the following vars: # TCL_TOP_DIR_NATIVE # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh} AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS]) AC_MSG_CHECKING([for Tcl private include files]) TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" # Check to see if tclPort.h isn't already with the public headers # Don't look for tclInt.h because that resides with tcl.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tclh}/tclWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then result="private headers found with public headers" else TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" if test "${TEA_PLATFORM}" = "windows"; then TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" else TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TCL_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -d "${TCL_BIN_DIR}/Headers" -a \ -d "${TCL_BIN_DIR}/PrivateHeaders"; then TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}" else TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TCL_INCLUDES}" else if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}]) fi result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" fi fi AC_SUBST(TCL_TOP_DIR_NATIVE) AC_SUBST(TCL_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TCL_HEADERS -- # # Locate the installed public Tcl header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tclinclude switch to configure. # Result is cached. # # Substitutes the following vars: # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [ AC_MSG_CHECKING([for Tcl public headers]) AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tclh, [ # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h]) fi else list="" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "${TCL_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude]) else AC_MSG_RESULT([${ac_cv_c_tclh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TCL_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TK_HEADERS -- # # Locate the private Tk include files # # Arguments: # # Requires: # TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has # already been called. # # Results: # # Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh} AC_REQUIRE([TEA_PUBLIC_TK_HEADERS]) AC_MSG_CHECKING([for Tk private include files]) TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}` TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\" # Check to see if tkPort.h isn't already with the public headers # Don't look for tkInt.h because that resides with tk.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tkh}/tkWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then result="private headers found with public headers" else TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\" TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\" if test "${TEA_PLATFORM}" = "windows"; then TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\" else TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TK_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}" # Detect and add ttk subdir if test -d "${TK_SRC_DIR}/generic/ttk"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\"" fi if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\"" fi if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\"" fi if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TK_DEFS} in *TK_FRAMEWORK*) if test -d "${TK_BIN_DIR}/Headers" -a \ -d "${TK_BIN_DIR}/PrivateHeaders"; then TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}" else TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TK_INCLUDES}" else if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}]) fi result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}" fi fi AC_SUBST(TK_TOP_DIR_NATIVE) AC_SUBST(TK_XLIB_DIR_NATIVE) AC_SUBST(TK_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TK_HEADERS -- # # Locate the installed public Tk header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tkinclude switch to configure. # Result is cached. # # Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [ AC_MSG_CHECKING([for Tk public headers]) AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tkh, [ # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h]) fi else list="" if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "${TK_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TK_INCLUDE_SPEC}" != x ; then d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude]) else AC_MSG_RESULT([${ac_cv_c_tkh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_INCLUDES) if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then # On Windows and Aqua, we need the X compat headers AC_MSG_CHECKING([for X11 header files]) if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_XINCLUDES) fi AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}]) fi ]) #------------------------------------------------------------------------ # TEA_PATH_CONFIG -- # # Locate the ${1}Config.sh file and perform a sanity check on # the ${1} compile flags. These are used by packages like # [incr Tk] that load *Config.sh files from more than Tcl and Tk. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-$1=... # # Defines the following vars: # $1_BIN_DIR Full path to the directory containing # the $1Config.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_CONFIG], [ # # Ok, lets find the $1 configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-$1 # if test x"${no_$1}" = x ; then # we reset no_$1 in case something fails here no_$1=true AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) AC_MSG_CHECKING([for $1 configuration]) AC_CACHE_VAL(ac_cv_c_$1config,[ # First check to see if --with-$1 was specified. if test x"${with_$1config}" != x ; then case ${with_$1config} in */$1Config.sh ) if test -f ${with_$1config}; then AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself]) with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'` fi;; esac if test -f "${with_$1config}/$1Config.sh" ; then ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` else AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) fi fi # then check for a private $1 installation if test x"${ac_cv_c_$1config}" = x ; then for i in \ ../$1 \ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../$1 \ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../../$1 \ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ${srcdir}/../$1 \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi if test -f "$i/unix/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_$1config}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_$1config}" = x ; then $1_BIN_DIR="# no $1 configs found" AC_MSG_WARN([Cannot find $1 configuration definitions]) exit 0 else no_$1= $1_BIN_DIR=${ac_cv_c_$1config} AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG -- # # Load the $1Config.sh file # # Arguments: # # Requires the following vars to be set: # $1_BIN_DIR # # Results: # # Substitutes the following vars: # $1_SRC_DIR # $1_LIB_FILE # $1_LIB_SPEC #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG], [ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh]) if test -f "${$1_BIN_DIR}/$1Config.sh" ; then AC_MSG_RESULT([loading]) . "${$1_BIN_DIR}/$1Config.sh" else AC_MSG_RESULT([file not found]) fi # # If the $1_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable $1_LIB_SPEC will be set to the value # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC # instead of $1_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f "${$1_BIN_DIR}/Makefile" ; then AC_MSG_WARN([Found Makefile - using build library specs for $1]) $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC} $1_LIBRARY_PATH=${$1_LIBRARY_PATH} fi AC_SUBST($1_VERSION) AC_SUBST($1_BIN_DIR) AC_SUBST($1_SRC_DIR) AC_SUBST($1_LIB_FILE) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_STUB_LIB_FILE) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_PATH) # Allow the caller to prevent this auto-check by specifying any 2nd arg AS_IF([test "x$2" = x], [ # Check both upper and lower-case variants # If a dev wanted non-stubs libs, this function could take an option # to not use _STUB in the paths below AS_IF([test "x${$1_STUB_LIB_SPEC}" = x], [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)], [TEA_LOAD_CONFIG_LIB($1_STUB)]) ]) ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG_LIB -- # # Helper function to load correct library from another extension's # ${PACKAGE}Config.sh. # # Results: # Adds to LIBS the appropriate extension library #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG_LIB], [ AC_MSG_CHECKING([For $1 library for LIBS]) # This simplifies the use of stub libraries by automatically adding # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS, # but this is called before CONFIG_CFLAGS. More importantly, this adds # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD. if test "x${$1_LIB_SPEC}" != "x" ; then if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"]) AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}]) else TEA_ADD_LIBS([${$1_LIB_SPEC}]) AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}]) fi else AC_MSG_RESULT([file not found]) fi ]) #------------------------------------------------------------------------ # TEA_EXPORT_CONFIG -- # # Define the data to insert into the ${PACKAGE}Config.sh file # # Arguments: # # Requires the following vars to be set: # $1 # # Results: # Substitutes the following vars: #------------------------------------------------------------------------ AC_DEFUN([TEA_EXPORT_CONFIG], [ #-------------------------------------------------------------------- # These are for $1Config.sh #-------------------------------------------------------------------- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib) eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}" eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}" else eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`" eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`" fi if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then eval $1_STUB_LIB_FLAG="-l$1stub" fi $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}" $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}" $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}" $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}" $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}" $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}" AC_SUBST($1_BUILD_LIB_SPEC) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_BUILD_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_BUILD_STUB_LIB_PATH) AC_SUBST($1_STUB_LIB_PATH) AC_SUBST(MAJOR_VERSION) AC_SUBST(MINOR_VERSION) AC_SUBST(PATCHLEVEL) ]) #------------------------------------------------------------------------ # TEA_INSTALLER -- # # Configure the installer. # # Arguments: # none # # Results: # Substitutes the following vars: # INSTALL # INSTALL_DATA_DIR # INSTALL_DATA # INSTALL_PROGRAM # INSTALL_SCRIPT # INSTALL_LIBRARY #------------------------------------------------------------------------ AC_DEFUN([TEA_INSTALLER], [ INSTALL='$(SHELL) $(top_srcdir)/tclconfig/install-sh -c' INSTALL_DATA_DIR='${INSTALL} -d -m 755' INSTALL_DATA='${INSTALL} -m 644' INSTALL_PROGRAM='${INSTALL} -m 755' INSTALL_SCRIPT='${INSTALL} -m 755' TEA_CONFIG_SYSTEM case $system in HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;; *) INSTALL_LIBRARY='${INSTALL} -m 644' ;; esac AC_SUBST(INSTALL) AC_SUBST(INSTALL_DATA_DIR) AC_SUBST(INSTALL_DATA) AC_SUBST(INSTALL_PROGRAM) AC_SUBST(INSTALL_SCRIPT) AC_SUBST(INSTALL_LIBRARY) ]) ### # Tip 430 - ZipFS Modifications ### #------------------------------------------------------------------------ # TEA_ZIPFS_SUPPORT # Locate a zip encoder installed on the system path, or none. # # Arguments: # none # # Results: # Substitutes the following vars: # MACHER_PROG # ZIP_PROG # ZIP_PROG_OPTIONS # ZIP_PROG_VFSSEARCH # ZIP_INSTALL_OBJS #------------------------------------------------------------------------ AC_DEFUN([TEA_ZIPFS_SUPPORT], [ MACHER_PROG="" ZIP_PROG="" ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" AC_MSG_CHECKING([for macher]) AC_CACHE_VAL(ac_cv_path_macher, [ search_path=`echo ${PATH} | sed -e 's/:/ /g'` for dir in $search_path ; do for j in `ls -r $dir/macher 2> /dev/null` \ `ls -r $dir/macher 2> /dev/null` ; do if test x"$ac_cv_path_macher" = x ; then if test -f "$j" ; then ac_cv_path_macher=$j break fi fi done done ]) if test -f "$ac_cv_path_macher" ; then MACHER_PROG="$ac_cv_path_macher" AC_MSG_RESULT([$MACHER_PROG]) AC_MSG_RESULT([Found macher in environment]) fi AC_MSG_CHECKING([for zip]) AC_CACHE_VAL(ac_cv_path_zip, [ search_path=`echo ${PATH} | sed -e 's/:/ /g'` for dir in $search_path ; do for j in `ls -r $dir/zip 2> /dev/null` \ `ls -r $dir/zip 2> /dev/null` ; do if test x"$ac_cv_path_zip" = x ; then if test -f "$j" ; then ac_cv_path_zip=$j break fi fi done done ]) if test -f "$ac_cv_path_zip" ; then ZIP_PROG="$ac_cv_path_zip" AC_MSG_RESULT([$ZIP_PROG]) ZIP_PROG_OPTIONS="-rq" ZIP_PROG_VFSSEARCH="*" AC_MSG_RESULT([Found INFO Zip in environment]) # Use standard arguments for zip else # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}" ZIP_PROG_OPTIONS="-o -r" ZIP_PROG_VFSSEARCH="*" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH. Building minizip]) fi AC_SUBST(MACHER_PROG) AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) AC_SUBST(ZIP_PROG_VFSSEARCH) AC_SUBST(ZIP_INSTALL_OBJS) ]) # Local Variables: # mode: autoconf # End: rivet-3.3.1/tests/cookies.rvt000664 001750 001751 00000000320 15245054302 016750 0ustar00manghimanghi000000 000000 rivet-3.3.1/doc/rivet.xml000664 001750 001751 00000014045 15245054302 016046 0ustar00manghimanghi000000 000000 ]>
    Apache Rivet &version; 2002- Apache Software Foundation The Rivet Team The Apache Software Foundation
    rivet-dev@tcl.apache.org
    This manual is released as part of Apache/Rivet &fullversion; (). &intro.xml; &install.xml; &cmake.xml; &directives.xml; &processing.xml; &request.xml; &commands.xml; &examples.xml; &packages.xml; &dio.xml; &diodisplay.xml; &session.xml; &form.xml; &calendar.xml; &entities.xml; &asciiglyphs.xml; &formbroker.xml; &help.xml; &internals.xml; &lazybridge.xml;
    rivet-3.3.1/rivet/packages/tclrivet/parse.tcl000775 001750 001751 00000001132 15245054302 022003 0ustar00manghimanghi000000 000000 #!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" # Parse a rivet file and execute it. if {![info exists argv]} { return } # more consistent manipulation of auto_path as suggested by # Harald Oehlmann. Fixes bug #52898 set auto_path [linsert $auto_path 0 [file dirname [info script]]] package require tclrivet proc main {} { global argv for {set i 0} {$i < [llength $argv] - 1} {incr i} { source [lindex $argv $i] } set script [rivet::parserivet [lindex $argv end]] if { [catch {eval $script } err] } { puts "Error: $err" } } main rivet-3.3.1/doc/html/escape_shell_command.html000664 001750 001751 00000005555 15245054474 022172 0ustar00manghimanghi000000 000000 escape_shell_command

    Name

    escape_shell_command — escape shell metacharacters in a string.

    Synopsis

    ::rivet::escape_shell_command ?string?

    Description

    Scans through each character in the specified string looking for any shell metacharacters, such as asterisk, less than and greater than, parens, square brackets, curly brackets, angle brackets, dollar signs, backslashes, semicolons, ampersands, vertical bars, etc.

    For each metacharacter found, it is quoted in the result by prepending it with a backslash, returning the result.

    rivet-3.3.1/rivet/packages/rivet_ncgi/000775 001750 001751 00000000000 15245054302 020462 5ustar00manghimanghi000000 000000 rivet-3.3.1/rivet/packages/session/session-create-oracle.sql000664 001750 001751 00000001563 15245054302 024731 0ustar00manghimanghi000000 000000 -- -- Session management database creation for Oracle -- -- Arnulf -- CREATE TABLE rivet_session (ip_address VARCHAR2(23) DEFAULT NULL, session_start_time DATE DEFAULT NULL, session_update_time DATE DEFAULT NULL, session_id VARCHAR2(64) NOT NULL ) / ALTER TABLE rivet_session ADD PRIMARY KEY (session_id) / CREATE TABLE rivet_session_cache (session_id VARCHAR2(128) DEFAULT NULL, package_ VARCHAR2(128) DEFAULT NULL, key_ VARCHAR2(256) DEFAULT NULL, data VARCHAR2(4096) DEFAULT NULL ) / CREATE UNIQUE INDEX riv_sess_cache_ix ON rivet_session_cache ( session_id, package_, key_ ) / CREATE INDEX rivet_session_cache_idx ON rivet_session_cache ( session_id ) rivet-3.3.1/doc/html/diodisplay.html000664 001750 001751 00000003506 15245054474 020200 0ustar00manghimanghi000000 000000 DIODisplay - Database Interface Objects Display Class

    DIODisplay - Database Interface Objects Display Class

    rivet-3.3.1/rivet/rivet-tcl/lmatch.tcl000664 001750 001751 00000002734 15245054302 020446 0ustar00manghimanghi000000 000000 ### ## ## lmatch ?-exact|-glob|-regexp? ## ## Look for elements in that match . This command emulates ## the TclX lmatch command, but if TclX isn't available, it's a decent ## substitute. ## ## Note: Native Tcl's "lsearch" has been greatly enhanced since lmatch was ## written -- programmers should consider using lmatch instead. ## ## $Id$ ## ### namespace eval ::rivet { proc lmatch {args} { set modes(-exact) 0 set modes(-glob) 1 set modes(-regexp) 2 if {[llength $args] == 3} { lassign $args mode list pattern } elseif {[llength $args] == 2} { set mode -glob lassign $args list pattern } else { return -code error \ {wrong # args: should be "lmatch ?mode? list pattern"} } if {![info exists modes($mode)]} { return -code error \ "bad search mode \"$mode\": must be -exact, -glob, or -regexp" } set mode $modes($mode) set return {} foreach elem $list { if {$mode == 0} { if {[string compare $elem $pattern] == 0} { lappend return $elem } } if {$mode == 1} { if {[string match $pattern $elem]} { lappend return $elem } } if {$mode == 2} { if {[regexp $pattern $elem]} { lappend return $elem } } } return $return } } rivet-3.3.1/doc/examples/hello1.rvt000664 001750 001751 00000000025 15245054302 017723 0ustar00manghimanghi000000 000000 rivet-3.3.1/rivet/packages/session/session-create-postgresql.sql000664 001750 001751 00000001125 15245054302 025661 0ustar00manghimanghi000000 000000 -- -- Define SQL tables for session management code (Postgresql) -- -- $Id$ -- -- create table rivet_session( ip_address inet, session_start_time timestamp, session_update_time timestamp, session_id varchar, UNIQUE( session_id ) ); create table rivet_session_cache( session_id varchar REFERENCES rivet_session(session_id) ON DELETE CASCADE, package_ varchar, key_ varchar, data varchar, UNIQUE( session_id, package_, key_ ) ); create index rivet_session_cache_idx ON rivet_session_cache( session_id ); rivet-3.3.1/rivet/packages/dio/dio11.tcl000664 001750 001751 00000066675 15245054302 020551 0ustar00manghimanghi000000 000000 # dio.tcl -- implements a database abstraction layer. # Copyright 2002-2004 The Apache Software Foundation # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. catch {package require Tclx} package require Itcl ##set auto_path [linsert $auto_path 0 [file dirname [info script]]] namespace eval ::DIO { proc handle {interface args} { set obj \#auto set first [lindex $args 0] if {![::rivet::lempty $first] && [string index $first 0] != "-"} { set obj [lindex $args 0] set args [lreplace $args 0 0] } uplevel \#0 package require dio_$interface return [uplevel \#0 ::DIO::$interface $obj $args] } ## # DATABASE CLASS ## ::itcl::class Database { constructor {args} { eval configure $args } destructor { close } # # result - generate a new DIO result object for the specified database # interface, with key-value pairs that get configured into the new # result object. # protected method result {interface args} { return [eval uplevel \#0 ::DIO::${interface}Result \#auto $args] } # # quote - given a string, return the same string with any single # quote characters preceded by a backslash # method quote {string} { regsub -all {'} $string {\'} string return $string } # # build_select_query - build a select query based on given arguments, # which can include a table name, a select statement, switches to # turn on boolean AND or OR processing, and possibly # some key-value pairs that cause the where clause to be # generated accordingly # protected method build_select_query {args} { set bool AND set first 1 set req "" set myTable $table set what "*" # for each argument passed us... # (we go by integers because we mess with the index based on # what we find) for {set i 0} {$i < [llength $args]} {incr i} { # fetch the argument we're currently processing set elem [lindex $args $i] switch -- [::string tolower $elem] { "-and" { # -and -- switch to AND-style processing set bool AND } "-or" { # -or -- switch to OR-style processing set bool OR } "-table" { # -table -- identify which table the query is about set myTable [lindex $args [incr i]] } "-select" { # -select - set what [lindex $args [incr i]] } default { # it wasn't -and, -or, -table, or -select... # if the first character of the element is a dash, # it's a field name and a value if {[::string index $elem 0] == "-"} { set field [::string range $elem 1 end] set elem [lindex $args [incr i]] # if it's the first field being processed, append # WHERE to the SQL request we're generating if {$first} { append req " WHERE" set first 0 } else { # it's not the first variable in the comparison # expression, so append the boolean state, either # AND or OR append req " $bool" } # convert any asterisks to percent signs in the # value field regsub -all {\*} $elem {%} elem # if there is a percent sign in the value # field now (having been there originally or # mapped in there a moment ago), the SQL aspect # is appended with a "field LIKE value" if {[::string first {%} $elem] != -1} { append req " $field LIKE [makeDBFieldValue $myTable $field $elem]" } elseif {[regexp {^([<>]) *([0-9.]*)$} $elem _ fn val]} { # value starts with <, or >, then space, # and a something append req " $field$fn$val" } elseif {[regexp {^([<>]=) *([0-9.]*)$} $elem _ fn val]} { # value starts with <= or >=, space, and something. append req " $field$fn$val" } else { # otherwise it's a straight key=value comparison append req " $field=[makeDBFieldValue $myTable $field $elem]" } continue } append req " $elem" } } } return "select $what from $myTable $req" } # # build_insert_query -- given an array name, a list of fields, and # possibly a table name, return a SQL insert statement inserting # into the named table (or the object's table variable, if none # is specified) for all of the fields specified, with their values # coming from the array # protected method build_insert_query {arrayName fields {myTable ""}} { upvar 1 $arrayName array if {[::rivet::lempty $myTable]} { set myTable $table } set vals [::list] set vars [::list] foreach field $fields { if {![info exists array($field)]} { continue } lappend vars "$field" lappend vals "[makeDBFieldValue $myTable $field $array($field)]" } return "insert into $myTable ([join $vars {,}]) VALUES ([join $vals {,}])" } # # build_update_query -- given an array name, a list of fields, and # possibly a table name, return a SQL update statement updating # the named table (or using object's table variable, if none # is named) for all of the fields specified, with their values # coming from the array # # note that after use a where clause still neds to be added or # you might update a lot more than you bargained for # protected method build_update_query {arrayName fields {myTable ""}} { upvar 1 $arrayName array if {[::rivet::lempty $myTable]} { set myTable $table } set string [::list] foreach field $fields { if {![info exists array($field)]} { continue } lappend string "$field=[makeDBFieldValue $myTable $field $array($field)]" } return "UPDATE $myTable SET [join $string {,}]" } # # lassign_array - given a list, an array name, and a variable number # of arguments consisting of variable names, assign each element in # the list, in turn, to elements corresponding to the variable # arguments, into the named array. From TclX. # protected method lassign_array {list arrayName args} { upvar 1 $arrayName array foreach elem $list field $args { set array($field) $elem } } # # configure_variable - given a variable name and a string, if the # string is empty return the variable name, otherwise set the # variable to the string. # protected method configure_variable {varName string} { if {[::rivet::lempty $string]} { return [cget -$varName] } configure -$varName $string } # # build_where_key_clause - given a list of one or more key fields and # a corresponding list of one or more key values, construct a # SQL where clause that boolean ANDs all of the key-value pairs # together. # protected method build_key_where_clause {myKeyfield myKey} { ## If we're not using multiple keyfields, just return a simple ## where clause. if {[llength $myKeyfield] < 2} { return " WHERE $myKeyfield = [makeDBFieldValue $table $myKeyfield $myKey]" } # multiple fields, construct it as a where-and set req " WHERE 1 = 1" foreach field $myKeyfield key $myKey { append req " AND $field = [makeDBFieldValue $table $field $key]" } return $req } ## ## makekey -- Given an array containing a key-value pairs and # an optional list of key fields (we use the object's keyfield # if none is specified)... # # if we're doing auto keys, create and return a new key, # otherwise if it's a single key, just return its value # from the array, else if it's multiple keys, return all their # values as a list ## method makekey {arrayName {myKeyfield ""}} { if {[::rivet::lempty $myKeyfield]} { set myKeyfield $keyfield } if {[::rivet::lempty $myKeyfield]} { return -code error "No -keyfield specified in object" } upvar 1 $arrayName array ## If we're not using multiple keyfields, we want to check and see ## if we're using auto keys. If we are, create a new key and ## return it. If not, just return the value of the single keyfield ## in the array. if {[llength $myKeyfield] < 2} { if {$autokey} { set array($myKeyfield) [$this nextkey] } else { if {![info exists array($myKeyfield)]} { return -code error \ "${arrayName}($myKeyfield) does not exist" } } return $array($myKeyfield) } ## We're using multiple keys. Return a list of all the keyfield ## values. foreach field $myKeyfield { if {![info exists array($field)]} { return -code error "$field does not exist in $arrayName" } lappend key $array($field) } return $key } method destroy {} { ::itcl::delete object $this } # # string - execute a SQL request and only return a string of one row. # method string {req} { set res [exec $req] $res next -list val $res destroy return $val } # # list - execute a request and return a list of the first element of each # row returned. # method list {req} { set res [exec $req] set list "" $res forall -list line { lappend list [lindex $line 0] } $res destroy return $list } # # array - execute a request and setup an array containing elements # with the field names as the keys and the first row results as # the values # method array {req arrayName} { upvar 1 $arrayName $arrayName set res [exec $req] set ret [$res next -array $arrayName] $res destroy return $ret } # # forall - execute a SQL select and iteratively fill the named array # with elements named with the matching field names, containing the # matching values, executing the specified code body for each, in turn. # method forall {req arrayName body} { upvar 1 $arrayName $arrayName set res [exec $req] $res forall -array $arrayName { uplevel 1 $body } if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } set ret [$res numrows] $res destroy return $ret } # # table_check - internal method to populate the data array with # a -table element containing the table name, a -keyfield element # containing the key field or list of key fields, and a list of # key-value pairs to get set into the data table. # # afterwards, it's an error if -table or -keyfield hasn't somehow been # determined. # protected method table_check {list {tableVar myTable} {keyVar myKeyfield}} { upvar 1 $tableVar $tableVar $keyVar $keyVar set data(-table) $table set data(-keyfield) $keyfield ::array set data $list if {[::rivet::lempty $data(-table)]} { return -code error -errorcode missing_table "-table not specified in DIO object" } set $tableVar $data(-table) if {[::rivet::lempty $data(-keyfield)]} { return -code error -errorcode missing_keyfield "-keyfield not specified in DIO object" } set $keyVar $data(-keyfield) } # # key_check - given a list of key fields and a list of keys, it's # an error if there aren't the same number of each, and if it's # autokey, there can't be more than one key. # protected method key_check {myKeyfield myKey} { if {[llength $myKeyfield] < 2} { return } if {$autokey} { return -code error "Cannot have autokey and multiple keyfields" } if {[llength $myKeyfield] != [llength $myKey]} { return -code error "Bad key length." } } # # fetch - given a key (or list of keys) an array name, and some # extra key-value arguments like -table and -keyfield, fetch # the key into the array # method fetch {key arrayName args} { table_check $args key_check $myKeyfield $key upvar 1 $arrayName $arrayName set req "select * from $myTable" append req [build_key_where_clause $myKeyfield $key] set res [$this exec $req] if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } set rows_found [expr [$res numrows] > 0] $res next -array $arrayName $res destroy return $rows_found } # # store - given an array containing key-value pairs and optional # arguments like -table and -keyfield, insert or update the # corresponding table entry. # method store {arrayName args} { table_check $args upvar 1 $arrayName $arrayName $arrayName array if {[llength $myKeyfield] > 1 && $autokey} { return -code error "Cannot have autokey and multiple keyfields" } set key [makekey $arrayName $myKeyfield] set req "select * from $myTable" append req [build_key_where_clause $myKeyfield $key] set res [exec $req] if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } set numrows [$res numrows] $res destroy if {$numrows} { $this update $arrayName {*}$args } else { $this insert $myTable $arrayName } return 1 } # # update - a pure update, without store's somewhat clumsy # efforts to see if it needs to be an update rather than # an insert # method update {arrayName args} { table_check $args upvar 1 $arrayName $arrayName $arrayName array set key [makekey $arrayName $myKeyfield] set fields [::array names array] set req [build_update_query array $fields $myTable] append req [build_key_where_clause $myKeyfield $key] set res [exec $req] if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } # this doesn't work on postgres, you've got to use cmdRows, # we need to figure out what to do with this set numrows [$res numrows] $res destroy return $numrows } # # update_with_explicit_key - an update where the key is specified # as an argument to the proc rather than being dug out of the array # # this is a kludge until we come up with a better way to # solve the problem of updating a row where we actually # want to change the value of a key field # method update_with_explicit_key {key arrayName args} { table_check $args key_check $myKeyfield $key upvar 1 $arrayName $arrayName $arrayName array set fields [::array names array] set req [build_update_query array $fields $myTable] append req [build_key_where_clause $myKeyfield $key] set res [exec $req] if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } # this doesn't work on postgres, you've got to use cmdRows, # we need to figure out what to do with this set numrows [$res numrows] $res destroy return $numrows } # # insert - a pure insert, without store's somewhat clumsy # efforts to see if it needs to be an update rather than # an insert -- this shouldn't require fields, it's broken # method insert {table arrayName} { upvar 1 $arrayName $arrayName $arrayName array set req [build_insert_query array [::array names array] $table] set res [exec $req] if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } $res destroy return 1 } # # delete - delete matching record from the specified table # method delete {key args} { table_check $args set req "DELETE FROM $myTable" append req [build_key_where_clause $myKeyfield $key] set res [exec $req] if {[$res error]} { set errinf [$res errorinfo] $res destroy return -code error "Got '$errinf' executing '$req'" } set n_deleted_rows [$res numrows] $res destroy return $n_deleted_rows } # # keys - return all keys in a table # method keys {args} { table_check $args set req "select * from $myTable" set obj [$this exec $req] set keys "" $obj forall -array a { lappend keys [makekey a $myKeyfield] } $obj destroy return $keys } # # search - construct and execute a SQL select statement using # build_select_query style and return the result handle. # method search {args} { set req [eval build_select_query $args] return [exec $req] } # # count - return a count of the specified (or current) table. # method count {args} { # table_check returns an error if either a keyfield or a table were not set. # In order to count the rows in a table we don't need a keyfield, so we check # if table_check is returning missing_table and in case we rethrow the error, # otherwise we continue if {[catch {table_check $args} e]} { if {$e != "missing_keyfield"} { return -code error -errorcode $e "error in table_check ($e)" } } return [string "select count(*) from $myTable"] } method makeDBFieldValue {table_name field_name val} { return "'[quote $val]'" } method registerSpecialField {table_name field_name type} { set specialFields(${table_name}@${field_name}) $type } ## ## These are methods which should be defined by each individual database ## interface class. ## method open {args} {} method close {args} {} method exec {args} {} method nextkey {args} {} method lastkey {args} {} method now {} {} method last_inserted_rec {} {} ## ## Functions to get and set public variables. ## method interface {{string ""}} { return [configure_variable interface $string] } method errorinfo {{string ""}} { return [configure_variable errorinfo $string] } method db {{string ""}} { return [configure_variable db $string] } method table {{string ""}} { return [configure_variable table $string] } method keyfield {{string ""}} { return [configure_variable keyfield $string] } method autokey {{string ""}} { return [configure_variable autokey $string] } method sequence {{string ""}} { return [configure_variable sequence $string] } method user {{string ""}} { return [configure_variable user $string] } method pass {{string ""}} { return [configure_variable pass $string] } method host {{string ""}} { return [configure_variable host $string] } method port {{string ""}} { return [configure_variable port $string] } protected variable specialFields public variable interface "" public variable errorinfo "" public variable db "" public variable table "" public variable sequence "" public variable user "" public variable pass "" public variable host "" public variable port "" protected method handle_client_arguments {cargs} { } public variable clientargs "" { handle_client_arguments $clientargs } public variable keyfield "" { if {[llength $keyfield] > 1 && $autokey} { return -code error "Cannot have autokey and multiple keyfields" } } public variable autokey 0 { if {[llength $keyfield] > 1 && $autokey} { return -code error "Cannot have autokey and multiple keyfields" } } } ; ## ::itcl::class Database # # DIO Result object # ::itcl::class Result { constructor {args} { eval configure $args } destructor { } method destroy {} { ::itcl::delete object $this } # # configure_variable - given a variable name and a string, if the # string is empty return the variable name, otherwise set the # variable to the string. # protected method configure_variable {varName string} { if {[::rivet::lempty $string]} { return [cget -$varName] } configure -$varName $string } # # lassign_array - given a list, an array name, and a variable number # of arguments consisting of variable names, assign each element in # the list, in turn, to elements corresponding to the variable # arguments, into the named array. From TclX. # protected method lassign_array {list arrayName args} { upvar 1 $arrayName array foreach elem $list field $args { set array($field) $elem } } # # seek - set the current row ID (our internal row cursor, if you will) # to the specified row ID # method seek {newrowid} { set rowid $newrowid } method cache {{size "all"}} { set cacheSize $size if {$size == "all"} { set cacheSize $numrows } ## Delete the previous cache array. catch {unset cacheArray} set autostatus $autocache set currrow $rowid set autocache 1 seek 0 set i 0 while {[next -list list]} { if {[incr i] >= $cacheSize} { break } } set autocache $autostatus seek $currrow set cached 1 } # # forall -- walk the result object, executing the code body over it # method forall {type varName body} { upvar 1 $varName $varName set currrow $rowid seek 0 while {[next $type $varName]} { uplevel 1 $body } set rowid $currrow return } method next {type {varName ""}} { set return 1 if {![::rivet::lempty $varName]} { upvar 1 $varName var set return 0 } catch {unset var} set list "" ## If we have a cached result for this row, use it. if {[info exists cacheArray($rowid)]} { set list $cacheArray($rowid) } else { set list [$this nextrow] if {[::rivet::lempty $list]} { if {$return} { return } set var "" return 0 } if {$autocache} { set cacheArray($rowid) $list } } incr rowid switch -- $type { "-list" { if {$return} { return $list } else { set var $list } } "-array" { if {$return} { foreach field $fields elem $list { lappend var $field $elem } return $var } else { eval lassign_array [list $list] var $fields } } "-keyvalue" { foreach field $fields elem $list { lappend var -$field $elem } if {$return} { return $var } } "-dict" { foreach field $fields elem $list { lappend var $field $elem } if {$return} { return [dict create {*}$var] } } default { incr rowid -1 return -code error \ "In-valid type: must be -list, -array, -dict or -keyvalue" } } return [expr [::rivet::lempty $list] == 0] } public method mkdict {key} { set query_res_d [dict create] # we check on the first row a value # for the corresponding key exists if {[$this next -dict d] > 0} { if {[dict exists $d $key]} { set keyvalue [dict get $d $key] dict unset d $key dict set query_res_d $keyvalue $d } else { return -code error \ "Value for key '$key' not existing in the query results" } } # then we proceed with the remaining rows to # be processed while {[$this next -dict d]} { set keyvalue [dict get $d $key] dict unset d $key dict set query_res_d $keyvalue $d } return $query_res_d } method resultid {{string ""}} { return [configure_variable resultid $string] } method fields {{string ""}} { return [configure_variable fields $string] } method rowid {{string ""}} { return [configure_variable rowid $string] } method numrows {{string ""}} { return [configure_variable numrows $string] } method error {{string ""}} { return [configure_variable error $string] } method errorcode {{string ""}} { return [configure_variable errorcode $string] } method errorinfo {{string ""}} { return [configure_variable errorinfo $string] } method autocache {{string ""}} { return [configure_variable autocache $string] } public variable resultid "" public variable fields "" public variable rowid 0 public variable numrows 0 public variable error 0 public variable errorcode 0 public variable errorinfo "" public variable autocache 1 protected variable cached 0 protected variable cacheSize 0 protected variable cacheArray } ; ## ::itcl::class Result } ; ## namespace eval DIO package provide DIO 1.1 rivet-3.3.1/rivet/rivet-tcl/redirect.tcl000664 001750 001751 00000003235 15245054302 020774 0ustar00manghimanghi000000 000000 # # -- ::rivet::redirect # # Redirecting to a new URL by issuing a 301 or 302 (permanent) # diversion to a new resource. # # Arguments: # # - url - URL to which we are redirecting the client # - permanent:[0 | 1] - whether redirection will be permanent (default: 0) # or # - permanent: code - returns any HTTP integer code. In this context # only the 3xx status codes are meaningful # namespace eval ::rivet { proc redirect {url {permanent 0}} { if {[::rivet::headers sent]} { return -code error \ -errorcode headers_already_sent \ -errorinfo "Impossible to redirect: headers already sent" } # In order to preserve compatibility # with the past we check whether we are # dealing with a boolean argument and handle # it accordingly if {[string is boolean $permanent] } { if {[string is true $permanent]} { set http_code 301 } else { set http_code 302 } } elseif {[string is integer $permanent] && ($permanent > 0)} { set http_code $permanent } else { return -code error \ -errorcode invalid_http_code \ -errorinfo "Invalid HTTP status code: $permanent" } ::rivet::no_body ; ## don’t output anything on a redirect ::rivet::headers set Location $url ::rivet::headers numeric $http_code ::rivet::abort_page [dict create error_code redirect location $url] ; ## stop any further processing return -error ok } } rivet-3.3.1/doc/html/images/acrobat.png000644 001750 001751 00000000607 15245054474 020534 0ustar00manghimanghi000000 000000 ‰PNG  IHDR [‚jgAMA±� üasRGB®Îé cHRMz&€„ú€èu0ê`:˜pœºQ<PLTEÿÿÿÿÿÿÞÌÛþªÃý�´ÿy’õEWéÀLAÑtRNS@æØfbKGDˆH pHYsHHFÉk>PIDAT× Ç± € @Ñï€[ï& `¬M”H°¶r#ëKõòÀJ20D70Fçk eõ×ÎZ;7g±¢†\œÚ…¨’úDêÓ:·ö[û?’ö ln{%tEXtdate:create2012-10-01T18:40:16+02:00퀀.%tEXtdate:modify2012-10-01T18:40:16+02:00œÝ8’IEND®B`‚rivet-3.3.1/rivet/packages/aida/000775 001750 001751 00000000000 15245054302 017227 5ustar00manghimanghi000000 000000 rivet-3.3.1/rivet/init.tcl.in000664 001750 001751 00000021270 15245054302 016631 0ustar00manghimanghi000000 000000 # # init.tcl -- # # # Copyright 2002-2017 The Apache Rivet Team # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. package require @RIVETLIB_PACKAGE@ @RIVETLIB_PACKAGE_VERSION@ # the ::rivet namespace is created in mod_rivet_commoc.c:Rivet_PerInterpInit # namespace eval ::rivet {} ; ## create namespace namespace eval ::Rivet {} ; ## create namespace ## ::Rivet::init ## ## Initialize the interpreter with all that Rivet goodness. This is called ## once when this file is loaded (down at the bottom) and sets up the interp ## for all things Rivet. proc ::Rivet::init {} { set ::Rivet::init [info script] set ::Rivet::root [file dirname $::Rivet::init] set ::Rivet::packages [file join $::Rivet::root packages] set ::Rivet::rivet_tcl [file join $::Rivet::root rivet-tcl] ## Setup auto_path within the interp to include all the places ## we've stored Rivet's scripts: rivet-tcl, packages, packages-local, ## packages$tcl_version, init_script_dir, and . ## Put these at the head of the list. set ::auto_path [linsert $::auto_path 0 $::Rivet::root \ $::Rivet::rivet_tcl $::Rivet::packages $::Rivet::packages-local] ## This will allow users to create proc libraries and tclIndex files ## in the local directory that can be autoloaded. ## Perhaps this must go to the front of the list to allow the user ## to override even Rivet's procs. lappend ::auto_path ${::Rivet::packages}${::tcl_version} . ## As we moved the command set to the ::rivet namespace we ## still want to guarantee the commands to be accessible ## at the global level by putting them on the export list. ## Importing the ::rivet namespace is deprecated and we should ## make it clear in the manual. if {[string is true -strict [::rivet::inspect ExportRivetNS]] || [string is true -strict [::rivet::inspect ImportRivetNS]]} { set ::rivet::cmd_export_list \ [tcl_commands_export_list $::Rivet::rivet_tcl] ## init.tcl is run by mod_rivet (which creates the ::rivet ## namespace) but it gets run standalone by mkPkgindex during ## the installation phase. We have to make sure the procedure ## won't fail in this case, so we check for the existence of ## the variable. namespace eval ::rivet { ## Commands in cmd_export_list are prefixed with ::rivet, ## so we have to remove it to build an export list. set export_list [list] foreach c $cmd_export_list { lappend export_list [namespace tail $c] } namespace export {*}$export_list } } ## If we are running from within mod_rivet we have already ## defined ::rivet::exit (mod_rivet_common.c: Rivet_PerInterpInit) ## and we move Tcl's exit command out of the way and replace it with ## our own that handles bailing from a page request properly. if {[info commands ::rivet::exit] != ""} { rename ::exit ::Rivet::tclcore_exit proc ::exit {code} { if {![string is integer -strict $code]} { set code 0 } ::rivet::exit $code } } ## If Rivet was configured for backward compatibility, import commands ## from the ::rivet namespace into the global namespace. if {[string is true -strict [::rivet::inspect ImportRivetNS]]} { uplevel #0 { namespace import ::rivet::* } } #unset -nocomplain ::module_conf } ### ## This routine gets called each time a new request comes in. ## It sets up the request namespace and creates a global command ## to replace the default global. This ensures that when a user ## uses global variables, they're actually contained within the ## namespace. So, everything gets deleted when the request is finished. ### proc ::Rivet::initialize_request {} { catch { namespace delete ::request } namespace eval ::request {} proc ::request::global {args} { foreach arg $args { uplevel "::global ::request::$arg" } } } ## ::Rivet::handle_error ## ## If an ErrorScript has been specified, this routine will not be called. proc ::Rivet::handle_error {} { puts "
    $::errorInfo

    OUTPUT BUFFER:

    $::Rivet::script
    " } ## ::Rivet::request_handling ## ## Process the actual request. This is the main handler for each request. ## This collects all of the necessary BeforeScripts, AfterScripts, and ## other bits and calls them in order. proc ::Rivet::request_handling {} { ::try { uplevel #0 ::Rivet::initialize_request } on error {err} { ::rivet::apache_log_error crit \ "Rivet request initialization failed: $::errorInfo" } ::try { set script [::rivet::inspect BeforeScript] if {$script ne ""} { set ::Rivet::script $script uplevel #0 $script } set script [::rivet::url_script] if {$script ne ""} { set ::Rivet::script $script namespace eval ::request $script } set script [::rivet::inspect AfterScript] if {$script ne ""} { set ::Rivet::script $script uplevel #0 $script } } trap {RIVET ABORTPAGE} {err opts} { ::Rivet::finish_request $script $err $opts AbortScript } trap {RIVET THREAD_EXIT} {err opts} { ::Rivet::finish_request $script $err $opts AbortScript } on error {err opts} { ::Rivet::finish_request $script $err $opts } finally { ::Rivet::finish_request $script "" "" AfterEveryScript } } ## ::Rivet::finish_request ## ## Finish processing the request by checking our error state and executing ## whichever script we need to close things up. If this script results in ## an error, we'll try to call ErrorScript before bailing. proc ::Rivet::finish_request {script errorCode errorOpts {scriptName ""}} { set ::Rivet::errorCode $errorCode set ::Rivet::errorOpts $errorOpts if {$scriptName ne ""} { set scriptBody [::rivet::inspect $scriptName] ::try { uplevel #0 $scriptBody } on ok {} { return } on error {} { ::rivet::apache_log_error err \ "Rivet $scriptName failed: $::errorInfo" print_error_message "Rivet $scriptName failed" } } set error_script [::rivet::inspect ErrorScript] if {$error_script eq ""} { set ::errorOutbuf $script ; ## legacy variable set error_script ::Rivet::handle_error } ::try { set ::Rivet::script $script uplevel #0 $error_script } on error {err} { ::rivet::apache_log_error err "Rivet ErrorScript failed: $::errorInfo" print_error_message "Rivet ErrorScript failed" } } ## ::Rivet::print_error_message ## ## This message should be transparently equivalent to the ## Rivet_PrintErrorMessage function in mod_rivet_generator.c proc ::Rivet::print_error_message {error_header} { puts "$error_header
    $::errorInfo
    " } ## ::Rivet::tcl_commands_export_list ## ## this is temporary hack to export names of Tcl commands in rivet-tcl/. ## This function will be removed in future versions of Rivet and it's ## meant to provide a basic way to guarantee compatibility with older ## versions of Rivet (see code in ::Rivet::init) proc ::Rivet::tcl_commands_export_list {tclpath} { # we collect the commands in rivet-tcl by reading the tclIndex # file and then we extract the command list from auto_index namespace eval ::Rivet::temp {} set ::Rivet::temp::tclpath $tclpath namespace eval ::Rivet::temp { variable auto_index array set auto_index {} # The auto_index in ${tclpath}/tclIndex is loaded. # This array is used to fetch a list of Rivet commands # implemented in Rivet set dir $tclpath source [file join $tclpath tclIndex] # Rivet Tcl commands not meant to go onto the export list must # be unset from auto_index here unset auto_index(::rivet::catch) unset auto_index(::rivet::try) } set commands [namespace eval ::Rivet::temp {array names auto_index}] # we won't leave anything behind namespace delete ::Rivet::temp return $commands } ::Rivet::init package provide Rivet @INIT_VERSION@ rivet-3.3.1/doc/html/clock_to_rfc.html000664 001750 001751 00000004767 15245054474 020500 0ustar00manghimanghi000000 000000 clock_to_rfc850_gmt

    Name

    clock_to_rfc850_gmt — create a rfc850 time from [clock seconds].

    Synopsis

    ::rivet::clock_to_rfc850_gmt ?seconds?

    Description

    Convert an integer-seconds-since-1970 click value to RFC850 format, with the additional requirement that it be GMT only.

    rivet-3.3.1/TODO000664 001750 001751 00000004105 15245054302 014112 0ustar00manghimanghi000000 000000 BUGS ==== TODO ==== * getting the plain post data. I use mod_dtcl as an xml server and I need to collect the broken xml (due to query string proccessing). if the user enters in the xml "=" I am lost. (From yahalom emet). * session handling. this feature can not be added by a tcl package so it is missing from the interface. (From yahalom emet). * Write commands like 'open' and such in the request namespace that keep track of open file pointers and close them in the cleanup. * Complete the NWS package. * Swipe include_* from NWS and rework it like: include ?-virtual? ?-noparse? file * Re-write load_file. This basically loads an entire .tcl file into the current document instead of sourcing it. This will allow us to cache even pages which only source a huge .tcl file. load_virtual should do the same but relative to the document root. * Create escape_string and unescape_string using Apache conventions. * Free Rivet commands of apache dependencies, which are moved into the TclWebapache.c file. Compatible file, for CGI only operating, TclWebcgi.c needs to be created. * Create replacements, in Tcl where possible, for Rivet commands in order to enable the aforementioned 'CGI' mode of operation. * Need to add a local.tcl for local procs and setup. * Script timeouts - limit time scripts can run before bailing out. * Safe mode. * Add documentation for commands implemented in Tcl. * Make some tests for commands implemented in Tcl. * Integrate package documentation with main documentation. * Document the 'form' package. * Integrate ncgi package, to help migration for people using it. * I think we need some kind of unified interface to launching tcl 'services'. These are separate Tcl processes that most likely exist to allow the Apache children to share data. * Find a way of integrating the Tcl event loop? * Document and add tests for parserivetdata command. MAYBE ===== * Maybe move ::request commands into a file called request.tcl. DONE ==== * Nice logo. * Documentation in XML. * var_get and var_post commands. * Apache 2 interface. rivet-3.3.1/doc/html/load_headers.html000664 001750 001751 00000005050 15245054474 020445 0ustar00manghimanghi000000 000000 load_headers

    Name

    load_headers — get client request's headers.

    Synopsis

    ::rivet::load_headers ?array_name?

    Description

    Load the headers that come from a client request into the provided array name, or use headers if no name is provided.

    rivet-3.3.1/doc/html/images/toc-minus.png000644 001750 001751 00000000403 15245054474 021031 0ustar00manghimanghi000000 000000 ‰PNG  IHDR Èä)‹bKGDª�#2IDATxÚch��ÿ`À¥ÿÏg  I×�j?}-p®ZóºECtEXtSoftware@(#)ImageMagick 4.2.8 99/08/01 cristy@mystic.es.dupont.com‘º!¸*tEXtSignatureecf413ef47524404f90c44d8c7d12a2e݈þš tEXtPage15x9+0+07vð¸IEND®B`‚rivet-3.3.1/doc/html/images/remote.png000644 001750 001751 00000001067 15245054474 020415 0ustar00manghimanghi000000 000000 ‰PNG  IHDR žr‡gAMA±� üasRGB®Îé cHRMz&€„ú€èu0ê`:˜pœºQ<¨PLTEÿÿÿÈÃÁ|…�9H )wvrÇÀ»½ºº%" #5œîùÿ "Op¼¸·ÑÌÌ((œÞÿZ˜¸$ y{{ :TŠyzyÎîÿ+-?!% $11TcyyxZ�œ1Rc((…’’%#�Òð,)ÔÒÒ½¹¸)* )"Gb»·µÈÂÀ{€…%+  vtoÇÀ¼ÿÿÿYy'ŸtRNS@æØfbKGDˆH pHYsHHFÉk>pIDAT×-Íé‚0à�-X¶*x.Þ‚·ïÿh”†ùõe2Éèyý� a3OˆTM“ ³™i$içlŽ…Z;ç(”«­WX+·1f³ÅnÏŽR �'&“‰œ/Àõv‘ª~´gÏ×ûóýý�Ð o¥êÈ$%tEXtdate:create2012-10-01T18:27:32+02:00Qƒrz%tEXtdate:modify2012-10-01T18:27:32+02:00 ÞÊÆIEND®B`‚rivet-3.3.1/doc/html/internals.html000664 001750 001751 00000061552 15245054474 020043 0ustar00manghimanghi000000 000000 Rivet Internals

    Rivet Internals

    This section easily falls out of date, as new code is added, old code is removed, and changes are made. The best place to look is the source code itself. If you are interested in the changes themselves, the Subversion revision control system (svn) can provide you with information about what has been happening with the code.

    Rivet approach to Apache Multiprocessing Models

    The Apache HTTP web server has an extremely modular architecture that made it very popular among web developers. Most of the server features can be implemented in external modules, including some of the way the server interfaces to the operative system. The multiprocessing modules are meant to provide different models for distributing the server workload but also to cope with different operative systems having their specific architectures and services.

    From the very beginning mod_rivet was designed to work with the prefork MPM MPM (Multi Processing Module) which assumes the OS to have 'fork' capabilities. This prerequisite basically restricted mod_rivet to work only with Unix-like operative systems. Starting with version 3.0 we reorganized mod_rivet to offer a design that could work together with more MPM and hopefully pave the way to support different OS that have no 'fork' call. At the same time we tried to preserve some of the basic features of mod_rivet when working with the prefork MPM, chiefly the feature of the Unix fork system call of 'cloning' a parent process memory into its child, thus allowing fast initialization of interpreters.

    The central design of mod_rivet now relies on the idea of “MPM bridges�, loadable modules that are responsible to adapt the module procedural design to a given class of Apache MPMs. This design is open to the development of more MPM bridges coping with different multi-processing models but also to the development of different approaches to resource consumption and workload balance. Currently we have 3 bridges:

    • rivet_prefork_mpm.c: a bridge for the prefork MPM
    • rivet_worker_mpm.c: a threaded bridge creating a pool of threads each running Tcl interpreters and communicating with the worker MPM threads through a thread safe queue. This bridge is needed by the worker MPM and by any the winnt MPM on Windows.
    • rivet_lazy_mpm.c: a threaded bridge where Tcl threads are started “on demandâ€�. The bridge creates no threads and Tcl interpreters at start up, only when requests come in Tcl execution threads are created. This bridge is explained in detail in the the section called “Example: the “Lazyâ€� bridgeâ€�. Since the resource demand at startup is minimal this bridge should suit development machines that go through frequent web server restarts.

    mod_rivet MPM Bridge callbacks

    A bridge is a loadable library implementing different ways to handle specific features needed to mod_rivet. It was originally meant as a way to handle the prefork/worker/event MPM specificities, at the same time avoiding the need to stuff the code with conditional statements that would have implied useless complexity (an instance of the Apache web server can run only an MPM at a time), error prone programming and performance costs. New bridges could be imagined also to implement different models of workload and resource management (like the resources demanded by the Tcl interpreters). We designed an interface between the core of mod_rivet and its MPM bridges based on a set of functions defined in the rivet_bridge_table structure.

    typedef struct _mpm_bridge_table {
        RivetBridge_ServerInit    *server_init;
        RivetBridge_ThreadInit    *thread_init;
        RivetBridge_Request       *request_processor;
        RivetBridge_Finalize      *child_finalize;
        RivetBridge_Exit_Handler  *exit_handler;
        RivetBridge_Thread_Interp *thread_interp;
    } rivet_bridge_table;

    • mpm_server_init: pointer to any specific server inititalization function. This field can be NULL if no bridge specific initialization is needed. The core of mod_rivet runs the ServerInitScript before calling this function.
    • mpm_child_init: Bridge specific child process initialization. If the pointer is assigned with a non-NULL value the function is called by Rivet_ChildInit.
    • mpm_request: This pointer must be a valid function pointer to the content generator implemented by the bridge. If the pointer is not defined the Apache web server will stop at start up. This condition is motivated by the need of avoiding useless testing of the pointer. The fundamental purpose of a content generator module (like mod_rivet) is to respond to requests creating content, thus whatever it is a content generating function must exist (during the early stages of development you can create a simple test function for that). In a threaded MPM this function typically prepares the request processing stuffing somewhere the pointer to the request_rec structure passed by the web server and then it calls some method to communicate these data to the Tcl execution thread waiting for result to be returned. The “preforkâ€� bridge is an exception since there are no threads and the bridge calls directly Rivet_SendContent
    • mpm_finalize: pointer to a finalization function called during a child process exit. This function is registered as child process memory pool cleanup function. If the pointer is NULL the pool is given a default cleanup function (apr_pool_cleanup_null) defined in src/mod_rivet/mod_rivet.c. For instance the finalize function in the worker MPM bridge notifies a supervisor thread demanding the whole pool of threads running Tcl interpreters to orderly exit. This pointer can be NULL if the bridge has no special need when a child process must exit (unlikely if you have multiple threads running)
    • mpm_exit_handler: mod_rivet replaces the core exit command with a new one (::rivet::exit). This command must handle the process exit in the best possible way for the bridge and the threading model it implements (for the 2 current threaded bridges this implies signaling the threads to exit). The ::rivet::exit actually doesn't terminate the process, but interrupts execution returning a specific error code commands ::rivet::catch and ::rivet::try can detect. Before the process is terminated the AbortScript script is fired and ::rivet::abort_code returns a message describing the exit condition. For instance the worker MPM bridge the finalize function is called after the current thread itself is set up for termination. See function Rivet_ExitCmd in rivetCore.c to have details on how and at what stage this callback is invoked.
    • mpm_thread_interp must be a function returning the interpreter object (a pointer to record of type rivet_thread_interp) associated to a given configuration as stored in a rivet_server_conf* object. This element was temporarily introduced in the mpm_bridge_table table and should be accessed through the macro RIVET_PEEK_INTERP.
      interp_obj = RIVET_PEEK_INTERP(private,private->conf);
      Every bridge implementation should have its own way to store interpreter data and manage their status. So this macro (and associated function) should hide from the module core function the specific approach followed in a particular bridge

    Server Initialization and MPM Bridge

    RivetChan

    The RivetChan system was created in order to have an actual Tcl channel that we could redirect standard output to. This enables us use, for instance, the regular puts command in .rvt pages. It works by creating a channel that buffers output, and, at predetermined times, passes it on to Apache's I/O system. Tcl's regular standard output is replaced with an instance of this channel type, so that, by default, output will go to the web page.

    The global Command

    Rivet aims to run standard Tcl code with as few surprises as possible. At times this involves some compromises - in this case regarding the global command. The problem is that the command will create truly global variables. If the user is just cut'n'pasting some Tcl code into Rivet, they most likely just want to be able to share the variable in question with other procs, and don't really care if the variable is actually persistant between pages. The solution we have created is to create a proc ::request::global that takes the place of the global command in Rivet templates. If you really need a true global variable, use either ::global or add the :: namespace qualifier to variables you wish to make global.

    Page Parsing, Execution and Caching

    When a Rivet page is requested, it is transformed into an ordinary Tcl script by parsing the file for the <? ?> processing instruction tags. Everything outside these tags becomes a large puts statement, and everything inside them remains Tcl code.

    Each .rvt file is evaluated in its own ::request namespace, so that it is not necessary to create and tear down interpreters after each page. By running in its own namespace, though, each page will not run afoul of local variables created by other scripts, because they will be deleted automatically when the namespace goes away after Apache finishes handling the request.

    [Note]Note
    One current problem with this system is that while variables are garbage collected, file handles are not, so that it is very important that Rivet script authors make sure to close all the files they open.

    After a script has been loaded and parsed into it's "pure Tcl" form, it is also cached, so that it may be used in the future without having to reload it (and re-parse it) from the disk. The number of scripts stored in memory is configurable. This feature can significantly improve performance.

    Extending Rivet by developing C code procedures

    Rivet endows the Tcl interpreter with new commands serving as interface between the application layer and the Apache web server. Many of these commands are meaningful only when a HTTP request is under way and therefore a request_rec object allocated by the framework is existing and was passed to mod_rivet as argument of a callback. In case commands have to gain access to a valid request_rec object the C procedure must check if such a pointer exists and it's initialized with valid data. For this purpose the procedure handling requests (Rivet_SendContent) makes a copy of such pointer and keeps it in an internal structure. The copy is set to NULL just before returning to the framework, right after mod_rivet's has carried out its request processing. When the pointer copy is NULL the module is outside any request processing and this condition invalidates the execution of many of the Rivet commands. In case they are called (for example in a ChildInitScript, GlobalInitScript, ServerInitScript or ChildExitScript) they fail with a Tcl error you can handle with a catch command.

    For this purpose in src/rivet.h the macro CHECK_REQUEST_REC was defined accepting two arguments: the thread private data object and the command name. If the pointer is NULL the macro calls Tcl_NoRequestRec and returns TCL_ERROR causing the command to fail. These are the steps to follow in order to write a new C language command for mod_rivet

    • Define the command and associated C language procedure in src/mod_rivet_ng/rivetCore.c using the macro RIVET_OBJ_CMD
      RIVET_OBJ_CMD("mycmd",Rivet_MyCmd,private)
      This macro ensures the command is defined as ::rivet::mycmd and its ClientData pointer is defined with the thread private data
    • Add the code of Rivet_MyCmd to src/mod_rivet_ng/rivetCore.c (in case the code resides in a different file also src/Makefile.am should be changed to tell the build system how to compile the code and link it into mod_rivet.so)
    • If the code must have access to the request record in private->r use the macro THREAD_PRIVATE_DATA in order to claim the thread private data, then check for the validity of the pointer using the macro CHECK_REQUEST_REC(private,"::rivet::<cmd_name>")
      TCL_CMD_HEADER(Rivet_MyCmd)
      {
          /* we have to get the thread private data */
          
          THREAD_PRIVATE_DATA(private)
      
      	/* if ::rivet::mycmd works within a request processing we have
      	 * to check if 'private' is carrying a non null request_rec pointer
      	 */
          
          CHECK_REQUEST_REC(private,"::rivet::mycmd");
          ....
          
          return TCL_OK;
      }
    • Add a test for this command in tests/checkfails.tcl. For instance
      ...
      check_fail no_body
      check_fail virtual_filename unkn
      check_fail my_cmd <arg1> <arg2>
      ....
      Where <arg1> <arg2> are optional arguments in case the command has different forms depending on the arguments. Then, if ::rivet::mycmd must fail also tests/failtest.tcl should modified as
      virtual_filename->1
      mycmd->1
      The value associated to the test must be 0 in case the command doesn't need to test the private->r pointer.

    Debugging Rivet and Apache

    If you are interested in hacking on Rivet, you're welcome to contribute! Invariably, when working with code, things go wrong, and it's necessary to do some debugging. In a server environment like Apache, it can be a bit more difficult to find the right way to do this. Here are some techniques to try.

    The first thing you should know is that Apache can be launched as a single process with the -X argument:

    httpd -X
    .

    On Linux, one of the first things to try is the system call tracer, strace. You don't even have to recompile Rivet or Apache for this to work.

    strace -o /tmp/outputfile -S 1000 httpd -X

    This command will run httpd in the system call tracer, which leaves its output (there is potentially a lot of it) in /tmp/outputfile. The -S option tells strace to only record the first 1000 bytes of a syscall. Some calls such as write can potentially be much longer than this, so you may want to increase this number. The results are a list of all the system calls made by the program. You want to look at the end, where the failure presumably occured, to see if you can find anything that looks like an error. If you're not sure what to make of the results, you can always ask on the Rivet development mailing list.

    If strace (or its equivalent on your operating system) doesn't answer your question, it may be time to debug Apache and Rivet. To do this, you will need to rebuild mod_rivet. First of all you have to configure the build by running the ./configure script with the -enable-symbols option and after you have set the CFLAGS and LDFLAGS environment variables

    export CFLAGS="-g -O0"
    export LDFLAGS="-g"
    ./configure --enable-symbols ......
    make
    make install

    Arguments to ./configure must fit your Apache HTTP web server installation. See the output produced by

    ./configure --help

    And check the the section called “Apache Rivet 3.3 Installation� page to have further information. Since it's easier to debug a single process, we'll still run Apache in single process mode with -X:

    @ashland [~] $ gdb /usr/sbin/apache.dbg
    GNU gdb 5.3-debian
    Copyright 2002 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "powerpc-linux"...
    (gdb) run -X
    Starting program: /usr/sbin/apache.dbg -X
    [New Thread 16384 (LWP 13598)]
    .
    .
    .

    When your apache session is up and running, you can request a web page with the browser, and see where things go wrong (if you are dealing with a crash, for instance).

    rivet-3.3.1/src/mod_rivet_ng/TclWebapache.c000664 001750 001751 00000077447 15245054302 021376 0ustar00manghimanghi000000 000000 /* -- TclWeb.c: Common API layer. */ /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Rivet config */ #ifdef HAVE_CONFIG_H #include #endif #include #include #ifndef WIN32 #include #endif /* WIN32 */ #include #include #include #include #include "apache_request.h" #include "mod_rivet.h" #include "TclWeb.h" extern module rivet_module; extern mod_rivet_globals* module_globals; /* It's kind of an overkill: we define macros for handling the * flags that control the handling of the three environment variables * classes (common, CGI and include variables). */ #define ENV_COMMON_VARS_M 1 #define ENV_CGI_VARS_M 2 #define ENV_VARS_M 4 #define ENV_VARS_RESET(env) env = 0; #define ENV_COMMON_VARS(env) env |= ENV_COMMON_VARS_M; #define ENV_CGI_VARS(env) env |= ENV_CGI_VARS_M; #define ENV_VARS(env) env |= ENV_VARS_M; #define ENV_LOADED(env) env |= ENV_COMMON_VARS_M | ENV_CGI_VARS_M | ENV_VARS_M; #define ENV_IS_LOADED(env) (env == (ENV_COMMON_VARS_M | ENV_CGI_VARS_M | ENV_VARS_M)) #define ENV_COMMON_VARS_LOADED(env) (env & ENV_COMMON_VARS_M) != 0 #define ENV_CGI_VARS_LOADED(env) (env & ENV_CGI_VARS_M) != 0 #define ENV_VARS_LOADED(env) (env & ENV_VARS_M) != 0 /* This is used below to determine what part of the parmsarray to parse. */ #define PARMSARRAY_COORDINATES(i,j,parray,nargs) i = 0; j = parray->nelts; \ if (source == VAR_SRC_QUERYSTRING) { j = nargs; } \ else if (source == VAR_SRC_POST) { i = nargs; } /* * -- TclWeb_NewRequestObject * * */ TclWebRequest* TclWeb_NewRequestObject (apr_pool_t *p) { TclWebRequest* req = (TclWebRequest *)apr_pcalloc(p, sizeof(TclWebRequest)); req->interp = NULL; req->req = NULL; req->apachereq = ApacheRequest_new(p); req->headers_printed = 0; req->headers_set = 0; ENV_VARS_RESET(req->environment_set) req->charset = NULL; /* we will test against NULL to check if a charset * * was specified in the conf */ return req; } /* * -- TclWeb_InitRequest * * called once on every HTTP request initializes fields and * objects referenced in a TclWebRequest object * * Arguments: * * TclWebRequest* req: a pointer to a TclWebRequest object to be intialized * Tcl_Interp* interp: current Tcl_Interp object serving the request * void* arg: generic pointer. Current implementation passes the * request_rec object pointer * */ int TclWeb_InitRequest(rivet_thread_private* private, Tcl_Interp *interp) { request_rec* r = private->r; TclWebRequest* req = private->req; size_t content_type_len = strlen(r->content_type); req->interp = interp; req->req = r; req->apachereq = ApacheRequest_init(req->apachereq,r); req->headers_printed = 0; req->headers_set = 0; ENV_VARS_RESET(req->environment_set) req->charset = NULL; /* * if strlen(req->content_type) > strlen([RIVET|TCL]_FILE_CTYPE) * a charset parameters might be in the configuration like * * AddType 'application/x-httpd-rivet;charset=utf-8' rvt */ if (((private->ctype==RIVET_TEMPLATE) && (content_type_len > strlen(RIVET_TEMPLATE_CTYPE))) || \ ((private->ctype==RIVET_TCLFILE) && (content_type_len > strlen(RIVET_TCLFILE_CTYPE)))) { char* charset; /* we parse the content type: we are after a 'charset' parameter definition */ charset = (char *) strstr(r->content_type,"charset"); if (charset != NULL) { char* charset_value; Tcl_Channel outchannel; charset = apr_pstrdup(r->pool,charset); /* ther's some freedom about spaces in the AddType lines: let's strip them off */ apr_collapse_spaces(charset,charset); req->charset = charset; /* The response charset is also the external encoding of the * Tcl output channel. Configure it for every request so a prior * binary response cannot leak its channel state. */ charset_value = strchr(charset, '='); outchannel = Tcl_GetStdChannel(TCL_STDOUT); if (charset_value != NULL && outchannel != NULL && Tcl_SetChannelOption(interp, outchannel, "-encoding", charset_value + 1) != TCL_OK) { return TCL_ERROR; } } } return TCL_OK; } INLINE int TclWeb_SendHeaders(TclWebRequest *req) { //TODO: fix ap_send_http_header ap_send_http_header(req->req); return TCL_OK; } INLINE int TclWeb_StopSending(TclWebRequest *req) { req->req->connection->aborted = 1; return TCL_OK; } /* Set up the content type header */ int TclWeb_SetHeaderType(char *header, TclWebRequest *req) { if (req->headers_set) return TCL_ERROR; ap_set_content_type(req->req,apr_pstrdup(req->req->pool, header)); req->headers_set = 1; return TCL_OK; } /* Printer headers if they haven't been printed yet */ int TclWeb_PrintHeaders(TclWebRequest *req) { if (req->headers_printed) return TCL_ERROR; /* Let's set the charset in the headers if one was set in the configuration */ if (!req->headers_set && (req->charset != NULL)) { TclWeb_SetHeaderType(apr_pstrcat(req->req->pool,"text/html;",req->charset,NULL),req); } if (req->headers_set == 0) { TclWeb_SetHeaderType(DEFAULT_HEADER_TYPE, req); } /* * seems that ap_send_http_header is redefined to ; in Apache2.2 * ap_send_http_header(req->req); */ TclWeb_SendHeaders(req); req->headers_printed = 1; return TCL_OK; } /* Print nice HTML formatted errors */ int TclWeb_PrintError(const char *errstr, int htmlflag, TclWebRequest *req) { TclWeb_SetHeaderType(DEFAULT_HEADER_TYPE, req); TclWeb_PrintHeaders(req); if (htmlflag != 1) ap_rputs(ER1, req->req); if (errstr != NULL) { if (htmlflag != 1) { ap_rputs(ap_escape_html(req->req->pool,errstr),req->req); } else { ap_rputs(errstr, req->req); } } if (htmlflag != 1) ap_rputs(ER2, req->req); return TCL_OK; } INLINE int TclWeb_HeaderSet(char *header, char *val, TclWebRequest *req) { apr_table_set(req->req->headers_out, header, val); return TCL_OK; } /* * accessing output headers * * * -- TclWeb_OutputHeaderSet: replicates the role of TclWeb_HeaderSet * * - the name stresses the fact it's an accessor to the output * headers * - it returns nothing since it's a wrapper around an APR call * that doesn't return anything * * -- TclWeb_OutputHeaderGet: reads from the output headers and * returns the value associated to a key. If the key is not * existing it returns NULL * */ INLINE void TclWeb_OutputHeaderSet(char *header, char *val, TclWebRequest *req) { apr_table_set(req->req->headers_out, header, val); } INLINE const char* TclWeb_OutputHeaderGet(char *header, TclWebRequest *req) { return apr_table_get(req->req->headers_out, header); } INLINE int TclWeb_HeaderAdd(char *header, char *val, TclWebRequest *req) { apr_table_add(req->req->headers_out, header, val); return TCL_OK; } INLINE int TclWeb_SetStatus(int status, TclWebRequest *req) { req->req->status = status; return TCL_OK; } INLINE int TclWeb_MakeURL(Tcl_Obj *result, char *filename, TclWebRequest *req) { Tcl_SetStringObj(result,ap_construct_url(req->req->pool,filename,req->req),-1); return TCL_OK; } int TclWeb_GetVar(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) { int i,j; apr_array_header_t *parmsarray = (apr_array_header_t *)apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; int flag = 0; PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) /* This isn't real efficient - move to hash table later on... */ while (i < j) { char *parmkey = TclWeb_StringToUtf(parms[i].key, req); if (!strncmp(varname,parmkey, strlen(varname) < strlen(parmkey) ? strlen(parmkey) : strlen(varname))) { /* The following makes sure that we get one string, with no sub lists. */ if (flag == 0) { flag = 1; Tcl_SetStringObj (result,TclWeb_StringToUtf(parms[i].val,req),-1); } else { Tcl_Obj *tmpobj; Tcl_Obj *tmpobjv[2]; tmpobjv[0] = result; tmpobjv[1] = TclWeb_StringToUtfToObj (parms[i].val,req); tmpobj = Tcl_ConcatObj (2,tmpobjv); Tcl_SetStringObj (result,Tcl_GetString(tmpobj),-1); } } i++; } /* * We are assuming that checking result->length is a sane way to * establish the Tcl object representation character lenght but it * would obviously be more appropriate to call Tcl_GetCharLength(result) */ if (result->length == 0) { Tcl_AddErrorInfo(req->interp,apr_psprintf(req->req->pool,"Variable '%s' not found",varname)); return TCL_ERROR; } return TCL_OK; } int TclWeb_GetVarAsList(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) { int i, j; apr_array_header_t *parmsarray = (apr_array_header_t *) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) /* This isn't real efficient - move to hash table later on. */ while (i < j) { int tclcode; if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req), strlen(varname) < strlen(parms[i].key) ? strlen(parms[i].key) : strlen(varname))) { tclcode = Tcl_ListObjAppendElement(req->interp,result, TclWeb_StringToUtfToObj(parms[i].val, req)); if (tclcode != TCL_OK) { return tclcode; } } i++; } return TCL_OK; } int TclWeb_GetAllVars(Tcl_Obj *result, int source, TclWebRequest *req) { int i,j; apr_array_header_t *parmsarray = (apr_array_header_t *) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) while (i < j) { int tclcode; tclcode = Tcl_ListObjAppendElement(req->interp,result, TclWeb_StringToUtfToObj(parms[i].key,req)); if (tclcode != TCL_OK) { return tclcode; } tclcode = Tcl_ListObjAppendElement(req->interp,result, TclWeb_StringToUtfToObj(parms[i].val,req)); if (tclcode != TCL_OK) { return tclcode; } i++; } return TCL_OK; } int TclWeb_GetVarNames(Tcl_Obj *result, int source, TclWebRequest *req) { int i,j; apr_array_header_t *parmsarray = (apr_array_header_t *) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) while (i < j) { int tclcode; tclcode= Tcl_ListObjAppendElement(req->interp, result, TclWeb_StringToUtfToObj(parms[i].key, req)); if (tclcode != TCL_OK) { return tclcode; } i++; } return TCL_OK; } int TclWeb_VarExists(Tcl_Obj *result, char *varname, int source, TclWebRequest *req) { int i, j; apr_array_header_t *parmsarray = (apr_array_header_t *) apr_table_elts(req->apachereq->parms); apr_table_entry_t *parms = (apr_table_entry_t *)parmsarray->elts; PARMSARRAY_COORDINATES(i,j,parmsarray,req->apachereq->nargs) /* This isn't real efficient - move to hash table later on. */ while (i < j) { if (!strncmp(varname, TclWeb_StringToUtf(parms[i].key, req), strlen(varname) < strlen(parms[i].key) ? strlen(parms[i].key) : strlen(varname))) { Tcl_SetIntObj(result, 1); return TCL_OK; } i++; } Tcl_SetIntObj(result, 0); return TCL_OK; } int TclWeb_VarNumber(Tcl_Obj *result, int source, TclWebRequest *req) { apr_array_header_t *parmsarray = (apr_array_header_t *) apr_table_elts(req->apachereq->parms); if (source == VAR_SRC_QUERYSTRING) { Tcl_SetIntObj(result, req->apachereq->nargs); } else if (source == VAR_SRC_POST) { Tcl_SetIntObj(result, parmsarray->nelts - req->apachereq->nargs); } else { Tcl_SetIntObj(result, parmsarray->nelts); } return TCL_OK; } /* Environment variables. Include variables handling */ /* These 2 array must be aligned and a one-to-one correspondence preserved * The enum include_vars_idx *must* be terminated by 'invalid_env_var' * Adding a new env variable requires * + the name of the variable be listed in include_env_vars * + a new value in the enumerator include_vars_idx must be added in the * corresponding position * + the switch construct in function TclWeb_SelectEnvIncludeVar must * be expanded to handle the new case identified by the new enumerator value */ static const char* include_env_vars[] = { "DATE_LOCAL","DATE_GMT","LAST_MODIFIED","DOCUMENT_URI","DOCUMENT_PATH_INFO","DOCUMENT_NAME", "QUERY_STRING_UNESCAPED","USER_NAME","RIVET_CACHE_FREE","RIVET_CACHE_SIZE", NULL }; enum include_vars_idx { date_local=0,date_gmt,last_modified,document_uri,document_path_info,document_name, query_string_unescaped,user_name,rivet_cache_free,rivet_cache_size, invalid_env_var }; /* -- TclWeb_SelectEnvIncludeVar * * Depending on the value idx of the enumerator a method is selected * to return a string of a specific environment variable methods * Adding new environment variables need new cases of the switch * construct to be added, provided the data can be obtained from * the rivet_thread_private structure * * Arguments: * * + rivet_thread_private* private: pointer to a thread private data structure * + int idx: an integer value listed in the enumerator include_vars_idx * * Results: * * A character string pointer to the value of the environment variable or * NULL if the enumerator value idx was invalid or resolving the environment * variable was impossible * */ static char* TclWeb_SelectEnvIncludeVar (rivet_thread_private* private,int idx) { switch (idx) { case date_local: { apr_pool_t* pool = private->req->req->pool; apr_time_t date = private->req->req->request_time; return ap_ht_time(pool,date,DEFAULT_TIME_FORMAT,0); } case date_gmt: { apr_pool_t* pool = private->req->req->pool; apr_time_t date = private->req->req->request_time; return ap_ht_time(pool,date,DEFAULT_TIME_FORMAT,1); } case last_modified: { apr_pool_t* pool = private->req->req->pool; return ap_ht_time(pool,private->req->req->finfo.mtime,DEFAULT_TIME_FORMAT,1); } case document_uri: { return private->req->req->uri; } case document_path_info: { return private->req->req->path_info; } case document_name: { char *t; if ((t = strrchr(private->req->req->filename,'/'))) { return ++t; } else { return private->req->req->uri; } } case query_string_unescaped: { if (private->req->req->args) { apr_pool_t* pool = private->req->req->pool; char *arg_copy = (char*) apr_pstrdup(pool,private->req->req->args); ap_unescape_url(arg_copy); return ap_escape_shell_cmd(pool,arg_copy); } else { return NULL; } } case user_name: { #ifndef WIN32 struct passwd *pw = (struct passwd *) getpwuid(private->req->req->finfo.user); if (pw) { //apr_table_set( table, "USER_NAME", // apr_pstrdup( pool, pw->pw_name ) ); return pw->pw_name; } else { apr_pool_t* pool = private->req->req->pool; return (char*) apr_psprintf(pool,"user#%lu",(unsigned long)private->req->req->finfo.user); } #else return NULL; #endif } case rivet_cache_free: { apr_pool_t* pool = private->req->req->pool; return (char*) apr_psprintf (pool, "%d",(RIVET_PEEK_INTERP(private,private->running_conf))->cache_free); } case rivet_cache_size: { apr_pool_t* pool = private->req->req->pool; return (char*) apr_psprintf (pool, "%d",(RIVET_PEEK_INTERP(private,private->running_conf))->cache_size); } } return NULL; } /* * -- TclWeb_InitEnvVars * * Load the CGI and environment variables into the request_rec environment structure * Variables belong to 3 cathegories * * + common variables (ap_add_common_vars) * + CGI variables (ad_cgi_vars) * + a miscellaneous set of variables * listed in the array include_env_vars * * Each cathegory is controlled by flags in order to reduce the overhead of getting them * into request_rec in case previous call to ::rivet::env could have already forced them * into request_rec */ static void TclWeb_InitEnvVars (rivet_thread_private* private) { TclWebRequest *req = private->req; if (ENV_IS_LOADED(req->environment_set)) return; /* Retrieve cgi variables. */ if (!ENV_CGI_VARS_LOADED(req->environment_set)) { ap_add_cgi_vars(req->req); } if (!ENV_COMMON_VARS_LOADED(req->environment_set)) { ap_add_common_vars(req->req); } /* Loading into 'req->req->subprocess_env' the include vars */ /* actually this check is not necessary. ENV_VARS_M is set only here therefore * if it's set this function has been called already and it should have returned * at the beginning of ies execution. I keep it for clarity and uniformity with the * CGI variables and in case the incremental environment handling is extended */ if (!ENV_VARS_LOADED(req->environment_set)) { apr_table_t *table; int idx; table = req->req->subprocess_env; for (idx = 0;idx < invalid_env_var;idx++) { apr_table_set(table,include_env_vars[idx],TclWeb_SelectEnvIncludeVar(private,idx)); } } ENV_LOADED(req->environment_set) } /* -- TclWeb_GetEnvIncludeVar * * the environment variable named in key is searched among the include * variables and then resolved by calling TclWeb_SelectEnvIncludeVar * * Result: * * a character string pointer to the environment variable value or * NULL if the environment variable name in invalid or the variable * could not be resolved * */ static char* TclWeb_GetEnvIncludeVar (rivet_thread_private* private,char* key) { int idx; for (idx = 0;idx < invalid_env_var; idx++) { const char* include_var_p = include_env_vars[idx]; if (strncmp(key,include_var_p,strlen(key) < strlen(include_var_p) ? strlen(key) : strlen(include_var_p)) == 0) { return TclWeb_SelectEnvIncludeVar(private,idx); } } return NULL; } int TclWeb_GetEnvVars(Tcl_Obj *envvar,rivet_thread_private* private) { int i; apr_array_header_t *env_arr; apr_table_entry_t *env; Tcl_Obj *key; Tcl_Obj *val; TclWebRequest *req; TclWeb_InitEnvVars(private); req = private->req; Tcl_IncrRefCount(envvar); /* Transfer Apache internal CGI variables to TCL request namespace. */ env_arr = (apr_array_header_t *) apr_table_elts(req->req->subprocess_env); env = (apr_table_entry_t *) env_arr->elts; for (i = 0; i < env_arr->nelts; ++i) { if ((!env[i].key) || (!env[i].val)) { continue; } key = TclWeb_StringToUtfToObj(env[i].key, req); val = TclWeb_StringToUtfToObj(env[i].val, req); Tcl_IncrRefCount(key); Tcl_IncrRefCount(val); /* Variable scope resolution changed to default (flags: 0) * to enable creation of the array in the caller's local scope. * Default behavior (creation in the ::request namespace) * is now more consistently constrained by fully qualifying * the default array names (see rivetCore.c). This should fix * Bug #48963 */ Tcl_ObjSetVar2(req->interp, envvar, key, val, 0); Tcl_DecrRefCount(key); Tcl_DecrRefCount(val); } Tcl_DecrRefCount(envvar); return TCL_OK; } int TclWeb_GetHeaderVars(Tcl_Obj *headersvar,rivet_thread_private* private) { int i; TclWebRequest *req; apr_array_header_t *hdrs_arr; apr_table_entry_t *hdrs; Tcl_Obj *key; Tcl_Obj *val; req = private->req; // I actually don't see why we need to load the whole environment here //TclWeb_InitEnvVars(private); Tcl_IncrRefCount(headersvar); /* Transfer client request headers to TCL request namespace. */ hdrs_arr = (apr_array_header_t*) apr_table_elts(req->req->headers_in); hdrs = (apr_table_entry_t *) hdrs_arr->elts; for (i = 0; i < hdrs_arr->nelts; ++i) { if (!hdrs[i].key) continue; key = TclWeb_StringToUtfToObj(hdrs[i].key, req); val = TclWeb_StringToUtfToObj(hdrs[i].val, req); Tcl_IncrRefCount(key); Tcl_IncrRefCount(val); /* See comment in TclWeb_GetEnvVars concerning Bug #48963*/ Tcl_ObjSetVar2(req->interp, headersvar, key, val, 0); Tcl_DecrRefCount(key); Tcl_DecrRefCount(val); } /* Transfer Apache internal CGI variables to TCL request namespace. */ Tcl_DecrRefCount(headersvar); return TCL_OK; } INLINE int TclWeb_Base64Encode(char *out, char *in, TclWebRequest *req) { out = ap_pbase64encode(req->req->pool, in); return TCL_OK; } INLINE int TclWeb_Base64Decode(char *out, char *in, TclWebRequest *req) { out = ap_pbase64decode(req->req->pool, in); return TCL_OK; } INLINE int TclWeb_EscapeShellCommand(char *out, char *in, TclWebRequest *req) { out = ap_escape_shell_cmd(req->req->pool, in); return TCL_OK; } /* Functions to convert strings to UTF encoding */ /* These API's are a bit different, because it's so much more * practical. */ #if 0 #undef Tcl_ExternalToUtfDString #define Tcl_ExternalToUtfDString(encoding, src, len, ds) \ (Tcl_ExternalToUtfDStringEx(NULL,(encoding),(src),(len), \ TCL_ENCODING_PROFILE_TCL8, (ds), NULL)) #endif char *TclWeb_StringToUtf (char *in,TclWebRequest *req) { char *tmp; Tcl_DString dstr; Tcl_DStringInit(&dstr); tmp = (char*) apr_pstrdup(req->req->pool,Tcl_ExternalToUtfDString(NULL,in,(signed)strlen(in),&dstr)); Tcl_DStringFree(&dstr); return tmp; } INLINE Tcl_Obj * TclWeb_StringToUtfToObj(char *in, TclWebRequest *req) { return Tcl_NewStringObj(TclWeb_StringToUtf(in, req), -1); } int TclWeb_PrepareUpload(char *varname, TclWebRequest *req) { req->upload = ApacheUpload_find(req->apachereq->upload, varname); if (req->upload == NULL) { return TCL_ERROR; } else { return TCL_OK; } } int TclWeb_UploadChannel(char *varname, TclWebRequest *req) { Tcl_Channel chan; chan = Tcl_OpenFileChannel(req->interp,req->upload->tempname,"r",0); if (chan == NULL) { return TCL_ERROR; } else { Tcl_Obj* result; /* Tcl 9 has no "binary" encoding; binary translation is portable. */ if (Tcl_SetChannelOption(req->interp,chan,"-translation","binary") == TCL_ERROR) { (void) Tcl_Close(NULL, chan); return TCL_ERROR; } Tcl_RegisterChannel(req->interp,chan); result = Tcl_NewObj(); Tcl_SetStringObj(result, Tcl_GetChannelName(chan), -1); Tcl_SetObjResult(req->interp, result); return TCL_OK; } } int TclWeb_UploadTempname(TclWebRequest *req) { Tcl_Obj *tempname = Tcl_NewObj(); Tcl_SetStringObj(tempname,TclWeb_StringToUtf(req->upload->tempname,req), -1); Tcl_SetObjResult(req->interp, tempname); return TCL_OK; } int TclWeb_UploadSave(char *varname, Tcl_Obj *filename, TclWebRequest *req) { apr_status_t status; status = apr_file_copy(req->upload->tempname,Tcl_GetString(filename),APR_FILE_SOURCE_PERMS,req->req->pool); if (status == APR_SUCCESS) { return TCL_OK; } else { /* apr_strerror docs don't tell anything about a demanded buffer size, we're just adopting a reasonable guess */ char error_msg[1024]; char* tcl_error_msg; apr_strerror(status,error_msg,1024); tcl_error_msg = apr_psprintf(req->req->pool,"Error copying upload '%s' to '%s' (%s)", req->upload->tempname, Tcl_GetString(filename), error_msg); Tcl_AddErrorInfo(req->interp,tcl_error_msg); return TCL_ERROR; } } int TclWeb_UploadData(char *varname, TclWebRequest *req) { Tcl_Obj* result; rivet_server_conf *rsc = NULL; rsc = RIVET_SERVER_CONF( req->req->server->module_config ); /* This sucks - we should use the hook, but I want to get everything fixed and working first */ if (rsc->upload_files_to_var) { Tcl_Channel chan; chan = Tcl_OpenFileChannel (req->interp, req->upload->tempname, "r", 0); if (chan == NULL) { char* tcl_error_msg; int error_number = Tcl_GetErrno(); Tcl_AddErrorInfo(req->interp,"Error opening channel to uploaded data"); tcl_error_msg = apr_psprintf(req->req->pool,"Error setting channel option '%s': %s", Tcl_ErrnoId(), Tcl_ErrnoMsg(error_number)); Tcl_AddErrorInfo(req->interp,tcl_error_msg); return TCL_ERROR; } if (Tcl_SetChannelOption(req->interp, chan, "-translation", "binary") == TCL_ERROR) { char* tcl_error_msg; int error_number = Tcl_GetErrno(); tcl_error_msg = apr_psprintf(req->req->pool,"Error setting channel option '%s': %s", Tcl_ErrnoId(), Tcl_ErrnoMsg(error_number)); Tcl_AddErrorInfo(req->interp,tcl_error_msg); (void) Tcl_Close(NULL, chan); return TCL_ERROR; } /* Put data in a variable */ result = Tcl_NewObj(); Tcl_ReadChars(chan, result, (int)ApacheUpload_size(req->upload), 0); if (Tcl_Close(req->interp, chan) == TCL_ERROR) { return TCL_ERROR; } Tcl_SetObjResult(req->interp, result); } else { Tcl_AppendResult(req->interp, "RivetServerConf UploadFilesToVar is not set", NULL); return TCL_ERROR; } return TCL_OK; } int TclWeb_UploadSize(TclWebRequest *req) { Tcl_Obj* result = Tcl_NewObj(); Tcl_SetIntObj(result, (int)ApacheUpload_size(req->upload)); Tcl_SetObjResult(req->interp, result); return TCL_OK; } int TclWeb_UploadType(TclWebRequest *req) { Tcl_Obj *type = Tcl_NewObj(); /* If there is a type, return it, if not, return blank. */ Tcl_SetStringObj(type, ApacheUpload_type(req->upload) ? (char *)ApacheUpload_type(req->upload) : (char *)"", -1); Tcl_SetObjResult(req->interp, type); return TCL_OK; } int TclWeb_UploadFilename(TclWebRequest *req) { Tcl_Obj *filename = Tcl_NewObj(); Tcl_SetStringObj(filename,TclWeb_StringToUtf(req->upload->filename,req), -1); Tcl_SetObjResult(req->interp, filename); return TCL_OK; } int TclWeb_UploadNames(TclWebRequest *req) { ApacheUpload *upload; Tcl_Obj *names = Tcl_NewObj(); upload = ApacheRequest_upload(req->apachereq); while (upload) { Tcl_ListObjAppendElement(req->interp,names,TclWeb_StringToUtfToObj(upload->name,req)); upload = upload->next; } Tcl_SetObjResult(req->interp,names); return TCL_OK; } /* * -- TclWeb_GetEnvVar * * basically is the core of the ::rivet::env rivet command. The argument to * the command is stored in 'key' and the function starts a search in various * tables following the following order * * + though undocumented in the manual the first table checked is HTTP * headers table. ::rivet::env is actually like ::rivet::headers but for * the *request_rec->headers_in table * + the common CGI variables table is checked * + the CGI 1.1 headers table is checked * + the include variables list is checked calling TclWeb_GetEnvIncludeVar * * Arguments: * * - key: a string with the environment variable name * * Results: * * - a string pointer to the string with the variable translation or * NULL if the environment variable is not found * */ char * TclWeb_GetEnvVar(rivet_thread_private* private,char *key) { char *val; TclWebRequest *req = private->req; /* Check to see if it's a header variable first. */ val = (char *)apr_table_get (req->req->headers_in,key); if (val) { return val; } /* We incrementally prepare subprocess_env */ /* CGI common vars first */ if (!ENV_COMMON_VARS_LOADED(req->environment_set)) { ap_add_common_vars(req->req); ENV_COMMON_VARS(req->environment_set) } val = (char *)apr_table_get(req->req->subprocess_env,key); if (val) { return val; } /* CGI HTTP 1.1 vars */ if (!ENV_CGI_VARS_LOADED(req->environment_set)) { ap_add_cgi_vars(req->req); ENV_CGI_VARS(req->environment_set) } val = (char *)apr_table_get(req->req->subprocess_env,key); if (val) { return val; } /* If everything failed we assumed the variable is one of * the 'include variables' and we try to resolve it calling * TclWeb_GetEnvIncludeVar, which returns NULL if the variable * is undefined */ return TclWeb_GetEnvIncludeVar(private,key); } char * TclWeb_GetVirtualFile(TclWebRequest *req, char *virtualname) { request_rec *apreq; char *filename = NULL; apreq = ap_sub_req_lookup_uri( virtualname, req->req, NULL ); //if( apreq->status == 200 && apreq->finfo.st_mode != 0 ) { //TODO: is this the right behaviour? if( apreq->status == 200 && apreq->finfo.filetype != APR_NOFILE ) { filename = apreq->filename; } if( apreq != NULL ) ap_destroy_sub_req( apreq ); return( filename ); } /* *----------------------------------------------------------------------------- * * TclWeb_GetRawPost -- * * Fetch the raw POST data from the request. * * Results: * The data, or NULL if it's not a POST or there is no data. * * Side Effects: * None. * *----------------------------------------------------------------------------- */ char * TclWeb_GetRawPost ( TclWebRequest *req, int *len ) { return ApacheRequest_get_raw_post(req->apachereq, len); } rivet-3.3.1/doc/images/disk.png000664 001750 001751 00000000551 15245054302 017075 0ustar00manghimanghi000000 000000 ‰PNG  IHDR [‚jgAMA±� üasRGB®Îé cHRMz&€„ú€èu0ê`:˜pœºQ<PLTEÿÿÿ{{{ ¾ÝýWœä[[âë¦ÿÿÿhU\ütRNS@æØfbKGDˆH pHYsHHFÉk>2IDAT×cRRR``Pv5„PÆ @*4D‚rqqqRnii”�¢  ’¯ J=ê"%tEXtdate:create2012-10-01T18:29:36+02:00»fÚ%tEXtdate:modify2004-02-19T05:48:44+01:00”�"IEND®B`‚rivet-3.3.1/doc/examples/hello.rvt000664 001750 001751 00000000031 15245054302 017637 0ustar00manghimanghi000000 000000 rivet-3.3.1/doc/html/xml_calendar.html000664 001750 001751 00000032663 15245054474 020476 0ustar00manghimanghi000000 000000 XmlCalendar

    Name

    XmlCalendar — Prints XML formatted calendar tables

    Synopsis

    XmlCalendar calendar_name ?-option1 option_list? ?-option2 option_list? ?...?

    An XmlCalendar object is created and returned. XmlCalendar objects print XML formatted calendar tables. The markup can be customized using the configuration options.

    Configuration options accept odd-length lists as values. An option_list has the following structure

    tag_name attr11 val1 attr2 val2 ...

    The first element of an option list is a tag name, the remaining terms are therefore an even-length sublist which is interpreted as a sequence of attribute-value pairs that will in turn become attributes of the tag.

    Methods

    cal_obj emit -opt1 val1 -opt2 val2
    cal_obj emit ?month? ?year? -opt1 val1 -opt2 val2
    cal_obj emit ? month | year? -opt1 val1 -opt2 val2
    The method 'emit' if invoked without arguments returns an XML calendar table of the current month

    Options

    -container (tag_name attr11 val1 attr2 val2 ...)
    Assigns an options list to the XML element that will hold the whole table.
    The default tag for the container is 'calendar', with no attributes.
    -header (tag_name attr11 val1 attr2 val2 ...)
    Assigns tag name and attributes to the XML header element (default: calheader)
    -body (tag_name attr11 val1 attr2 val2 ...)
    Assigns tag name and attributes to the XML body element of the table (default: calbody)
    -banner (tag_name attr11 val1 attr2 val2 ...)
    Assigns tag name and attributes to the XML banner element of the table (default: monthyear)
    The header of a calendar table is made of a banner, showing the Month and Year number, and of a weekdays bar.
    -foot (tag_name attr11 val1 attr2 val2 ...)
    Assigns tag name and attributes to the XML foot element of the table (default: calfoot).
    [Note]Note
    This option was added for completeness, but it's not implemented yet
    -banner_month (tag_name attr11 val1 attr2 val2 ...)
    Tag name and attributes for the XML element holding the month name (default:month)
    -banner_year (tag_name attr11 val1 attr2 val2 ...)
    Tag name and attributes for the XML element holding the month name (default: year)
    -weekdays (tag_name attr11 val1 attr2 val2 ...)
    Tag name and attributes for the XML element holding the weekday header (default: weekdays)
    -weekdays_cell (tag_name attr11 val1 attr2 val2 ...)
    Tag name and attributes for the XML element holding the each single weekday (default: wkdays)
    -days_row (tag_name attr11 val1 attr2 val2 ...)
    Tag name and attributes for the XML element holding the each row of the calendar table (default: week)
    -days_cell (tag_name attr11 val1 attr2 val2 ...)
    Tag name and attributes for the XML element representing a cell in the calendar table (default: day)
    -cell_function proc
    If set this option is the name of a procedure that gets called for every day of the month. The procedure must accept 4 argument representing day, month, year and weekday and must return an odd-length list interpreted in the same way as options lists.
    -current_day day
    This option works as a simple method for pointing out a specific day of the month. If set with a day number that day will get the class attribute automatically set as "current"
    -current_weekday 0-6 | today
    This option works as a simple method for pointing out a specific weekday of the month. If set with a weekday index (0: Sunday, 6: Saturday) the corresponding cell in the weekdays header will get the class attribute automatically set as "current_wkday"
    rivet-3.3.1/rivet/packages/dio/dio_Mysql04.tcl000664 001750 001751 00000020461 15245054302 021717 0ustar00manghimanghi000000 000000 # -- dio_Mysql.tcl -- Mysql backend. # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. package require -exact DIO 1.1 package provide dio_Mysql 0.4 namespace eval DIO { ::itcl::class Mysql { inherit Database constructor {args} {eval configure $args} { if { [catch {package require Mysqltcl}] \ && [catch {package require mysqltcl}] \ && [catch {package require mysql}]} { return -code error "No MySQL Tcl package available" } eval configure $args if {[::rivet::lempty $db]} { if {[::rivet::lempty $user]} { set user $::env(USER) } set db $user } } destructor { close } method open {} { set command "mysqlconnect" if {![::rivet::lempty $user]} { lappend command -user $user } if {![::rivet::lempty $pass]} { lappend command -password $pass } if {![::rivet::lempty $port]} { lappend command -port $port } if {![::rivet::lempty $host]} { lappend command -host $host } #if {![::rivet::lempty $encoding]} { lappend command -encoding $encoding } if {$clientargs != ""} { set command [lappend command {*}$clientargs] } #puts stderr "evaluating $command" if {[catch $command error]} { return -code error $error } set conn $error if {![::rivet::lempty $db]} { mysqluse $conn $db } } method close {} { if {![info exists conn]} { return } catch {mysqlclose $conn} unset conn } method exec {req} { if {![info exists conn] || ![mysqlping $conn]} { open } set cmd mysqlexec # # if {[::string tolower [lindex $req 0]] == "select"} { set cmd mysqlsel } # select is a 6 characters word, so let's see if the query is a select # set q [::string trim $req] # set q [::string tolower $q] # set q [::string range $q 0 5] # if {[::string match select $q]} { set cmd mysqlsel } if {[regexp -nocase {^\(*\s*select\s+} $q]} { set cmd mysqlsel } set errorinfo "" if {[catch {$cmd $conn $req} error]} { set errorinfo $error set obj [result Mysql -error 1 -errorinfo [::list $error]] return $obj } if {[catch {mysqlcol $conn -current name} fields]} { set fields "" } set obj [result Mysql -resultid $conn \ -numrows [::list $error] \ -fields [::list $fields]] return $obj } method lastkey {} { if {![info exists conn] || ![mysqlping $conn]} { return } return [mysqlinsertid $conn] } method quote {string} { if {![catch {mysqlquote $string} result]} { return $result } regsub -all {'} $string {\'} string return $string } method sql_limit_syntax {limit {offset ""}} { if {[::rivet::lempty $offset]} { return " LIMIT $limit" } return " LIMIT [expr $offset - 1],$limit" } method handle {} { if {![info exists conn] || ![mysqlping $conn]} { open } return $conn } method makeDBFieldValue {table_name field_name val {convert_to {}}} { if {[info exists specialFields(${table_name}@${field_name})]} { switch $specialFields(${table_name}@${field_name}) { DATE { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d}] return "DATE_FORMAT('$my_val','%Y-%m-%d')" } DATETIME { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d %T}] return "DATE_FORMAT('$my_val','%Y-%m-%d %T')" } NOW { # we try to be coherent with the original purpose of this method whose # goal is endow the class with a uniform way to handle timestamps. # E.g.: Package session expects this case to return a timestamp in seconds # so that differences with timestamps returned by [clock seconds] # can be done and session expirations are computed consistently. # (Bug #53703) switch $convert_to { SECS { if {[::string compare $val "now"] == 0} { # set secs [clock seconds] # set my_val [clock format $secs -format {%Y%m%d%H%M%S}] # return $my_val return [clock seconds] } else { return "UNIX_TIMESTAMP($field_name)" } } default { if {[::string compare $val, "now"] == 0} { set secs [clock seconds] } else { set secs [clock scan $val] } # this is kind of going back and forth from the same # format, #set my_val [clock format $secs -format {%Y-%m-%d %T}] return "FROM_UNIXTIME('$secs')" } } } NULL { if {[::string toupper $val] == "NULL"} { return $val } else { return "'[quote $val]'" } } default { # no special code for that type!! return "'[quote $val]'" } } } else { return "'[quote $val]'" } } public variable db "" { if {[info exists conn] && [mysqlping $conn]} { mysqluse $conn $db } } protected method handle_client_arguments {cargs} { # we assign only the accepted options set clientargs {} foreach {a v} $cargs { if {($a == "-encoding") || \ ($a == "-localfiles") || \ ($a == "-ssl") || \ ($a == "-sslkey") || \ ($a == "-sslcert") || \ ($a == "-sslca") || \ ($a == "-sslcapath") || \ ($a == "-sslcipher") || \ ($a == "-socket")} { lappend clientargs $a $v } } } public variable interface "Mysql" private variable conn } ; ## ::itcl::class Mysql ::itcl::class MysqlResult { inherit Result constructor {args} { eval configure $args } destructor { } method nextrow {} { return [mysqlnext $resultid] } } ; ## ::itcl::class MysqlResult } rivet-3.3.1/src/mod_rivet_ng/mod_rivet_cache.h000664 001750 001751 00000004100 15245054302 022144 0ustar00manghimanghi000000 000000 /* mod_rivet_cache.h -- The mod_rivet cache */ /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef __mod_rivet_cache_h__ #define __mod_rivet_cache_h__ /* * This is the absolute minimum size of the cache, unless CacheSize is set */ #define RIVET_CACHE_SIZE_MINIMUM 50 EXTERN int RivetCache_DefaultSize (void); EXTERN void RivetCache_Create (apr_pool_t *p, rivet_thread_interp* interp_obj); EXTERN void RivetCache_Cleanup (rivet_thread_private* private,rivet_thread_interp* rivet_interp); EXTERN char* RivetCache_MakeKey (apr_pool_t* pool, char* filename, time_t ctime, time_t mtime, unsigned int user_conf, int toplevel); EXTERN Tcl_HashEntry* RivetCache_EntryLookup (rivet_thread_interp* rivet_interp,char* hashKey); EXTERN Tcl_HashEntry* RivetCache_CreateEntry (rivet_thread_interp* rivet_interp,char* hashKey,int* isNew); EXTERN Tcl_Obj* RivetCache_FetchScript (Tcl_HashEntry* entry); EXTERN int RivetCache_StoreScript(rivet_thread_interp* rivet_interp, Tcl_HashEntry* entry, Tcl_Obj* script); EXTERN void RivetCache_DeleteEntry (Tcl_HashEntry *entry); #endif /* __mod_rivet_cache_h__ */ rivet-3.3.1/doc/xml/processing.xml000664 001750 001751 00000012005 15245054302 017663 0ustar00manghimanghi000000 000000
    Apache Rivet HTTP Request Processing
    Tcl Scripts Processing Until &version2-generic; versions Rivet handled requests following the vision that inspired the original design which was summarized in the definition Web programming like in PHP, but with Tcl. HTTP requests triggered the execution of Tcl scripts or a Rivet (.rvt file) templates whose path is encoded in the URI (an alias translation or URL rewriting might occur to establish the real path). The execution of such scripts can be preceded and/or followed by the execution of scripts common to a whole web site or to a hierarchy of directories the BeforeScript and AfterScript directives. These scripts can be configured on a per virtual host, per directory or per user basis. Execution of such combined scripts can break because of coding errors (thus triggering the ErrorScript execution) or it can deliberately interrupt ordinary execution by calling ::rivet::abort_page (which triggers the execution of a script defined by the directive AbortScript). This scheme is in case terminated by a further configurable script (AfterEveryScript). This model of request handling was coded within the module mod_rivet.so itself. With Rivet &version30; we changed this approach and landed to a new much simpler and flexible model where each request is by default handled by the following Tcl procedure &request_handler.tcl; Note the call to new &version3-generic; command ::rivet::url_script that returns the body of the Tcl script or Rivet template pointed by the URL. This procedure emulates the &version2-generic; scheme and as such works as a fully compatible request handling but opens to the programmers the option of replacing it with their own application request handling procedure Note that if you redefine the core request handler you'll need to handle yourself any error conditions and any code interruption brought about by calling ::rivet::abort_page. The current procedure might work as a template to be reworked into your own request handler.
    Example: basic OO Rivet Application An applications may have no interest in running a script pointed by the URL as in the traditional approach followed by rivet inspired to the PHP philosophy of scripting the HTML. A web based application could be driven entirely by the URL encoded arguments and by the data POSTed with HTML forms, still retaining the ability of exploiting the template engine of Rivet through the ::rivet::parse. In other words an application could hinge on a single entry point to handle requests, regardless the complexity of its internal design. This section shows a template for such an application (let's call it MyRivetApp) based on an Itcl (or TclOO for what it matters) object instance. In myrivetapp.tcl the application class is defined and an instance of it is created in the global namespace. &myrivetapp.tcl; which provides a very basic interface for both initialization and request processing. Such script will be sourced into the Tcl interpreter at the mod_rivet initialization stage. In the Apache configuration (most likely within a <VirtualHost myrivetapp.com:80>...</VirtualHost> definition block) <IfModule rivet_module> RivetServerConf ChildInitScript "source myrivetapp.tcl" </IfModule> By running this script when an a thread is started we set it up to respond requests, but we still need to tell mod_rivet what code will eventually handle requests and how the method MyRivetApp::request_processing will be called with appropriate arguments &myapp_request_handler.tcl;
    Finally we have to tell mod_rivet to run this script when a request is delivered to myApplication and we do so using the &version30; directive RequestHandler <IfModule rivet_module> RivetServerConf ChildInitScript "source myrivetapp.tcl" RivetServerConf RequestHandler "myapp_request_handler.tcl" </IfModule> Notice that the argument of the directive RequestHandler is a file name not a Tcl script as for ChildInitScript With such approach only the ChildInitScript, ChildExitScript and GlobalInitScript configuration directives are effective, while the effect of other handler is devolved to our request handler script.
    rivet-3.3.1/doc/html/toglyphs.html000664 001750 001751 00000004713 15245054474 017711 0ustar00manghimanghi000000 000000 toGlyphs

    Name

    toGlyphs — print large ASCII glyphs

    Synopsis

    ::AsciiGlyphs toGlyphs string

    Description

    prints the ASCII glyphs corresponding to the characters forming the argument string

    rivet-3.3.1/cmake/cmake_extra_modules/FindAPR.cmake000664 001750 001751 00000006716 15245054302 022754 0ustar00manghimanghi000000 000000 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # - Find Apache Portable Runtime # Find the APR includes and libraries # This module defines # APR_INCLUDE_DIR and APRUTIL_INCLUDE_DIR, where to find apr.h, etc. # APR_LIBRARIES and APRUTIL_LIBRARIES, the libraries needed to use APR. # APR_FOUND and APRUTIL_FOUND, If false, do not try to use APR. # also defined, but not for general use are # APR_LIBRARY and APRUTIL_LIBRARY, where to find the APR library. # APR first. FIND_PATH(APR_INCLUDE_DIR apr.h /usr/local/include/apr-1 /usr/local/include/apr-1.0 /usr/include/apr-1 /usr/include/apr-1.0 ${APR_INCLUDE_DIR_HINTS} ${APACHE_INCLUDE_DIR_HINTS} ${APACHE_ROOT}/include ) SET(APR_NAMES ${APR_NAMES} libapr-1 apr-1) FIND_LIBRARY(APR_LIBRARY NAMES ${APR_NAMES} PATHS /usr/lib /usr/local/lib ${APR_LIBRARY_HINTS} ${APACHE_ROOT}/lib ) IF (APR_LIBRARY AND APR_INCLUDE_DIR) SET(APR_LIBRARIES ${APR_LIBRARY}) SET(APR_FOUND "YES") ELSE (APR_LIBRARY AND APR_INCLUDE_DIR) SET(APR_FOUND "NO") ENDIF (APR_LIBRARY AND APR_INCLUDE_DIR) IF (APR_FOUND) IF (NOT APR_FIND_QUIETLY) MESSAGE(STATUS "Found APR: ${APR_LIBRARIES}") ENDIF (NOT APR_FIND_QUIETLY) ELSE (APR_FOUND) IF (APR_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could not find APR library") ENDIF (APR_FIND_REQUIRED) ENDIF (APR_FOUND) # Deprecated declarations. SET (NATIVE_APR_INCLUDE_PATH ${APR_INCLUDE_DIR} ) GET_FILENAME_COMPONENT (NATIVE_APR_LIB_PATH ${APR_LIBRARY} PATH) MARK_AS_ADVANCED( APR_LIBRARY APR_INCLUDE_DIR ) # Next, APRUTIL. FIND_PATH(APRUTIL_INCLUDE_DIR apu.h /usr/local/include/apr-1 /usr/local/include/apr-1.0 /usr/include/apr-1 /usr/include/apr-1.0 ${APRUTIL_INCLUDE_DIR_HINTS} ${APACHE_INCLUDE_DIR_HINTS} ${APACHE_ROOT}/include ) SET(APRUTIL_NAMES ${APRUTIL_NAMES} libaprutil-1 aprutil-1 ) FIND_LIBRARY(APRUTIL_LIBRARY NAMES ${APRUTIL_NAMES} PATHS /usr/lib /usr/local/lib ${APRUTIL_LIBRARY_HINTS} ${APR_LIBRARY} ${APACHE_ROOT}/lib ${APR_LIBRARY_HINTS} ) IF (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR) SET(APRUTIL_LIBRARIES ${APRUTIL_LIBRARY}) SET(APRUTIL_FOUND "YES") ELSE (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR) SET(APRUTIL_FOUND "NO") ENDIF (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR) IF (APRUTIL_FOUND) IF (NOT APRUTIL_FIND_QUIETLY) MESSAGE(STATUS "Found APRUTIL: ${APRUTIL_LIBRARIES}") ENDIF (NOT APRUTIL_FIND_QUIETLY) ELSE (APRUTIL_FOUND) IF (APRUTIL_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could not find APRUTIL library") ENDIF (APRUTIL_FIND_REQUIRED) ENDIF (APRUTIL_FOUND) # Deprecated declarations. SET (NATIVE_APRUTIL_INCLUDE_PATH ${APRUTIL_INCLUDE_DIR} ) GET_FILENAME_COMPONENT (NATIVE_APRUTIL_LIB_PATH ${APRUTIL_LIBRARY} PATH) MARK_AS_ADVANCED( APRUTIL_LIBRARY APRUTIL_INCLUDE_DIR ) rivet-3.3.1/tests/hello.rvt000664 001750 001751 00000000226 15245054302 016424 0ustar00manghimanghi000000 000000

    日本語 (UTF-8 Japanese text)

    rivet-3.3.1/doc/html/unescape_string.html000664 001750 001751 00000005344 15245054474 021232 0ustar00manghimanghi000000 000000 unescape_string

    Name

    unescape_string — unescape escaped characters in a string.

    Synopsis

    ::rivet::unescape_string ?string?

    Description

    Scans through each character in the specified string looking for escaped character sequences (characters containing a percent sign and two hexadecimal characters), unescaping them back to their original character values, as needed, also mapping plus signs to spaces, and returning the result.

    This is useful for unquoting strings that have been quoted to be part of a URL.

    rivet-3.3.1/doc/html/formbroker.html000664 001750 001751 00000006615 15245054474 020213 0ustar00manghimanghi000000 000000 The Form Broker

    The Form Broker

    Introduction

    The FormBroker package creates instances of form data description objects. These objects instances have a simple set of methods to validate and control data as typically posted by HTML forms, thus data represented as the map of form variables to their values. In Rivet this association can be obtained either calling load_response or var, (form variables can be selectively read also calling ::rivet::var_post or ::rivet::var_qs)

    [Note]Note
    The FormBroker package is still experimental. Basic functionalities and interface are not likely to change but internal details and implementation could be redesigned in future releases. More specifically the external validator mechanism will likely need design improvements.
    rivet-3.3.1/rivet/rivet-tcl/parray_table.tcl000664 001750 001751 00000002441 15245054302 021636 0ustar00manghimanghi000000 000000 ## ## -- parray_table ?pattern? ?html-attibutes? ## ## tablearray prints an array data in HTML table ## This is good when a table is enough to print consistently ## related data. ## ## arrayName - Name of the array to display ## pattern - Wildcard pattern of variables. An empty string ## is tantamout a "*" and prints the whole array ## html-attributes - ## list attribute-value pairs to be given ## to the element tag ## ## $Id$ ## ## namespace eval ::rivet { proc parray_table {arrayName {pattern "*"} {htmlAttributes ""}} { upvar 1 $arrayName array if {![array exists array]} { return -code error "\"$arrayName\" isn't an array" } puts -nonewline stdout "" puts stdout "" foreach name [lsort [array names array $pattern]] { puts stdout [format "" [::rivet::escape_sgml_chars $name] \ [::rivet::escape_sgml_chars $array($name)]] } puts stdout "
    $arrayName
    %s%s
    " } } rivet-3.3.1/rivet/packages/dio/formatters.tcl000664 001750 001751 00000024535 15245054302 022007 0ustar00manghimanghi000000 000000 # formatters.tcl -- connector for tdbc, the Tcl database abstraction layer # # Copyright 2024 The Apache Software Foundation # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. package require Itcl namespace eval ::DIO::formatters { # ::itcl::class RootFormatter # # we devolve the role of special field formatter to this # class. By design this is more sensible with respect to # the current approach of having such method in subclasses # because it allows to reuse the functionality of this # class in other DBMS connector. # this class must be subclassed for each dbms or SQL dialect ::itcl::class RootFormatter { private variable special_fields [dict create] public proc quote {a_string} { regsub -all {'} $a_string {\'} a_string return $a_string } public method register {table_name field_name ftype} { dict set special_fields $table_name $field_name $ftype } public method get_special_fields {table_name} { if {[dict exists $special_fields $table_name]} { return [dict keys [dict get $special_fields $table_name] } return "" } public method has_special_fields {table_name} { return [dict exists $special_fields $table_name] } public method build {table_name field_name val convert_to} { if {[dict exists $special_fields $table_name $field_name]} { set field_type [dict get $special_fields $table_name $field_name] if {[catch { set field_value [$this $field_type $field_name $val $convert_to] } e einfo]} { puts "
    Error: $e, $einfo
    " set field_value "'[quote $val]'" } return $field_value } else { return "'[quote $val]'" } } } ; ## ::itcl::class RootFormatter ::itcl::class Mysql { inherit RootFormatter public method DATE {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d}] return "DATE_FORMAT('$my_val','%Y-%m-%d')" } public method DATETIME {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d %T}] return "DATE_FORMAT('$my_val','%Y-%m-%d %T')" } public method NOW {field_name val convert_to} { # we try to be coherent with the original purpose of this method whose # goal endows the class with a uniform way to handle timestamps. # E.g.: Package session expects this case to return a timestamp in seconds # so that differences with timestamps returned by [clock seconds] # can be done and session expirations are computed consistently. # (Bug #53703) switch $convert_to { SECS { if {[::string compare $val "now"] == 0} { # set secs [clock seconds] # set my_val [clock format $secs -format {%Y%m%d%H%M%S}] # return $my_val return [clock seconds] } else { return "UNIX_TIMESTAMP($field_name)" } } default { if {[::string compare $val, "now"] == 0} { set secs [clock seconds] } else { set secs [clock scan $val] } # this is kind of going back and forth from the same # format, #set my_val [clock format $secs -format {%Y-%m-%d %T}] return "FROM_UNIXTIME('$secs')" } } } public method NULL {field_name val convert_to} { if {[::string toupper $val] == "NULL"} { return $val } else { return "'[quote $val]'" } } } ::itcl::class Sqlite3 { inherit RootFormatter # # quote - given a string, return the same string with any single # quote characters preceded by a backslash # method quote {a_string} { regsub -all {'} $a_string {''} a_string return $a_string } public method DATE {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d}] return "date('$my_val')" } public method DATETIME {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d %T}] return "datetime('$my_val')" } public method NOW {field_name val convert_to} { # we try to be coherent with the original purpose of this method whose # goal is to provide a uniform way to handle timestamps. # E.g.: Package session expects this case to return a timestamp in seconds # so that differences with timestamps returned by [clock seconds] # can be done and session expirations are computed consistently. # (Bug #53703) switch $convert_to { SECS { if {[::string compare $val "now"] == 0} { # set secs [clock seconds] # set my_val [clock format $secs -format "%Y%m%d%H%M%S"] return [clock seconds] } else { # the numbers of seconds must be returned as 'utc' to # be compared with values returned by [clock seconds] return "strftime('%s',$field_name,'utc')" } } default { if {[::string compare $val, "now"] == 0} { set secs [clock seconds] } else { set secs [clock scan $val] } set my_val [clock format $secs -format {%Y-%m-%d %T}] return "datetime('$my_val')" } } } } ::itcl::class Postgres { inherit RootFormatter public method DATE {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d}] return "'$my_val'" } public method DATETIME {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d %T}] return "'$my_val'" } public method NOW {field_name val convert_to} { # we try to be coherent with the original purpose of this method whose # goal is to provide a uniform way to handle timestamps. # E.g.: Package session expects this case to return a timestamp in seconds # so that differences with timestamps returned by [clock seconds] # can be done and session expirations are computed consistently. # (Bug #53703) switch $convert_to { SECS { if {[::string compare $val "now"] == 0} { return [clock seconds] } else { return "extract(epoch from $field_name)" } } default { if {[::string compare $val, "now"] == 0} { set secs [clock seconds] } else { set secs [clock scan $val] } # this is kind of going back and forth from the same # format, return "'[clock format $secs -format {%Y-%m-%d %T}]'" } } } } ::itcl::class Oracle { inherit RootFormatter public method DATE {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d}] return "to_date('$my_val','YYYY-MM-DD')" } public method DATETIME {field_name val convert_to} { set secs [clock scan $val] set my_val [clock format $secs -format {%Y-%m-%d %T}] return "to_date('$my_val','YYYY-MM-DD HH24:MI:SS')" } public method NOW {field_name val convert_to} { switch $convert_to { SECS { if {[::string compare $val "now"] == 0} { set secs [clock seconds] set my_val [clock format $secs -format {%Y%m%d%H%M%S}] return $my_val } else { return "($field_name - to_date('1970-01-01')) * 86400" #return "to_char($field_name, 'YYYYMMDDHH24MISS')" } } default { if {[::string compare $val "now"] == 0} { set secs [clock seconds] } else { set secs [clock scan $val] } set my_val [clock format $secs -format {%Y-%m-%d %T}] return "to_date('$my_val', 'YYYY-MM-DD HH24:MI:SS')" } } } } }; ## namespace eval DIO package provide dio::formatters 1.1 rivet-3.3.1/rivet/packages/form/pkgIndex.tcl000664 001750 001751 00000000102 15245054302 021542 0ustar00manghimanghi000000 000000 package ifneeded form 1.0 [list source [file join $dir form.tcl]] rivet-3.3.1/rivet/packages/dio/dio_Sqlite.tcl000664 001750 001751 00000024676 15245054302 021723 0ustar00manghimanghi000000 000000 # dio_Sqlite.tcl -- DIO interface for sqlite # Copyright 2002-2024 The Apache Software Foundation # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. package require DIO 1.2 package provide dio_Sqlite 1.2 namespace eval DIO { variable sqlite_seq -1 catch { ::itcl::delete class Sqlite } ::itcl::class Sqlite { inherit Database private variable dbcmd "" #public variable interface "Sqlite" constructor {args} {eval configure -interface Sqlite $args} { if {[catch {package require sqlite}] && \ [catch {package require sqlite3}]} { return -code error "No Sqlite Tcl package available" } eval configure $args } destructor { close } public method create_field_formatter {} { set special_fields_formatter [::DIO::formatters::Sqlite3 ::DIO::formatters::#auto] } method open {} { variable ::DIO::sqlite_seq if {$dbcmd != ""} { return } set dbcmd dbcmd[incr sqlite_seq] ::sqlite3 $dbcmd $db set dbcmd [namespace which $dbcmd] } method close {} { catch { $dbcmd close } } method exec {req} { open if {[$dbcmd complete $req] == 0} { append req ";" if {[$dbcmd complete $req] == 0} { return -code error "Incomplete SQL" } } set obj [::DIO::SqliteResult #auto -request $req -dbcmd $dbcmd -select 0] # If it's a select statement, defer caching of results. # if {[regexp {^[^[:graph:]]*([[:alnum:]]*)} $req _ word]} if {[::string range [::string trim $req] 0 5] == "select"} { $obj configure -select 1 } else { # Actually perform the query $obj cache } return [namespace which $obj] } method list {req} { open set result "" $dbcmd eval $req a { lappend result $a([lindex $a(*) 0]) } return $result } method sql_limit_syntax {limit {offset ""}} { set sql " LIMIT $limit" if {![::rivet::lempty $offset]} { append sql " OFFSET $offset" } return $sql } ## If they change DBs, we need to close the database. It'll be reopened ## on the first exec public variable db "" { if {"$dbcmd" != ""} { close set dbcmd "" } } # # quote - given a string, return the same string with any single # quote characters preceded by a backslash # method quote {a_string} { regsub -all {'} $a_string {''} a_string return $a_string } } catch { ::itcl::delete class SqliteResult } # Not inheriting Result because there's just too much stuff that needs # to be re-done when you're deferring execution ::itcl::class SqliteResult { constructor {args} { eval configure $args if {"$request" == "--"} { return -code error "No SQL code provided for result" } if {"$dbcmd" == "--"} { return -code error "No SQLite DB command provided" } } destructor { clear } method clear {} { set cache {} set cache_loaded 0 } method destroy {} { ::itcl::delete object $this } method resultid {args} { if [llength $args] { set resultid [lindex $args 0] } if ![info exists resultid] { return $request } return $resultid } method numrows {args} { if [llength $args] { set numrows [lindex $args 0] } if ![info exists numrows] { if ![load_cache] { return 0 } } return $numrows } method fields {args} { if [llength $args] { set fields [lindex $args 0] } if ![info exists fields] { if ![load_cache] { return {} } } return $fields } method errorcode {args} { if [llength $args] { set errorcode [lindex $args 0] } if ![info exists errorcode] { check_ok } return $errorcode } method error {args} { if [llength $args] { set error [lindex $args 0] } if ![info exists error] { check_ok } return $error } method errorinfo {args} { if [llength $args] { set errorinfo [lindex $args 0] } if ![info exists errorinfo] { check_ok } if $error { return $errorinfo } return "" } method autocache {args} { if [llength $args] { set autocache $args } return $autocache } method cache {} { load_cache } protected method load_cache {} { if {$error_exists} { return 0 } if {$cache_loaded} { return 1 } if [catch { set numrows 0 set cache {} # Doing a loop here because it's the only way to get the fields $dbcmd eval $request a { incr numrows set names $a(*) set row {} foreach field $names { lappend row $a($field) } lappend cache $row } # some SQL commands actually don't run the script # argument of method 'eval'. We therefore rely on # the method 'changes' which returns the number # of affected rows # (http://www.sqlite.org/tclsqlite.html#changes) if {($numrows == 0) && ($select == 0)} { set numrows [$dbcmd changes] } if {[info exists names] && ![info exists fields]} { set fields $names } else { set fields "" } } err] { return [check_ok 1 $err] } set cache_loaded 1 return [check_ok 0] } method forall {type varname body} { upvar 1 $varname var if $cache_loaded { foreach row $cache { setvar $type var $row uplevel 1 $body } } else { set numrows 0 $dbcmd eval $request a { incr numrows set names $a(*) set row {} foreach field $names { lappend row $a($field) } if $autocache { lappend cache $row } if ![info exists fields] { set fields $names } setvar $type var $row uplevel 1 $body } if $autocache { set cache_loaded 1 check_ok 0 } } } method next {type varname} { if ![load_cache] { return -1 } if {$rowid + 1 > $numrows} { return -1 } upvar 1 $varname var incr rowid setvar $type var [lindex $cache $rowid] return $rowid } protected method setvar {type varname row} { upvar 1 $varname var switch -- $type { -list { set var $row } -array { foreach name $fields value $row { set var($name) $value } } -keyvalue { set var {} foreach name $fields value $row { lappend var -$name $value } } default { return -code error "Unknown type $type" } } } protected method check_ok {{val -1} {info ""}} { if {$error_checked} { return [expr !$error] } if {$val < 0} { set val [catch {$dbcmd onecolumn $request} info] } set error $val set errorcode $val set error_checked 1 set error_exists $val if {$val > 0} { set errorinfo $info } else { set rowid -1 } return [expr !$val] } public variable autocache 0 public variable error public variable errorcode public variable errorinfo public variable fields public variable numrows public variable resultid public variable rowid -1 public variable select 0 public variable request "--" public variable dbcmd "--" protected variable cache protected variable cache_loaded 0 protected variable error_checked 0 protected variable error_exists 0 } ; ## ::itcl::class SqliteResult } rivet-3.3.1/doc/html/escape_string.html000664 001750 001751 00000005264 15245054474 020670 0ustar00manghimanghi000000 000000 escape_string

    Name

    escape_string — convert a string into escaped characters.

    Synopsis

    ::rivet::escape_string ?string?

    Description

    Scans through each character in the specified string looking for special characters, escaping them as needed, mapping special characters to a quoted hexadecimal equivalent, returning the result.

    This is useful for quoting strings that are going to be part of a URL.

    rivet-3.3.1/tests/channel.rvt000664 001750 001751 00000000237 15245054302 016733 0ustar00manghimanghi000000 000000 HTML MORE HTML LAST HTML rivet-3.3.1/rivet/packages/form/form.tcl000664 001750 001751 00000033652 15245054302 020754 0ustar00manghimanghi000000 000000 # form.tcl -- generate forms automatically. # Copyright 2002-2004 The Apache Software Foundation # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # package require Itcl package provide form 1.0 # # Rivet form class # ::itcl::class form { constructor {args} { # first of all we make sure DefaultValues is an array array set DefaultValues {} # set the form method to be a post and the action to be # a refetching of the current page set arguments(method) post set arguments(action) [::rivet::env DOCUMENT_URI] # use $this for the type for form-global stuff like form arguments import_data form $this arguments $args if {[info exists arguments(defaults)]} { # make the public variable contain the name of the array # we are sucking default values out of set defaults $arguments(defaults) upvar 1 $arguments(defaults) callerDefaults array set DefaultValues [array get callerDefaults] unset arguments(defaults) } } destructor { } method destroy {} { ::itcl::delete object $this } # # import_data -- given a field type, field name, name of an array, and a # list of key-value pairs, prepend any default key-value pairs, # set a default value if one exists, then store the resulting # key-value pairs in the named array # protected method import_data {type name arrayName list} { upvar 1 $arrayName data # # If there are elements in the defaultArgs array for the # specified type, combine them with the list of key-value # pairs, putting the DefaultArgs values first so the # key-value pairs from list can possibly override them. # if {[info exists DefaultArgs($type)]} { set list [concat $DefaultArgs($type) $list] } # # if there is a default value for the name stored in the # DefaultValues array in this class, set the value # element of the array the caller named to contain that # value # if {[info exists DefaultValues($name)]} { set data(value) $DefaultValues($name) } # # if we don't have an even number of key-value pairs, # that just ain't right # if {[llength $list] % 2} { return -code error "Unmatched key-value pairs" } # # for each key-value pair in the list, strip the first # dash character from the key part and map it to lower # case, then use that as the key for the passed-in # array and store the corresonding value in there # # we also prep and return the list of key-value pairs, normalized # with the lowercase thing # set return "" foreach {var val} $list { set var [string range [string tolower $var] 1 end] set data($var) $val if {($var == "values") || ($var == "labels")} { continue } lappend return -$var $val } return $return } # # argstring - given an array name, construct a string of the # style key1="data1" key2="data2" etc for each key value pair in the # array # protected method argstring {arrayName} { upvar 1 $arrayName data set string "" foreach arg [lsort [array names data]] { append string " $arg=\"$data($arg)\"" } return $string } # # default_value -- if only a name is given, returns a default value # for that name if one exists else an empty list. # # if a name and a value are given, the default value is set to that # name (and the new default value is returned). # method default_value {name {newValue ""}} { if {[::rivet::lempty $newValue]} { if {![info exists DefaultValues($name)]} { return } return $DefaultValues($name) } return [set DefaultValues($name) $newValue] } # # default_args - given a type and a variable number of arguments, # if there are no arguments other than the type, return the # element of that name from the DefaultArgs array, if that element # exists, else return an empty list. # # if a name and a value are given, sets the DefaultArgs to the variable # list of arguments. # method default_args {type args} { # if only one argument was specified if {[::rivet::lempty $args]} { if {![info exists DefaultArgs($type)]} { return } return $DefaultArgs($type) } # make sure we have an even number of key-value pairs if {[llength $args] % 2} { return -code error "Unmatched key-value pairs" } # set the DefaultArgs for the specified type return [set DefaultArgs($type) $args] } # # start - generate the
    with all of its arguments # method start {{args ""}} { if {![::rivet::lempty $args]} { # replicated in constructor import_data form $this arguments $args } ::rivet::html "" } # # end - generate the
    # method end {} { ::rivet::html "" } # # field - emit a field of the given field type and name, including # any default key-value pairs defined for this field type and # optional key-value pairs included with the statement # method field {type name args} { # import any default key-value pairs, then any specified in this # field declaration import_data $type $name data $args switch -- $type { "radio" - "checkbox" { # if there's a label then prepare to output it. if {[info exists data(label)]} { # if there's no id defined, generate something # unique so we can reference it. if {![info exists data(id)]} { set data(id) "autogen[incr field_cnt]" } set label "" } # ...and if the is a default value for this field # and it matches the value we have for it, make # the field show up as selected (checked) if {[info exists DefaultValues($name)] && [info exists data(value)]} { # if there is no __$var variable in the defaults we are # dealing with a single value so we don't look it up # with lsearch, but we compare the 2 variable as strings, # so that spaces in the value won't be confused as a list of # multiple elements.... if {![info exists DefaultValues(__${name})]} { if {[string match $DefaultValues($name) $data(value)]} { set data(checked) "checked" } } else { if {[lsearch $DefaultValues($name) $data(value)] >= 0} { set data(checked) "checked" } } } } } # generate the field definition set string "" if {[info exists label]} { append string $label } # ...and emit it ::rivet::html $string } # # text -- emit an HTML "text" field # method text {name args} { eval field text $name $args } # # password -- emit an HTML "password" field # method password {name args} { eval field password $name $args } # # hidden -- emit an HTML "hidden" field # method hidden {name args} { eval field hidden $name $args } # # submit -- emit an HTML "submit" field # method submit {name args} { eval field submit $name $args } # # button -- emit an HTML "button" field # method button {name args} { eval field button $name $args } # # reset -- emit an HTML "reset" button # method reset {name args} { eval field reset $name $args } # # image -- emit an HTML image field # method image {name args} { eval field image $name $args } # # checkbox -- emit an HTML "checkbox" form field # method checkbox {name args} { eval field checkbox $name $args } # # radio -- emit an HTML "radiobutton" form field # method radio {name args} { eval field radio $name $args } # # color -- emit an HTML 5 "color" form field # method color {name args} { eval field color $name $args } # # date -- emit an HTML 5 "date" form field # method date {name args} { eval field date $name $args } # # datetime -- emit an HTML 5 "datetime" form field # method datetime {name args} { eval field datetime $name $args } # # datetime_local -- emit an HTML 5 "datetime-local" form field # method datetime_local {name args} { eval field datetime-local $name $args } # # email -- emit an HTML 5 "email" form field # method email {name args} { eval field email $name $args } # # file -- emit an HTML 5 "file" form field # method file {name args} { eval field file $name $args } # # month -- emit an HTML 5 "month" form field # method month {name args} { eval field month $name $args } # # number -- emit an HTML 5 "number" form field # method number {name args} { eval field number $name $args } # # range -- emit an HTML 5 "range" form field # method range {name args} { eval field range $name $args } # # search -- emit an HTML 5 "search" form field # method search {name args} { eval field search $name $args } # # tel -- emit an HTML 5 "tel" form field # method tel {name args} { eval field tel $name $args } # # time -- emit an HTML 5 "time" form field # method time {name args} { eval field time $name $args } # # url -- emit an HTML 5 "url" form field # method url {name args} { eval field url $name $args } # # week -- emit an HTML 5 "week" form field # method week {name args} { eval field week $name $args } # # radiobuttons -- # method radiobuttons {name args} { set data(values) [list] set data(labels) [list] set list [import_data radiobuttons $name data $args] if {[::rivet::lempty $data(labels)]} { set data(labels) $data(values) } foreach label $data(labels) value $data(values) { eval radio $name $list -label $label -value $value } } # # select -- generate a selector # # part of the key value pairs can include -values with a list, # and -labels with a list and it'll populate the