source: project/wiki/eggref/4/srfi-29 @ 34118

Last change on this file since 34118 was 34118, checked in by kon, 14 months ago

rel

File size: 13.3 KB
Line 
1[[tags: egg]]
2
3== srfi-29
4
5[[toc:]]
6
7
8== Documentation
9
10A Chicken implementation of
11[[http://srfi.schemers.org/srfi-29/srfi-29.html|SRFI 29]].
12
13The addition of the escape code {{~[n]@*}} to the SRFI 28 {{format}} is
14'''not''' part of this extension.
15
16=== Conditions
17
18==== undefined-condition?
19
20<procedure>(undefined-condition? OBJECT) => boolean</procedure>
21
22Is the {{OBJECT}} an instance of the SRFI 29 {{undefined-condition}}.
23
24A {{composite-property-condition}} of {{(exn srfi-29 undefined)}}.
25
26==== unbound-variable-condition?
27
28<procedure>(unbound-variable-condition? OBJECT) => boolean</procedure>
29
30Is the {{OBJECT}} an instance of the SRFI 29 {{unbound-variable-condition}}.
31
32A {{composite-property-condition}} of {{(exn srfi-29 unbound)}}.
33
34=== Parameters
35
36==== current-language
37
38<parameter>(current-language [LANGUAGE])</parameter>
39
40Gets or sets the {{LANGUAGE}} symbol.
41
42==== current-country
43
44<parameter>(current-country [COUNTRY])</parameter>
45
46Gets or sets the {{COUNTRY}} symbol.
47
48==== current-locale-details
49
50<parameter>(current-locale-details [LOCALE-DETAILS])</parameter>
51
52Gets or sets the {{LOCALE-DETAILS}} list.
53
54==== current-locale-format-function
55
56<parameter>(current-locale-format-function [FORMAT-PROCEDURE])</parameter>
57
58Gets or sets the {{FORMAT-PROCEDURE}}.
59
60This procedure must at least have the signature of a SRFI 28 {{format}}
61procedure. The default is the Chicken {{extras#format}} procedure.
62
63This is '''not''' a {{paramter}} but a {{variable}}. It is '''not''' ''thread-local''.
64
65==== reset-locale-parameters
66
67<procedure>(reset-locale-parameters)</procedure>
68
69When the {{current-locale}} is changed, (see the [[locale|locale egg]]),
70the {{current-*}} parameters need not be set individually. This will
71update those parameters to the values in the new locale. (Reset as in set
72anew.)
73
74=== Bundle Operations
75
76* A {{BUNDLE-SPECIFIER}} is a list of symbols of the form
77{{(PACKAGE-NAME [LANGUAGE] [COUNTRY] [DETAILS...])}}.
78
79* A {{BUNDLE-ALIST}} is an association-list over with key {{TEMPLATE-NAME}} &
80value {{TEMPLATE-VALUE}}. The association-list elements must be of the form
81{{(TEMPLATE-NAME . TEMPLATE-VALUE)}}.
82
83That is {{(cons 'template-example 'value-example)}} is legal, whereas {{(list
84'template-example 'value-example)}} is not. The form {{(list 'template-example
85'value-example)}} will have the value {{(list 'value-example)}}, and not
86{{'value-example}}, as expected.
87
88* A {{TEMPLATE-NAME}} is something suitable as a key, such as a {{symbol}} or
89{{string}}, but can be any {{object}} with a readable printname.
90
91* A {{TEMPLATE-VALUE}} maybe any object, but should have a readable printname.
92
93==== declare-bundle!
94
95<procedure>(declare-bundle! BUNDLE-SPECIFIER BUNDLE-ALIST)</procedure>
96
97Creates a bundle.
98
99==== undeclare-bundle!
100
101<procedure>(undeclare-bundle! BUNDLE-SPECIFIER)</procedure>
102
103Removes the bundle specified by {{BUNDLE-SPECIFIER}} from the active bundles.
104
105
106=== Bundle Database Operations
107
108SRFI 29 does not specify how bundles are stored. This extension uses the
109filesystem for the bundle database.
110
111Bundles are stored in the system bundle directory, {{(make-pathname
112(repository-path) "srfi-29-bundles")}}, unless an {{ALTERNATE}} directory is
113specified.
114
115Within a bundle directory the structure is {{(directory [LANGUAGE] [COUNTRY] [SCRIPT]
116[CODESET] [MODIFIER] PACKAGE-NAME)}}.
117
118==== store-bundle!
119
120<procedure>(store-bundle! BUNDLE-SPECIFIER [ALTERNATE])</procedure>
121
122Stores the bundle using the {{write}} procedure.
123
124==== load-bundle!
125
126<procedure>(load-bundle! BUNDLE-SPECIFIER [ALTERNATE])</procedure>
127
128Loads the bundle using the {{read}} procedure.
129
130==== load-best-available-bundle!
131
132<procedure>(load-best-available-bundle! BUNDLE-SPECIFIER [ALTERNATE])</procedure>
133
134Attempts {{(load-bundle! BUNDLE-SPECIFIER [ALTERNATE])}}, from most
135to least specific.
136
137See {{most-specific-bundle-specifier}}.
138
139==== remove-bundle!
140
141<procedure>(remove-bundle! BUNDLE-SPECIFIER [ALTERNATE])</procedure>
142
143Removes the bundle specified by {{BUNDLE-SPECIFIER}} from the active bundles,
144and from the filesystem.
145
146Will not remove the locale directory hierarchy created by
147{{(store-bundle!...)}}.
148
149==== remove-bundle-directory!
150
151<procedure>(remove-bundle-directory! BUNDLE-SPECIFIER [ALTERNATE])</procedure>
152
153Removes the bundle directory hierarchy created by {{(store-bundle!...)}}. Will
154only remove empty directories. Returns {{#t}} if operation succeeded, {{#f}}
155when a non-empty directory encountered.
156
157Does not remove the bundle, if any, from the active bundles. A filesystem only
158operation.
159
160This procedure should be used with caution.
161
162==== declared-bundle-specifiers
163
164<procedure>(declared-bundle-specifiers) => list</procedure>
165
166Returns a list of all the declared {{BUNDLE-SPECIFIER}}s.
167
168==== declared-bundle-templates
169
170<procedure>(declared-bundle-templates BUNDLE-SPECIFIER) => list</procedure>
171
172Returns an association-list of all the templates for the {{BUNDLE-SPECIFIER}}.
173
174==== most-specific-bundle-specifier
175
176<procedure>(most-specific-bundle-specifier PACKAGE-NAME) => bundle-specifier</procedure>
177
178Returns the most specific bundle specifier for the current locale.
179
180The current locale is composed of the {{(current-language)}},
181{{(current-country)}}, and {{(current-locale-details)}}.
182
183Note that the {{most-specific-bundle-specifier}} may not be a declared bundle.
184
185
186=== Bundle Template Operations
187
188These routines will use the most specific declared bundle for the package
189{{PACKAGE-NAME}} in the current locale.
190
191==== required-localized-template
192
193<procedure>(required-localized-template PACKAGE-NAME TEMPLATE-NAME) => *</procedure>
194
195Returns the object for the {{TEMPLATE-NAME}} in {{PACKAGE-NAME}}. Otherwise a
196{{undefined-condition}} exception is raised.
197
198==== localized-template
199
200<procedure>(localized-template PACKAGE-NAME TEMPLATE-NAME [PACKAGE-NOT-FOUND [TEMPLATE-NOT-FOUND]]) => *</procedure>
201
202Returns the object for the {{TEMPLATE-NAME}} in {{PACKAGE-NAME}}. Otherwise the
203appropriate {{...-NOT-FOUND}} value.
204
205{{PACKAGE-NOT-FOUND}} and {{TEMPLATE-NOT-FOUND}} have default {{#t}},
206
207==== localized-template/default
208
209<procedure>(localized-template/default PACKAGE-NAME TEMPLATE-NAME [PACKAGE-NOT-FOUND [TEMPLATE-NOT-FOUND]]) => *</procedure>
210
211Returns {{(localized-template PACKAGE-NAME TEMPLATE-NAME PACKAGE-NOT-FOUND TEMPLATE-NOT-FOUND)}}.
212
213{{PACKAGE-NOT-FOUND}} and {{TEMPLATE-NOT-FOUND}} have default {{TEMPLATE-NAME}}.
214
215Somewhat like the Posix 'gettext' routine.
216
217==== make-localized-template
218
219<procedure>(make-localized-template PACKAGE-NAME) => (procedure (symbol #!optional * *) *)</procedure>
220
221Returns a {{localized-template}}-like procedure curried upon the
222{{PACKAGE-NAME}}.
223
224==== make-localized-template/default
225
226<procedure>(make-localized-template/default PACKAGE-NAME) => (procedure (symbol #!optional * *) *)</procedure>
227
228Returns a {{localized-template/default}}-like procedure curried upon the
229{{PACKAGE-NAME}}.
230
231==== make-required-localized-template
232
233<procedure>(make-required-localized-template PACKAGE-NAME) => (procedure (symbol) *)</procedure>
234
235Like {{make-localized-template}} but raises an {{undefined-condition}}
236exception should the package or template be missing.
237
238==== localized-format
239
240<procedure>(localized-format PACKAGE-NAME TEMPLATE-NAME ARG0...) => string</procedure>
241
242Returns the formatted string using the {{(current-locale-format-function)}} and
243the format string {{(localized-template PACKAGE-NAME TEMPLATE-NAME)}} on the
244arguments {{ARG0...}}.
245
246When a localized-template is not found and the {{TEMPLATE-NAME}} is a
247{{string}} then it is used a the format-string.
248
249A representation is always displayed, even when no template is found. Just not
250a localized one.
251
252==== localized-template-set!
253
254<procedure>(localized-template-set! PACKAGE-NAME TEMPLATE-NAME VALUE) => boolean</procedure>
255
256Creates or updates the {{VALUE}} for the {{TEMPLATE-NAME}} in {{PACKAGE-NAME}}
257and returns {{#t}}, when the package exists. Otherwise returns {{#f}}.
258
259This can be used to extend the meaning of a package template at runtime. For
260example: caching the actual closure for a named procedure.
261
262==== load-localized-compiled-code
263
264<procedure>(load-localized-compiled-code LIBRARY PACKAGE-NAME TEMPLATE-NAMES)</procedure>
265
266Loads a Scheme code library and replaces the toplevel variable references from
267the templates with the actual value. Each item {{package-name+template-name}}
268has a variable reference upon entry. Upon exit this is replaced with the
269variable value after load.
270
271Every item {{package-name+template-name}} referenced '''must''' be defined.
272Otherwise a {{(exn srfi-29 undefined)}} exception if raised.
273
274{{LIBRARY}} is an absolute {{pathname}}, relative {{pathname}}, or {{(unitname
275pathname)}}. The corresponding load call is {{load-relative}}, {{load-relative}}, and
276{{load-library}}. (See [[Unit eval]].)
277
278{{TEMPLATE-NAMES}} is a {{list}} of {{template-name}}.
279
280A {{variable-reference}} is a {{symbol}} or {{(symbol symbol)}}. The later is a
281{{module}} import reference; this is a ''brittle'' feature as it relies upon
282knowledge of implementation details.
283
284''Note'' that only {{load-relative}} is used for a library {{pathname}}. Be sure
285to provide an {{absolute-pathname}} when a {{current-directory}} relative
286{{pathname}} is needed.
287
288==== localized-templates
289
290<procedure>(localized-templates PACKAGE-NAME) => list</procedure>
291
292Returns an association-list of all the templates for the {{PACKAGE-NAME}}.
293
294
295=== Exceptions
296
297* {{undefined-condition}} Signaled for unknown bundle-specification, package,
298template.
299
300* {{unbound-variable-condition}} Signaled for an unbound reference during
301''localized code'' resolution.
302
303* {{(exn type)}} Signaled for argument type errors.
304
305* {{(exn) message = "invalid library load specificiation" arguments = LIBSPEC}}
306Signaled during ''localized code'' resolution for a bad library load name form.
307
308
309=== Thread Local Storage
310
311Just as the [[locale]] extension supports per thread locale information so does
312this extension support per thread bundles. However, localized information is
313probably accessed more frequently than locale information. So the support for
314per thread bundles is delayed until runtime. Setting the environment variable
315{{SRFI29_TLS}} to {{[Yy1]}} will activate the feature.
316
317When active each thread may have a different bundle for a package; i.e. a user
318of [[SRFI 19|srfi-19] can have a different language in each thread.
319
320
321== Usage
322
323<enscript language=scheme>
324(require-extension srfi-29)
325</enscript>
326
327
328== Notes
329
330* Possible race condition exists creating a bundle file or directory should
331another thread be performing the same action.
332
333Just do not allow this to happen.
334
335* The locale symbols must have a lowercase printname! As such they do not truly
336reflect ISO 639-1/2 & ISO 3166-1 standard names. This is a SRFI 29 restriction.
337
338* {{(current-locale-details)}} is ill-defined by the SRFI 29 document. Which
339symbol means what? This implementation defines locale details as a 3 element
340{{list}} {{(SCRIPT CODESET MODIFIER)}} where the elements are {{symbols}} or {{#f}}.
341
342* The SRFI 29 document uses the term {{country}} for what the [[locale]]
343extension knows as {{region}}.
344
345
346== Requirements
347
348[[lookup-table|lookup-table]]
349[[variable-item|variable-item]]
350[[posix-utils|posix-utils]]
351[[locale|locale]]
352[[check-errors|check-errors]]
353
354
355== Bugs and Limitations
356
357* Currently there is no support for source-form code. Such is considered an
358even worse security-hole than loading compiled code. However, a possibility is
359use of the [[sandbox]]. Should there be sufficient interest this area
360can be explored.
361
362* {{store-bundle!}} does not ensure filemode of 'a+rx' for the created directory tree.
363
364
365== Author
366
367[[/users/kon-lovett|Kon Lovett]]
368
369
370== Version history
371
372; 2.3.3 :
373; 2.3.2 : Ensures filemode of 'a+rx' for bundles directory.
374; 2.3.1 :
375; 2.2.0 : Added runtime support for package per thread. Removed deprecated identifiers.
376; 2.1.3 : Added {{unbound-variable-condition?}}. Deprecated {{!localized-template}} & {{make-!localized-template}} in favor of {{required-localized-template}} & {{make-required-localized-template}}.
377; 2.1.2 :
378; 2.1.1 :
379; 2.1.0 : Added {{undefined-condition?}}, {{!localized-template}}, {{make-localized-template}}, {{make-localized-template/default}}, {{load-localized-compiled-code}}. {{localized-template}} & {{localized-template/default}} now distinguish an undefined template from an undefined package.
380; 2.0.1 : Fixs for {{bundle-specifier?}} and {{load-best-available-bundle!}}
381; 2.0.0 : Intitial Chicken 4 release. Added introspection routines. Removed {{PORT}} parameter for {{localized-format}}.
382
383
384== License
385
386Copyright (C) 2010-2017 Kon Lovett.  All rights reserved.
387
388Permission is hereby granted, free of charge, to any person obtaining a copy of
389this software and associated documentation files (the Software), to deal in the
390Software without restriction, including without limitation the rights to use,
391copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
392Software, and to permit persons to whom the Software is furnished to do so,
393subject to the following conditions:
394
395The above copyright notice and this permission notice shall be included in all
396copies or substantial portions of the Software.
397
398THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
399IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
400FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
401AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
402LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
403OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
404SOFTWARE.
Note: See TracBrowser for help on using the repository browser.