root/trunk/pcc/runtime/php-ini.scm

Revision 376, 8.0 KB (checked in by weyrick, 11 months ago)

more work on efficiency during runtime reset, e.g. only reseting
variables if they were used during the last page load

Line 
1;; ***** BEGIN LICENSE BLOCK *****
2;; Roadsend PHP Compiler Runtime Libraries
3;; Copyright (C) 2007 Roadsend, Inc.
4;;
5;; This program is free software; you can redistribute it and/or
6;; modify it under the terms of the GNU Lesser General Public License
7;; as published by the Free Software Foundation; either version 2.1
8;; of the License, or (at your option) any later version.
9;;
10;; This program is distributed in the hope that it will be useful,
11;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13;; GNU Lesser General Public License for more details.
14;;
15;; You should have received a copy of the GNU Lesser General Public License
16;; along with this program; if not, write to the Free Software
17;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18;; ***** END LICENSE BLOCK *****
19(module php-ini
20   (import
21    (utils "utils.scm")
22    (php-runtime "php-runtime.scm")
23    (php-hash "php-hash.scm")
24    (php-errors "php-errors.scm"))
25   (export
26    (set-ini-entry name value)
27    (get-ini-entry name)
28    (default-ini-entry name value)
29    (config-ini-entry name value)
30    (reset-ini!)
31    (generate-config-ini-entries)
32    (ini-file-parse fname::bstring parse-sections?::bool)))
33
34
35
36;;;;ini file
37(define *ini-table* (make-hashtable))
38(define *default-ini-table* (make-hashtable))
39(define *config-ini-table* (make-hashtable))
40
41(define (reset-ini!)
42   ;; reset ini settings to config file state
43   (unless (or (=fx (hashtable-size *ini-table*) 0)
44               (=fx (hashtable-size *ini-table*) (hashtable-size *config-ini-table*)))
45      (set! *ini-table* (make-hashtable))
46      (hashtable-for-each *config-ini-table*
47                          (lambda (k v)
48                             (hashtable-put! *ini-table* k v)))))
49
50; return current value, attemping a default if current doesn't exist
51(define (get-ini-entry name)
52   (let ((ival (hashtable-get *ini-table* (mkstr name))))
53      (debug-trace 9 (format "(runtime) getting ~a which is ~a" name ival))
54      (if ival
55          ival
56          (hashtable-get *default-ini-table* (mkstr name)))))     
57
58; used by php land code and .htaccess to override
59(define (set-ini-entry name value)
60   (debug-trace 9 (format "(runtime) setting ~a to ~a" name value))
61   (hashtable-put! *ini-table* (mkstr name) value)
62   ; precision?
63   (when (string=? (mkstr name) "precision")
64      (set! *float-precision* (mkfixnum value))))
65
66; used only by config file reader
67; ini table will be reset to this after every page load
68(define (config-ini-entry name value)
69   (debug-trace 9 (format "(runtime) config setting ~a to ~a" name value))
70   (hashtable-put! *config-ini-table* (mkstr name) value)
71   ; initially we also setup the main ini
72   ; it will be reset every page load
73   (set-ini-entry name value))
74
75;; generate code to re-create ini entries from the config file
76(define (generate-config-ini-entries)
77   (let ((code '()))
78      (hashtable-for-each *config-ini-table*
79         (lambda (k v)
80            (set! code (cons `(config-ini-entry ,k ,v) code))))
81      `(begin ,@(reverse code))))
82
83; used by extensions to set base values
84; these will be used if no other is available
85(define (default-ini-entry name value)
86   (hashtable-put! *default-ini-table* (mkstr name) value))
87
88
89
90;
91; This module implements reading an INI file
92; into a php hash. it is used in the builtin functions
93; in stdlib (parse_ini_file) and also by the compiler
94; to process project files from the IDE
95;
96
97;
98; this still needs more work to be compatible with php:
99;  1) it will replace constants with their values
100;  2) bitewise operations
101
102(define *current-lineno* 1)
103
104(define *first-eof-p* #t)
105
106(define *ini-surface*
107   (regular-grammar
108         ((crlf (: (* "\r") #\newline )))
109      ; yadda
110      ("[" 'lbrak)
111      ("]" 'rbrak)
112      ("=" 'assign)
113      ; space, newlines
114      ((+ (in space #\Tab)) (ignore))
115      ;
116      (crlf (begin
117               (set! *current-lineno* (+ *current-lineno* 1))
118               'nl))
119      ; comment
120      ((: (in #\; #\#) (* all) crlf)
121       (begin
122               (set! *current-lineno* (+ *current-lineno* 1))
123               'nl))
124      ; value (quoted string)
125      ((: #\" (* (or (out #\\ #\") (: #\\ (or all crlf)))) #\")
126       ; XXX if the string was multiline, our current-lineno isn't advanced. does this happen?
127       (cons 'string (the-substring 1 (-fx (the-length) 1))))
128      ; value (symbol)
129      ((+ (out space #\= #\newline #\tab "\r" #\[ #\] #\" #\; #\#))
130       (cons 'symbol (the-string)))
131      (else
132       ;; this trick is so that the first time we see the eof, it will
133       ;; be returned as a newline, and the second time the actual eof
134       ;; will be returned.  It allows us to read ini files that don't
135       ;; end in a newline.
136       (cond
137          ((and *first-eof-p*
138                (eof-object? (the-failure)))
139           (set! *first-eof-p* #f)
140           'nl)
141          (else
142           ;; reset *first-eof-p*
143           (set! *first-eof-p* #t)
144           (the-failure))))))
145
146
147(define *ini-grammar*
148   (lalr-grammar
149      ; terminals
150      (assign lbrak rbrak string symbol nl)
151
152      (inifile
153       ((line inifile) (cons line inifile))
154       (() '()))
155
156      (line
157       ; section header
158       ; XXX symbol-list here because headers can contain spaces
159       ((lbrak symbol-list rbrak nl) (cons 'section symbol-list))
160
161       ; XXX this symbol-list gets us around not supporting bitwise
162       ; operations on constants (e.g. error_reporting). we just concat the symbols together
163       ((symbol@key assign symbol-list nl) (cons* 'value key symbol-list))
164
165       ; value assign, quoted string
166       ((symbol@key assign string@val nl) (cons* 'value key val))
167
168       ; value assign, blank string
169       ((symbol assign nl) (cons* 'value symbol ""))
170
171       ; blank line
172       ((nl) '()))
173
174      (symbol-list
175       ((symbol symbol-list) (string-append symbol symbol-list))
176       ((symbol) symbol))
177     
178       ))
179
180
181(define (ini-file-parse fname::bstring parse-sections?::bool)
182   (bind-exit (exit)
183      (if (file-exists? fname)
184          (let ((rhash (make-php-hash))
185                (current-section "")
186                (ini-toks '()))
187; XXX grammer debug         
188;            (set! *current-lineno* 1)
189;            (with-input-from-file fname
190;               (lambda ()
191;                  (pp (get-tokens *ini-surface* (current-input-port)))))
192             (set! *current-lineno* 1)       
193             (try
194              (set! ini-toks (with-input-from-file fname
195                                (lambda ()
196                                   (read/lalrp *ini-grammar* *ini-surface* (current-input-port)))))
197              (lambda (e p m o)
198                 (php-warning (format "On line ~a of ~a: ~a" *current-lineno* fname m))
199                 (exit #f)))
200             ; go through tokens and build php hash
201             (for-each (lambda (a)
202                          (unless (null? a)
203                          (let ((tok (car a)))
204                             (cond
205                                ;
206                                ; NOTE: assumes parser has already handler conversion to string
207                                ;
208                                ((eqv? tok 'section) (set! current-section (cdr a)))
209                                ((eqv? tok 'value) (let* ((key (cadr a))
210                                                          (val (cddr a))
211                                                          (down-val (string-downcase val)))
212                                                      (when (or (string=? down-val "on")
213                                                                (string=? down-val "true"))
214                                                         (set! val "1"))
215                                                      (when (or (string=? down-val "off")
216                                                                (string=? down-val "null")
217                                                                (string=? down-val "false"))
218                                                         (set! val ""))
219                                                      (if (and parse-sections?
220                                                               (> (string-length current-section) 0))
221                                                          ; use section
222                                                          (let ((shash (php-hash-lookup rhash current-section)))
223                                                             (if (php-hash? shash)
224                                                                 ; already have the section
225                                                                 (php-hash-insert! shash key val)
226                                                                 ; make a new section hash
227                                                                 (begin
228                                                                    (set! shash (make-php-hash))
229                                                                    (php-hash-insert! shash key val)
230                                                                    (php-hash-insert! rhash current-section shash))))
231                                                          ; no sections or none current
232                                                          (php-hash-insert! rhash key val))))))))
233                       ini-toks)
234             ; make hash
235             rhash)
236          ; bad file
237          #f)))
238   
239
240;;;;;;;;;
241;
242; defaults
243;
244
245; url rewriter tag defaults
246(default-ini-entry "url_rewriter.tags" "a=href,area=href,frame=src,input=src,form=fakeentry")
247(default-ini-entry "arg_separator.input" "&")
248(default-ini-entry "precision" "12")
249(default-ini-entry "register_globals" #f)
Note: See TracBrowser for help on using the browser.