Main Page

Parser3 Source Code Documentation

Part 1

  • Build targets
  • Memory: work with memory
  • Exceptions: work with errors
  • String
  • Compiler
  • Executor
  • Value
  • Class: parent+methods+fields
  • Object: class+fields
  • Methoded: configurable class

Part 2

  • Example of creating simple class (with methods only)
  • Sample of creating simple class (with fields only)
  • Sample of creating class (methods and fields)
Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


File Index

Parser3 Source Code File List

Here is a list of all files with brief descriptions:
acconfig.h [code] |
apr.h [code] |
apr_errno.h [code] | APR Error Codes
apr_file_info.h [code] | APR File handling
apr_file_io.C [code] | Parser: implementation of apr functions
apr_file_io.h [code] | APR File I/O Handling
apr_pools.h [code] | APR memory allocation
apr_sdbm.h [code] | Apr-util SDBM library
apr_strings.C [code] | Parser: implementation of apr functions
apr_strings.h [code] | APR Strings library
apu.h [code] |
chartables.c [code] |
class.dox |
classes.C [code] | Parser: Methoded and Methoded_array classes
classes.h [code] | Parser: Methoded class decl
ClassExample1.dox |
ClassExample2.dox |
ClassExample3.dox |
comms.C [code] | Parser: SMTP sender impl
compile.C [code] | Parser: compiler part of request class
compile.y [code] |
compile_tools.C [code] | Parser: compiler support helper functions
compile_tools.h [code] | Parser: compiler support helper functions decls
compiler.dox |
config.h [code] |
config_fixed.h [code] |
cord.h [code] |
cord_pos.h [code] |
cordbscs.c [code] |
cordprnt.c [code] |
cordxtra.c [code] |
date.C [code] | Parser: date parser class
dftables.c [code] |
double.C [code] | Parser: double parser class
ec.h [code] |
exception.dox |
execute.C [code] | Parser: executor part of request class
executor.dox |
file.C [code] | Parser: file parser class
form.C [code] | Parser: form parser class
gc.h [code] |
get.c [code] |
getopt.c [code] |
getopt.h [code] |
gif.C [code] | Parser: image manipulations impl1
gif.h [code] | Parser: image manipulations decls
gifio.C [code] | Parser: image manipulations impl2
hash.C [code] | Parser: hash parser class
hashfile.C [code] | Parser: hashfile parser class
image.C [code] | Parser: image parser class
index.dox |
int.C [code] | Parser: int parser class
internal.h [code] |
ltdl.c [code] |
ltdl.h [code] |
mail.C [code] | Parser: mail parser class
maketables.c [code] |
math.C [code] | Parser: math parser class
memory.C [code] | Parser: memory parser class
memory.dox |
methoded.dox |
mod_parser3.c [code] | Parser: apache 1.3 module, part, compiled by Apache
mod_parser3_core.C [code] | Parser: apache 1.3 module, part, compiled by parser3project
mtables.h [code] |
object.dox |
op.C [code] | Parser: parser operators
pa_array.h [code] | Parser: Array & Array_iterator classes decls
pa_cache_managers.C [code] | Parser: status press center implementation
pa_cache_managers.h [code] | Parser: cache managers center decl
pa_charset.C [code] | Parser: Charset connection implementation
pa_charset.h [code] | Parser: Charset connection decl
pa_charsets.C [code] | Parser: sql driver manager implementation
pa_charsets.h [code] | Parser: sql driver manager decl
pa_common.C [code] | Parser: commonly functions
pa_common.h [code] | Parser: commonly used functions
pa_config_fixed.h [code] | Parser: Configure file for autoconf-disabled platforms
pa_config_includes.h [code] | Parser: includes all Configure-d headers
pa_dictionary.C [code] | Parser: dictionary class impl
pa_dictionary.h [code] | Parser: dictionary class decl
pa_dir.C [code] | Parser: directory scanning for different OS-es
pa_dir.h [code] | Parser: directory scanning for different OS-es decls
pa_exception.C [code] | Parser: exception class
pa_exception.h [code] | Parser: exception decls
pa_exec.C [code] | Parser: program executing for different OS-es
pa_exec.h [code] | Parser: program executing for different OS-es decls
pa_globals.C [code] | Parser: globals
pa_globals.h [code] | Parser: global decls
pa_hash.h [code] | Parser: hash class decl
pa_http.C [code] | Parser: http support functions
pa_http.h [code] | Parser: commonly used functions
pa_httpd.h [code] | Parser: http wrapper
pa_junction.h [code] | Parser: Junction class decl
pa_md5.h [code] | Parser: copied from apache 1.3.20 sources
pa_md5c.c [code] | Parser: copied from apache 1.3.20 sources
pa_memory.C [code] | Parser: memory reference counting classes
pa_memory.h [code] | Parser: memory reference counting classes decls
pa_method.h [code] | Parser: Method class decl
pa_opcode.h [code] | Parser: compiled code related decls
pa_operation.h [code] | Parser: compiled code related decls
pa_os.C [code] | Parser: commonly functions
pa_os.h [code] | Parser: commonly used functions
pa_pool.C [code] | Parser: pool class
pa_pool.h [code] | Parser: pool class decl
pa_property.h [code] | Parser: Property class decl
pa_request.C [code] | Parser: request class main part
pa_request.h [code] | Parser: request class decl
pa_request_charsets.h [code] | Parser: request charsets class decl
pa_request_info.h [code] | Parser: request info class decl
pa_sapi.h [code] | Parser: web server api interface object decl
pa_socks.C [code] | Parser: socks initialization/finalization
pa_socks.h [code] | Parser: socks initialization/finalization decls
pa_sql_connection.h [code] | Parser: sql fconnection decl
pa_sql_driver.h [code] | Parser: sql driver interface
pa_sql_driver_manager.C [code] | Parser: sql driver manager implementation
pa_sql_driver_manager.h [code] | Parser: sql driver manager decl
pa_stack.h [code] | Parser: stack class decl
pa_string.C [code] | Parser: string class
pa_string.h [code] | Parser: string class decl
pa_stylesheet_connection.C [code] | Parser: Stylesheet connection implementation
pa_stylesheet_connection.h [code] | Parser: Stylesheet connection decl
pa_stylesheet_manager.C [code] | Parser: sql driver manager implementation
pa_stylesheet_manager.h [code] | Parser: Stylesheet manager decl
pa_table.C [code] | Parser: table class
pa_table.h [code] | Parser: table class decl
apache13core/pa_threads.C [code] | Parser: Mutex realization class
cgi/pa_threads.C [code] | Parser: zero Mutex realization class
isapi/pa_threads.C [code] | Parser: zero Mutex realization class
pa_threads.h [code] | Parser: mutex & helpers decls
pa_types.h [code] | Parser: generally used types & constants decls
pa_uue.C [code] | Parser: uuencoding impl
pa_uue.h [code] | Parser: uue encoding module
pa_value.C [code] | Parser: Value class
pa_value.h [code] | Parser: Value, Method, Junction
pa_vbool.h [code] | Parser: bool class decls
pa_vclass.C [code] | Parser: class parser class impl
pa_vclass.h [code] | Parser: class parser class decl
pa_vcode_frame.h [code] | Parser: code_frame write wrapper write context
pa_vconsole.h [code] | Parser: console class decl
pa_vcookie.C [code] | Parser: cookie class
pa_vcookie.h [code] | Parser: cookie class decls
pa_vdate.h [code] | Parser: date parser class decl
pa_vdouble.h [code] | Parser: double parser class decl
pa_venv.C [code] | Parser: env class
pa_venv.h [code] | Parser: env class decl
pa_version.h [code] |
pa_vfile.C [code] | Parser: file parser type
pa_vfile.h [code] | Parser: file parser type decl
pa_vform.C [code] | Parser: form class
pa_vform.h [code] | Parser: form class decls
pa_vhash.C [code] | Parser: hash class
pa_vhash.h [code] | Parser: hash parser type decl
pa_vhashfile.C [code] | Parser: table class
pa_vhashfile.h [code] | Parser: hashfile parser type decl
pa_vimage.C [code] | Parser: image parser type
pa_vimage.h [code] | Parser: image parser type decl
pa_vint.h [code] | Parser: int parser class decl
pa_vjunction.h [code] | Parser: junction class decl
pa_vmail.C [code] | Parser: mail class
pa_vmail.h [code] | Parser: mail class decls
pa_vmath.C [code] | Parser: math class
pa_vmath.h [code] | Parser: math class decls
pa_vmemory.h [code] | Parser: memory parser class
pa_vmethod_frame.C [code] | Parser: method frame class
pa_vmethod_frame.h [code] | Parser: method_frame write context
pa_vobject.C [code] | Parser: object class impl
pa_vobject.h [code] | Parser: object class decl
pa_vproperty.h [code] | Parser: property class decl
pa_vrequest.C [code] | Parser: request class
pa_vrequest.h [code] | Parser: request class decl
pa_vresponse.C [code] | Parser: response class
pa_vresponse.h [code] | Parser: response class
pa_vstateless_class.C [code] | Parser: stateless class
pa_vstateless_class.h [code] | Parser: stateless class decls
pa_vstateless_object.h [code] | Parser: stateless_object class decl
pa_vstatus.C [code] | Parser: status class impl
pa_vstatus.h [code] | Parser: status class decl
pa_vstring.C [code] | Parser: string class
pa_vstring.h [code] | Parser: string parser class decl
pa_vtable.C [code] | Parser: table class
pa_vtable.h [code] | Parser: table parser class decl
pa_vvoid.C [code] | Parser: string class
pa_vvoid.h [code] | Parser: void parser class
pa_vxdoc.C [code] |
pa_vxdoc.h [code] | Parser: xdoc parser class decl
pa_vxnode.C [code] |
pa_vxnode.h [code] | Parser: xnode parser class decl
pa_wcontext.C [code] | Parser: write context class
pa_wcontext.h [code] | Parser: write context class decl
pa_wwrapper.h [code] | Parser: write_wrapper write context
pa_xml_exception.C [code] | Parser: exception class
pa_xml_exception.h [code] | Parser: xml exception decls
pa_xml_io.C [code] | Parser: plugins to xml library, controlling i/o; implementation
pa_xml_io.h [code] | Parser: plugins to xml library, controlling i/o
parser3.C [code] | Parser: scripting and CGI main
parser3isapi.C [code] | Parser: IIS extension
pcre.c [code] |
pcre.h [code] |
pcre_parser_ctype.c [code] | Parser: $MAIN:CTYPE character types for Perl-Compatible Regular Expressions
pooled.dox |
response.C [code] | Parser: response parser class
sdbm.c [code] |
sdbm_hash.c [code] |
sdbm_lock.c [code] |
sdbm_pair.c [code] |
sdbm_pair.h [code] |
sdbm_private.h [code] |
sdbm_tune.h [code] |
smtp.C [code] | Parser: SMTP sender
smtp.h [code] | Parser: SMTP sender decl
string.C [code] | Parser: string parser class
string.dox |
study.c [code] |
table.C [code] | Parser: table parser class
targets.dox |
untaint.C [code] | Parser: String class part: untaint mechanizm
value.dox |
void.C [code] | Parser: VOID parser class
xdoc.C [code] | Parser: xdoc parser class
xnode.C [code] | Parser: dom parser class
xnode.h [code] | Parser: dnode methods class - MDnode class decl


acconfig.h File Reference

Go to the source code of this file.


acconfig.h Source File

acconfig.h

Go to the documentation of this file.
00001 /* Define if you have the GNU dld library.  */
00002 #undef HAVE_DLD
00003
00004 /* Define if you have the libdl library or equivalent.  */
00005 #undef HAVE_LIBDL
00006
00007 /* Define if you have the shl_load function.  */
00008 #undef HAVE_SHL_LOAD


apr.h File Reference

Include dependency graph for apr.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | APR_DECLARE(type) type
The public APR functions are declared with APR_DECLARE(), so they may use the most appropriate calling convention. More...

#define | APR_DECLARE_NONSTD(type) type
The public APR functions using variable arguments are declared with AP_DECLARE(), as they must use the C language calling convention. More...

#define | APR_DECLARE_DATA
The public APR variables are declared with AP_MODULE_DECLARE_DATA. More...

Typedefs

typedef int | apr_int32_t
typedef int | apr_off_t
typedef size_t | apr_size_t

Define Documentation

#define APR_DECLARE ( type ) type

The public APR functions are declared with APR_DECLARE(), so they may use the most appropriate calling convention.

Public APR functions with variable arguments must use APR_DECLARE_NONSTD().

@deffunc APR_DECLARE(rettype) apr_func(args);

Definition at line 87 of file apr.h.

#define APR_DECLARE_NONSTD ( type ) type

The public APR functions using variable arguments are declared with AP_DECLARE(), as they must use the C language calling convention.

@deffunc APR_DECLARE_NONSTD(rettype) apr_func(args, ...);

Definition at line 95 of file apr.h.

#define APR_DECLARE_DATA

The public APR variables are declared with AP_MODULE_DECLARE_DATA.

This assures the appropriate indirection is invoked at compile time.

@deffunc APR_DECLARE_DATA type apr_variable; @tip APR_DECLARE_DATA extern type apr_variable; syntax is required for declarations within headers to properly import the variable.

Definition at line 105 of file apr.h.

Typedef Documentation

typedef int apr_int32_t

Definition at line 65 of file apr.h.

Referenced by prep().

typedef int apr_off_t

Definition at line 107 of file apr.h.

typedef size_t apr_size_t

Definition at line 108 of file apr.h.


apr.h Source File

apr.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #ifndef APR_H
00056 #define APR_H
00057
00058 #include "pa_config_includes.h"
00059 #ifdef HAVE_ERRNO_H
00060 #define APR_HAVE_ERRNO_H 1
00061 #endif
00062
00063 #include <stddef.h>
00064
00065 typedef  int               apr_int32_t;
00066
00087 #define APR_DECLARE(type)            type
00088
00095 #define APR_DECLARE_NONSTD(type)     type
00096
00105 #define APR_DECLARE_DATA
00106
00107 typedef  int         apr_off_t;
00108 typedef size_t apr_size_t;
00109
00110 #endif /* APR_H */
00111


apr_errno.h File Reference

APR Error Codes. More...

Include dependency graph for apr_errno.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | APR_OS_START_ERROR 20000
APR_OS_START_ERROR is where the APR specific error values start. More...

#define | APR_OS_ERRSPACE_SIZE 50000
APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit into one of the error/status ranges below -- except for APR_OS_START_USERERR, which see. More...

#define | APR_OS_START_STATUS (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE)
APR_OS_START_STATUS is where the APR specific status codes start. More...

#define | APR_OS_START_USERERR (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE)
APR_OS_START_USERERR are reserved for applications that use APR that layer their own error codes along with APR's. More...

#define | APR_OS_START_USEERR APR_OS_START_USERERR
APR_OS_START_USEERR is obsolete, defined for compatibility only. More...

#define | APR_OS_START_CANONERR
APR_OS_START_CANONERR is where APR versions of errno values are defined on systems which don't have the corresponding errno. More...

#define | APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into apr_status_t values. More...

#define | APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)
APR_OS_START_SYSERR folds platform-specific system error values into apr_status_t values. More...

#define | APR_SUCCESS 0
no error. More...

#define | APR_ENOSTAT (APR_OS_START_ERROR + 1)
#define | APR_ENOPOOL (APR_OS_START_ERROR + 2)
#define | APR_EBADDATE (APR_OS_START_ERROR + 4)
#define | APR_EINVALSOCK (APR_OS_START_ERROR + 5)
#define | APR_ENOPROC (APR_OS_START_ERROR + 6)
#define | APR_ENOTIME (APR_OS_START_ERROR + 7)
#define | APR_ENODIR (APR_OS_START_ERROR + 8)
#define | APR_ENOLOCK (APR_OS_START_ERROR + 9)
#define | APR_ENOPOLL (APR_OS_START_ERROR + 10)
#define | APR_ENOSOCKET (APR_OS_START_ERROR + 11)
#define | APR_ENOTHREAD (APR_OS_START_ERROR + 12)
#define | APR_ENOTHDKEY (APR_OS_START_ERROR + 13)
#define | APR_EGENERAL (APR_OS_START_ERROR + 14)
#define | APR_ENOSHMAVAIL (APR_OS_START_ERROR + 15)
#define | APR_EBADIP (APR_OS_START_ERROR + 16)
#define | APR_EBADMASK (APR_OS_START_ERROR + 17)
#define | APR_EDSOOPEN (APR_OS_START_ERROR + 19)
#define | APR_EABSOLUTE (APR_OS_START_ERROR + 20)
#define | APR_ERELATIVE (APR_OS_START_ERROR + 21)
#define | APR_EINCOMPLETE (APR_OS_START_ERROR + 22)
#define | APR_EABOVEROOT (APR_OS_START_ERROR + 23)
#define | APR_EBADPATH (APR_OS_START_ERROR + 24)
#define | APR_INCHILD (APR_OS_START_STATUS + 1)
#define | APR_INPARENT (APR_OS_START_STATUS + 2)
#define | APR_DETACH (APR_OS_START_STATUS + 3)
#define | APR_NOTDETACH (APR_OS_START_STATUS + 4)
#define | APR_CHILD_DONE (APR_OS_START_STATUS + 5)
#define | APR_CHILD_NOTDONE (APR_OS_START_STATUS + 6)
#define | APR_TIMEUP (APR_OS_START_STATUS + 7)
#define | APR_INCOMPLETE (APR_OS_START_STATUS + 8)
#define | APR_BADCH (APR_OS_START_STATUS + 12)
#define | APR_BADARG (APR_OS_START_STATUS + 13)
#define | APR_EOF (APR_OS_START_STATUS + 14)
#define | APR_NOTFOUND (APR_OS_START_STATUS + 15)
#define | APR_ANONYMOUS (APR_OS_START_STATUS + 19)
#define | APR_FILEBASED (APR_OS_START_STATUS + 20)
#define | APR_KEYBASED (APR_OS_START_STATUS + 21)
#define | APR_EINIT (APR_OS_START_STATUS + 22)
#define | APR_ENOTIMPL (APR_OS_START_STATUS + 23)
#define | APR_EMISMATCH (APR_OS_START_STATUS + 24)
#define | APR_EBUSY (APR_OS_START_STATUS + 25)
#define | APR_EACCES (APR_OS_START_CANONERR + 1)
#define | APR_EEXIST (APR_OS_START_CANONERR + 2)
#define | APR_ENAMETOOLONG (APR_OS_START_CANONERR + 3)
#define | APR_ENOENT (APR_OS_START_CANONERR + 4)
#define | APR_ENOTDIR (APR_OS_START_CANONERR + 5)
#define | APR_ENOSPC (APR_OS_START_CANONERR + 6)
#define | APR_ENOMEM (APR_OS_START_CANONERR + 7)
#define | APR_EMFILE (APR_OS_START_CANONERR + 8)
#define | APR_ENFILE (APR_OS_START_CANONERR + 9)
#define | APR_EBADF (APR_OS_START_CANONERR + 10)
#define | APR_EINVAL (APR_OS_START_CANONERR + 11)
#define | APR_ESPIPE (APR_OS_START_CANONERR + 12)
#define | APR_EAGAIN (APR_OS_START_CANONERR + 13)
#define | APR_EINTR (APR_OS_START_CANONERR + 14)
#define | APR_ENOTSOCK (APR_OS_START_CANONERR + 15)
#define | APR_ECONNREFUSED (APR_OS_START_CANONERR + 16)
#define | APR_EINPROGRESS (APR_OS_START_CANONERR + 17)
#define | APR_ECONNABORTED (APR_OS_START_CANONERR + 18)
#define | APR_ECONNRESET (APR_OS_START_CANONERR + 19)
#define | APR_ETIMEDOUT (APR_OS_START_CANONERR + 20)
#define | APR_EHOSTUNREACH (APR_OS_START_CANONERR + 21)
#define | APR_ENETUNREACH (APR_OS_START_CANONERR + 22)
#define | APR_EFTYPE (APR_OS_START_CANONERR + 23)
#define | APR_EPIPE (APR_OS_START_CANONERR + 24)
#define | APR_EXDEV (APR_OS_START_CANONERR + 25)
#define | APR_ENOTEMPTY (APR_OS_START_CANONERR + 26)

Typedefs

typedef int | apr_status_t
Type for specifying an error or status code. More...

Detailed Description

APR Error Codes.

Definition in file apr_errno.h.


apr_errno.h Source File

apr_errno.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #ifndef APR_ERRNO_H
00056 #define APR_ERRNO_H
00057
00058 #include "apr.h"
00059
00060 #if APR_HAVE_ERRNO_H
00061 #include <errno.h>
00062 #endif
00063
00064 #ifdef __cplusplus
00065 extern "C" {
00066 #endif /* __cplusplus */
00067
00081 typedef int apr_status_t;
00082
00086 #define APR_OS_START_ERROR     20000
00087
00092 #define APR_OS_ERRSPACE_SIZE 50000
00093
00096 #define APR_OS_START_STATUS    (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE)
00097
00104 #define APR_OS_START_USERERR    (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE)
00105
00109 #define APR_OS_START_USEERR     APR_OS_START_USERERR
00110
00114 #define APR_OS_START_CANONERR  (APR_OS_START_USERERR \
00115                                  + (APR_OS_ERRSPACE_SIZE * 10))
00116
00120 #define APR_OS_START_EAIERR    (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
00121
00125 #define APR_OS_START_SYSERR    (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)
00126
00128 #define APR_SUCCESS 0
00129
00130 /* APR ERROR VALUES */
00189 #define APR_ENOSTAT        (APR_OS_START_ERROR + 1)
00190
00191 #define APR_ENOPOOL        (APR_OS_START_ERROR + 2)
00192 /* empty slot: +3 */
00194 #define APR_EBADDATE       (APR_OS_START_ERROR + 4)
00195
00196 #define APR_EINVALSOCK     (APR_OS_START_ERROR + 5)
00197
00198 #define APR_ENOPROC        (APR_OS_START_ERROR + 6)
00199
00200 #define APR_ENOTIME        (APR_OS_START_ERROR + 7)
00201
00202 #define APR_ENODIR         (APR_OS_START_ERROR + 8)
00203
00204 #define APR_ENOLOCK        (APR_OS_START_ERROR + 9)
00205
00206 #define APR_ENOPOLL        (APR_OS_START_ERROR + 10)
00207
00208 #define APR_ENOSOCKET      (APR_OS_START_ERROR + 11)
00209
00210 #define APR_ENOTHREAD      (APR_OS_START_ERROR + 12)
00211
00212 #define APR_ENOTHDKEY      (APR_OS_START_ERROR + 13)
00213
00214 #define APR_EGENERAL       (APR_OS_START_ERROR + 14)
00215
00216 #define APR_ENOSHMAVAIL    (APR_OS_START_ERROR + 15)
00217
00218 #define APR_EBADIP         (APR_OS_START_ERROR + 16)
00219
00220 #define APR_EBADMASK       (APR_OS_START_ERROR + 17)
00221 /* empty slot: +18 */
00223 #define APR_EDSOOPEN       (APR_OS_START_ERROR + 19)
00224
00225 #define APR_EABSOLUTE      (APR_OS_START_ERROR + 20)
00226
00227 #define APR_ERELATIVE      (APR_OS_START_ERROR + 21)
00228
00229 #define APR_EINCOMPLETE    (APR_OS_START_ERROR + 22)
00230
00231 #define APR_EABOVEROOT     (APR_OS_START_ERROR + 23)
00232
00233 #define APR_EBADPATH       (APR_OS_START_ERROR + 24)
00234
00235 /* APR STATUS VALUES */
00237 #define APR_INCHILD        (APR_OS_START_STATUS + 1)
00238
00239 #define APR_INPARENT       (APR_OS_START_STATUS + 2)
00240
00241 #define APR_DETACH         (APR_OS_START_STATUS + 3)
00242
00243 #define APR_NOTDETACH      (APR_OS_START_STATUS + 4)
00244
00245 #define APR_CHILD_DONE     (APR_OS_START_STATUS + 5)
00246
00247 #define APR_CHILD_NOTDONE  (APR_OS_START_STATUS + 6)
00248
00249 #define APR_TIMEUP         (APR_OS_START_STATUS + 7)
00250
00251 #define APR_INCOMPLETE     (APR_OS_START_STATUS + 8)
00252 /* empty slot: +9 */
00253 /* empty slot: +10 */
00254 /* empty slot: +11 */
00256 #define APR_BADCH          (APR_OS_START_STATUS + 12)
00257
00258 #define APR_BADARG         (APR_OS_START_STATUS + 13)
00259
00260 #define APR_EOF            (APR_OS_START_STATUS + 14)
00261
00262 #define APR_NOTFOUND       (APR_OS_START_STATUS + 15)
00263 /* empty slot: +16 */
00264 /* empty slot: +17 */
00265 /* empty slot: +18 */
00267 #define APR_ANONYMOUS      (APR_OS_START_STATUS + 19)
00268
00269 #define APR_FILEBASED      (APR_OS_START_STATUS + 20)
00270
00271 #define APR_KEYBASED       (APR_OS_START_STATUS + 21)
00272
00273 #define APR_EINIT          (APR_OS_START_STATUS + 22)
00274
00275 #define APR_ENOTIMPL       (APR_OS_START_STATUS + 23)
00276
00277 #define APR_EMISMATCH      (APR_OS_START_STATUS + 24)
00278
00279 #define APR_EBUSY          (APR_OS_START_STATUS + 25)
00280
00285 /* APR CANONICAL ERROR VALUES */
00287 #ifdef EACCES
00288 #define APR_EACCES EACCES
00289 #else
00290 #define APR_EACCES         (APR_OS_START_CANONERR + 1)
00291 #endif
00292
00294 #ifdef EEXIST
00295 #define APR_EEXIST EEXIST
00296 #else
00297 #define APR_EEXIST         (APR_OS_START_CANONERR + 2)
00298 #endif
00299
00301 #ifdef ENAMETOOLONG
00302 #define APR_ENAMETOOLONG ENAMETOOLONG
00303 #else
00304 #define APR_ENAMETOOLONG   (APR_OS_START_CANONERR + 3)
00305 #endif
00306
00308 #ifdef ENOENT
00309 #define APR_ENOENT ENOENT
00310 #else
00311 #define APR_ENOENT         (APR_OS_START_CANONERR + 4)
00312 #endif
00313
00315 #ifdef ENOTDIR
00316 #define APR_ENOTDIR ENOTDIR
00317 #else
00318 #define APR_ENOTDIR        (APR_OS_START_CANONERR + 5)
00319 #endif
00320
00322 #ifdef ENOSPC
00323 #define APR_ENOSPC ENOSPC
00324 #else
00325 #define APR_ENOSPC         (APR_OS_START_CANONERR + 6)
00326 #endif
00327
00329 #ifdef ENOMEM
00330 #define APR_ENOMEM ENOMEM
00331 #else
00332 #define APR_ENOMEM         (APR_OS_START_CANONERR + 7)
00333 #endif
00334
00336 #ifdef EMFILE
00337 #define APR_EMFILE EMFILE
00338 #else
00339 #define APR_EMFILE         (APR_OS_START_CANONERR + 8)
00340 #endif
00341
00343 #ifdef ENFILE
00344 #define APR_ENFILE ENFILE
00345 #else
00346 #define APR_ENFILE         (APR_OS_START_CANONERR + 9)
00347 #endif
00348
00350 #ifdef EBADF
00351 #define APR_EBADF EBADF
00352 #else
00353 #define APR_EBADF          (APR_OS_START_CANONERR + 10)
00354 #endif
00355
00357 #ifdef EINVAL
00358 #define APR_EINVAL EINVAL
00359 #else
00360 #define APR_EINVAL         (APR_OS_START_CANONERR + 11)
00361 #endif
00362
00364 #ifdef ESPIPE
00365 #define APR_ESPIPE ESPIPE
00366 #else
00367 #define APR_ESPIPE         (APR_OS_START_CANONERR + 12)
00368 #endif
00369
00374 #ifdef EAGAIN
00375 #define APR_EAGAIN EAGAIN
00376 #elif defined(EWOULDBLOCK)
00377 #define APR_EAGAIN EWOULDBLOCK
00378 #else
00379 #define APR_EAGAIN         (APR_OS_START_CANONERR + 13)
00380 #endif
00381
00383 #ifdef EINTR
00384 #define APR_EINTR EINTR
00385 #else
00386 #define APR_EINTR          (APR_OS_START_CANONERR + 14)
00387 #endif
00388
00390 #ifdef ENOTSOCK
00391 #define APR_ENOTSOCK ENOTSOCK
00392 #else
00393 #define APR_ENOTSOCK       (APR_OS_START_CANONERR + 15)
00394 #endif
00395
00397 #ifdef ECONNREFUSED
00398 #define APR_ECONNREFUSED ECONNREFUSED
00399 #else
00400 #define APR_ECONNREFUSED   (APR_OS_START_CANONERR + 16)
00401 #endif
00402
00404 #ifdef EINPROGRESS
00405 #define APR_EINPROGRESS EINPROGRESS
00406 #else
00407 #define APR_EINPROGRESS    (APR_OS_START_CANONERR + 17)
00408 #endif
00409
00415 #ifdef ECONNABORTED
00416 #define APR_ECONNABORTED ECONNABORTED
00417 #else
00418 #define APR_ECONNABORTED   (APR_OS_START_CANONERR + 18)
00419 #endif
00420
00422 #ifdef ECONNRESET
00423 #define APR_ECONNRESET ECONNRESET
00424 #else
00425 #define APR_ECONNRESET     (APR_OS_START_CANONERR + 19)
00426 #endif
00427
00429 #ifdef ETIMEDOUT
00430 #define APR_ETIMEDOUT ETIMEDOUT
00431 #else
00432 #define APR_ETIMEDOUT      (APR_OS_START_CANONERR + 20)
00433 #endif
00434
00436 #ifdef EHOSTUNREACH
00437 #define APR_EHOSTUNREACH EHOSTUNREACH
00438 #else
00439 #define APR_EHOSTUNREACH   (APR_OS_START_CANONERR + 21)
00440 #endif
00441
00443 #ifdef ENETUNREACH
00444 #define APR_ENETUNREACH ENETUNREACH
00445 #else
00446 #define APR_ENETUNREACH    (APR_OS_START_CANONERR + 22)
00447 #endif
00448
00450 #ifdef EFTYPE
00451 #define APR_EFTYPE EFTYPE
00452 #else
00453 #define APR_EFTYPE        (APR_OS_START_CANONERR + 23)
00454 #endif
00455
00457 #ifdef EPIPE
00458 #define APR_EPIPE EPIPE
00459 #else
00460 #define APR_EPIPE         (APR_OS_START_CANONERR + 24)
00461 #endif
00462
00464 #ifdef EXDEV
00465 #define APR_EXDEV EXDEV
00466 #else
00467 #define APR_EXDEV         (APR_OS_START_CANONERR + 25)
00468 #endif
00469
00471 #ifdef ENOTEMPTY
00472 #define APR_ENOTEMPTY ENOTEMPTY
00473 #else
00474 #define APR_ENOTEMPTY     (APR_OS_START_CANONERR + 26)
00475 #endif
00476
00479 #ifdef __cplusplus
00480 }
00481 #endif
00482
00483 #endif  /* ! APR_ERRNO_H */


apr_file_info.h File Reference

APR File handling. More...

Include dependency graph for apr_file_info.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | apr_finfo_t

Defines

#define | APR_FINFO_SIZE 0x00000100
Size of the file. More...

Typedefs

typedef apr_int32_t | apr_fileperms_t
Structure for determining file permissions. More...

typedef apr_finfo_t | apr_finfo_t
The file information structure. More...

Detailed Description

APR File handling.

Definition in file apr_file_info.h.

Typedef Documentation

typedef apr_int32_t apr_fileperms_t

Structure for determining file permissions.

@defvar apr_fileperms_t

Definition at line 72 of file apr_file_info.h.

Referenced by prep().


apr_file_info.h Source File

apr_file_info.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #ifndef APR_FILE_INFO_H
00056 #define APR_FILE_INFO_H
00057
00058 #include "apr.h"
00059
00060 #ifdef __cplusplus
00061 extern "C" {
00062 #endif /* __cplusplus */
00063
00072 typedef apr_int32_t               apr_fileperms_t;
00073
00078 #ifdef LATER
00079 #define APR_FINFO_LINK   0x00000001
00080 #define APR_FINFO_MTIME  0x00000010
00081 #define APR_FINFO_CTIME  0x00000020
00082 #define APR_FINFO_ATIME  0x00000040
00083 #endif
00084 #define APR_FINFO_SIZE   0x00000100
00085 #ifdef LATER
00086 #define APR_FINFO_CSIZE  0x00000200
00087 #define APR_FINFO_DEV    0x00001000
00088 #define APR_FINFO_INODE  0x00002000
00089 #define APR_FINFO_NLINK  0x00004000
00090 #define APR_FINFO_TYPE   0x00008000
00091 #define APR_FINFO_USER   0x00010000
00092 #define APR_FINFO_GROUP  0x00020000
00093 #define APR_FINFO_UPROT  0x00100000
00094 #define APR_FINFO_GPROT  0x00200000
00095 #define APR_FINFO_WPROT  0x00400000
00096 #define APR_FINFO_ICASE  0x01000000
00097 #define APR_FINFO_NAME   0x02000000
00099 #define APR_FINFO_MIN    0x00008170
00100 #define APR_FINFO_IDENT  0x00003000
00101 #define APR_FINFO_OWNER  0x00030000
00102 #define APR_FINFO_PROT   0x00700000
00103 #define APR_FINFO_NORM   0x0073b170
00104 #define APR_FINFO_DIRENT 0x02000000
00105 #endif
00106
00111 typedef struct apr_finfo_t        apr_finfo_t;
00112
00113 struct apr_finfo_t {
00114 #ifdef LATER
00115
00116     apr_pool_t *pool;
00119     apr_int32_t valid;
00121     apr_fileperms_t protection;
00125     apr_filetype_e filetype;
00127     apr_uid_t user;
00129     apr_gid_t group;
00131     apr_ino_t inode;
00133     apr_dev_t device;
00135     apr_int32_t nlink;
00136 #endif
00137
00138     apr_off_t size;
00139 #ifdef LATER
00140
00141     apr_off_t csize;
00143     apr_time_t atime;
00145     apr_time_t mtime;
00147     apr_time_t ctime;
00149     const char *fname;
00151     const char *name;
00153     struct apr_file_t *filehand;
00154 #endif
00155 };
00156
00161 #ifdef __cplusplus
00162 }
00163 #endif
00164
00165 #endif  /* ! APR_FILE_INFO_H */


apr_file_io.C File Reference

Parser: implementation of apr functions. More...

Include dependency graph for apr_file_io.C:

Include dependency graph

Go to the source code of this file.

Compounds

struct | apr_file_t

Functions

APR_DECLARE (apr_status_t) apr_file_open(apr_file_t **new_file

Variables

const char *const | IDENT = "$Date: 2005/11/18 10:04:41 $"
const char * | fname
const char apr_int32_t | flag
const char apr_int32_t apr_fileperms_t | perm

Detailed Description

Parser: implementation of apr functions.

Copyright(c) 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file apr_file_io.C.

Variable Documentation

const char* const IDENT = "$Date: 2005/11/18 10:04:41 $" [static]

Definition at line 8 of file apr_file_io.C.

const char* fname

Definition at line 19 of file apr_file_io.C.

const char apr_int32_t flag

Definition at line 19 of file apr_file_io.C.

const char apr_int32_t apr_fileperms_t perm

Definition at line 19 of file apr_file_io.C.


apr_file_io.C Source File

apr_file_io.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT="$Date: 2005/11/18 10:04:41 $";
00009
00010 #include "apr_file_io.h"
00011
00012 #include "pa_memory.h"
00013 #include "pa_os.h"
00014
00015 struct apr_file_t {
00016     int handle;
00017 };
00018
00019 APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new_file, const char *fname,
00020                                    apr_int32_t flag, apr_fileperms_t perm,
00021                                    apr_pool_t *)
00022 {
00023     int oflags = 0;
00024 #if APR_HAS_THREADS
00025     apr_status_t rv;
00026 #endif
00027
00028     (*new_file) = (apr_file_t*)pa_malloc_atomic(sizeof(apr_file_t));
00029 //    (*new_file)->flags = flag;
00030     (*new_file)->handle = -1;
00031
00032     if ((flag & APR_READ) && (flag & APR_WRITE)) {
00033         oflags = O_RDWR;
00034     }
00035     else if (flag & APR_READ) {
00036         oflags = O_RDONLY;
00037     }
00038     else if (flag & APR_WRITE) {
00039         oflags = O_WRONLY;
00040     }
00041     else {
00042         return APR_EACCES;
00043     }
00044
00045     if (flag & APR_CREATE) {
00046         oflags |= O_CREAT;
00047         if (flag & APR_EXCL) {
00048             oflags |= O_EXCL;
00049         }
00050     }
00051     if ((flag & APR_EXCL) && !(flag & APR_CREATE)) {
00052         return APR_EACCES;
00053     }
00054
00055     if (flag & APR_APPEND) {
00056         oflags |= O_APPEND;
00057     }
00058     if (flag & APR_TRUNCATE) {
00059         oflags |= O_TRUNC;
00060     }
00061 #ifdef O_BINARY
00062     if (flag & APR_BINARY) {
00063         oflags |= O_BINARY;
00064     }
00065 #endif
00066
00067     if(((*new_file)->handle = open(fname, oflags, /*apr_unix_perms2mode*/(perm))) <0 )
00068         return errno;
00069
00070     return APR_SUCCESS;
00071 }
00072
00073 APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file)
00074 {
00075     return close(file->handle);
00076 }
00077
00078 APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *file, int type)
00079 {
00080     if(type & APR_FLOCK_NONBLOCK)
00081         pa_lock_exclusive_nonblocking(file->handle);
00082
00083     if ((type & APR_FLOCK_TYPEMASK) == APR_FLOCK_SHARED)
00084         return pa_lock_shared_blocking(file->handle);
00085
00086     return pa_lock_exclusive_blocking(file->handle);
00087 }
00088
00089 APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *file)
00090 {
00091     return pa_unlock(file->handle);
00092 }
00093
00094 APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
00095                                           apr_int32_t /*wanted*/,
00096                                           apr_file_t *file)
00097 {
00098     struct stat info;
00099
00100     if (fstat(file->handle, &info) == 0) {
00101         finfo->size=info.st_size;
00102         return APR_SUCCESS;
00103     }
00104     else {
00105         return errno;
00106     }
00107 }
00108
00109
00110 APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *file,
00111                                    apr_seek_where_t where,
00112                                    apr_off_t *offset)
00113 {
00114     apr_off_t rv = lseek(file->handle, *offset, where);
00115     *offset = rv;
00116     return rv == -1? errno: APR_SUCCESS;
00117 }
00118
00119
00120 APR_DECLARE(apr_status_t) apr_file_read_full(apr_file_t *file, void *buf,
00121                                         apr_size_t nbytes,
00122                                         apr_size_t *p_bytes_read)
00123 {
00124     int l_bytes_read = read(file->handle, buf, nbytes);
00125     if (l_bytes_read == 0)
00126         return APR_EOF;
00127     else if (l_bytes_read == -1)
00128         return errno;
00129
00130     if(p_bytes_read)
00131         *p_bytes_read=(apr_size_t)l_bytes_read;
00132
00133     return APR_SUCCESS;
00134 }
00135
00136
00137 APR_DECLARE(apr_status_t) apr_file_write_full(apr_file_t *file, const void *buf,
00138                                          apr_size_t nbytes,
00139                                          apr_size_t *bytes_written)
00140 {
00141     apr_size_t rv;
00142     do {
00143         rv = write(file->handle, buf, nbytes);
00144     } while (rv == (apr_size_t)-1 && errno == EINTR);
00145
00146     if (rv == (apr_size_t)-1) {
00147         if(bytes_written)
00148             *bytes_written = 0;
00149         return errno;
00150     }
00151     if(bytes_written)
00152         *bytes_written=rv;
00153     return APR_SUCCESS;
00154 }


apr_file_io.h File Reference

APR File I/O Handling. More...

Include dependency graph for apr_file_io.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | APR_READ 1
Open the file for reading. More...

#define | APR_WRITE 2
Open the file for writing. More...

#define | APR_CREATE 4
Create the file if not there. More...

#define | APR_APPEND 8
Append to the end of the file. More...

#define | APR_TRUNCATE 16
Open the file and truncate to 0 length. More...

#define | APR_BINARY 32
Open the file in binary mode. More...

#define | APR_EXCL 64
Open should fail if APR_CREATE and file exists. More...

#define | APR_BUFFERED 128
Open the file for buffered I/O. More...

#define | APR_DELONCLOSE 256
Delete the file after close. More...

#define | APR_XTHREAD 512
Platform dependent tag to open the file for use across multiple threads. More...

#define | APR_SHARELOCK 1024
Platform dependent support for higher level locked read/write access to support writes across process/machines. More...

#define | APR_FILE_NOCLEANUP 2048
Do not register a cleanup when the file is opened. More...

#define | APR_SET SEEK_SET
#define | APR_CUR SEEK_CUR
#define | APR_END SEEK_END
#define | APR_FLOCK_SHARED 1
Shared lock. More...

#define | APR_FLOCK_EXCLUSIVE 2
Exclusive lock. More...

#define | APR_FLOCK_TYPEMASK 0x000F
mask to extract lock type. More...

#define | APR_FLOCK_NONBLOCK 0x0010
do not block while acquiring the file lock. More...

Typedefs

typedef int | apr_seek_where_t
should be same as whence type in lseek, POSIX defines this as int. More...

typedef apr_file_t | apr_file_t
Structure for referencing files. More...

Functions

APR_DECLARE (apr_status_t) apr_file_open(apr_file_t **new_file
Open the specified file. More...

Variables

const char * | fname
const char apr_int32_t | flag
const char apr_int32_t apr_fileperms_t | perm
const char apr_int32_t apr_fileperms_t
apr_pool_t * 		cont
int | type
apr_int32_t wanted
apr_int32_t apr_file_t * thefile
apr_seek_where_t where
apr_seek_where_t apr_off_t * offset
void * | buf
void apr_size_t | nbytes
void apr_size_t apr_size_t * | bytes_read
const void apr_size_t apr_size_t * | bytes_written

Detailed Description

APR File I/O Handling.

Definition in file apr_file_io.h.


apr_file_io.h Source File

apr_file_io.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #ifndef APR_FILE_IO_H
00056 #define APR_FILE_IO_H
00057
00067 #include <stdio.h>
00068
00069 #include "apr_errno.h"
00070 #include "apr_pools.h"
00071 #include "apr_file_info.h"
00072
00073 #ifdef __cplusplus
00074 extern "C" {
00075 #endif /* __cplusplus */
00076
00082 #define APR_READ       1
00083 #define APR_WRITE      2
00084 #define APR_CREATE     4
00085 #define APR_APPEND     8
00086 #define APR_TRUNCATE   16
00087 #define APR_BINARY     32
00088 #define APR_EXCL       64
00090 #define APR_BUFFERED   128
00091 #define APR_DELONCLOSE 256
00092 #define APR_XTHREAD    512
00094 #define APR_SHARELOCK  1024
00097 #define APR_FILE_NOCLEANUP  2048
00107 /* flags for apr_file_seek */
00108 #define APR_SET SEEK_SET
00109 #define APR_CUR SEEK_CUR
00110 #define APR_END SEEK_END
00111
00114 typedef int       apr_seek_where_t;
00115
00120 typedef struct apr_file_t         apr_file_t;
00121
00122 /* File lock types/flags */
00128 #define APR_FLOCK_SHARED        1
00134 #define APR_FLOCK_EXCLUSIVE     2
00139 #define APR_FLOCK_TYPEMASK      0x000F
00140 #define APR_FLOCK_NONBLOCK      0x0010
00177 APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new_file, const char *fname,
00178                                    apr_int32_t flag, apr_fileperms_t perm,
00179                                    apr_pool_t *cont);
00180
00185 APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file);
00186
00187
00199 APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type);
00200
00205 APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile);
00206
00207
00214 APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
00215                                           apr_int32_t wanted,
00216                                           apr_file_t *thefile);
00217
00231 APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile,
00232                                    apr_seek_where_t where,
00233                                    apr_off_t *offset);
00234
00235
00255 APR_DECLARE(apr_status_t) apr_file_read_full(apr_file_t *thefile, void *buf,
00256                                         apr_size_t nbytes,
00257                                         apr_size_t *bytes_read);
00258
00277 APR_DECLARE(apr_status_t) apr_file_write_full(apr_file_t *thefile, const void *buf,
00278                                          apr_size_t nbytes,
00279                                          apr_size_t *bytes_written);
00280
00281 #ifdef __cplusplus
00282 }
00283 #endif
00284
00285 #endif  /* ! APR_FILE_IO_H */


apr_pools.h File Reference

APR memory allocation. More...

Include dependency graph for apr_pools.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Typedefs

typedef void apr_pool_t

Detailed Description

APR memory allocation.

Resource allocation routines...

designed so that we don't have to keep track of EVERYTHING so that it can be explicitly freed later (a fundamentally unsound strategy --- particularly in the presence of die()).

Instead, we maintain pools, and allocate items (both memory and I/O handlers) from the pools --- currently there are two, one for per transaction info, and one for config info. When a transaction is over, we can delete everything in the per-transaction apr_pool_t without fear, and without thinking too hard about it either.

Definition in file apr_pools.h.

Typedef Documentation

typedef void apr_pool_t

Definition at line 81 of file apr_pools.h.

Referenced by prep().


apr_pools.h Source File

apr_pools.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #ifndef APR_POOLS_H
00056 #define APR_POOLS_H
00057
00058 #include "apr_errno.h"
00059
00060 #ifdef __cplusplus
00061 extern "C" {
00062 #endif
00063
00081 typedef void apr_pool_t;
00082
00083 #ifdef __cplusplus
00084 }
00085 #endif
00086
00087 #endif /* !APR_POOLS_H */


apr_sdbm.h File Reference

apr-util SDBM library. More...

Include dependency graph for apr_sdbm.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | apr_sdbm_datum_t
Structure for referencing the datum record within an sdbm. More...

Defines

#define | APR_SDBM_DIRFEXT ".dir"
#define | APR_SDBM_PAGFEXT ".pag"
#define | APR_SDBM_INSERT 0
#define | APR_SDBM_REPLACE 1
#define | APR_SDBM_INSERTDUP 2

Typedefs

typedef apr_sdbm_t | apr_sdbm_t
Structure for referencing an sdbm. More...

Functions

APU_DECLARE (apr_status_t) apr_sdbm_open(apr_sdbm_t **db
Open an sdbm database by file name. More...

APU_DECLARE (int) apr_sdbm_rdonly(apr_sdbm_t *db)
Returns true if the sdbm database opened for read-only access. More...

Variables

const char * | name
const char apr_int32_t | mode
const char apr_int32_t apr_fileperms_t | perms
const char apr_int32_t apr_fileperms_t
apr_pool_t * 		p
int | type
apr_sdbm_datum_t * value
apr_sdbm_datum_t apr_sdbm_datum_t key
apr_sdbm_datum_t apr_sdbm_datum_t
int 		opt

Detailed Description

apr-util SDBM library.

Definition in file apr_sdbm.h.


apr_sdbm.h Source File

apr_sdbm.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * sdbm - ndbm work-alike hashed database library
00057  * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
00058  * author: oz@nexus.yorku.ca
00059  * status: ex-public domain
00060  */
00061
00062 #ifndef APR_SDBM_H
00063 #define APR_SDBM_H
00064
00065 #include "apu.h"
00066 #include "apr_errno.h"
00067 #include "apr_file_io.h"   /* for apr_fileperms_t */
00068
00069 #ifdef __cplusplus
00070 extern "C" {
00071 #endif
00072
00073
00087 typedef struct apr_sdbm_t apr_sdbm_t;
00088
00092 typedef struct {
00094     char *dptr;
00096     int dsize;
00097 } apr_sdbm_datum_t;
00098
00099 /* The extensions used for the database files */
00100 #define APR_SDBM_DIRFEXT    ".dir"
00101 #define APR_SDBM_PAGFEXT    ".pag"
00102
00103 /* flags to sdbm_store */
00104 #define APR_SDBM_INSERT     0
00105 #define APR_SDBM_REPLACE    1
00106 #define APR_SDBM_INSERTDUP  2
00107
00126 APU_DECLARE(apr_status_t) apr_sdbm_open(apr_sdbm_t **db, const char *name,
00127                                         apr_int32_t mode,
00128                                         apr_fileperms_t perms, apr_pool_t *p);
00129
00134 APU_DECLARE(apr_status_t) apr_sdbm_close(apr_sdbm_t *db);
00135
00151 APU_DECLARE(apr_status_t) apr_sdbm_lock(apr_sdbm_t *db, int type);
00152
00157 APU_DECLARE(apr_status_t) apr_sdbm_unlock(apr_sdbm_t *db);
00158
00165 APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db,
00166                                          apr_sdbm_datum_t *value,
00167                                          apr_sdbm_datum_t key);
00168
00180 APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key,
00181                                          apr_sdbm_datum_t value, int opt);
00182
00189 APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db,
00190                                           const apr_sdbm_datum_t key);
00191
00201 APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db, apr_sdbm_datum_t *key);
00202
00208 APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db, apr_sdbm_datum_t *key);
00209
00214 APU_DECLARE(int) apr_sdbm_rdonly(apr_sdbm_t *db);
00217 #ifdef __cplusplus
00218 }
00219 #endif
00220
00221 #endif /* APR_SDBM_H */


apr_strings.C File Reference

Parser: implementation of apr functions. More...

Include dependency graph for apr_strings.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | MAX_SAVED_LENGTHS 6
this is used to cache lengths in apr_pstrcat. More...

Functions

APR_DECLARE_NONSTD (char *) apr_pstrcat(apr_pool_t *p

Variables

const char *const | IDENT = "$Date: 2003/11/20 16:34:26 $"

Detailed Description

Parser: implementation of apr functions.

Copyright(c) 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file apr_strings.C.

Define Documentation

#define MAX_SAVED_LENGTHS 6

this is used to cache lengths in apr_pstrcat.

Definition at line 14 of file apr_strings.C.

Variable Documentation

const char* const IDENT = "$Date: 2003/11/20 16:34:26 $" [static]

Definition at line 8 of file apr_strings.C.


apr_strings.C Source File

apr_strings.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT="$Date: 2003/11/20 16:34:26 $";
00009
00010 #include "apr_strings.h"
00011 #include "pa_memory.h"
00012
00014 #define MAX_SAVED_LENGTHS  6
00015
00016 APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...)
00017 {
00018     char *cp, *argp, *res;
00019     apr_size_t saved_lengths[MAX_SAVED_LENGTHS];
00020     int nargs = 0;
00021
00022     /* Pass one --- find length of required string */
00023
00024     apr_size_t len = 0;
00025     va_list adummy;
00026
00027     va_start(adummy, p);
00028
00029     while ((cp = va_arg(adummy, char *)) != NULL) {
00030         apr_size_t cplen = strlen(cp);
00031         if (nargs < MAX_SAVED_LENGTHS) {
00032             saved_lengths[nargs++] = cplen;
00033         }
00034         len += cplen;
00035     }
00036
00037     va_end(adummy);
00038
00039     /* Allocate the required string */
00040
00041     res = (char *) pa_malloc_atomic(len + 1);
00042     cp = res;
00043
00044     /* Pass two --- copy the argument strings into the result space */
00045
00046     va_start(adummy, p);
00047
00048     nargs = 0;
00049     while ((argp = va_arg(adummy, char *)) != NULL) {
00050         if (nargs < MAX_SAVED_LENGTHS) {
00051             len = saved_lengths[nargs++];
00052         }
00053         else {
00054             len = strlen(argp);
00055         }
00056
00057         memcpy(cp, argp, len);
00058         cp += len;
00059     }
00060
00061     va_end(adummy);
00062
00063     /* Return the result string */
00064
00065     *cp = '\0';
00066
00067     return res;
00068 }


apr_strings.h File Reference

APR Strings library. More...

Include dependency graph for apr_strings.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

APR_DECLARE_NONSTD (char *) apr_pstrcat(apr_pool_t *p
Concatenate multiple strings, allocating memory out a pool. More...

Detailed Description

APR Strings library.

Definition in file apr_strings.h.


apr_strings.h Source File

apr_strings.h

Go to the documentation of this file.
00001
00003 /* ====================================================================
00004  * The Apache Software License, Version 1.1
00005  *
00006  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00007  * reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in
00018  *    the documentation and/or other materials provided with the
00019  *    distribution.
00020  *
00021  * 3. The end-user documentation included with the redistribution,
00022  *    if any, must include the following acknowledgment:
00023  *       "This product includes software developed by the
00024  *        Apache Software Foundation (http://www.apache.org/)."
00025  *    Alternately, this acknowledgment may appear in the software itself,
00026  *    if and wherever such third-party acknowledgments normally appear.
00027  *
00028  * 4. The names "Apache" and "Apache Software Foundation" must
00029  *    not be used to endorse or promote products derived from this
00030  *    software without prior written permission. For written
00031  *    permission, please contact apache@apache.org.
00032  *
00033  * 5. Products derived from this software may not be called "Apache",
00034  *    nor may "Apache" appear in their name, without prior written
00035  *    permission of the Apache Software Foundation.
00036  *
00037  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00038  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00039  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00040  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00041  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00042  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00043  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00044  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00045  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00046  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00047  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00048  * SUCH DAMAGE.
00049  * ====================================================================
00050  *
00051  * This software consists of voluntary contributions made by many
00052  * individuals on behalf of the Apache Software Foundation.  For more
00053  * information on the Apache Software Foundation, please see
00054  * <http://www.apache.org/>.
00055  */
00056
00057 /* Portions of this file are covered by */
00058 /* -*- mode: c; c-file-style: "k&r" -*-
00059
00060   strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
00061   Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
00062
00063   This software is provided 'as-is', without any express or implied
00064   warranty.  In no event will the authors be held liable for any damages
00065   arising from the use of this software.
00066
00067   Permission is granted to anyone to use this software for any purpose,
00068   including commercial applications, and to alter it and redistribute it
00069   freely, subject to the following restrictions:
00070
00071   1. The origin of this software must not be misrepresented; you must not
00072      claim that you wrote the original software. If you use this software
00073      in a product, an acknowledgment in the product documentation would be
00074      appreciated but is not required.
00075   2. Altered source versions must be plainly marked as such, and must not be
00076      misrepresented as being the original software.
00077   3. This notice may not be removed or altered from any source distribution.
00078 */
00079
00080 #ifndef APR_STRINGS_H
00081 #define APR_STRINGS_H
00082
00083 #include "pa_config_includes.h"
00084
00085 #include "apr.h"
00086 #include "apr_errno.h"
00087 #include "apr_pools.h"
00088
00089 #ifdef HAVE_STDARG_H
00090 #include <stdarg.h>
00091 #endif
00092
00093
00094 #ifdef __cplusplus
00095 extern "C" {
00096 #endif /* __cplusplus */
00097
00112 APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...);
00113
00116 #ifdef __cplusplus
00117 }
00118 #endif
00119
00120 #endif  /* !APR_STRINGS_H */


apu.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | APU_DECLARE(type) type
The public APR-UTIL functions are declared with APU_DECLARE(), so they may use the most appropriate calling convention. More...

#define | APU_DECLARE_NONSTD(type) type
The public APR-UTIL functions using variable arguments are declared with APU_DECLARE_NONSTD(), as they must use the C language calling convention. More...

#define | APU_DECLARE_DATA
The public APR-UTIL variables are declared with APU_DECLARE_DATA. More...

#define | APU_HAVE_SDBM


apu.h Source File

apu.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * apu.h is generated from apu.h.in by configure -- do not edit apu.h
00057  */
00058 /* @file apu.h
00059  * @brief APR-Utility main file
00060  */
00067 #ifndef APU_H
00068 #define APU_H
00069
00090 #define APU_DECLARE(type)            type
00091
00097 #define APU_DECLARE_NONSTD(type)     type
00098
00106 #define APU_DECLARE_DATA
00107 /*
00108  * we always have SDBM (it's in our codebase)
00109  */
00110 #define APU_HAVE_SDBM
00111
00112 #endif /* APU_H */
00113


chartables.c File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Variables

unsigned char pcre_default_tables []

Variable Documentation

unsigned char pcre_default_tables[]

Definition at line 13 of file chartables.c.


chartables.c Source File

chartables.c

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005 /* This file is automatically written by the dftables auxiliary
00006 program. If you edit it by hand, you might like to edit the Makefile to
00007 prevent its ever being regenerated.
00008
00009 This file is #included in the compilation of pcre.c to build the default
00010 character tables which are used when no tables are passed to the compile
00011 function. */
00012
00013 unsigned char pcre_default_tables[] = {
00014
00015 /* This table is a lower casing table. */
00016
00017     0,  1,  2,  3,  4,  5,  6,  7,
00018     8,  9, 10, 11, 12, 13, 14, 15,
00019    16, 17, 18, 19, 20, 21, 22, 23,
00020    24, 25, 26, 27, 28, 29, 30, 31,
00021    32, 33, 34, 35, 36, 37, 38, 39,
00022    40, 41, 42, 43, 44, 45, 46, 47,
00023    48, 49, 50, 51, 52, 53, 54, 55,
00024    56, 57, 58, 59, 60, 61, 62, 63,
00025    64, 97, 98, 99,100,101,102,103,
00026   104,105,106,107,108,109,110,111,
00027   112,113,114,115,116,117,118,119,
00028   120,121,122, 91, 92, 93, 94, 95,
00029    96, 97, 98, 99,100,101,102,103,
00030   104,105,106,107,108,109,110,111,
00031   112,113,114,115,116,117,118,119,
00032   120,121,122,123,124,125,126,127,
00033   128,129,130,131,132,133,134,135,
00034   136,137,138,139,140,141,142,143,
00035   144,145,146,147,148,149,150,151,
00036   152,153,154,155,156,157,158,159,
00037   160,161,162,163,164,165,166,167,
00038   168,169,170,171,172,173,174,175,
00039   176,177,178,179,180,181,182,183,
00040   184,185,186,187,188,189,190,191,
00041   192,193,194,195,196,197,198,199,
00042   200,201,202,203,204,205,206,207,
00043   208,209,210,211,212,213,214,215,
00044   216,217,218,219,220,221,222,223,
00045   224,225,226,227,228,229,230,231,
00046   232,233,234,235,236,237,238,239,
00047   240,241,242,243,244,245,246,247,
00048   248,249,250,251,252,253,254,255,
00049
00050 /* This table is a case flipping table. */
00051
00052     0,  1,  2,  3,  4,  5,  6,  7,
00053     8,  9, 10, 11, 12, 13, 14, 15,
00054    16, 17, 18, 19, 20, 21, 22, 23,
00055    24, 25, 26, 27, 28, 29, 30, 31,
00056    32, 33, 34, 35, 36, 37, 38, 39,
00057    40, 41, 42, 43, 44, 45, 46, 47,
00058    48, 49, 50, 51, 52, 53, 54, 55,
00059    56, 57, 58, 59, 60, 61, 62, 63,
00060    64, 97, 98, 99,100,101,102,103,
00061   104,105,106,107,108,109,110,111,
00062   112,113,114,115,116,117,118,119,
00063   120,121,122, 91, 92, 93, 94, 95,
00064    96, 65, 66, 67, 68, 69, 70, 71,
00065    72, 73, 74, 75, 76, 77, 78, 79,
00066    80, 81, 82, 83, 84, 85, 86, 87,
00067    88, 89, 90,123,124,125,126,127,
00068   128,129,130,131,132,133,134,135,
00069   136,137,138,139,140,141,142,143,
00070   144,145,146,147,148,149,150,151,
00071   152,153,154,155,156,157,158,159,
00072   160,161,162,163,164,165,166,167,
00073   168,169,170,171,172,173,174,175,
00074   176,177,178,179,180,181,182,183,
00075   184,185,186,187,188,189,190,191,
00076   192,193,194,195,196,197,198,199,
00077   200,201,202,203,204,205,206,207,
00078   208,209,210,211,212,213,214,215,
00079   216,217,218,219,220,221,222,223,
00080   224,225,226,227,228,229,230,231,
00081   232,233,234,235,236,237,238,239,
00082   240,241,242,243,244,245,246,247,
00083   248,249,250,251,252,253,254,255,
00084
00085 /* This table contains bit maps for digits, 'word' chars, and white
00086 space. Each map is 32 bytes long and the bits run from the least
00087 significant end of each byte. */
00088
00089   0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
00090   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00091   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00092   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00093
00094   0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
00095   0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
00096   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00097   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00098
00099   0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
00100   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00101   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00102   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
00103
00104 /* This table identifies various classes of character by individual bits:
00105   0x01   white space character
00106   0x02   letter
00107   0x04   decimal digit
00108   0x08   hexadecimal digit
00109   0x10   alphanumeric or '_'
00110   0x80   regular expression metacharacter or binary zero
00111 */
00112
00113   0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */
00114   0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */
00115   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */
00116   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */
00117   0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /*    - '  */
00118   0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /*  ( - /  */
00119   0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /*  0 - 7  */
00120   0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /*  8 - ?  */
00121   0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  @ - G  */
00122   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */
00123   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */
00124   0x12,0x12,0x12,0x80,0x00,0x00,0x80,0x10, /*  X - _  */
00125   0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  ` - g  */
00126   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  h - o  */
00127   0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  p - w  */
00128   0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /*  x -127 */
00129   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
00130   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
00131   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
00132   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
00133   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
00134   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
00135   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
00136   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
00137   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
00138   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
00139   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
00140   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
00141   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
00142   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
00143   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
00144   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
00145
00146 /* End of chartables.c */


class.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


classes.C File Reference

Parser: Methoded and Methoded_array classes. More...

Include dependency graph for classes.C:

Include dependency graph

Go to the source code of this file.

Functions

Methoded_array & methoded_array ()
void | configure_admin_one (Methoded_array::element_type methoded, Request *r)
void | configure_user_one (Methoded_array::element_type methoded, Request *r)
void | register_one (Methoded_array::element_type methoded, Request *r)

Variables

const char *const | IDENT_CLASSES_C = "$Date: 2005/08/09 08:14:47 $"

Detailed Description

Parser: Methoded and Methoded_array classes.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file classes.C.

Function Documentation

Methoded_array& methoded_array ( )

Definition at line 29 of file classes.C.

References result.

Referenced by Request::configure(), Request::configure_admin(), and Request::Request().

void configure_admin_one | ( | Methoded_array::element_type | methoded,
 |  | Request * | r
 | ) | [static]

Definition at line 61 of file classes.C.

void configure_user_one | ( | Methoded_array::element_type | methoded,
 |  | Request * | r
 | ) | [static]

Definition at line 69 of file classes.C.

void register_one | ( | Methoded_array::element_type | methoded,
 |  | Request * | r
 | ) | [static]

Definition at line 77 of file classes.C.

Variable Documentation

const char* const IDENT_CLASSES_C = "$Date: 2005/08/09 08:14:47 $" [static]

Definition at line 8 of file classes.C.


classes.C Source File

classes.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_CLASSES_C="$Date: 2005/08/09 08:14:47 $";
00009
00010 #include "classes.h"
00011 #include "pa_request.h"
00012
00013 // Methoded
00014
00015 void Methoded::register_directly_used(Request& r) {
00016     if(used_directly()) {
00017         r.classes().put(name(), this);
00018     }
00019
00020     // prevent system classes from modification [calling add_method]
00021     // ^process[$string:CLASS]{@method} prohibited from now on...
00022     this->lock();
00023 }
00024
00025 // Methoded_array
00026
00027 // global variable
00028
00029 Methoded_array& methoded_array() {
00030     static Methoded_array* result=0;
00031     if(!result)
00032         result=new Methoded_array;
00033
00034     return *result;
00035 }
00036
00037 // methods
00038
00039 Methoded_array::Methoded_array() {
00040 #   include "classes.inc"
00041 }
00042
00043 static void configure_admin_one(Methoded_array::element_type methoded, Request *r) {
00044     if(methoded)
00045         methoded->configure_admin(*r);
00046 }
00047 void Methoded_array::configure_admin(Request& r) {
00048     for_each(configure_admin_one, &r);
00049 }
00050
00051 static void configure_user_one(Methoded_array::element_type methoded, Request *r) {
00052     if(methoded)
00053         methoded->configure_user(*r);
00054 }
00055 void Methoded_array::configure_user(Request& r) {
00056     for_each(configure_user_one, &r);
00057 }
00058
00059 static void register_one(Methoded_array::element_type methoded, Request *r) {
00060     if(methoded)
00061         methoded->register_directly_used(*r);
00062 }
00063 void Methoded_array::register_directly_used(Request& r) {
00064     for_each(register_one, &r);
00065 }


classes.h File Reference

Parser: Methoded class decl. More...

Include dependency graph for classes.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Methoded
Pure virtual base for configurable Methoded descendants. More...

class | Methoded_array
all Methoded registered here in autogenerated classes.C. More...

Defines

#define | DECLARE_CLASS_VAR(name, self, base)

Functions

Methoded_array & methoded_array ()

Variables

const char *const | IDENT_CLASSES_H = "$Date: 2005/08/09 08:14:47 $"

Detailed Description

Parser: Methoded class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file classes.h.

Define Documentation

#define DECLARE_CLASS_VAR | ( | name,
 |  | self,
 |  | base | )

Value:

Methoded* name##_class=self; \
    Methoded* name##_base_class=base

Definition at line 73 of file classes.h.

Function Documentation

Methoded_array& methoded_array ( )

Definition at line 29 of file classes.C.

References result.

Referenced by Request::configure(), Request::configure_admin(), and Request::Request().

Variable Documentation

const char* const IDENT_CLASSES_H = "$Date: 2005/08/09 08:14:47 $" [static]

Definition at line 11 of file classes.h.


classes.h Source File

classes.h

Go to the documentation of this file.
00001
00008 #ifndef CLASSES_H
00009 #define CLASSES_H
00010
00011 static const char * const IDENT_CLASSES_H="$Date: 2005/08/09 08:14:47 $";
00012
00013 // include
00014
00015 #include "pa_vstateless_class.h"
00016 #include "pa_array.h"
00017
00021 class Methoded: public VStateless_class {
00022 public: // Value
00023
00024     override const VJunction* put_element(Value& /*self*/, const String& /*name*/, Value * /*value*/) {
00025         return 0; // fewer useless Exceptions
00026     }
00027
00028 public: // Methoded
00029
00035     virtual bool used_directly() =0;
00037     virtual void configure_admin(Request& ) {}
00039     virtual void configure_user(Request& ) {}
00041     virtual void construct_statics() {}
00042
00043 public: // usage
00044
00045     Methoded(const char* aname, VStateless_class* abase=0):
00046         VStateless_class(new String(aname), abase) {
00047     }
00048
00049     void register_directly_used(Request& r);
00050
00051 };
00052
00054 class Methoded_array: public Array<Methoded*> {
00055 public:
00056     Methoded_array();
00057
00058 public: // Methoded for_each-es
00060     void configure_admin(Request& r);
00062     void configure_user(Request& r);
00064     void register_directly_used(Request& r);
00065 };
00066
00067 // globals
00068
00069 Methoded_array& methoded_array();
00070
00071 // defines
00072
00073 #define DECLARE_CLASS_VAR(name, self, base) \
00074     Methoded* name##_class=self; \
00075     Methoded* name##_base_class=base
00076
00077 #endif


ClassExample1.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


ClassExample2.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


ClassExample3.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


comms.C File Reference

Parser: SMTP sender impl. More...

Include dependency graph for comms.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_COMMS_C = "$Date: 2005/08/09 08:14:51 $"

Detailed Description

Parser: SMTP sender impl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file comms.C.

Variable Documentation

const char* const IDENT_COMMS_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 8 of file comms.C.


comms.C Source File

comms.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_COMMS_C="$Date: 2005/08/09 08:14:51 $";
00009
00010 #include "smtp.h"
00011
00012 // ---------------------------------------------------------------------------
00013 int
00014 SMTP:: IsAddressARawIpaddress(const char*  string)
00015 {
00016     while( *string )
00017     {
00018         if( !isdigit((unsigned char)*string) )
00019         {
00020             return 0;
00021         }
00022         string++;
00023     }
00024     return 1;
00025 }
00026
00027 //---------------------------------------------------------------------------
00029 int SMTP::
00030 ResolveService(const char* service, u_short *our_port)
00031 {
00032     struct servent  *serventry = NULL;
00033
00034     if( IsAddressARawIpaddress(service) )
00035     {
00036         char * tail;
00037
00038         *our_port = (u_short)strtol(service, &tail, 10);
00039
00040         if( tail == service )
00041         {
00042             return WSAEPROTONOSUPPORT;
00043         }
00044         else
00045         {
00046             *our_port = htons(*our_port);
00047         }
00048     }
00049     else
00050     {
00051         serventry = getservbyname(service, "tcp");
00052
00053         if( serventry )
00054             *our_port = serventry->s_port;
00055         else
00056         {
00057 #ifdef WIN32
00058             int retval = WSAGetLastError();
00059             if( (retval == WSANO_DATA) || (retval == WSANO_RECOVERY) )
00060             {
00061                 return WSAEPROTONOSUPPORT;
00062             }
00063             else
00064             {
00065                 return (retval - 5000);
00066             }
00067 #else
00068         return WSAEPROTONOSUPPORT;
00069 #endif
00070         }
00071     }
00072
00073     return 0;
00074 }
00075
00076 //---------------------------------------------------------------------------
00078 int SMTP::
00079 ResolveHostname(const char* hostname, struct sockaddr_in *sa_in)
00080 {
00081     struct hostent *hostentry = NULL;
00082     unsigned long       ip_address;
00083
00084     if( (ip_address = inet_addr(hostname)) != INADDR_NONE )
00085     {
00086         sa_in->sin_addr.s_addr = ip_address;
00087     }
00088     else
00089     {
00090         if( (hostentry = gethostbyname(hostname)) == NULL )
00091         {
00092             return WSAHOST_NOT_FOUND;
00093         }
00094
00095         sa_in->sin_addr.s_addr = *(long *)hostentry->h_addr;
00096     }
00097
00098     return 0;
00099 }
00100
00101 //---------------------------------------------------------------------------
00102 int
00103 SMTP:: GetAndSetTheSocket(SOCKET *the_socket)
00104 {
00105     if( INVALID_SOCKET == (*the_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP/*áûë 0, âëîæåííî íå ðàáîòàë*/)) )
00106     {
00107         return WSAESOCKTNOSUPPORT;
00108     }
00109
00110     // To enable SO_DONTLINGER (that is, disable SO_LINGER)
00111     // l_onoff should be set to zero and setsockopt should be called
00112     linger dont_linger={0,0};
00113     setsockopt(*the_socket, SOL_SOCKET, SO_LINGER, (const char *)&dont_linger, sizeof(dont_linger));
00114
00115     return 0;
00116 }
00117
00118 //---------------------------------------------------------------------------
00119 int
00120 SMTP:: GetConnection(SOCKET the_socket, struct sockaddr_in *sa_in)
00121 {
00122
00123     if( connect(the_socket,
00124                                 (struct sockaddr *)sa_in,
00125                                 sizeof(struct sockaddr_in))<0
00126       )
00127     {
00128     int     retval = 0;
00129         switch( (retval = WSAGetLastError()) )
00130         {
00131             case WSAEWOULDBLOCK:
00132                 break;
00133
00134             case WSAECONNREFUSED:
00135                 return WSAECONNREFUSED;
00136
00137             default:
00138                 //wsprintf(message, "unexpected error %d from winsock\n", retval);
00139                 //ShowError(message);
00140                 return WSAHOST_NOT_FOUND;
00141         }
00142     }
00143
00144     return 0;
00145 }
00146
00147 //---------------------------------------------------------------------------
00148 void
00149 SMTP:: MiscSocketSetup(SOCKET soc, fd_set *fds, struct timeval *timeout)
00150 {
00151 #ifdef FIONBIO
00152     unsigned long   ioctl_blocking = 1;
00153     ioctlsocket(soc, FIONBIO, &ioctl_blocking);
00154 #endif
00155
00156     FD_ZERO(fds);
00157     FD_SET(soc, fds);
00158
00159     timeout->tv_sec = 30;
00160     timeout->tv_usec = 0;
00161 }
00162
00163 //---------------------------------------------------------------------------


compile.C File Reference

Parser: compiler part of request class. More...

Include dependency graph for compile.C:

Include dependency graph

Go to the source code of this file.

Functions

int | yyparse (void *)

Variables

const char *const | IDENT_COMPILE_C = "$Date: 2005/08/09 08:14:51 $"
int | yydebug

Detailed Description

Parser: compiler part of request class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file compile.C.

Function Documentation

int yyparse ( void * )

Referenced by Request::compile().

Variable Documentation

const char* const IDENT_COMPILE_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 8 of file compile.C.

int yydebug

Definition at line 14 of file compile.C.


compile.C Source File

compile.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_COMPILE_C="$Date: 2005/08/09 08:14:51 $";
00009
00010 #include "pa_opcode.h"
00011 #include "pa_request.h"
00012 #include "compile_tools.h"
00013
00014 extern int yydebug;
00015 extern int yyparse (void *);
00016
00017 VStateless_class& Request::compile(VStateless_class* aclass,
00018                    const char* source, const String* main_alias,
00019                    uint file_no,
00020                    int line_no_offset) {
00021     // prepare to parse
00022     Parse_control pc(*this, aclass, source, main_alias, file_no, line_no_offset);
00023
00024     // parse=compile!
00025     //yydebug=1;
00026     if(yyparse(&pc)) { // error?
00027         pc.pos_prev_c();
00028         if(!pc.explicit_result)
00029             if(pc.pos.col==0) // expecting something after EOL means they've expected it BEFORE
00030                 pc.pos_prev_c();
00031
00032         throw Exception("parser.compile",
00033             0,
00034             "%s(%d:%d): %s",  file_list[file_no].cstr(), 1+pc.pos.line, 1+pc.pos.col,  pc.error);
00035     }
00036
00037     // result
00038     return *pc.cclass;
00039 }


compile.y File Reference

Include dependency graph for compile.y:

Include dependency graph

Go to the source code of this file.

Defines

#define | YYSTYPE ArrayOperation*
#define | YYPARSE_PARAM pc
#define | YYLEX_PARAM pc
#define | YYDEBUG 1
#define | YYERROR_VERBOSE 1
#define | yyerror(msg) real_yyerror((Parse_control *)pc, msg)
#define | YYPRINT(file, type, value) yyprint(file, type, value)
#define | USE_CONTROL_METHOD_NAME "USE"
#define | PC (*(Parse_control *)pc)
#define | POOL (*PC.pool)
#define | lexical_brackets_nestage pc.brackets_nestages[pc.ls_sp]
#define | RC {result=c; goto break2; }

Define Documentation

#define YYSTYPE ArrayOperation*

#define YYPARSE_PARAM pc

#define YYLEX_PARAM pc

#define YYDEBUG 1

#define YYERROR_VERBOSE 1

#define yyerror ( msg ) real_yyerror((Parse_control *)pc, msg)

#define YYPRINT | ( | file,
 |  | type,
 |  | value | ) | yyprint(file, type, value)

#define USE_CONTROL_METHOD_NAME "USE"

#define PC (*(Parse_control *)pc)

#define POOL (*PC.pool)

#define lexical_brackets_nestage pc.brackets_nestages[pc.ls_sp]

#define RC {result=c; goto break2; }


compile.y Source File

compile.y

Go to the documentation of this file.
00001 %{
00022 #define YYSTYPE  ArrayOperation*
00023 #define YYPARSE_PARAM  pc
00024 #define YYLEX_PARAM  pc
00025 #define YYDEBUG  1
00026 #define YYERROR_VERBOSE 1
00027 #define yyerror(msg)  real_yyerror((Parse_control *)pc, msg)
00028 #define YYPRINT(file, type, value)  yyprint(file, type, value)
00029
00030 // includes
00031
00032 #include "compile_tools.h"
00033 #include "pa_value.h"
00034 #include "pa_request.h"
00035 #include "pa_vobject.h"
00036 #include "pa_vdouble.h"
00037 #include "pa_globals.h"
00038 #include "pa_vvoid.h"
00039 #include "pa_vmethod_frame.h"
00040
00041 // defines
00042
00043 #define USE_CONTROL_METHOD_NAME "USE"
00044
00045 // forwards
00046
00047 static int real_yyerror(Parse_control* pc, char* s);
00048 static void yyprint(FILE* file, int type, YYSTYPE value);
00049 static int yylex(YYSTYPE* lvalp, void* pc);
00050
00051 static const VBool vfalse(false);
00052 static const VBool vtrue(true);
00053 static const VVoid vvoid;
00054
00055 // local convinient inplace typecast & var
00056 #undef PC
00057 #define PC  (*(Parse_control *)pc)
00058 #undef POOL
00059 #define POOL  (*PC.pool)
00060 #ifndef DOXYGEN
00061 %}
00062
00063 %pure_parser
00064
00065 %token EON
00066 %token STRING
00067 %token BOGUS
00068
00069 %token BAD_STRING_COMPARISON_OPERATOR
00070 %token BAD_HEX_LITERAL
00071 %token BAD_METHOD_DECL_START
00072 %token BAD_METHOD_PARAMETER_NAME_CHARACTER
00073 %token BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE
00074
00075 %token LAND "&&"
00076 %token LOR "||"
00077 %token LXOR "!||"
00078 %token NXOR "!|"
00079
00080 %token NLE "<="
00081 %token NGE ">="
00082 %token NEQ "=="
00083 %token NNE "!="
00084 %token NSL "<<"
00085 %token NSR ">>"
00086
00087 %token SLT "lt"
00088 %token SGT "gt"
00089 %token SLE "le"
00090 %token SGE "ge"
00091 %token SEQ "eq"
00092 %token SNE "ne"
00093
00094 %token DEF "def"
00095 %token IN "in"
00096 %token FEXISTS "-f"
00097 %token DEXISTS "-d"
00098 %token IS "is"
00099
00100 %token LITERAL_TRUE "true"
00101 %token LITERAL_FALSE "false"
00102
00103 /* logical */
00104 %left "!||"
00105 %left "||"
00106 %left "&&"
00107 %left '<' '>' "<=" ">="   "lt" "gt" "le" "ge"
00108 %left "==" "!="  "eq" "ne"
00109 %left "is" "def" "in" "-f" "-d"
00110
00111 /* bitwise */
00112 %left "!|"
00113 %left '|'
00114 %left '&'
00115 %left "<<"  ">>"
00116
00117 /* numerical */
00118 %left '+' '-'
00119 %left '*' '/' '\\' '%'
00120 %left NUNARY   /* unary - + */
00121
00122 /* out-of-group */
00123 %left '~' /* bitwise */
00124 %left '!'  /* logical */
00125
00126 %%
00127 all:
00128     one_big_piece {
00129     Method& method=*new Method(Method::CT_ANY,
00130         0, 0, /*min, max numbered_params_count*/
00131         0/*param_names*/, 0/*local_names*/,
00132         $1/*parser_code*/, 0/*native_code*/);
00133     PC.cclass->add_method(PC.alias_method(main_method_name), method);
00134 }
00135 |   methods;
00136
00137 methods: method | methods method;
00138 one_big_piece: maybe_codes;
00139
00140 method: control_method | code_method;
00141
00142 control_method: '@' STRING '\n'
00143                 maybe_control_strings {
00144     const String& command=*LA2S(*$2);
00145     YYSTYPE strings_code=$4;
00146     if(strings_code->count()<1*OPERATIONS_PER_OPVALUE) {
00147         strcpy(PC.error, "@");
00148         strcat(PC.error, command.cstr());
00149         strcat(PC.error, " is empty");
00150         YYERROR;
00151     }
00152     if(command==CLASS_NAME) {
00153         if(PC.cclass->base_class()) { // already changed from default?
00154             strcpy(PC.error, "class already have a name '");
00155             strncat(PC.error, PC.cclass->name().cstr(), 100);
00156             strcat(PC.error, "'");
00157             YYERROR;
00158         }
00159         if(strings_code->count()==1*OPERATIONS_PER_OPVALUE) {
00160             // new class' name
00161             const String& name=*LA2S(*strings_code);
00162             // creating the class
00163             VStateless_class* cclass=new VClass;
00164             PC.cclass=cclass;
00165             PC.cclass->set_name(name);
00166             // append to request's classes
00167             PC.request.classes().put(name, cclass);
00168         } else {
00169             strcpy(PC.error, "@"CLASS_NAME" must contain only one line with class name (contains more then one)");
00170             YYERROR;
00171         }
00172     } else if(command==USE_CONTROL_METHOD_NAME) {
00173         for(size_t i=0; i<strings_code->count(); i+=OPERATIONS_PER_OPVALUE)
00174             PC.request.use_file(PC.request.main_class, *LA2S(*strings_code, i));
00175     } else if(command==BASE_NAME) {
00176         if(PC.cclass->base_class()) { // already changed from default?
00177             strcpy(PC.error, "class already have a base '");
00178             strncat(PC.error, PC.cclass->base_class()->name().cstr(), 100);
00179             strcat(PC.error, "'");
00180             YYERROR;
00181         }
00182         if(strings_code->count()==1*OPERATIONS_PER_OPVALUE) {
00183             const String& base_name=*LA2S(*strings_code);
00184             if(Value* base_class_value=PC.request.classes().get(base_name)) {
00185                 // @CLASS == @BASE sanity check
00186                 if(VStateless_class *base_class=base_class_value->get_class()) {
00187                     if(PC.cclass==base_class) {
00188                         strcpy(PC.error, "@"CLASS_NAME" equals @"BASE_NAME);
00189                         YYERROR;
00190                     }
00191                     PC.cclass->get_class()->set_base(base_class);
00192                 } else { // they asked to derive from a class without methods ['env' & co]
00193                     strcpy(PC.error, base_name.cstr());
00194                     strcat(PC.error, ": you can not derive from this class in @"BASE_NAME);
00195                     YYERROR;
00196                 }
00197             } else {
00198                 strcpy(PC.error, base_name.cstr());
00199                 strcat(PC.error, ": undefined class in @"BASE_NAME);
00200                 YYERROR;
00201             }
00202         } else {
00203             strcpy(PC.error, "@"BASE_NAME" must contain sole name");
00204             YYERROR;
00205         }
00206     } else {
00207         strcpy(PC.error, "'");
00208         strncat(PC.error, command.cstr(), MAX_STRING/2);
00209         strcat(PC.error, "' invalid special name. valid names are "
00210             "'"CLASS_NAME"', '"USE_CONTROL_METHOD_NAME"' and '"BASE_NAME"'");
00211         YYERROR;
00212     }
00213 };
00214 maybe_control_strings: empty | control_strings;
00215 control_strings: control_string | control_strings control_string { $$=$1; P(*$$, *$2) };
00216 control_string: maybe_string '\n';
00217 maybe_string: empty | STRING;
00218
00219 code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' {
00220     PC.explicit_result=false;
00221     const String& name=*LA2S(*$2);
00222
00223     YYSTYPE params_names_code=$3;
00224     ArrayString* params_names=0;
00225     if(int size=params_names_code->count()) {
00226         params_names=new ArrayString;
00227         for(int i=0; i<size; i+=OPERATIONS_PER_OPVALUE)
00228             *params_names+=LA2S(*params_names_code, i);
00229     }
00230
00231     YYSTYPE locals_names_code=$4;
00232     ArrayString* locals_names=0;
00233     if(int size=locals_names_code->count()) {
00234         locals_names=new ArrayString;
00235         for(int i=0; i<size; i+=OPERATIONS_PER_OPVALUE) {
00236             const String* local_name=LA2S(*locals_names_code, i);
00237             if(*local_name==RESULT_VAR_NAME)
00238                 PC.explicit_result=true;
00239             else
00240                 *locals_names+=local_name;
00241         }
00242     }
00243
00244     Method* method=new Method(
00245         //name,
00246         Method::CT_ANY,
00247         0, 0/*min,max numbered_params_count*/,
00248         params_names, locals_names,
00249         0/*to be filled later in next {} */, 0);
00250     PC.cclass->add_method(PC.alias_method(name), *method);
00251     *reinterpret_cast<Method**>(&$$)=method;
00252
00253     // todo: check [][;result;]
00254 } maybe_codes {
00255     // fill in the code
00256     reinterpret_cast<Method*>($7)->parser_code=$8;
00257 };
00258
00259 maybe_bracketed_strings: empty | bracketed_maybe_strings;
00260 bracketed_maybe_strings: '[' maybe_strings ']' {$$=$2};
00261 maybe_strings: empty | strings;
00262 strings: STRING | strings ';' STRING { $$=$1; P(*$$, *$3) };
00263
00264 maybe_comment: empty | STRING;
00265
00266 /* codes */
00267
00268 maybe_codes: empty | codes;
00269
00270 codes: code | codes code { $$=$1; P(*$$, *$2) };
00271 code: write_string | action;
00272 action: get | put | call;
00273
00274 /* get */
00275
00276 get: get_value {
00277     $$=$1; /* stack: resulting value */
00278     changetail_or_append(*$$,
00279         OP_GET_ELEMENT, false,  /*->*/OP_GET_ELEMENT__WRITE,
00280         /*or */OP_WRITE_VALUE
00281         ); /* value=pop; wcontext.write(value) */
00282 };
00283 get_value: '$' get_name_value { $$=$2 };
00284 get_name_value: name_without_curly_rdive EON | name_in_curly_rdive;
00285 name_in_curly_rdive: '{' name_without_curly_rdive '}' { $$=$2 };
00286 name_without_curly_rdive:
00287     name_without_curly_rdive_read
00288 |   name_without_curly_rdive_class;
00289 name_without_curly_rdive_read: name_without_curly_rdive_code {
00290     $$=N();
00291     ArrayOperation* diving_code=$1;
00292     const String* first_name=LA2S(*diving_code);
00293     // self.xxx... -> xxx...
00294     // OP_VALUE+origin+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+...
00295     if(first_name && *first_name==SELF_ELEMENT_NAME) {
00296         O(*yyval, OP_WITH_SELF); /* stack: starting context */
00297         P(*yyval, *diving_code,
00298             /* skip over... */
00299             diving_code->count()>=4?4/*OP_VALUE+origin+string+OP_GET_ELEMENTx*/:3/*OP_+origin+string*/);
00300     } else {
00301         O(*yyval, OP_WITH_READ); /* stack: starting context */
00302
00303         // ^if ELEMENT -> ^if ELEMENT_OR_OPERATOR
00304         // OP_VALUE+origin+string+OP_GET_ELEMENT. -> OP_VALUE+origin+string+OP_GET_ELEMENT_OR_OPERATOR.
00305         if(PC.in_call_value && diving_code->count()==4)
00306             diving_code->put(4-1, OP_GET_ELEMENT_OR_OPERATOR);
00307         P(*$$, *diving_code);
00308     }
00309     /* diving code; stack: current context */
00310 };
00311 name_without_curly_rdive_class: class_prefix name_without_curly_rdive_code { $$=$1; P(*$$, *$2) };
00312 name_without_curly_rdive_code: name_advance2 | name_path name_advance2 { $$=$1; P(*$$, *$2) };
00313
00314 /* put */
00315
00316 put: '$' name_expr_wdive construct {
00317     $$=$2; /* stack: context,name */
00318     P(*$$, *$3); /* stack: context,name,constructor_value */
00319 };
00320 name_expr_wdive:
00321     name_expr_wdive_root
00322 |   name_expr_wdive_write
00323 |   name_expr_wdive_class;
00324 name_expr_wdive_root: name_expr_dive_code {
00325     $$=N();
00326     ArrayOperation* diving_code=$1;
00327     const String* first_name=LA2S(*diving_code);
00328     // $self.xxx... -> $xxx...
00329     // OP_VALUE+origin+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+...
00330     if(first_name && *first_name==SELF_ELEMENT_NAME) {
00331         O(*$$, OP_WITH_SELF); /* stack: starting context */
00332         P(*$$, *diving_code,
00333             /* skip over... */
00334             diving_code->count()>=4?4/*OP_VALUE+origin+string+OP_GET_ELEMENTx*/:3/*OP_+origin+string*/);
00335     } else {
00336         O(*$$, OP_WITH_ROOT); /* stack: starting context */
00337         P(*$$, *diving_code);
00338     }
00339     /* diving code; stack: current context */
00340 };
00341 name_expr_wdive_write: '.' name_expr_dive_code {
00342     $$=N();
00343     O(*$$, OP_WITH_WRITE); /* stack: starting context */
00344     P(*$$, *$2); /* diving code; stack: context,name */
00345 };
00346 name_expr_wdive_class: class_prefix name_expr_dive_code { $$=$1; P(*$$, *$2) };
00347
00348 construct:
00349     construct_square
00350 |   construct_round
00351 |   construct_curly
00352 ;
00353 construct_square: '[' {
00354     // allow $result_or_other_variable[ letters here any time ]
00355     *reinterpret_cast<bool*>(&$$)=PC.explicit_result; PC.explicit_result=false;
00356 } any_constructor_code_value {
00357     PC.explicit_result=*reinterpret_cast<bool*>(&$2);
00358 } ']' {
00359     // stack: context, name
00360     $$=$3; // stack: context, name, value
00361     O(*$$, OP_CONSTRUCT_VALUE); /* value=pop; name=pop; context=pop; construct(context,name,value) */
00362 }
00363 ;
00364 construct_round: '(' expr_value ')' {
00365     $$=N();
00366     O(*$$, OP_PREPARE_TO_EXPRESSION);
00367     // stack: context, name
00368     P(*$$, *$2); // stack: context, name, value
00369     O(*$$, OP_CONSTRUCT_EXPR); /* value=pop->as_expr_result; name=pop; context=pop; construct(context,name,value) */
00370 }
00371 ;
00372 construct_curly: '{' maybe_codes '}' {
00373     // stack: context, name
00374     $$=N();
00375     OA(*$$, OP_CURLY_CODE__CONSTRUCT, $2); /* code=pop; name=pop; context=pop; construct(context,name,junction(code)) */
00376 };
00377
00378 any_constructor_code_value:
00379     void_value /* optimized $var[] case */
00380 |   STRING /* optimized $var[STRING] case */
00381 |   constructor_code_value /* $var[something complex] */
00382 ;
00383 constructor_code_value: constructor_code {
00384     $$=N();
00385     OA(*$$, OP_OBJECT_POOL, $1); /* stack: empty write context */
00386     /* some code that writes to that context */
00387     /* context=pop; stack: context.value() */
00388 };
00389 constructor_code: codes__excluding_sole_str_literal;
00390 codes__excluding_sole_str_literal: action | code codes { $$=$1; P(*$$, *$2) };
00391
00392 /* call */
00393
00394 call: call_value {
00395     $$=$1; /* stack: value */
00396     changetail_or_append(*$$,
00397         OP_CALL, true,  /*->*/ OP_CALL__WRITE,
00398         /*or */OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */
00399 };
00400 call_value: '^' {
00401                     PC.in_call_value=true;
00402             }
00403             call_name {
00404                 PC.in_call_value=false;
00405             }
00406             store_params EON { /* ^field.$method{vasya} */
00407     $$=$3; /* with_xxx,diving code; stack: context,method_junction */
00408
00409     YYSTYPE params_code=$5;
00410     if(params_code->count()==4) { // probably [] case. [OP_VALUE+origin+Void+STORE_PARAM]
00411         if(Value* value=LA2V(*params_code)) // it is OP_VALUE+origin+value?
00412             if(value->is_void()) // value is VVoid?
00413                 params_code=0; // ^zzz[] case. don't append lone empty param.
00414     }
00415     /* stack: context, method_junction */
00416     OA(*$$, OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value
00417 };
00418
00419 call_name: name_without_curly_rdive;
00420
00421 store_params: store_param | store_params store_param { $$=$1; P(*$$, *$2) };
00422 store_param:
00423     store_square_param
00424 |   store_round_param
00425 |   store_curly_param
00426 ;
00427 store_square_param: '[' {
00428     // allow ^call[ letters here any time ]
00429     *reinterpret_cast<bool*>(&$$)=PC.explicit_result; PC.explicit_result=false;
00430 } store_code_param_parts {
00431     PC.explicit_result=*reinterpret_cast<bool*>(&$2);
00432 } ']' {$$=$3};
00433 store_round_param: '(' store_expr_param_parts ')' {$$=$2};
00434 store_curly_param: '{' store_curly_param_parts '}' {$$=$2};
00435 store_code_param_parts:
00436     store_code_param_part
00437 |   store_code_param_parts ';' store_code_param_part { $$=$1; P(*$$, *$3) }
00438 ;
00439 store_expr_param_parts:
00440     store_expr_param_part
00441 |   store_expr_param_parts ';' store_expr_param_part { $$=$1; P(*$$, *$3) }
00442 ;
00443 store_curly_param_parts:
00444     store_curly_param_part
00445 |   store_curly_param_parts ';' store_curly_param_part { $$=$1; P(*$$, *$3) }
00446 ;
00447 store_code_param_part: code_param_value {
00448     $$=$1;
00449     O(*$$, OP_STORE_PARAM);
00450 };
00451 store_expr_param_part: expr_value {
00452     YYSTYPE expr_code=$1;
00453     if(expr_code->count()==3
00454         && (*expr_code)[0].code==OP_VALUE) { // optimizing (double/bool/incidently 'string' too) case. [OP_VALUE+origin+Double]
00455         $$=expr_code;
00456         O(*$$, OP_STORE_PARAM); // no evaluating
00457     } else {
00458         ArrayOperation* code=N();
00459         O(*code, OP_PREPARE_TO_EXPRESSION);
00460         P(*code, *expr_code);
00461         O(*code, OP_WRITE_EXPR_RESULT);
00462         $$=N();
00463         OA(*$$, OP_EXPR_CODE__STORE_PARAM, code);
00464     }
00465 };
00466 store_curly_param_part: maybe_codes {
00467     $$=N();
00468     OA(*$$, OP_CURLY_CODE__STORE_PARAM, $1);
00469 };
00470 code_param_value:
00471     void_value /* optimized [;...] case */
00472 |   STRING /* optimized [STRING] case */
00473 |   constructor_code_value /* [something complex] */
00474 ;
00475
00476 /* name */
00477
00478 name_expr_dive_code: name_expr_value | name_path name_expr_value { $$=$1; P(*$$, *$2) };
00479
00480 name_path: name_step | name_path name_step { $$=$1; P(*$$, *$2) };
00481 name_step: name_advance1 '.';
00482 name_advance1: name_expr_value {
00483     // we know that name_advance1 not called from ^xxx context
00484     // so we'll not check for operator call possibility as we do in name_advance2
00485
00486     /* stack: context */
00487     $$=$1; /* stack: context,name */
00488     O(*$$, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */
00489 };
00490 name_advance2: name_expr_value {
00491     /* stack: context */
00492     $$=$1; /* stack: context,name */
00493     O(*$$, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */
00494 }
00495 |   STRING BOGUS
00496 ;
00497 name_expr_value:
00498     STRING /* subname_is_const */
00499 |   name_expr_subvar_value /* $subname_is_var_value */
00500 |   name_expr_with_subvar_value /* xxx$part_of_subname_is_var_value */
00501 |   name_square_code_value /* [codes] */
00502 ;
00503 name_expr_subvar_value: '$' subvar_ref_name_rdive {
00504     $$=$2;
00505     O(*$$, OP_GET_ELEMENT);
00506 };
00507 name_expr_with_subvar_value: STRING subvar_get_writes {
00508     ArrayOperation* code;
00509     {
00510         change_string_literal_to_write_string_literal(*(code=$1));
00511         P(*code, *$2);
00512     }
00513     $$=N();
00514     OA(*$$, OP_STRING_POOL, code);
00515 };
00516 name_square_code_value: '[' {
00517     // allow $result_or_other_variable[ letters here any time ]
00518     *reinterpret_cast<bool*>(&$$)=PC.explicit_result; PC.explicit_result=false;
00519 } codes {
00520     PC.explicit_result=*reinterpret_cast<bool*>(&$2);
00521 } ']' {
00522     $$=N();
00523     OA(*$$, OP_OBJECT_POOL, $3); /* stack: empty write context */
00524     /* some code that writes to that context */
00525     /* context=pop; stack: context.value() */
00526 };
00527 subvar_ref_name_rdive: STRING {
00528     $$=N();
00529     O(*$$, OP_WITH_READ);
00530     P(*$$, *$1);
00531 };
00532 subvar_get_writes: subvar__get_write | subvar_get_writes subvar__get_write { $$=$1; P(*$$, *$2) };
00533 subvar__get_write: '$' subvar_ref_name_rdive {
00534     $$=$2;
00535     O(*$$, OP_GET_ELEMENT__WRITE);
00536 };
00537
00538 class_prefix:
00539     class_static_prefix
00540 |   class_constructor_prefix
00541 ;
00542 class_static_prefix: STRING ':' {
00543     $$=$1; // stack: class name string
00544     if(*LA2S(*$$) == BASE_NAME) { // pseudo BASE class
00545         if(VStateless_class* base=PC.cclass->base_class()) {
00546             change_string_literal_value(*$$, base->name());
00547         } else {
00548             strcpy(PC.error, "no base class declared");
00549             YYERROR;
00550         }
00551     }
00552     O(*$$, OP_GET_CLASS);
00553 };
00554 class_constructor_prefix: class_static_prefix ':' {
00555     $$=$1;
00556     if(!PC.in_call_value) {
00557         strcpy(PC.error, ":: not allowed here");
00558         YYERROR;
00559     }
00560     O(*$$, OP_PREPARE_TO_CONSTRUCT_OBJECT);
00561 };
00562
00563
00564 /* expr */
00565
00566 expr_value: expr;
00567 expr:
00568     double_or_STRING
00569 |   true_value
00570 |   false_value
00571 |   get_value
00572 |   call_value
00573 |   '"' string_inside_quotes_value '"' { $$ = $2 }
00574 |   '\'' string_inside_quotes_value '\'' { $$ = $2 }
00575 |   '(' expr ')' { $$ = $2; }
00576 /* stack: operand // stack: @operand */
00577 |   '-' expr %prec NUNARY { $$=$2;  O(*$$, OP_NEG) }
00578 |   '+' expr %prec NUNARY { $$=$2 }
00579 |   '~' expr { $$=$2;    O(*$$, OP_INV) }
00580 |   '!' expr { $$=$2;  O(*$$, OP_NOT) }
00581 |   "def" expr { $$=$2;  O(*$$, OP_DEF) }
00582 |   "in" expr { $$=$2;  O(*$$, OP_IN) }
00583 |   "-f" expr { $$=$2;  O(*$$, OP_FEXISTS) }
00584 |   "-d" expr { $$=$2;  O(*$$, OP_DEXISTS) }
00585 /* stack: a,b // stack: a@b */
00586 |   expr '-' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_SUB) }
00587 |   expr '+' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_ADD) }
00588 |   expr '*' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_MUL) }
00589 |   expr '/' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_DIV) }
00590 |   expr '%' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_MOD) }
00591 |   expr '\\' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_INTDIV) }
00592 |   expr "<<" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_BIN_SL) }
00593 |   expr ">>" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_BIN_SR) }
00594 |   expr '&' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_BIN_AND) }
00595 |   expr '|' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_BIN_OR) }
00596 |   expr "!|" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_BIN_XOR) }
00597 |   expr "&&" expr { $$=$1;  OA(*$$, OP_NESTED_CODE, $3);  O(*$$, OP_LOG_AND) }
00598 |   expr "||" expr { $$=$1;  OA(*$$, OP_NESTED_CODE, $3);  O(*$$, OP_LOG_OR) }
00599 |   expr "!||" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_LOG_XOR) }
00600 |   expr '<' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_NUM_LT) }
00601 |   expr '>' expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_NUM_GT) }
00602 |   expr "<=" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_NUM_LE) }
00603 |   expr ">=" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_NUM_GE) }
00604 |   expr "==" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_NUM_EQ) }
00605 |   expr "!=" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_NUM_NE) }
00606 |   expr "lt" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_STR_LT) }
00607 |   expr "gt" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_STR_GT) }
00608 |   expr "le" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_STR_LE) }
00609 |   expr "ge" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_STR_GE) }
00610 |   expr "eq" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_STR_EQ) }
00611 |   expr "ne" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_STR_NE) }
00612 |   expr "is" expr { $$=$1;  P(*$$, *$3);  O(*$$, OP_IS) }
00613 ;
00614
00615 double_or_STRING: STRING {
00616     // optimized from OP_STRING->OP_VALUE for doubles
00617     maybe_change_string_literal_to_double_literal(*($$=$1));
00618 };
00619
00620 string_inside_quotes_value: maybe_codes {
00621     $$=N();
00622     OA(*$$, OP_STRING_POOL, $1); /* stack: empty write context */
00623     /* some code that writes to that context */
00624     /* context=pop; stack: context.get_string() */
00625 };
00626
00627 /* basics */
00628
00629 write_string: STRING {
00630     // optimized from OP_STRING+OP_WRITE_VALUE to OP_STRING__WRITE
00631     change_string_literal_to_write_string_literal(*($$=$1))
00632 };
00633
00634 void_value: /* empty */ { $$=VL(/*we know that we will not change it*/const_cast<VVoid*>(&vvoid), 0, 0, 0) }
00635 true_value: "true" { $$ = VL(/*we know that we will not change it*/const_cast<VBool*>(&vtrue), 0, 0, 0) }
00636 false_value: "false" { $$ = VL(/*we know that we will not change it*/const_cast<VBool*>(&vfalse), 0, 0, 0) }
00637
00638 empty: /* empty */ { $$=N() };
00639
00640 %%
00641 #endif
00642
00643 /*
00644         000$111(2222)00
00645         000$111{3333}00
00646         $,^: push,=0
00647         1:( { break=pop
00648         2:( )  pop
00649         3:{ }  pop
00650
00651         000^111(2222)4444{33333}4000
00652         $,^: push,=0
00653         1:( { break=pop
00654         2:( )=4
00655         3:{ }=4
00656         4:[^({]=pop
00657 */
00658
00659 inline void ungetc(Parse_control& pc, uint last_line_end_col) {
00660     pc.source--;
00661     if(pc.pos.col==0) {
00662         --pc.pos.line; pc.pos.col=last_line_end_col;
00663     } else
00664         --pc.pos.col;
00665
00666 }
00667 static int yylex(YYSTYPE *lvalp, void *apc) {
00668     register Parse_control& pc=*static_cast<Parse_control*>(apc);
00669
00670     #define lexical_brackets_nestage pc.brackets_nestages[pc.ls_sp]
00671     #define RC {result=c; goto break2; }
00672
00673     register int c;
00674     int result;
00675
00676     if(pc.pending_state) {
00677         result=pc.pending_state;
00678         pc.pending_state=0;
00679         return result;
00680     }
00681
00682     const char *begin=pc.source;
00683     Pos begin_pos=pc.pos;
00684     const char *end;
00685     int skip_analized=0;
00686     while(true) {
00687         c=*(end=(pc.source++));
00688 //      fprintf(stderr, "\nchar: %c %02X; nestage: %d, sp=%d", c, c, lexical_brackets_nestage, pc.sp);
00689
00690         if(c=='\n')
00691             pc.pos_next_line();
00692         else
00693             pc.pos_next_c(c);
00694 //      fprintf(stderr, "\nchar: %c file(%d:%d)", c, pc.pos.line, pc.pos.col);
00695
00696         if(pc.pos.col==0+1 && c=='@') {
00697             if(pc.ls==LS_DEF_SPECIAL_BODY) {
00698                 // @SPECIAL
00699                 // ...
00700                 // @<here =
00701                 pop_LS(pc); // exiting from LS_DEF_SPECIAL_BODY state
00702             } // continuing checks
00703             if(pc.ls==LS_USER) {
00704                 push_LS(pc, LS_DEF_NAME);
00705                 RC;
00706             } else // @ in first column inside some code [when could that be?]
00707                 result=BAD_METHOD_DECL_START;
00708             goto break2;
00709         }
00710         if(c=='^') {
00711             if(pc.ls==LS_METHOD_AFTER) {
00712                 // handle after-method situation
00713                 pop_LS(pc);
00714                 result=EON;
00715                 skip_analized=-1; // return to punctuation afterwards to assure it's literality
00716                 goto break2;
00717             }
00718             switch(pc.ls) {
00719 case LS_EXPRESSION_VAR_NAME_WITH_COLON:
00720 case LS_EXPRESSION_VAR_NAME_WITHOUT_COLON:
00721 case LS_VAR_NAME_SIMPLE_WITH_COLON:
00722 case LS_VAR_NAME_SIMPLE_WITHOUT_COLON:
00723 case LS_VAR_NAME_CURLY:
00724 case LS_METHOD_NAME:
00725 case LS_USER_COMMENT:
00726 case LS_DEF_COMMENT:
00727     // no literals in names, please
00728     break;
00729 default:
00730             switch(*pc.source) {
00731             // ^escaping some punctuators
00732             case '^': case '$': case ';':
00733             case '(': case ')':
00734             case '[': case ']':
00735             case '{': case '}':
00736             case '"':  case ':':
00737                 if(end!=begin) {
00738                     if(!pc.string_start)
00739                         pc.string_start=begin_pos;
00740                     // append piece till ^
00741                     pc.string.append_strdup_know_length(begin, end-begin);
00742                 }
00743                 // reset piece 'begin' position & line
00744                 begin=pc.source; // ->punctuation
00745                 begin_pos=pc.pos;
00746                 // skip over _ after ^
00747                 pc.source++;  pc.pos.col++;
00748                 // skip analysis = forced literal
00749                 continue;
00750
00751             // converting ^#HH into char(hex(HH))
00752             case '#':
00753                 if(end!=begin) {
00754                     if(!pc.string_start)
00755                         pc.string_start=begin_pos;
00756                     // append piece till ^
00757                     pc.string.append_strdup_know_length(begin, end-begin);
00758                 }
00759                 // #HH ?
00760                 if(pc.source[0]=='#' && pc.source[1] && pc.source[2]) {
00761                     char c=(char)(
00762                         hex_value[(unsigned char)pc.source[1]]*0x10+
00763                         hex_value[(unsigned char)pc.source[2]]);
00764                     if(c==0) {
00765                         result=BAD_HEX_LITERAL;
00766                         goto break2; // wrong hex value[no ^#00 chars allowed]: bail out
00767                     }
00768                     // append char(hex(HH))
00769                     pc.string.append(c);
00770                     // skip over ^#HH
00771                     pc.source+=3;
00772                     pc.pos.col+=3;
00773                     // reset piece 'begin' position & line
00774                     begin=pc.source; // ->after ^#HH
00775                     begin_pos=pc.pos;
00776                     // skip analysis = forced literal
00777                     continue;
00778                 }
00779                 break;
00780             }
00781             break;
00782             }
00783         }
00784         // #comment  start skipping
00785         if(c=='#' && pc.pos.col==1) {
00786             if(end!=begin) {
00787                 if(!pc.string_start)
00788                     pc.string_start=begin_pos;
00789                 // append piece till #
00790                 pc.string.append_strdup_know_length(begin, end-begin);
00791             }
00792             // fall into COMMENT lexical state [wait for \n]
00793             push_LS(pc, LS_USER_COMMENT);
00794             continue;
00795         }
00796         switch(pc.ls) {
00797
00798         // USER'S = NOT OURS
00799         case LS_USER:
00800         case LS_NAME_SQUARE_PART: // name.[here].xxx
00801             if(pc.trim_bof)
00802                 switch(c) {
00803                 case '\n': case ' ': case '\t':
00804                     begin=pc.source;
00805                     begin_pos=pc.pos;
00806                     continue; // skip it
00807                 default:
00808                     pc.trim_bof=false;
00809                 }
00810             switch(c) {
00811             case '$':
00812                 push_LS(pc, LS_VAR_NAME_SIMPLE_WITH_COLON);
00813                 RC;
00814             case '^':
00815                 push_LS(pc, LS_METHOD_NAME);
00816                 RC;
00817             case ']':
00818                 if(pc.ls==LS_NAME_SQUARE_PART)
00819                     if(--lexical_brackets_nestage==0) {// $name.[co<]?>de<]?>
00820                         pop_LS(pc); // $name.[co<]>de<]!>
00821                         RC;
00822                     }
00823                 break;
00824             case '[': // $name.[co<[>de]
00825                 if(pc.ls==LS_NAME_SQUARE_PART)
00826                     lexical_brackets_nestage++;
00827                 break;
00828             }
00829             if(pc.explicit_result && c)
00830                 switch(c) {
00831                 case '\n': case ' ': case '\t':
00832                     begin=pc.source;
00833                     begin_pos=pc.pos;
00834                     continue; // skip it
00835                 default:
00836                     result=BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE;
00837                     goto break2;
00838                 }
00839             break;
00840
00841         // #COMMENT
00842         case LS_USER_COMMENT:
00843             if(c=='\n') {
00844                 // skip comment
00845                 begin=pc.source;
00846                 begin_pos=pc.pos;
00847
00848                 pop_LS(pc);
00849                 continue;
00850             }
00851             break;
00852
00853         // STRING IN EXPRESSION
00854         case LS_EXPRESSION_STRING_QUOTED:
00855         case LS_EXPRESSION_STRING_APOSTROFED:
00856             switch(c) {
00857             case '"':
00858             case '\'':
00859                 if(
00860                     pc.ls == LS_EXPRESSION_STRING_QUOTED && c=='"' ||
00861                     pc.ls == LS_EXPRESSION_STRING_APOSTROFED && c=='\'') {
00862                     pop_LS(pc); //"abc". | 'abc'.
00863                     RC;
00864                 }
00865                 break;
00866             case '$':
00867                 push_LS(pc, LS_VAR_NAME_SIMPLE_WITH_COLON);
00868                 RC;
00869             case '^':
00870                 push_LS(pc, LS_METHOD_NAME);
00871                 RC;
00872             }
00873             break;
00874
00875         // METHOD DEFINITION
00876         case LS_DEF_NAME:
00877             switch(c) {
00878             case '[':
00879                 pc.ls=LS_DEF_PARAMS;
00880                 RC;
00881             case '\n':
00882                 pc.ls=LS_DEF_SPECIAL_BODY;
00883                 RC;
00884             }
00885             break;
00886
00887         case LS_DEF_PARAMS:
00888             switch(c) {
00889             case '$': // common error
00890                 result=BAD_METHOD_PARAMETER_NAME_CHARACTER;
00891                 goto break2;
00892             case ';':
00893                 RC;
00894             case ']':
00895                 pc.ls=*pc.source=='['?LS_DEF_LOCALS:LS_DEF_COMMENT;
00896                 RC;
00897             case '\n': // wrong. bailing out
00898                 pop_LS(pc);
00899                 RC;
00900             }
00901             break;
00902
00903         case LS_DEF_LOCALS:
00904             switch(c) {
00905             case '[':
00906             case ';':
00907                 RC;
00908             case ']':
00909                 pc.ls=LS_DEF_COMMENT;
00910                 RC;
00911             case '\n': // wrong. bailing out
00912                 pop_LS(pc);
00913                 RC;
00914             }
00915             break;
00916
00917         case LS_DEF_COMMENT:
00918             if(c=='\n') {
00919                 pop_LS(pc);
00920                 RC;
00921             }
00922             break;
00923
00924         case LS_DEF_SPECIAL_BODY:
00925             if(c=='\n')
00926                 RC;
00927             break;
00928
00929         // (EXPRESSION)
00930         case LS_VAR_ROUND:
00931         case LS_METHOD_ROUND:
00932             switch(c) {
00933             case ')':
00934                 if(--lexical_brackets_nestage==0)
00935                     if(pc.ls==LS_METHOD_ROUND) // method round param ended
00936                         pc.ls=LS_METHOD_AFTER; // look for method end
00937                     else // pc.ls==LS_VAR_ROUND // variable constructor ended
00938                         pop_LS(pc); // return to normal life
00939                 RC;
00940             case '#': // comment start skipping
00941                 if(end!=begin) {
00942                     if(!pc.string_start)
00943                         pc.string_start=begin_pos;
00944                     // append piece till #
00945                     pc.string.append_strdup_know_length(begin, end-begin);
00946                 }
00947                 // fall into COMMENT lexical state [wait for \n]
00948                 push_LS(pc, LS_EXPRESSION_COMMENT);
00949                 lexical_brackets_nestage=1;
00950                 continue;
00951             case '$':
00952                 push_LS(pc, LS_EXPRESSION_VAR_NAME_WITH_COLON);
00953                 RC;
00954             case '^':
00955                 push_LS(pc, LS_METHOD_NAME);
00956                 RC;
00957             case '(':
00958                 lexical_brackets_nestage++;
00959                 RC;
00960             case '-':
00961                 switch(*pc.source) {
00962                 case 'f': // -f
00963                     skip_analized=1;
00964                     result=FEXISTS;
00965                     goto break2;
00966                 case 'd': // -d
00967                     skip_analized=1;
00968                     result=DEXISTS;
00969                     goto break2;
00970                 default: // minus
00971                     result=c;
00972                     goto break2;
00973                 }
00974                 goto break2;
00975             case '+': case '*': case '/': case '%': case '\\':
00976             case '~':
00977             case ';':
00978                 RC;
00979             case '&': case '|':
00980                 if(*pc.source==c) { // && ||
00981                     result=c=='&'?LAND:LOR;
00982                     skip_analized=1;
00983                 } else
00984                     result=c;
00985                 goto break2;
00986             case '!':
00987                 switch(pc.source[0]) {
00988                 case '|': // !| !||
00989                     skip_analized=1;
00990                     if(pc.source[1]=='|') {
00991                         skip_analized++;
00992                         result=LXOR;
00993                     } else
00994                         result=NXOR;
00995                     goto break2;
00996                 case '=': // !=
00997                     skip_analized=1;
00998                     result=NNE;
00999                     goto break2;
01000                 }
01001                 RC;
01002
01003             case '<': // <<, <=, <
01004                 switch(*pc.source) {
01005                 case '<': // <[<]
01006                     skip_analized=1; result=NSL; break;
01007                 case '=': // <[=]
01008                     skip_analized=1; result=NLE; break;
01009                 default: // <[]
01010                     result=c; break;
01011                 }
01012                 goto break2;
01013             case '>': // >>, >=, >
01014                 switch(*pc.source) {
01015                 case '>': // >[>]
01016                     skip_analized=1; result=NSR; break;
01017                 case '=': // >[=]
01018                     skip_analized=1; result=NGE; break;
01019                 default: // >[]
01020                     result=c; break;
01021                 }
01022                 goto break2;
01023             case '=': // ==
01024                 switch(*pc.source) {
01025                 case '=': // =[=]
01026                     skip_analized=1; result=NEQ; break;
01027                 default: // =[]
01028                     result=c; break; // not used now
01029                 }
01030                 goto break2;
01031
01032             case '"':
01033                 push_LS(pc, LS_EXPRESSION_STRING_QUOTED);
01034                 RC;
01035             case '\'':
01036                 push_LS(pc, LS_EXPRESSION_STRING_APOSTROFED);
01037                 RC;
01038             case 'l': case 'g': case 'e': case 'n':
01039                 if(end==begin) // right after whitespace
01040                     if(isspace(pc.source[1])) {
01041                         switch(*pc.source) {
01042                             //                  case '?': // ok [and bad cases, yacc would bark at them]
01043                         case 't': // lt gt [et nt]
01044                             result=c=='l'?SLT:c=='g'?SGT:BAD_STRING_COMPARISON_OPERATOR;
01045                             skip_analized=1;
01046                             goto break2;
01047                         case 'e': // le ge ne [ee]
01048                             result=c=='l'?SLE:c=='g'?SGE:c=='n'?SNE:BAD_STRING_COMPARISON_OPERATOR;
01049                             skip_analized=1;
01050                             goto break2;
01051                         case 'q': // eq [lq gq nq]
01052                             result=c=='e'?SEQ:BAD_STRING_COMPARISON_OPERATOR;
01053                             skip_analized=1;
01054                             goto break2;
01055                         }
01056                     }
01057                 break;
01058             case 'i':
01059                 if(end==begin) // right after whitespace
01060                     if(isspace(pc.source[1])) {
01061                         switch(pc.source[0]) {
01062                         case 'n': // in
01063                             skip_analized=1;
01064                             result=IN;
01065                             goto break2;
01066                         case 's': // is
01067                             skip_analized=1;
01068                             result=IS;
01069                             goto break2;
01070                         }
01071                     }
01072                 break;
01073             case 'd':
01074                 if(end==begin) // right after whitespace
01075                     if(pc.source[0]=='e' && pc.source[1]=='f') { // def
01076                         skip_analized=2;
01077                         result=DEF;
01078                         goto break2;
01079                     }
01080                 break;
01081             case 't':
01082                 if(end==begin) // right after whitespace
01083                     if(pc.source[0]=='r' && pc.source[1]=='u' && pc.source[2]=='e') { // def
01084                         skip_analized=3;
01085                         result=LITERAL_TRUE;
01086                         goto break2;
01087                     }
01088                 break;
01089             case 'f':
01090                 if(end==begin) // right after whitespace
01091                     if(pc.source[0]=='a' && pc.source[1]=='l' && pc.source[2]=='s' && pc.source[3]=='e') { // def
01092                         skip_analized=4;
01093                         result=LITERAL_FALSE;
01094                         goto break2;
01095                     }
01096                 break;
01097             case ' ': case '\t': case '\n':
01098                 if(end!=begin) { // there were a string after previous operator?
01099                     result=0; // return that string
01100                     goto break2;
01101                 }
01102                 // that's a leading|traling space or after-operator-space
01103                 // ignoring it
01104                 // reset piece 'begin' position & line
01105                 begin=pc.source; // after whitespace char
01106                 begin_pos=pc.pos;
01107                 continue;
01108             }
01109             break;
01110         case LS_EXPRESSION_COMMENT:
01111             if(c=='(')
01112                 lexical_brackets_nestage++;
01113
01114             switch(*pc.source) {
01115             case '\n': case ')':
01116                 if(*pc.source==')')
01117                     if(--lexical_brackets_nestage!=0)
01118                         continue;
01119
01120                 // skip comment
01121                 begin=pc.source;
01122                 begin_pos=pc.pos;
01123
01124                 pop_LS(pc);
01125                 continue;
01126             }
01127             break;
01128
01129         // VARIABLE GET/PUT/WITH
01130         case LS_VAR_NAME_SIMPLE_WITH_COLON:
01131         case LS_VAR_NAME_SIMPLE_WITHOUT_COLON:
01132         case LS_EXPRESSION_VAR_NAME_WITH_COLON:
01133         case LS_EXPRESSION_VAR_NAME_WITHOUT_COLON:
01134             if(
01135                 pc.ls==LS_EXPRESSION_VAR_NAME_WITH_COLON ||
01136                 pc.ls==LS_EXPRESSION_VAR_NAME_WITHOUT_COLON) {
01137                 // name in expr ends also before
01138                 switch(c) {
01139                 // expression minus
01140                 case '-':
01141                 // expression integer division
01142                 case '\\':
01143                     pop_LS(pc);
01144                     pc.ungetc();
01145                     result=EON;
01146                     goto break2;
01147                 }
01148             }
01149             if(
01150                 pc.ls==LS_VAR_NAME_SIMPLE_WITHOUT_COLON ||
01151                 pc.ls==LS_EXPRESSION_VAR_NAME_WITHOUT_COLON) {
01152                 // name already has ':', stop before next
01153                 switch(c) {
01154                 case ':':
01155                     pop_LS(pc);
01156                     pc.ungetc();
01157                     result=EON;
01158                     goto break2;
01159                 }
01160             }
01161             switch(c) {
01162             case 0:
01163             case ' ': case '\t': case '\n':
01164             case ';':
01165             case ']': case '}': case ')':
01166             case '"': case '\'':
01167             case '<': case '>':  // these stand for HTML brackets AND expression binary ops
01168             case '+': case '*': case '/': case '%':
01169             case '&': case '|':
01170             case '=': case '!':
01171             // common delimiters
01172             case ',': case '?': case '#':
01173             // before call
01174             case '^':
01175                 pop_LS(pc);
01176                 pc.ungetc();
01177                 result=EON;
01178                 goto break2;
01179             case '[':
01180                 // $name.<[>code]
01181                 if(pc.pos.col>1/*not first column*/ && (
01182                     end[-1]=='$'/*was start of get*/ ||
01183                     end[-1]==':'/*was class name delim */ ||
01184                     end[-1]=='.'/*was name delim */
01185                     )) {
01186                     push_LS(pc, LS_NAME_SQUARE_PART);
01187                     lexical_brackets_nestage=1;
01188                     RC;
01189                 }
01190                 pc.ls=LS_VAR_SQUARE;
01191                 lexical_brackets_nestage=1;
01192                 RC;
01193             case '{':
01194                 if(begin==end) { // ${name}, no need of EON, switching LS
01195                     pc.ls=LS_VAR_NAME_CURLY;
01196                 } else {
01197                     pc.ls=LS_VAR_CURLY;
01198                     lexical_brackets_nestage=1;
01199                 }
01200
01201                 RC;
01202             case '(':
01203                 pc.ls=LS_VAR_ROUND;
01204                 lexical_brackets_nestage=1;
01205                 RC;
01206             case '.': // name part delim
01207             case '$': // name part subvar
01208             case ':': // class<:>name
01209                 // go to _WITHOUT_COLON state variant...
01210                 if(pc.ls==LS_VAR_NAME_SIMPLE_WITH_COLON)
01211                     pc.ls=LS_VAR_NAME_SIMPLE_WITHOUT_COLON;
01212                 else if(pc.ls==LS_EXPRESSION_VAR_NAME_WITH_COLON)
01213                     pc.ls=LS_EXPRESSION_VAR_NAME_WITHOUT_COLON;
01214                 // ...stop before next ':'
01215                 RC;
01216             }
01217             break;
01218
01219         case LS_VAR_NAME_CURLY:
01220             switch(c) {
01221             case '[':
01222                 // ${name.<[>code]}
01223                 push_LS(pc, LS_NAME_SQUARE_PART);
01224                 lexical_brackets_nestage=1;
01225                 RC;
01226             case '}': // ${name} finished, restoring LS
01227                 pop_LS(pc);
01228                 RC;
01229             case '.': // name part delim
01230             case '$': // name part subvar
01231             case ':': // ':name' or 'class:name'
01232                 RC;
01233             }
01234             break;
01235
01236         case LS_VAR_SQUARE:
01237             switch(c) {
01238             case '$':
01239                 push_LS(pc, LS_VAR_NAME_SIMPLE_WITH_COLON);
01240                 RC;
01241             case '^':
01242                 push_LS(pc, LS_METHOD_NAME);
01243                 RC;
01244             case ']':
01245                 if(--lexical_brackets_nestage==0) {
01246                     pop_LS(pc);
01247                     RC;
01248                 }
01249                 break;
01250             case ';': // operator_or_fmt;value delim
01251                 RC;
01252             case '[':
01253                 lexical_brackets_nestage++;
01254                 break;
01255             }
01256             break;
01257
01258         case LS_VAR_CURLY:
01259             switch(c) {
01260             case '$':
01261                 push_LS(pc, LS_VAR_NAME_SIMPLE_WITH_COLON);
01262                 RC;
01263             case '^':
01264                 push_LS(pc, LS_METHOD_NAME);
01265                 RC;
01266             case '}':
01267                 if(--lexical_brackets_nestage==0) {
01268                     pop_LS(pc);
01269                     RC;
01270                 }
01271                 break;
01272             case '{':
01273                 lexical_brackets_nestage++;
01274                 break;
01275             }
01276             break;
01277
01278         // METHOD CALL
01279         case LS_METHOD_NAME:
01280             switch(c) {
01281             case '[':
01282                 // ^name.<[>code].xxx
01283                 if(pc.pos.col>1/*not first column*/ && (
01284                     end[-1]=='^'/*was start of call*/ || // never, ^[ is literal...
01285                     end[-1]==':'/*was class name delim */ ||
01286                     end[-1]=='.'/*was name delim */
01287                     )) {
01288                     push_LS(pc, LS_NAME_SQUARE_PART);
01289                     lexical_brackets_nestage=1;
01290                     RC;
01291                 }
01292                 pc.ls=LS_METHOD_SQUARE;
01293                 lexical_brackets_nestage=1;
01294                 RC;
01295             case '{':
01296                 pc.ls=LS_METHOD_CURLY;
01297                 lexical_brackets_nestage=1;
01298                 RC;
01299             case '(':
01300                 pc.ls=LS_METHOD_ROUND;
01301                 lexical_brackets_nestage=1;
01302                 RC;
01303             case '.': // name part delim
01304             case '$': // name part subvar
01305             case ':': // ':name' or 'class:name'
01306             case '^': // ^abc^xxx wrong. bailing out
01307             case ']': case '}': case ')': // ^abc]}) wrong. bailing out
01308             case ' ': // ^if ( wrong. bailing out
01309                 RC;
01310             }
01311             break;
01312
01313         case LS_METHOD_SQUARE:
01314             switch(c) {
01315             case '$':
01316                 push_LS(pc, LS_VAR_NAME_SIMPLE_WITH_COLON);
01317                 RC;
01318             case '^':
01319                 push_LS(pc, LS_METHOD_NAME);
01320                 RC;
01321             case ';': // param delim
01322                 RC;
01323             case ']':
01324                 if(--lexical_brackets_nestage==0) {
01325                     pc.ls=LS_METHOD_AFTER;
01326                     RC;
01327                 }
01328                 break;
01329             case '[':
01330                 lexical_brackets_nestage++;
01331                 break;
01332             }
01333             break;
01334
01335         case LS_METHOD_CURLY:
01336             switch(c) {
01337             case '$':
01338                 push_LS(pc, LS_VAR_NAME_SIMPLE_WITH_COLON);
01339                 RC;
01340             case '^':
01341                 push_LS(pc, LS_METHOD_NAME);
01342                 RC;
01343             case ';': // param delim
01344                 RC;
01345             case '}':
01346                 if(--lexical_brackets_nestage==0) {
01347                     pc.ls=LS_METHOD_AFTER;
01348                     RC;
01349                 }
01350                 break;
01351             case '{':
01352                 lexical_brackets_nestage++;
01353                 break;
01354             }
01355             if(pc.explicit_result && c)
01356                 switch(c) {
01357                 case '\n': case ' ': case '\t':
01358                     begin=pc.source;
01359                     begin_pos=pc.pos;
01360                     continue; // skip it
01361                 default:
01362                     result=BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE;
01363                     goto break2;
01364                 }
01365             break;
01366
01367         case LS_METHOD_AFTER:
01368             if(c=='[') {/* ][ }[ )[ */
01369                 pc.ls=LS_METHOD_SQUARE;
01370                 lexical_brackets_nestage=1;
01371                 RC;
01372             }
01373             if(c=='{') {/* ]{ }{ ){ */
01374                 pc.ls=LS_METHOD_CURLY;
01375                 lexical_brackets_nestage=1;
01376                 RC;
01377             }
01378             if(c=='(') {/* ]( }( )( */
01379                 pc.ls=LS_METHOD_ROUND;
01380                 lexical_brackets_nestage=1;
01381                 RC;
01382             }
01383             pop_LS(pc);
01384             pc.ungetc();
01385             result=EON;
01386             goto break2;
01387         }
01388         if(c==0) {
01389             result=-1;
01390             break;
01391         }
01392     }
01393
01394 break2:
01395     if(end!=begin) { // there is last piece?
01396         if((c=='@' || c==0) && end[-1]=='\n') { // we are before LS_DEF_NAME or EOF?
01397             // strip last \n
01398             end--;
01399             if(end!=begin && end[-1]=='\n') // allow one empty line before LS_DEF_NAME
01400                 end--;
01401         }
01402         if(end!=begin && pc.ls!=LS_USER_COMMENT) { // last piece still alive and not comment?
01403             if(!pc.string_start)
01404                 pc.string_start=begin_pos;
01405             // append it
01406             pc.string.append_strdup_know_length(begin, end-begin);
01407         }
01408     }
01409     if(!pc.string.is_empty()) { // something accumulated?
01410         // create STRING value: array of OP_VALUE+origin+vstring
01411         *lvalp=VL(
01412             new VString(*new String(pc.string, String::L_CLEAN)),
01413             pc.file_no, pc.string_start.line, pc.string_start.col);
01414         // new pieces storage
01415         pc.string.clear();
01416         pc.string_start.clear();
01417         // make current result be pending for next call, return STRING for now
01418         pc.pending_state=result;  result=STRING;
01419     }
01420     if(skip_analized) {
01421         pc.source+=skip_analized;  pc.pos.col+=skip_analized;
01422     }
01423     return result;
01424 }
01425
01426 static int real_yyerror(Parse_control *pc, char *s) {  // Called by yyparse on error
01427        strncpy(PC.error, s, MAX_STRING);
01428        return 1;
01429 }
01430
01431 static void yyprint(FILE *file, int type, YYSTYPE value) {
01432     if(type==STRING)
01433         fprintf(file, " \"%s\"", LA2S(*value)->cstr());
01434 }


compile_tools.C File Reference

Parser: compiler support helper functions. More...

Include dependency graph for compile_tools.C:

Include dependency graph

Go to the source code of this file.

Functions

Value * | LA2V (ArrayOperation &literal_string_array, int offset)
Literal Array to(2) Value
Returns:
Value from literal Array OP+origin+Value.
 More...

void | maybe_change_string_literal_to_double_literal (ArrayOperation &literal_array)
void | change_string_literal_value (ArrayOperation &literal_string_array, const String &new_value)
void | changetail_or_append (ArrayOperation &opcodes, OPCODE find, bool with_argument, OPCODE replace, OPCODE notfound)
void | push_LS (Parse_control &pc, lexical_state new_state)
void | pop_LS (Parse_control &pc)

Variables

const char *const | IDENT_COMPILE_TOOLS_C = "$Date: 2005/08/09 08:14:51 $"

Detailed Description

Parser: compiler support helper functions.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file compile_tools.C.

Function Documentation

Value* LA2V | ( | ArrayOperation & | literal_string_array,
 |  | int | offset
 | ) |

Literal Array to(2) Value

Returns:
Value from literal Array OP+origin+Value.

Definition at line 17 of file compile_tools.C.

References offset, and OP_VALUE.

Referenced by LA2S().

void maybe_change_string_literal_to_double_literal ( ArrayOperation & literal_array )

Definition at line 22 of file compile_tools.C.

References VString::as_expr_result(), assert, String::first_char(), OP_VALUE, Array< Operation >::put(), and VString::string().

void change_string_literal_value | ( | ArrayOperation & | literal_string_array,
 |  | const String & | new_value
 | ) |

Definition at line 29 of file compile_tools.C.

References assert, and OP_VALUE.

void changetail_or_append | ( | ArrayOperation & | opcodes,
 |  | OPCODE | find,
 |  | bool | with_argument,
 |  | OPCODE | replace,
 |  | OPCODE | notfound
 | ) |

Definition at line 34 of file compile_tools.C.

References Operation::code, Array< Operation >::count(), Array< Operation >::get_ref(), and OPCODE.

void push_LS | ( | Parse_control & | pc,
 |  | lexical_state | new_state
 | ) |

Definition at line 49 of file compile_tools.C.

References lexical_state, Parse_control::ls, Parse_control::ls_sp, and Parse_control::ls_stack.

void pop_LS ( Parse_control & pc )

Definition at line 57 of file compile_tools.C.

References Parse_control::ls, Parse_control::ls_sp, and Parse_control::ls_stack.

Variable Documentation

const char* const IDENT_COMPILE_TOOLS_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 8 of file compile_tools.C.


compile_tools.C Source File

compile_tools.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_COMPILE_TOOLS_C="$Date: 2005/08/09 08:14:51 $";
00009
00010 #include "compile_tools.h"
00011 #include "pa_string.h"
00012 #include "pa_array.h"
00013 #include "pa_exception.h"
00014 #include "pa_vstring.h"
00015 #include "pa_vdouble.h"
00016
00017 Value* LA2V(ArrayOperation& literal_string_array, int offset) {
00018     return literal_string_array[offset+0].code==OP_VALUE?literal_string_array[offset+2/*skip opcode&origin*/].value
00019         :0;
00020 }
00021
00022 void maybe_change_string_literal_to_double_literal(ArrayOperation& literal_array) {
00023     assert(literal_array[0].code==OP_VALUE);
00024     VString& vstring=*static_cast<VString*>(literal_array[2/*opcode+origin*/].value);
00025     if(isdigit(vstring.string().first_char()))
00026         literal_array.put(2/*opcode+origin*/, &vstring.as_expr_result());
00027 }
00028
00029 void change_string_literal_value(ArrayOperation& literal_string_array, const String& new_value) {
00030     assert(literal_string_array[0].code==OP_VALUE);
00031     static_cast<VString*>(literal_string_array[2/*opcode+origin*/].value)->set_string(new_value);
00032 }
00033
00034 void changetail_or_append(ArrayOperation& opcodes,
00035                           OPCODE find, bool with_argument, OPCODE replace, OPCODE notfound) {
00036     int tail=opcodes.count()-(with_argument?2:1);
00037     if(tail>=0) {
00038         Operation& op=opcodes.get_ref(tail);
00039         if(op.code==find) {
00040             op.code=replace;
00041             return;
00042         }
00043     }
00044
00045     opcodes+=Operation(notfound);
00046 }
00047
00048
00049 void push_LS(Parse_control& pc, lexical_state new_state) {
00050     if(pc.ls_sp<MAX_LEXICAL_STATES) {
00051         pc.ls_stack[pc.ls_sp++]=pc.ls;
00052         pc.ls=new_state;
00053     } else
00054         throw Exception(0, 0,
00055             "push_LS: ls_stack overflow");
00056 }
00057 void pop_LS(Parse_control& pc) {
00058     if(--pc.ls_sp>=0)
00059         pc.ls=pc.ls_stack[pc.ls_sp];
00060     else
00061         throw Exception(0, 0,
00062             "pop_LS: ls_stack underflow");
00063 }
00064
00065 const String& Parse_control::alias_method(const String& name) {
00066     return (main_alias && name==main_method_name)?*main_alias:name;
00067 }


compile_tools.h File Reference

Parser: compiler support helper functions decls. More...

Include dependency graph for compile_tools.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | Pos
class | Parse_control
compiler status. More...

state; initially

#define | MAX_LEXICAL_STATES 100
#define | MAX_LEXICAL_STATES 100

Defines

#define | TAB_SIZE 8
used to track source column number. More...

#define | TAB_SIZE 8
used to track source column number. More...

Enumerations

enum lexical_state {
LS_USER, LS_NAME_SQUARE_PART, LS_USER_COMMENT, LS_DEF_NAME,
LS_DEF_PARAMS, LS_DEF_LOCALS, LS_DEF_COMMENT, LS_DEF_SPECIAL_BODY,
LS_EXPRESSION_STRING_QUOTED, LS_EXPRESSION_STRING_APOSTROFED, LS_EXPRESSION_VAR_NAME_WITH_COLON, LS_EXPRESSION_VAR_NAME_WITHOUT_COLON,
LS_EXPRESSION_COMMENT, LS_VAR_NAME_SIMPLE_WITH_COLON, LS_VAR_NAME_SIMPLE_WITHOUT_COLON, LS_VAR_NAME_CURLY,
LS_VAR_ROUND, LS_VAR_SQUARE, LS_VAR_CURLY, LS_METHOD_NAME,
LS_METHOD_SQUARE, LS_METHOD_CURLY, LS_METHOD_ROUND, LS_METHOD_AFTER
}

Functions

ArrayOperation * N ()
New array // return empty array. More...

void | O (ArrayOperation &result, OPCODE code)
Assembler instruction // append ordinary instruction to ops. More...

void | P (ArrayOperation &result, ArrayOperation &code_array)
aPpend 'code_array' to 'result'. More...

void | P (ArrayOperation &result, ArrayOperation &code_array, int offset)
aPpend part of 'code_array', starting from offset, to 'result'. More...

void | OA (ArrayOperation &result, OPCODE code, ArrayOperation *code_array)
append cOde Array. More...

ArrayOperation * | VL (Value *value, uint file_no, uint line, uint col)
Value Literal // returns array with - first op: OP_VALUE instruction - second op: origin (debug information) - third op: string itself. More...

Value * | LA2V (ArrayOperation &literal_string_array, int offset=0)
Literal Array to(2) Value
Returns:
Value from literal Array OP+origin+Value.
 More...

const String * | LA2S (ArrayOperation &literal_string_array, int offset=0)
Literal Array to(2) String
Returns:
String value from literal Array OP+origin+String array.
 More...

void | change_string_literal_to_write_string_literal (ArrayOperation &literal_string_array)
void | maybe_change_string_literal_to_double_literal (ArrayOperation &literal_string_array)
void | change_string_literal_value (ArrayOperation &literal_string_array, const String &new_value)
void | changetail_or_append (ArrayOperation &opcodes, OPCODE find, bool with_argument, OPCODE replace, OPCODE notfound)
void | push_LS (Parse_control &pc, lexical_state new_state)
void | pop_LS (Parse_control &pc)

Variables

const char *const | IDENT_COMPILE_TOOLS_H = "$Date: 2005/12/09 07:18:07 $"

Detailed Description

Parser: compiler support helper functions decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file compile_tools.h.

Define Documentation

#define TAB_SIZE 8

used to track source column number.

Definition at line 19 of file compile_tools.h.

Referenced by Parse_control::pos_next_c().

#define MAX_LEXICAL_STATES 100

Definition at line 76 of file compile_tools.h.

#define TAB_SIZE 8

used to track source column number.

Definition at line 19 of file compile_tools.h.

#define MAX_LEXICAL_STATES 100

Definition at line 76 of file compile_tools.h.

Enumeration Type Documentation

enum lexical_state

Enumeration values:
LS_USER
LS_NAME_SQUARE_PART
LS_USER_COMMENT
LS_DEF_NAME
LS_DEF_PARAMS
LS_DEF_LOCALS
LS_DEF_COMMENT
LS_DEF_SPECIAL_BODY
LS_EXPRESSION_STRING_QUOTED
LS_EXPRESSION_STRING_APOSTROFED
LS_EXPRESSION_VAR_NAME_WITH_COLON
LS_EXPRESSION_VAR_NAME_WITHOUT_COLON
LS_EXPRESSION_COMMENT
LS_VAR_NAME_SIMPLE_WITH_COLON
LS_VAR_NAME_SIMPLE_WITHOUT_COLON
LS_VAR_NAME_CURLY
LS_VAR_ROUND
LS_VAR_SQUARE
LS_VAR_CURLY
LS_METHOD_NAME
LS_METHOD_SQUARE
LS_METHOD_CURLY
LS_METHOD_ROUND
LS_METHOD_AFTER

Definition at line 21 of file compile_tools.h.

Referenced by push_LS().

Function Documentation

ArrayOperation* N ( ) [inline]

New array // return empty array.

Definition at line 138 of file compile_tools.h.

Referenced by VL().

void O | ( | ArrayOperation & | result,
 |  | OPCODE | code
 | ) | [inline]

Assembler instruction // append ordinary instruction to ops.

Definition at line 143 of file compile_tools.h.

References OPCODE, and result.

void P | ( | ArrayOperation & | result,
 |  | ArrayOperation & | code_array
 | ) | [inline]

aPpend 'code_array' to 'result'.

Definition at line 148 of file compile_tools.h.

References Array< Operation >::append(), and result.

void P | ( | ArrayOperation & | result,
 |  | ArrayOperation & | code_array,
 |  | int | offset
 | ) | [inline]

aPpend part of 'code_array', starting from offset, to 'result'.

Definition at line 152 of file compile_tools.h.

References Array< Operation >::append(), offset, and result.

void OA | ( | ArrayOperation & | result,
 |  | OPCODE | code,
 |  | ArrayOperation * | code_array
 | ) | [inline]

append cOde Array.

Definition at line 157 of file compile_tools.h.

References OPCODE, and result.

ArrayOperation* VL | ( | Value * | value,
 |  | uint | file_no,
 |  | uint | line,
 |  | uint | col
 | ) | [inline]

Value Literal // returns array with - first op: OP_VALUE instruction - second op: origin (debug information) - third op: string itself.

Definition at line 168 of file compile_tools.h.

References N(), OP_VALUE, result, uint, and value.

Value* LA2V | ( | ArrayOperation & | literal_string_array,
 |  | int | offset = 0
 | ) |

Literal Array to(2) Value

Returns:
Value from literal Array OP+origin+Value.

Definition at line 17 of file compile_tools.C.

References offset, and OP_VALUE.

Referenced by LA2S().

const String* LA2S | ( | ArrayOperation & | literal_string_array,
 |  | int | offset = 0
 | ) | [inline]

Literal Array to(2) String

Returns:
String value from literal Array OP+origin+String array.

Definition at line 183 of file compile_tools.h.

References Value::get_string(), LA2V(), offset, and value.

void change_string_literal_to_write_string_literal ( ArrayOperation & literal_string_array ) [inline]

Definition at line 189 of file compile_tools.h.

References OP_STRING__WRITE, and Array< Operation >::put().

void maybe_change_string_literal_to_double_literal ( ArrayOperation & literal_string_array )

Definition at line 22 of file compile_tools.C.

References VString::as_expr_result(), assert, String::first_char(), OP_VALUE, Array< Operation >::put(), and VString::string().

void change_string_literal_value | ( | ArrayOperation & | literal_string_array,
 |  | const String & | new_value
 | ) |

Definition at line 29 of file compile_tools.C.

References assert, and OP_VALUE.

void changetail_or_append | ( | ArrayOperation & | opcodes,
 |  | OPCODE | find,
 |  | bool | with_argument,
 |  | OPCODE | replace,
 |  | OPCODE | notfound
 | ) |

Definition at line 34 of file compile_tools.C.

References Operation::code, Array< Operation >::count(), Array< Operation >::get_ref(), and OPCODE.

void push_LS | ( | Parse_control & | pc,
 |  | lexical_state | new_state
 | ) |

Definition at line 49 of file compile_tools.C.

References lexical_state, Parse_control::ls, Parse_control::ls_sp, and Parse_control::ls_stack.

void pop_LS ( Parse_control & pc )

Definition at line 57 of file compile_tools.C.

References Parse_control::ls, Parse_control::ls_sp, and Parse_control::ls_stack.

Variable Documentation

const char* const IDENT_COMPILE_TOOLS_H = "$Date: 2005/12/09 07:18:07 $" [static]

Definition at line 11 of file compile_tools.h.


compile_tools.h Source File

compile_tools.h

Go to the documentation of this file.
00001
00008 #ifndef COMPILE_TOOLS
00009 #define COMPILE_TOOLS
00010
00011 static const char * const IDENT_COMPILE_TOOLS_H="$Date: 2005/12/09 07:18:07 $";
00012
00013 #include "pa_opcode.h"
00014 #include "pa_types.h"
00015 #include "pa_vstring.h"
00016 #include "pa_request.h"
00017
00019 #define TAB_SIZE 8
00020
00021 enum lexical_state {
00022     LS_USER, LS_NAME_SQUARE_PART,
00023     LS_USER_COMMENT,
00024     LS_DEF_NAME,
00025     LS_DEF_PARAMS,
00026     LS_DEF_LOCALS,
00027     LS_DEF_COMMENT,
00028     LS_DEF_SPECIAL_BODY,
00029     LS_EXPRESSION_STRING_QUOTED,
00030     LS_EXPRESSION_STRING_APOSTROFED,
00031     LS_EXPRESSION_VAR_NAME_WITH_COLON, LS_EXPRESSION_VAR_NAME_WITHOUT_COLON,
00032     LS_EXPRESSION_COMMENT,
00033     LS_VAR_NAME_SIMPLE_WITH_COLON, LS_VAR_NAME_SIMPLE_WITHOUT_COLON,
00034     LS_VAR_NAME_CURLY,
00035     LS_VAR_ROUND,
00036     LS_VAR_SQUARE,
00037     LS_VAR_CURLY,
00038     LS_METHOD_NAME,
00039     LS_METHOD_SQUARE,
00040     LS_METHOD_CURLY,
00041     LS_METHOD_ROUND,
00042     LS_METHOD_AFTER
00043 };
00044
00045 struct Pos {
00046     int line;
00047     int col;
00048     Pos(int aline, int acol): line(aline), col(acol) {}
00049     Pos(): line(0), col(0) {}
00050
00051     void clear() { line=col=0; }
00052     operator bool() { return col!=0; }
00053 };
00054
00056 class Parse_control {
00057     const String* main_alias;
00058     uint last_line_end_col;
00059 public:
00060     const String& alias_method(const String& name);
00062
00063     Request& request;
00064     VStateless_class* cclass;
00065     const char* source;
00066     uint file_no;
00067     Pos pos;
00069
00070
00071     bool trim_bof;
00072     int pending_state;
00073     String::Body string;
00074     Pos string_start;
00075
00076 #define MAX_LEXICAL_STATES 100
00077     enum lexical_state ls;
00078     int ls_sp;
00079     enum lexical_state ls_stack[MAX_LEXICAL_STATES];
00080     int brackets_nestages[MAX_LEXICAL_STATES];
00081
00082     bool in_call_value;
00083     bool explicit_result;
00085
00087     char error[MAX_STRING];
00088
00089     Parse_control(Request& arequest,
00090         VStateless_class* aclass,
00091         const char* asource, const String* amain_alias,
00092         uint afile_no,
00093         int line_no_offset):
00094         main_alias(amain_alias),
00095         last_line_end_col(0),
00096
00097         request(arequest), // input
00098
00099         // we were told the class to compile to?
00100         cclass(aclass), // until changed with @CLASS would consider operators loading
00101         source(asource),
00102         file_no(afile_no),
00103         pos(line_no_offset, 0),
00104
00105         // initialize state
00106         trim_bof(true),
00107         pending_state(0),
00108         ls(LS_USER),
00109         ls_sp(0),
00110         in_call_value(false),
00111         explicit_result(false) {}
00112
00113     void pos_next_line() {
00114         pos.line++;
00115         last_line_end_col=pos.col;
00116         pos.col=0;
00117     }
00118     void pos_next_c(int c) {
00119         if(c=='\t')
00120             pos.col=(pos.col+TAB_SIZE)&~(TAB_SIZE-1);
00121         else
00122             pos.col++;
00123     }
00125     void pos_prev_c() {
00126         if(pos.col==0) {
00127             --pos.line;  pos.col=last_line_end_col;
00128         } else
00129             --pos.col;
00130     }
00131     void ungetc() {
00132         source--;
00133         pos_prev_c();
00134     }
00135 };
00136
00138 inline ArrayOperation* N() {
00139     return new ArrayOperation;
00140 }
00141
00143 inline void O(ArrayOperation& result, OPCODE code) {
00144     result+=Operation(code);
00145 }
00146
00148 inline void P(ArrayOperation& result, ArrayOperation& code_array) {
00149     result.append(code_array);
00150 }
00152 inline void P(ArrayOperation& result, ArrayOperation& code_array, int offset) {
00153     result.append(code_array, offset);
00154 }
00155
00157 inline void OA(ArrayOperation& result, OPCODE code, ArrayOperation* code_array) {
00158     result+=Operation(code); // append OP_CODE
00159     result+=Operation(code_array); // append 'code_array'
00160 }
00161
00168 inline ArrayOperation* VL(Value* value, uint file_no, uint line, uint col) {
00169     // empty ops array
00170     ArrayOperation& result=*N();
00171
00172     // append 'value' to 'result'
00173     result+=Operation(OP_VALUE);
00174     result+=Operation(file_no, line, col); // append origin
00175     result+=Operation(value); // append 'value'
00176
00177     return &result;
00178 }
00179
00181 Value* LA2V(ArrayOperation& literal_string_array, int offset=0);
00183 inline const String* LA2S(ArrayOperation& literal_string_array, int offset=0) {
00184     if(Value* value=LA2V(literal_string_array, offset))
00185         return value->get_string();
00186     return 0;
00187 }
00188
00189 inline void change_string_literal_to_write_string_literal(ArrayOperation& literal_string_array) {
00190     literal_string_array.put(0, OP_STRING__WRITE);
00191 }
00192
00193
00194 void maybe_change_string_literal_to_double_literal(ArrayOperation& literal_string_array);
00195
00196 void change_string_literal_value(ArrayOperation& literal_string_array, const String& new_value);
00197
00198 void changetail_or_append(ArrayOperation& opcodes,
00199                           OPCODE find, bool with_argument, OPCODE replace, OPCODE notfound);
00200
00201
00202 void push_LS(Parse_control& pc, lexical_state new_state);
00203 void pop_LS(Parse_control& pc);
00204
00205 #endif


compiler.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


config.h File Reference

Include dependency graph for config.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.


config.h Source File

config.h

Go to the documentation of this file.
00001 #if HAVE_CONFIG_H
00002 #   include "config_auto.h"
00003 #else
00004 #   include "config_fixed.h"
00005 #endif


config_fixed.h File Reference

Include dependency graph for config_fixed.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | dirent

Defines

#define | HAVE_CTYPE_H 1
#define | HAVE_ERRNO_H 1
#define | HAVE_MEMCPY 1
#define | HAVE_MEMMOVE 1
#define | HAVE_MEMORY_H 1
#define | HAVE_STDIO_H 1
#define | HAVE_STDLIB_H 1
#define | HAVE_STRCHR 1
#define | HAVE_STRCMP 1
#define | HAVE_STRINGS_H 1
#define | HAVE_STRING_H 1
#define | HAVE_STRRCHR 1
#define | HAVE_SYS_STAT_H 1
#define | HAVE_SYS_TYPES_H 1
#define | LTDL_OBJDIR ".libs/"
#define | LTDL_SHLIB_EXT ".dll"
#define | __STDC__ 1
#define | error_t int
#define | inline __inline
#define | R_OK 4
#define | access(name, flags) _access(name, flags)
#define | LT_D_NAMLEN(dirent) (0)
#define | opendir(name) 0
#define | readdir(dir) 0
#define | closedir(dir) 0

Typedefs

typedef void | DIR

Define Documentation

#define HAVE_CTYPE_H 1

Definition at line 5 of file config_fixed.h.

#define HAVE_ERRNO_H 1

Definition at line 6 of file config_fixed.h.

#define HAVE_MEMCPY 1

Definition at line 7 of file config_fixed.h.

#define HAVE_MEMMOVE 1

Definition at line 8 of file config_fixed.h.

#define HAVE_MEMORY_H 1

Definition at line 9 of file config_fixed.h.

#define HAVE_STDIO_H 1

Definition at line 11 of file config_fixed.h.

#define HAVE_STDLIB_H 1

Definition at line 12 of file config_fixed.h.

#define HAVE_STRCHR 1

Definition at line 13 of file config_fixed.h.

#define HAVE_STRCMP 1

Definition at line 14 of file config_fixed.h.

#define HAVE_STRINGS_H 1

Definition at line 15 of file config_fixed.h.

#define HAVE_STRING_H 1

Definition at line 16 of file config_fixed.h.

#define HAVE_STRRCHR 1

Definition at line 17 of file config_fixed.h.

#define HAVE_SYS_STAT_H 1

Definition at line 18 of file config_fixed.h.

#define HAVE_SYS_TYPES_H 1

Definition at line 19 of file config_fixed.h.

#define LTDL_OBJDIR ".libs/"

Definition at line 20 of file config_fixed.h.

#define LTDL_SHLIB_EXT ".dll"

Definition at line 21 of file config_fixed.h.

#define __STDC__ 1

Definition at line 26 of file config_fixed.h.

#define error_t int

Definition at line 27 of file config_fixed.h.

#define inline __inline

Definition at line 28 of file config_fixed.h.

#define R_OK 4

Definition at line 30 of file config_fixed.h.

Referenced by entry_readable().

#define access | ( | name,
 |  | flags | ) | _access(name, flags)

Definition at line 35 of file config_fixed.h.

Referenced by entry_readable(), file_executable(), and file_write_action_under_lock().

#define LT_D_NAMLEN ( dirent ) (0)

Definition at line 41 of file config_fixed.h.

#define opendir ( name ) 0

Definition at line 43 of file config_fixed.h.

#define readdir ( dir ) 0

Definition at line 44 of file config_fixed.h.

#define closedir ( dir ) 0

Definition at line 45 of file config_fixed.h.

Typedef Documentation

typedef void DIR

Definition at line 39 of file config_fixed.h.


config_fixed.h Source File

config_fixed.h

Go to the documentation of this file.
00001 /* pa_config_fixed.h. */
00002 /* Configure file for autoconf-disabled platforms  */
00003 /* tested only with MS Visual C++ V6 */
00004
00005 #define HAVE_CTYPE_H 1
00006 #define HAVE_ERRNO_H 1
00007 #define HAVE_MEMCPY 1
00008 #define HAVE_MEMMOVE 1
00009 #define HAVE_MEMORY_H 1
00010 #  include <memory.h>
00011 #define HAVE_STDIO_H 1
00012 #define HAVE_STDLIB_H 1
00013 #define HAVE_STRCHR 1
00014 #define HAVE_STRCMP 1
00015 #define HAVE_STRINGS_H 1
00016 #define HAVE_STRING_H 1
00017 #define HAVE_STRRCHR 1
00018 #define HAVE_SYS_STAT_H 1
00019 #define HAVE_SYS_TYPES_H 1
00020 #define LTDL_OBJDIR ".libs/"
00021 #define LTDL_SHLIB_EXT ".dll"
00022 /*
00023     MS is shy to admit it implements stdc when compiled with lang extensions
00024     without lang extensions libltdl does not compile
00025 */
00026 #define __STDC__ 1
00027 #define error_t int
00028 #define inline __inline
00029
00030 #define R_OK 4
00031
00032 /* dirent.h replacement  */
00033 #include <windows.h>
00034 #include <io.h>
00035 #define access(name, flags) _access(name, flags)
00036 struct dirent {
00037         char *d_name;
00038 };
00039 typedef void DIR;
00040
00041 #define LT_D_NAMLEN(dirent) (0)
00042
00043 #define opendir(name) 0
00044 #define readdir(dir) 0
00045 #define closedir(dir) 0


cord.h File Reference

Include dependency graph for cord.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | CORD_EMPTY 0
#define | CORD_IS_STRING(s) (*(s) != '\0')
#define | CORD_NO_FN ((CORD_batched_iter_fn)0)
#define | CORD_iter(x, f1, cd) CORD_iter5(x, 0, f1, CORD_NO_FN, cd)
#define | CORD_FOR(pos, cord) for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos))
#define | CORD_nul(i) CORD_chars('\0', (i))
#define | CORD_NOT_FOUND ((size_t)(-1))

Typedefs

typedef const char * | CORD
typedef char(* | CORD_fn )(size_t i, void *client_data)
typedef int(* | CORD_iter_fn )(char c, void *client_data)
typedef int(* | CORD_block_iter_fn )(char c, size_t len, void *client_data)
typedef int(* | CORD_batched_iter_fn )(const char *s, void *client_data)

Functions

CORD | CORD_cat (CORD x, CORD y)
CORD | CORD_cat_char_star (CORD x, const char *y, size_t leny)
size_t | CORD_len (CORD x)
CORD | CORD_from_fn (CORD_fn fn, void *client_data, size_t len)
CORD | CORD_from_fn_gen (CORD_fn fn, void *client_data, size_t len)
CORD | CORD_substr (CORD x, size_t i, size_t n)
CORD | CORD_balance (CORD x)
int | CORD_iter5 (CORD x, size_t i, CORD_iter_fn f1, CORD_batched_iter_fn f2, void *client_data)
int | CORD_block_iter (CORD x, size_t i, CORD_block_iter_fn f1, void *client_data)
int | CORD_iter (CORD x, CORD_iter_fn f1, void *client_data)
int | CORD_riter4 (CORD x, size_t i, CORD_iter_fn f1, void *client_data)
int | CORD_riter (CORD x, CORD_iter_fn f1, void *client_data)
void | CORD_dump (CORD x)
CORD | CORD_cat_char (CORD x, char c)
CORD | CORD_catn (int n,...)
char | CORD_fetch (CORD x, size_t i)
int | CORD_cmp (CORD x, CORD y)
int | CORD_ncmp (CORD x, size_t x_start, CORD y, size_t y_start, size_t len)
size_t | CORD_str (CORD x, size_t start, CORD s)
CORD | CORD_chars (char c, size_t i)
CORD | CORD_from_file (FILE *f)
CORD | CORD_from_file_eager (FILE *f)
CORD | CORD_from_file_lazy (FILE *f)
char * | CORD_to_char_star (CORD x)
CORD | CORD_from_char_star (const char *s)
const char * | CORD_to_const_char_star (CORD x)
int | CORD_put (CORD x, FILE *f)
size_t | CORD_chr (CORD x, size_t i, int c)
size_t | CORD_rchr (CORD x, size_t i, int c)
int | CORD_sprintf (CORD *out, CORD format,...)
int | CORD_vsprintf (CORD *out, CORD format, va_list args)
int | CORD_fprintf (FILE *f, CORD format,...)
int | CORD_vfprintf (FILE *f, CORD format, va_list args)
int | CORD_printf (CORD format,...)
int | CORD_vprintf (CORD format, va_list args)

Variables

void(* | CORD_oom_fn )(void)

Define Documentation

#define CORD_EMPTY 0

Definition at line 72 of file cord.h.

Referenced by String::Body::Body(), String::Body::clear(), CORD_add_forest(), CORD_cat(), CORD_cat_char_star(), CORD_catn(), CORD_cmp(), CORD_set_pos(), CORD_str(), String::Body::is_empty(), and String::String().

#define CORD_IS_STRING ( s ) (*(s) != '\0')

Definition at line 75 of file cord.h.

Referenced by CORD__extend_path(), CORD__next(), CORD_balance(), CORD_balance_insert(), CORD_block_iter(), CORD_cat(), CORD_cat_char_star(), CORD_cmp(), CORD_dump_inner(), CORD_iter5(), CORD_riter4(), CORD_str(), CORD_substr_checked(), and CORD_to_const_char_star().

#define CORD_NO_FN ((CORD_batched_iter_fn)0)

Definition at line 135 of file cord.h.

Referenced by CORD_iter(), and CORD_iter5().

#define CORD_iter | ( | x,
 |  | f1,
 |  | cd | ) | CORD_iter5(x, 0, f1, CORD_NO_FN, cd)

Definition at line 153 of file cord.h.

Referenced by String::Body::for_each().

#define CORD_FOR | ( | pos,
 |  | cord | ) | for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos))

Definition at line 205 of file cord.h.

#define CORD_nul ( i ) CORD_chars('\0', (i))

Definition at line 244 of file cord.h.

Referenced by CORD_cat_char(), and CORD_from_file_eager().

#define CORD_NOT_FOUND ((size_t)(-1))

Definition at line 291 of file cord.h.

Referenced by String::pos().

Typedef Documentation

typedef const char* CORD

Definition at line 69 of file cord.h.

Referenced by String::Languages::append(), String::Body::Body(), CORD__extend_path(), CORD__next(), CORD__pos_fetch(), CORD_add_forest(), CORD_balance(), CORD_balance_insert(), CORD_block_count(), CORD_block_iter(), CORD_cat(), CORD_cat_char(), CORD_cat_char_star(), CORD_catn(), CORD_chars(), CORD_chr(), CORD_cmp(), CORD_concat_forest(), CORD_dump(), CORD_dump_inner(), CORD_ec_append_cord(), CORD_fetch(), CORD_fill_buf(), CORD_fprintf(), CORD_from_char_star(), CORD_from_file_eager(), CORD_from_fn(), CORD_iter(), CORD_iter5(), CORD_len(), CORD_ncmp(), CORD_pos_to_cord(), CORD_printf(), CORD_put(), CORD_range_contains_chr_greater_then(), CORD_rchr(), CORD_riter(), CORD_riter4(), CORD_set_pos(), CORD_sprintf(), CORD_str(), CORD_substr(), CORD_substr_checked(), CORD_substr_closure(), CORD_to_char_star(), CORD_to_const_char_star(), CORD_vfprintf(), CORD_vprintf(), CORD_vsprintf(), and String::Languages::make_langs().

typedef char(* CORD_fn)(size_t i, void * client_data)

Definition at line 97 of file cord.h.

Referenced by CORD__next(), CORD_from_fn(), and CORD_substr_closure().

typedef int(* CORD_iter_fn)(char c, void * client_data)

Definition at line 126 of file cord.h.

Referenced by CORD_iter(), CORD_iter5(), CORD_riter(), CORD_riter4(), and String::Body::for_each().

typedef int(* CORD_block_iter_fn)(char c, size_t len, void* client_data)

Definition at line 129 of file cord.h.

Referenced by CORD_block_iter(), and String::Languages::for_each().

typedef int(* CORD_batched_iter_fn)(const char * s, void * client_data)

Definition at line 134 of file cord.h.

Referenced by CORD_iter5(), and String::Body::for_each().

Function Documentation

CORD CORD_cat | ( | CORD | x,
 |  | CORD | y
 | ) |

Definition at line 243 of file cordbscs.c.

References CONCAT_HDR, CORD, CORD_balance(), CORD_cat_char_star(), CORD_EMPTY, CORD_IS_STRING, DEPTH, GC_NEW, LEN, MAX_DEPTH, MAX_LEFT_LEN, OUT_OF_MEMORY, and result.

Referenced by String::Languages::append(), CORD_add_forest(), CORD_cat_char(), CORD_catn(), CORD_concat_forest(), CORD_ec_append_cord(), CORD_from_file_eager(), CORD_substr_checked(), CORD_vsprintf(), and String::Body::operator<<().

CORD CORD_cat_char_star | ( | CORD | x,
 |  | const char * | y,
 |  | size_t | leny
 | ) |

Definition at line 155 of file cordbscs.c.

References ABORT, CONCAT_HDR, CORD, CORD_balance(), CORD_EMPTY, CORD_IS_STRING, DEPTH, GC_MALLOC_ATOMIC, GC_NEW, IS_CONCATENATION, LEN, MAX_DEPTH, MAX_LEFT_LEN, OUT_OF_MEMORY, result, and SHORT_LIMIT.

Referenced by String::Body::append_know_length(), CORD_cat(), CORD_cat_char(), and CORD_ec_flush_buf().

size_t CORD_len ( CORD x )

Definition at line 321 of file cordbscs.c.

References CORD, and GEN_LEN.

Referenced by CORD_riter(), CORD_str(), CORD_substr(), CORD_to_char_star(), CORD_vsprintf(), ec_len(), String::Languages::invariant(), and String::Body::length().

CORD CORD_from_fn | ( | CORD_fn | fn,
 |  | void * | client_data,
 |  | size_t | len
 | ) |

Definition at line 285 of file cordbscs.c.

References CORD, CORD_fn, FN_HDR, GC_MALLOC_ATOMIC, GC_NEW, OUT_OF_MEMORY, result, and SHORT_LIMIT.

Referenced by CORD_chars(), and CORD_substr_closure().

CORD CORD_from_fn_gen | ( | CORD_fn | fn,
 |  | void * | client_data,
 |  | size_t | len
 | ) |

CORD CORD_substr | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | n
 | ) |

Definition at line 458 of file cordbscs.c.

References ABORT, CORD, CORD_len(), and CORD_substr_checked().

Referenced by String::Languages::append(), CORD_str(), CORD_vsprintf(), String::Languages::make_langs(), and String::Body::mid().

CORD CORD_balance ( CORD x )

Definition at line 775 of file cordbscs.c.

References CORD, CORD_balance_insert(), CORD_concat_forest(), CORD_init_forest(), CORD_init_min_len(), CORD_IS_STRING, LEN, and min_len_init.

Referenced by CORD_cat(), CORD_cat_char_star(), CORD_from_file_eager(), and CORD_vsprintf().

int CORD_iter5 | ( | CORD | x,
 |  | size_t | i,
 |  | CORD_iter_fn | f1,
 |  | CORD_batched_iter_fn | f2,
 |  | void * | client_data
 | ) |

Definition at line 475 of file cordbscs.c.

References ABORT, CORD, CORD_batched_iter_fn, CORD_IS_STRING, CORD_iter_fn, CORD_NO_FN, IS_CONCATENATION, LEFT_LEN, p, and result.

Referenced by CORD_chr(), CORD_fill_buf(), CORD_iter(), CORD_put(), String::Body::for_each(), and String::Body::hash_code().

int CORD_block_iter | ( | CORD | x,
 |  | size_t | i,
 |  | CORD_block_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 521 of file cordbscs.c.

References ABORT, CORD, CORD_apply_access_fn(), CORD_block_iter_fn, CORD_index_access_fn(), CORD_IS_STRING, CordRep::function, IS_CONCATENATION, LEFT_LEN, p, result, and substr_args::sa_cord.

Referenced by CORD_block_count(), CORD_range_contains_chr_greater_then(), and String::Languages::for_each().

int CORD_iter | ( | CORD | x,
 |  | CORD_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 579 of file cordbscs.c.

References CORD, CORD_iter5(), CORD_iter_fn, and CORD_NO_FN.

int CORD_riter4 | ( | CORD | x,
 |  | size_t | i,
 |  | CORD_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 584 of file cordbscs.c.

References ABORT, CORD, CORD_IS_STRING, CORD_iter_fn, IS_CONCATENATION, LEFT_LEN, and p.

Referenced by CORD_rchr(), and CORD_riter().

int CORD_riter | ( | CORD | x,
 |  | CORD_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 627 of file cordbscs.c.

References CORD, CORD_iter_fn, CORD_len(), and CORD_riter4().

void CORD_dump ( CORD x )

Definition at line 149 of file cordbscs.c.

References CORD, and CORD_dump_inner().

Referenced by String::Languages::dump(), and String::Body::dump().

CORD CORD_cat_char | ( | CORD | x,
 |  | char | c
 | ) |

Definition at line 59 of file cordxtra.c.

References CORD, CORD_cat(), CORD_cat_char_star(), CORD_nul, GC_MALLOC_ATOMIC, and OUT_OF_MEMORY.

Referenced by String::Body::append().

CORD CORD_catn | ( | int | n,
 |  | ... |
 | ) |

Definition at line 71 of file cordxtra.c.

References CORD, CORD_cat(), CORD_EMPTY, and result.

char CORD_fetch | ( | CORD | x,
 |  | size_t | i
 | ) |

Definition at line 255 of file cordxtra.c.

References ABORT, CORD, CORD_pos_fetch, CORD_pos_valid, and CORD_set_pos().

Referenced by String::Body::fetch().

int CORD_cmp | ( | CORD | x,
 |  | CORD | y
 | ) |

Definition at line 137 of file cordxtra.c.

References CORD, CORD_EMPTY, CORD_IS_STRING, CORD_next, CORD_pos_advance, CORD_pos_chars_left, CORD_pos_cur_char_addr, CORD_pos_fetch, CORD_pos_valid, CORD_set_pos(), and result.

Referenced by String::Body::operator!=(), String::Body::operator<(), String::Body::operator<=(), String::Body::operator==(), String::Body::operator>(), and String::Body::operator>=().

int CORD_ncmp | ( | CORD | x,
 |  | size_t | x_start,
 |  | CORD | y,
 |  | size_t | y_start,
 |  | size_t | len
 | ) |

Definition at line 180 of file cordxtra.c.

References CORD, CORD_next, CORD_pos_advance, CORD_pos_chars_left, CORD_pos_cur_char_addr, CORD_pos_fetch, CORD_pos_valid, CORD_set_pos(), and result.

Referenced by CORD_str(), and String::Body::ncmp().

size_t CORD_str | ( | CORD | x,
 |  | size_t | start,
 |  | CORD | s
 | ) |

Definition at line 358 of file cordxtra.c.

References CORD, CORD_EMPTY, CORD_IS_STRING, CORD_len(), CORD_ncmp(), CORD_next, CORD_pos_fetch, CORD_set_pos(), CORD_substr(), and CORD_to_char_star().

Referenced by String::Body::pos().

CORD CORD_chars | ( | char | c,
 |  | size_t | i
 | ) |

Definition at line 436 of file cordxtra.c.

References CORD, CORD_from_fn(), and CORD_nul_func().

Referenced by String::Languages::append(), and String::Languages::make_langs().

CORD CORD_from_file ( FILE * f )

CORD CORD_from_file_eager ( FILE * f )

Definition at line 441 of file cordxtra.c.

References CORD, CORD_balance(), CORD_cat(), CORD_ec_append, CORD_ec_flush_buf(), CORD_ec_init, CORD_ec_to_cord, CORD_nul, and CORD_ec_struct::ec_cord.

CORD CORD_from_file_lazy ( FILE * f )

char* CORD_to_char_star ( CORD x )

Definition at line 225 of file cordxtra.c.

References CORD, CORD_fill_buf(), CORD_len(), GC_MALLOC_ATOMIC, OUT_OF_MEMORY, and result.

Referenced by CORD_str(), CORD_to_const_char_star(), and String::Body::cstrm().

CORD CORD_from_char_star ( const char * s )

Definition at line 236 of file cordxtra.c.

References CORD, GC_MALLOC_ATOMIC, OUT_OF_MEMORY, and result.

const char* CORD_to_const_char_star ( CORD x )

Definition at line 248 of file cordxtra.c.

References CORD, CORD_IS_STRING, and CORD_to_char_star().

Referenced by String::Body::cstr(), String::Languages::v(), and String::Body::v().

int CORD_put | ( | CORD | x,
 |  | FILE * | f
 | ) |

Definition at line 280 of file cordxtra.c.

References CORD, CORD_batched_put_proc(), CORD_iter5(), and CORD_put_proc().

Referenced by CORD_fprintf(), CORD_printf(), CORD_vfprintf(), and CORD_vprintf().

size_t CORD_chr | ( | CORD | x,
 |  | size_t | i,
 |  | int | c
 | ) |

Definition at line 326 of file cordxtra.c.

References CORD, CORD_batched_chr_proc(), CORD_chr_proc(), CORD_iter5(), chr_data::pos, and chr_data::target.

Referenced by String::Body::pos().

size_t CORD_rchr | ( | CORD | x,
 |  | size_t | i,
 |  | int | c
 | ) |

Definition at line 339 of file cordxtra.c.

References CORD, CORD_rchr_proc(), CORD_riter4(), chr_data::pos, and chr_data::target.

int CORD_sprintf | ( | CORD * | out,
 |  | CORD | format,
 |  | ... |
 | ) |

Definition at line 342 of file cordprnt.c.

References CORD, CORD_vsprintf(), and result.

int CORD_vsprintf | ( | CORD * | out,
 |  | CORD | format,
 |  | va_list | args
 | ) |

Definition at line 162 of file cordprnt.c.

References CONV_RESULT_LEN, CONV_SPEC_LEN, CORD, CORD_balance(), CORD_BUFSZ, CORD_cat(), CORD_ec_append, CORD_ec_append_cord(), CORD_ec_flush_buf(), CORD_ec_init, CORD_ec_to_cord, CORD_len(), CORD_next, CORD_pos_fetch, CORD_pos_valid, CORD_set_pos(), CORD_substr(), CORD_ec_struct::ec_buf, CORD_ec_struct::ec_bufptr, ec_len(), extract_conv_spec(), GC_MALLOC_ATOMIC, NONE, result, str, and VARIABLE.

Referenced by CORD_fprintf(), CORD_printf(), CORD_sprintf(), CORD_vfprintf(), and CORD_vprintf().

int CORD_fprintf | ( | FILE * | f,
 |  | CORD | format,
 |  | ... |
 | ) |

Definition at line 353 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

int CORD_vfprintf | ( | FILE * | f,
 |  | CORD | format,
 |  | va_list | args
 | ) |

Definition at line 366 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

int CORD_printf | ( | CORD | format,
 |  | ... |
 | ) |

Definition at line 376 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

int CORD_vprintf | ( | CORD | format,
 |  | va_list | args
 | ) |

Definition at line 389 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

Variable Documentation

void(* CORD_oom_fn)(void)

Definition at line 211 of file cord.h.


cord.h Source File

cord.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993-1994 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to use or copy this program
00008  * for any purpose,  provided the above notices are retained on all copies.
00009  * Permission to modify the code and to distribute modified code is granted,
00010  * provided the above notices are retained, and a notice that the code was
00011  * modified is included with the above copyright notice.
00012  *
00013  * Author: Hans-J. Boehm (boehm@parc.xerox.com)
00014  */
00015 /* Boehm, October 5, 1995 4:20 pm PDT */
00016
00017 /*
00018  * Cords are immutable character strings.  A number of operations
00019  * on long cords are much more efficient than their strings.h counterpart.
00020  * In particular, concatenation takes constant time independent of the length
00021  * of the arguments.  (Cords are represented as trees, with internal
00022  * nodes representing concatenation and leaves consisting of either C
00023  * strings or a functional description of the string.)
00024  *
00025  * The following are reasonable applications of cords.  They would perform
00026  * unacceptably if C strings were used:
00027  * - A compiler that produces assembly language output by repeatedly
00028  *   concatenating instructions onto a cord representing the output file.
00029  * - A text editor that converts the input file to a cord, and then
00030  *   performs editing operations by producing a new cord representing
00031  *   the file after echa character change (and keeping the old ones in an
00032  *   edit history)
00033  *
00034  * For optimal performance, cords should be built by
00035  * concatenating short sections.
00036  * This interface is designed for maximum compatibility with C strings.
00037  * ASCII NUL characters may be embedded in cords using CORD_from_fn.
00038  * This is handled correctly, but CORD_to_char_star will produce a string
00039  * with embedded NULs when given such a cord.
00040  *
00041  * This interface is fairly big, largely for performance reasons.
00042  * The most basic constants and functions:
00043  *
00044  * CORD - the type of a cord;
00045  * CORD_EMPTY - empty cord;
00046  * CORD_len(cord) - length of a cord;
00047  * CORD_cat(cord1,cord2) - concatenation of two cords;
00048  * CORD_substr(cord, start, len) - substring (or subcord);
00049  * CORD_pos i;  CORD_FOR(i, cord) {  ... CORD_pos_fetch(i) ... } -
00050  *    examine each character in a cord.  CORD_pos_fetch(i) is the char.
00051  * CORD_fetch(int i) - Retrieve i'th character (slowly).
00052  * CORD_cmp(cord1, cord2) - compare two cords.
00053  * CORD_from_file(FILE * f) - turn a read-only file into a cord.
00054  * CORD_to_char_star(cord) - convert to C string.
00055  *   (Non-NULL C constant strings are cords.)
00056  * CORD_printf (etc.) - cord version of printf. Use %r for cords.
00057  */
00058 # ifndef CORD_H
00059
00060 # define CORD_H
00061 # include <stddef.h>
00062 # include <stdio.h>
00063 /* Cords have type const char *.  This is cheating quite a bit, and not */
00064 /* 100% portable.  But it means that nonempty character string      */
00065 /* constants may be used as cords directly, provided the string is  */
00066 /* never modified in place.  The empty cord is represented by, and  */
00067 /* can be written as, 0.                        */
00068
00069 typedef const char * CORD;
00070
00071 /* An empty cord is always represented as nil   */
00072 # define CORD_EMPTY 0
00073
00074 /* Is a nonempty cord represented as a C string? */
00075 #define CORD_IS_STRING(s) (*(s) != '\0')
00076
00077 /* Concatenate two cords.  If the arguments are C strings, they may     */
00078 /* not be subsequently altered.                     */
00079 CORD CORD_cat(CORD x, CORD y);
00080
00081 /* Concatenate a cord and a C string with known length.  Except for the */
00082 /* empty string case, this is a special case of CORD_cat.  Since the    */
00083 /* length is known, it can be faster.                   */
00084 /* The string y is shared with the resulting CORD.  Hence it should */
00085 /* not be altered by the caller.                    */
00086 /* PAF@design.ru:
00087     but there is a ~bug in case (0, "123", 2), it returns "123", and later appends after '3', not '2'.
00088     so BEWARE: NOT USE IT THAT WAY
00089     and changing 'leny' convention: now, if it's 0, then function does leny=strlen(y)
00090 */
00091 CORD CORD_cat_char_star(CORD x, const char * y, size_t leny);
00092
00093 /* Compute the length of a cord */
00094 size_t CORD_len(CORD x);
00095
00096 /* Cords may be represented by functions defining the ith character */
00097 typedef char (* CORD_fn)(size_t i, void * client_data);
00098
00099 /* Turn a functional description into a cord.   */
00100 CORD CORD_from_fn(CORD_fn fn, void * client_data, size_t len);
00101
00102 /* Turn a functional description into a cord, only conjunction&func.    */
00103 CORD CORD_from_fn_gen(CORD_fn fn, void * client_data, size_t len);
00104
00105 /* Return the substring (subcord really) of x with length at most n,    */
00106 /* starting at position i.  (The initial character has position 0.) */
00107 CORD CORD_substr(CORD x, size_t i, size_t n);
00108
00109 /* Return the argument, but rebalanced to allow more efficient      */
00110 /* character retrieval, substring operations, and comparisons.      */
00111 /* This is useful only for cords that were built using repeated     */
00112 /* concatenation.  Guarantees log time access to the result, unless */
00113 /* x was obtained through a large number of repeated substring ops  */
00114 /* or the embedded functional descriptions take longer to evaluate. */
00115 /* May reallocate significant parts of the cord.  The argument is not   */
00116 /* modified; only the result is balanced.               */
00117 CORD CORD_balance(CORD x);
00118
00119 /* The following traverse a cord by applying a function to each     */
00120 /* character.  This is occasionally appropriate, especially where   */
00121 /* speed is crucial.  But, since C doesn't have nested functions,   */
00122 /* clients of this sort of traversal are clumsy to write.  Consider */
00123 /* the functions that operate on cord positions instead.        */
00124
00125 /* Function to iteratively apply to individual characters in cord.  */
00126 typedef int (* CORD_iter_fn)(char c, void * client_data);
00127
00128 /* Function to iteratively apply to individual block in cord.   */
00129 typedef int (* CORD_block_iter_fn)(char c, size_t len, void* client_data);
00130
00131
00132 /* Function to apply to substrings of a cord.  Each substring is a  */
00133 /* a C character string, not a general cord.                */
00134 typedef int (* CORD_batched_iter_fn)(const char * s, void * client_data);
00135 # define CORD_NO_FN ((CORD_batched_iter_fn)0)
00136
00137 /* Apply f1 to each character in the cord, in ascending order,      */
00138 /* starting at position i. If                       */
00139 /* f2 is not CORD_NO_FN, then multiple calls to f1 may be replaced by   */
00140 /* a single call to f2.  The parameter f2 is provided only to allow */
00141 /* some optimization by the client.  This terminates when the right */
00142 /* end of this string is reached, or when f1 or f2 return != 0.  In the */
00143 /* latter case CORD_iter returns != 0.  Otherwise it returns 0.     */
00144 /* The specified value of i must be < CORD_len(x).          */
00145 int CORD_iter5(CORD x, size_t i, CORD_iter_fn f1,
00146            CORD_batched_iter_fn f2, void * client_data);
00147
00148 /* iterate over function block in cord */
00149 int CORD_block_iter(CORD x, size_t i, CORD_block_iter_fn f1, void * client_data);
00150
00151 /* A simpler version that starts at 0, and without f2:  */
00152 int CORD_iter(CORD x, CORD_iter_fn f1, void * client_data);
00153 # define CORD_iter(x, f1, cd) CORD_iter5(x, 0, f1, CORD_NO_FN, cd)
00154
00155 /* Similar to CORD_iter5, but end-to-beginning. No provisions for   */
00156 /* CORD_batched_iter_fn.                        */
00157 int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data);
00158
00159 /* A simpler version that starts at the end:    */
00160 int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data);
00161
00162 /* Functions that operate on cord positions.  The easy way to traverse  */
00163 /* cords.  A cord position is logically a pair consisting of a cord */
00164 /* and an index into that cord.  But it is much faster to retrieve a    */
00165 /* charcter based on a position than on an index.  Unfortunately,   */
00166 /* positions are big (order of a few 100 bytes), so allocate them with  */
00167 /* caution.                             */
00168 /* Things in cord_pos.h should be treated as opaque, except as      */
00169 /* described below.  Also note that                 */
00170 /* CORD_pos_fetch, CORD_next and CORD_prev have both macro and function */
00171 /* definitions.  The former may evaluate their argument more than once. */
00172 # include "private/cord_pos.h"
00173
00174 /*
00175     Visible definitions from above:
00176
00177     typedef <OPAQUE but fairly big> CORD_pos[1];
00178
00179     * Extract the cord from a position:
00180     CORD CORD_pos_to_cord(CORD_pos p);
00181
00182     * Extract the current index from a position:
00183     size_t CORD_pos_to_index(CORD_pos p);
00184
00185     * Fetch the character located at the given position:
00186     char CORD_pos_fetch(CORD_pos p);
00187
00188     * Initialize the position to refer to the given cord and index.
00189     * Note that this is the most expensive function on positions:
00190     void CORD_set_pos(CORD_pos p, CORD x, size_t i);
00191
00192     * Advance the position to the next character.
00193     * P must be initialized and valid.
00194     * Invalidates p if past end:
00195     void CORD_next(CORD_pos p);
00196
00197     * Move the position to the preceding character.
00198     * P must be initialized and valid.
00199     * Invalidates p if past beginning:
00200     void CORD_prev(CORD_pos p);
00201
00202     * Is the position valid, i.e. inside the cord?
00203     int CORD_pos_valid(CORD_pos p);
00204 */
00205 # define CORD_FOR(pos, cord) \
00206     for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos))
00207
00208
00209 /* An out of memory handler to call.  May be supplied by client.    */
00210 /* Must not return.                         */
00211 extern void (* CORD_oom_fn)(void);
00212
00213 /* Dump the representation of x to stdout in an implementation defined  */
00214 /* manner.  Intended for debugging only.                */
00215 void CORD_dump(CORD x);
00216
00217 /* The following could easily be implemented by the client.  They are   */
00218 /* provided in cordxtra.c for convenience.              */
00219
00220 /* Concatenate a character to the end of a cord.    */
00221 CORD CORD_cat_char(CORD x, char c);
00222 /* Concatenate n cords. */
00223 CORD CORD_catn(int n, /* CORD */ ...);
00224
00225 /* Return the character in CORD_substr(x, i, 1)     */
00226 char CORD_fetch(CORD x, size_t i);
00227
00228 /* Return < 0, 0, or > 0, depending on whether x < y, x = y, x > y  */
00229 int CORD_cmp(CORD x, CORD y);
00230
00231 /* A generalization that takes both starting positions for the      */
00232 /* comparison, and a limit on the number of characters to be compared.  */
00233 int CORD_ncmp(CORD x, size_t x_start, CORD y, size_t y_start, size_t len);
00234
00235 /* Find the first occurrence of s in x at position start or later.  */
00236 /* Return the position of the first character of s in x, or     */
00237 /* CORD_NOT_FOUND if there is none.                 */
00238 size_t CORD_str(CORD x, size_t start, CORD s);
00239
00240 /* Return a cord consisting of i copies of (possibly NUL) c.  Dangerous */
00241 /* in conjunction with CORD_to_char_star.               */
00242 /* The resulting representation takes constant space, independent of i. */
00243 CORD CORD_chars(char c, size_t i);
00244 # define CORD_nul(i) CORD_chars('\0', (i))
00245
00246 /* Turn a file into cord.  The file must be seekable.  Its contents */
00247 /* must remain constant.  The file may be accessed as an immediate  */
00248 /* result of this call and/or as a result of subsequent accesses to     */
00249 /* the cord.  Short files are likely to be immediately read, but    */
00250 /* long files are likely to be read on demand, possibly relying on  */
00251 /* stdio for buffering.                         */
00252 /* We must have exclusive access to the descriptor f, i.e. we may   */
00253 /* read it at any time, and expect the file pointer to be       */
00254 /* where we left it.  Normally this should be invoked as        */
00255 /* CORD_from_file(fopen(...))                       */
00256 /* CORD_from_file arranges to close the file descriptor when it is no   */
00257 /* longer needed (e.g. when the result becomes inaccessible).       */
00258 /* The file f must be such that ftell reflects the actual character */
00259 /* position in the file, i.e. the number of characters that can be  */
00260 /* or were read with fread.  On UNIX systems this is always true.  On   */
00261 /* MS Windows systems, f must be opened in binary mode.         */
00262 CORD CORD_from_file(FILE * f);
00263
00264 /* Equivalent to the above, except that the entire file will be read    */
00265 /* and the file pointer will be closed immediately.         */
00266 /* The binary mode restriction from above does not apply.       */
00267 CORD CORD_from_file_eager(FILE * f);
00268
00269 /* Equivalent to the above, except that the file will be read on demand.*/
00270 /* The binary mode restriction applies.                 */
00271 CORD CORD_from_file_lazy(FILE * f);
00272
00273 /* Turn a cord into a C string. The result shares no structure with */
00274 /* x, and is thus modifiable.                       */
00275 char * CORD_to_char_star(CORD x);
00276
00277 /* Turn a C string into a CORD.  The C string is copied, and so may */
00278 /* subsequently be modified.                        */
00279 CORD CORD_from_char_star(const char *s);
00280
00281 /* Identical to the above, but the result may share structure with  */
00282 /* the argument and is thus not modifiable.             */
00283 const char * CORD_to_const_char_star(CORD x);
00284
00285 /* Write a cord to a file, starting at the current position.  No    */
00286 /* trailing NULs are newlines are added.                */
00287 /* Returns EOF if a write error occurs, 1 otherwise.            */
00288 int CORD_put(CORD x, FILE * f);
00289
00290 /* "Not found" result for the following two functions.          */
00291 # define CORD_NOT_FOUND ((size_t)(-1))
00292
00293 /* A vague analog of strchr.  Returns the position (an integer, not */
00294 /* a pointer) of the first occurrence of (char) c inside x at position  */
00295 /* i or later. The value i must be < CORD_len(x).           */
00296 size_t CORD_chr(CORD x, size_t i, int c);
00297
00298 /* A vague analog of strrchr.  Returns index of the last occurrence */
00299 /* of (char) c inside x at position i or earlier. The value i       */
00300 /* must be < CORD_len(x).                       */
00301 size_t CORD_rchr(CORD x, size_t i, int c);
00302
00303
00304 /* The following are also not primitive, but are implemented in     */
00305 /* cordprnt.c.  They provide functionality similar to the ANSI C    */
00306 /* functions with corresponding names, but with the following       */
00307 /* additions and changes:                       */
00308 /* 1. A %r conversion specification specifies a CORD argument.  Field   */
00309 /*    width, precision, etc. have the same semantics as for %s.     */
00310 /*    (Note that %c,%C, and %S were already taken.)         */
00311 /* 2. The format string is represented as a CORD.               */
00312 /* 3. CORD_sprintf and CORD_vsprintf assign the result through the 1st  */  /*    argument. Unlike their ANSI C versions, there is no need to guess */
00313 /*    the correct buffer size.                      */
00314 /* 4. Most of the conversions are implement through the native      */
00315 /*    vsprintf.  Hence they are usually no faster, and          */
00316 /*    idiosyncracies of the native printf are preserved.  However,  */
00317 /*    CORD arguments to CORD_sprintf and CORD_vsprintf are NOT copied;  */
00318 /*    the result shares the original structure.  This may make them */
00319 /*    very efficient in some unusual applications.          */
00320 /*    The format string is copied.                  */
00321 /* All functions return the number of characters generated or -1 on */
00322 /* error.  This complies with the ANSI standard, but is inconsistent    */
00323 /* with some older implementations of sprintf.              */
00324
00325 /* The implementation of these is probably less portable than the rest  */
00326 /* of this package.                         */
00327
00328 #ifndef CORD_NO_IO
00329
00330 #include <stdarg.h>
00331
00332 int CORD_sprintf(CORD * out, CORD format, ...);
00333 int CORD_vsprintf(CORD * out, CORD format, va_list args);
00334 int CORD_fprintf(FILE * f, CORD format, ...);
00335 int CORD_vfprintf(FILE * f, CORD format, va_list args);
00336 int CORD_printf(CORD format, ...);
00337 int CORD_vprintf(CORD format, va_list args);
00338
00339 #endif /* CORD_NO_IO */
00340
00341 # endif /* CORD_H */


cord_pos.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | CORD_pe
struct | CORD_Pos

Defines

#define | MAX_DEPTH 48
#define | CORD_POS_INVALID (0x55555555)
#define | FUNCTION_BUF_SZ 8
#define | CORD_pos_fetch(p)
#define | CORD_next(p)
#define | CORD_prev(p)
#define | CORD_pos_to_index(p) ((p)[0].cur_pos)
#define | CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord)
#define | CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID)
#define | CORD_pos_chars_left(p) ((long)((p)[0].cur_end) - (long)((p)[0].cur_pos))
#define | CORD_pos_advance(p, n) ((p)[0].cur_pos += (n) - 1, CORD_next(p))
#define | CORD_pos_cur_char_addr(p) (p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)

Typedefs

typedef CORD_Pos | CORD_pos [1]

Functions

CORD CORD_pos_to_cord (CORD_pos p)
size_t | CORD_pos_to_index (CORD_pos p)
char | CORD_pos_fetch (CORD_pos p)
void | CORD_set_pos (CORD_pos p, CORD x, size_t i)
void | CORD_next (CORD_pos p)
void | CORD_prev (CORD_pos p)
int | CORD_pos_valid (CORD_pos p)
char | CORD__pos_fetch (CORD_pos)
void | CORD__next (CORD_pos)
void | CORD__prev (CORD_pos)

Define Documentation

#define MAX_DEPTH 48

Definition at line 21 of file cord_pos.h.

Referenced by CORD_balance_insert(), CORD_cat(), CORD_cat_char_star(), CORD_init_forest(), and CORD_init_min_len().

#define CORD_POS_INVALID (0x55555555)

Definition at line 35 of file cord_pos.h.

Referenced by CORD__extend_path(), CORD__next(), CORD__prev(), CORD_pos_valid(), and CORD_set_pos().

#define FUNCTION_BUF_SZ 8

Definition at line 50 of file cord_pos.h.

Referenced by CORD__next().

#define CORD_pos_fetch ( p )

Value:

(((p)[0].cur_end != 0)? \
        (p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \
        : CORD__pos_fetch(p))

Definition at line 85 of file cord_pos.h.

Referenced by CORD_cmp(), CORD_fetch(), CORD_ncmp(), CORD_str(), CORD_vsprintf(), ec_append(), extract_conv_spec(), and String::Body::trim().

#define CORD_next ( p )

Value:

(((p)[0].cur_pos + 1 < (p)[0].cur_end)? \
        (p)[0].cur_pos++ \
        : (CORD__next(p), 0))

Definition at line 90 of file cord_pos.h.

Referenced by CORD_cmp(), CORD_ncmp(), CORD_str(), CORD_vsprintf(), ec_append(), extract_conv_spec(), pa_CORD_pos_advance(), and String::Body::trim().

#define CORD_prev ( p )

Value:

(((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \
        (p)[0].cur_pos-- \
        : (CORD__prev(p), 0))

Definition at line 95 of file cord_pos.h.

Referenced by String::Body::trim().

#define CORD_pos_to_index ( p ) ((p)[0].cur_pos)

Definition at line 100 of file cord_pos.h.

#define CORD_pos_to_cord ( p ) ((p)[0].path[0].pe_cord)

Definition at line 102 of file cord_pos.h.

#define CORD_pos_valid ( p ) ((p)[0].path_len != CORD_POS_INVALID)

Definition at line 104 of file cord_pos.h.

Referenced by CORD_cmp(), CORD_fetch(), CORD_ncmp(), CORD_vsprintf(), and extract_conv_spec().

#define CORD_pos_chars_left ( p ) ((long)((p)[0].cur_end) - (long)((p)[0].cur_pos))

Definition at line 107 of file cord_pos.h.

Referenced by CORD_cmp(), CORD_ncmp(), and pa_CORD_pos_advance().

#define CORD_pos_advance | ( | p,
 |  | n | ) | ((p)[0].cur_pos += (n) - 1, CORD_next(p))

Definition at line 110 of file cord_pos.h.

Referenced by CORD_cmp(), CORD_ncmp(), and pa_CORD_pos_advance().

#define CORD_pos_cur_char_addr ( p ) (p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)

Definition at line 114 of file cord_pos.h.

Referenced by CORD_cmp(), and CORD_ncmp().

Typedef Documentation

typedef struct CORD_Pos CORD_pos[1]

Function Documentation

CORD CORD_pos_to_cord ( CORD_pos p )

Definition at line 965 of file cordbscs.c.

References CORD, p, CORD_Pos::path, and CORD_pe::pe_cord.

size_t CORD_pos_to_index ( CORD_pos p )

Definition at line 960 of file cordbscs.c.

References CORD_Pos::cur_pos, and p.

char CORD_pos_fetch ( CORD_pos p )

void CORD_set_pos | ( | CORD_pos | p,
 |  | CORD | x,
 |  | size_t | i
 | ) |

Definition at line 975 of file cordbscs.c.

References CORD, CORD__extend_path(), CORD_EMPTY, CORD_POS_INVALID, CORD_Pos::cur_pos, p, CORD_Pos::path, CORD_Pos::path_len, CORD_pe::pe_cord, and CORD_pe::pe_start_pos.

Referenced by CORD_cmp(), CORD_fetch(), CORD_ncmp(), CORD_str(), CORD_vsprintf(), and String::Body::set_pos().

void CORD_next ( CORD_pos p )

Definition at line 942 of file cordbscs.c.

References CORD__next(), CORD_Pos::cur_end, CORD_Pos::cur_pos, and p.

void CORD_prev ( CORD_pos p )

Definition at line 951 of file cordbscs.c.

References CORD__prev(), CORD_Pos::cur_end, CORD_Pos::cur_pos, CORD_Pos::cur_start, and p.

int CORD_pos_valid ( CORD_pos p )

Definition at line 970 of file cordbscs.c.

References CORD_POS_INVALID, p, and CORD_Pos::path_len.

char CORD__pos_fetch ( CORD_pos )

Referenced by CORD_pos_fetch().

void CORD__next ( CORD_pos )

Referenced by CORD_next().

void CORD__prev ( CORD_pos )

Referenced by CORD_prev().


cord_pos.h Source File

cord_pos.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993-1994 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to use or copy this program
00008  * for any purpose,  provided the above notices are retained on all copies.
00009  * Permission to modify the code and to distribute modified code is granted,
00010  * provided the above notices are retained, and a notice that the code was
00011  * modified is included with the above copyright notice.
00012  */
00013 /* Boehm, May 19, 1994 2:23 pm PDT */
00014 # ifndef CORD_POSITION_H
00015
00016 /* The representation of CORD_position.  This is private to the */
00017 /* implementation, but the size is known to clients.  Also  */
00018 /* the implementation of some exported macros relies on it. */
00019 /* Don't use anything defined here and not in cord.h.       */
00020
00021 # define MAX_DEPTH 48
00022     /* The maximum depth of a balanced cord + 1.        */
00023     /* We don't let cords get deeper than MAX_DEPTH.    */
00024
00025 struct CORD_pe {
00026     CORD pe_cord;
00027     size_t pe_start_pos;
00028 };
00029
00030 /* A structure describing an entry on the path from the root    */
00031 /* to current position.                     */
00032 typedef struct CORD_Pos {
00033     size_t cur_pos;
00034     int path_len;
00035 #   define CORD_POS_INVALID (0x55555555)
00036         /* path_len == INVALID <==> position invalid */
00037     const char *cur_leaf;   /* Current leaf, if it is a string. */
00038                     /* If the current leaf is a function,   */
00039                     /* then this may point to function_buf  */
00040                     /* containing the next few characters.  */
00041                     /* Always points to a valid string  */
00042                     /* containing the current character     */
00043                     /* unless cur_end is 0.         */
00044     size_t cur_start;   /* Start position of cur_leaf   */
00045     size_t cur_end; /* Ending position of cur_leaf  */
00046                 /* 0 if cur_leaf is invalid.    */
00047     struct CORD_pe path[MAX_DEPTH + 1];
00048         /* path[path_len] is the leaf corresponding to cur_pos  */
00049         /* path[0].pe_cord is the cord we point to.     */
00050 #   define FUNCTION_BUF_SZ 8
00051     char function_buf[FUNCTION_BUF_SZ]; /* Space for next few chars */
00052                         /* from function node.      */
00053 } CORD_pos[1];
00054
00055 /* Extract the cord from a position:    */
00056 CORD CORD_pos_to_cord(CORD_pos p);
00057
00058 /* Extract the current index from a position:   */
00059 size_t CORD_pos_to_index(CORD_pos p);
00060
00061 /* Fetch the character located at the given position:   */
00062 char CORD_pos_fetch(CORD_pos p);
00063
00064 /* Initialize the position to refer to the give cord and index. */
00065 /* Note that this is the most expensive function on positions:  */
00066 void CORD_set_pos(CORD_pos p, CORD x, size_t i);
00067
00068 /* Advance the position to the next character.  */
00069 /* P must be initialized and valid.     */
00070 /* Invalidates p if past end:           */
00071 void CORD_next(CORD_pos p);
00072
00073 /* Move the position to the preceding character.    */
00074 /* P must be initialized and valid.         */
00075 /* Invalidates p if past beginning:         */
00076 void CORD_prev(CORD_pos p);
00077
00078 /* Is the position valid, i.e. inside the cord?     */
00079 int CORD_pos_valid(CORD_pos p);
00080
00081 char CORD__pos_fetch(CORD_pos);
00082 void CORD__next(CORD_pos);
00083 void CORD__prev(CORD_pos);
00084
00085 #define CORD_pos_fetch(p)   \
00086     (((p)[0].cur_end != 0)? \
00087         (p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \
00088         : CORD__pos_fetch(p))
00089
00090 #define CORD_next(p)    \
00091     (((p)[0].cur_pos + 1 < (p)[0].cur_end)? \
00092         (p)[0].cur_pos++ \
00093         : (CORD__next(p), 0))
00094
00095 #define CORD_prev(p)    \
00096     (((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \
00097         (p)[0].cur_pos-- \
00098         : (CORD__prev(p), 0))
00099
00100 #define CORD_pos_to_index(p) ((p)[0].cur_pos)
00101
00102 #define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord)
00103
00104 #define CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID)
00105
00106 /* Some grubby stuff for performance-critical friends:  */
00107 #define CORD_pos_chars_left(p) ((long)((p)[0].cur_end) - (long)((p)[0].cur_pos))
00108     /* Number of characters in cache.  <= 0 ==> none    */
00109
00110 #define CORD_pos_advance(p,n) ((p)[0].cur_pos += (n) - 1, CORD_next(p))
00111     /* Advance position by n characters */
00112     /* 0 < n < CORD_pos_chars_left(p)   */
00113
00114 #define CORD_pos_cur_char_addr(p) \
00115     (p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)
00116     /* address of current character in cache.   */
00117
00118 #endif


cordbscs.c File Reference

Include dependency graph for cordbscs.c:

Include dependency graph

Go to the source code of this file.

Compounds

union | CordRep
struct | Concatenation
struct | Function
struct | Generic
struct | substr_args
struct | ForestElement

Defines

#define | OUT_OF_MEMORY
#define | ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
#define | MAX_LEFT_LEN 255
#define | CONCAT_HDR 1
#define | FN_HDR 4
#define | SUBSTR_HDR 6
#define | IS_CONCATENATION(s) (((CordRep *)s)->generic.header == CONCAT_HDR)
#define | IS_FUNCTION(s) ((((CordRep *)s)->generic.header & FN_HDR) != 0)
#define | IS_SUBSTR(s) (((CordRep *)s)->generic.header == SUBSTR_HDR)
#define | LEN(s) (((CordRep *)s) -> generic.len)
#define | DEPTH(s) (((CordRep *)s) -> generic.depth)
#define | GEN_LEN(s) (CORD_IS_STRING(s) ? strlen(s) : LEN(s))
#define | LEFT_LEN(c)
#define | SHORT_LIMIT (sizeof(CordRep) - 1)
#define | SUBSTR_LIMIT (10 * SHORT_LIMIT)

Typedefs

typedef void(* | oom_fn )(void)
typedef unsigned long | word
typedef ForestElement | Forest [MAX_DEPTH]

Functions

char | CORD_nul_func (size_t i, void *client_data)
void | CORD_dump_inner (CORD x, unsigned n)
void | CORD_dump (CORD x)
CORD | CORD_cat_char_star (CORD x, const char *y, size_t leny)
CORD | CORD_cat (CORD x, CORD y)
CORD | CORD_from_fn (CORD_fn fn, void *client_data, size_t len)
size_t | CORD_len (CORD x)
char | CORD_index_access_fn (size_t i, void *client_data)
char | CORD_apply_access_fn (size_t i, void *client_data)
CORD | CORD_substr_closure (CORD x, size_t i, size_t n, CORD_fn f)
CORD | CORD_substr_checked (CORD x, size_t i, size_t n)
CORD | CORD_substr (CORD x, size_t i, size_t n)
int | CORD_iter5 (CORD x, size_t i, CORD_iter_fn f1, CORD_batched_iter_fn f2, void *client_data)
int | CORD_block_iter (CORD x, size_t i, CORD_block_iter_fn fb, void *client_data)
int | CORD_iter (CORD x, CORD_iter_fn f1, void *client_data)
int | CORD_riter4 (CORD x, size_t i, CORD_iter_fn f1, void *client_data)
int | CORD_riter (CORD x, CORD_iter_fn f1, void *client_data)
void | CORD_init_min_len ()
void | CORD_init_forest (ForestElement *forest, size_t max_len)
void | CORD_add_forest (ForestElement *forest, CORD x, size_t len)
CORD | CORD_concat_forest (ForestElement *forest, size_t expected_len)
void | CORD_balance_insert (CORD x, size_t len, ForestElement *forest)
CORD | CORD_balance (CORD x)
void | CORD__extend_path (register CORD_pos p)
char | CORD__pos_fetch (register CORD_pos p)
void | CORD__next (register CORD_pos p)
void | CORD__prev (register CORD_pos p)
char | CORD_pos_fetch (register CORD_pos p)
void | CORD_next (CORD_pos p)
void | CORD_prev (CORD_pos p)
size_t | CORD_pos_to_index (CORD_pos p)
CORD CORD_pos_to_cord (CORD_pos p)
int | CORD_pos_valid (CORD_pos p)
void | CORD_set_pos (CORD_pos p, CORD x, size_t i)

Variables

oom_fn | CORD_oom_fn = (oom_fn) 0
size_t | min_len [MAX_DEPTH]
int | min_len_init = 0
int | CORD_max_len

Define Documentation

#define OUT_OF_MEMORY

Value:

{  if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
              ABORT("Out of memory\n"); }

Definition at line 35 of file cordbscs.c.

Referenced by CORD_cat(), CORD_cat_char_star(), CORD_from_fn(), CORD_substr_checked(), and CORD_substr_closure().

#define ABORT ( msg ) { fprintf(stderr, "%s\n", msg); abort(); }

Definition at line 37 of file cordbscs.c.

Referenced by CORD__pos_fetch(), CORD_block_iter(), CORD_cat_char_star(), CORD_fetch(), CORD_init_forest(), CORD_iter5(), CORD_riter4(), and CORD_substr().

#define MAX_LEFT_LEN 255

Definition at line 49 of file cordbscs.c.

Referenced by CORD_cat(), and CORD_cat_char_star().

#define CONCAT_HDR 1

Definition at line 73 of file cordbscs.c.

Referenced by CORD_cat(), and CORD_cat_char_star().

#define FN_HDR 4

Definition at line 75 of file cordbscs.c.

Referenced by CORD_from_fn().

#define SUBSTR_HDR 6

Definition at line 76 of file cordbscs.c.

Referenced by CORD_substr_closure().

#define IS_CONCATENATION ( s ) (((CordRep *)s)->generic.header == CONCAT_HDR)

Definition at line 83 of file cordbscs.c.

Referenced by CORD__extend_path(), CORD_balance_insert(), CORD_block_iter(), CORD_cat_char_star(), CORD_dump_inner(), CORD_iter5(), CORD_riter4(), and CORD_substr_checked().

#define IS_FUNCTION ( s ) ((((CordRep *)s)->generic.header & FN_HDR) != 0)

Definition at line 85 of file cordbscs.c.

Referenced by CORD__pos_fetch().

#define IS_SUBSTR ( s ) (((CordRep *)s)->generic.header == SUBSTR_HDR)

Definition at line 87 of file cordbscs.c.

Referenced by CORD_dump_inner(), and CORD_substr_checked().

#define LEN ( s ) (((CordRep *)s) -> generic.len)

Definition at line 89 of file cordbscs.c.

Referenced by CORD_balance(), CORD_cat(), and CORD_cat_char_star().

#define DEPTH ( s ) (((CordRep *)s) -> generic.depth)

Definition at line 90 of file cordbscs.c.

Referenced by CORD_balance_insert(), CORD_cat(), and CORD_cat_char_star().

#define GEN_LEN ( s ) (CORD_IS_STRING(s) ? strlen(s) : LEN(s))

Definition at line 91 of file cordbscs.c.

Referenced by CORD__extend_path(), and CORD_len().

#define LEFT_LEN ( c )

Value:

((c) -> left_len != 0? \
                (c) -> left_len \
                : (CORD_IS_STRING((c) -> left) ? \
                    (c) -> len - GEN_LEN((c) -> right) \
                    : LEN((c) -> left)))

Definition at line 93 of file cordbscs.c.

Referenced by CORD__extend_path(), CORD_balance_insert(), CORD_block_iter(), CORD_iter5(), CORD_riter4(), and CORD_substr_checked().

#define SHORT_LIMIT (sizeof(CordRep) - 1)

Definition at line 99 of file cordbscs.c.

Referenced by CORD_cat_char_star(), CORD_dump_inner(), and CORD_from_fn().

#define SUBSTR_LIMIT (10 * SHORT_LIMIT)

Definition at line 367 of file cordbscs.c.

Referenced by CORD_substr_checked().

Typedef Documentation

typedef void(* oom_fn)(void)

Definition at line 31 of file cordbscs.c.

typedef unsigned long word

Definition at line 39 of file cordbscs.c.

typedef ForestElement Forest[ MAX_DEPTH ]

Definition at line 658 of file cordbscs.c.

Function Documentation

char CORD_nul_func | ( | size_t | i,
 |  | void * | client_data
 | ) |

Definition at line 431 of file cordxtra.c.

Referenced by CORD_chars().

void CORD_dump_inner | ( | CORD | x,
 |  | unsigned | n
 | ) |

Definition at line 107 of file cordbscs.c.

References CORD, CORD_IS_STRING, func, IS_CONCATENATION, IS_SUBSTR, and SHORT_LIMIT.

Referenced by CORD_dump().

void CORD_dump ( CORD x )

Definition at line 149 of file cordbscs.c.

References CORD, and CORD_dump_inner().

Referenced by String::Body::dump(), and String::Languages::dump().

CORD CORD_cat_char_star | ( | CORD | x,
 |  | const char * | y,
 |  | size_t | leny
 | ) |

Definition at line 155 of file cordbscs.c.

References ABORT, CONCAT_HDR, CORD, CORD_balance(), CORD_EMPTY, CORD_IS_STRING, DEPTH, GC_MALLOC_ATOMIC, GC_NEW, IS_CONCATENATION, LEN, MAX_DEPTH, MAX_LEFT_LEN, OUT_OF_MEMORY, result, and SHORT_LIMIT.

Referenced by String::Body::append_know_length(), CORD_cat(), CORD_cat_char(), and CORD_ec_flush_buf().

CORD CORD_cat | ( | CORD | x,
 |  | CORD | y
 | ) |

Definition at line 243 of file cordbscs.c.

References CONCAT_HDR, CORD, CORD_balance(), CORD_cat_char_star(), CORD_EMPTY, CORD_IS_STRING, DEPTH, GC_NEW, LEN, MAX_DEPTH, MAX_LEFT_LEN, OUT_OF_MEMORY, and result.

Referenced by String::Languages::append(), CORD_add_forest(), CORD_cat_char(), CORD_catn(), CORD_concat_forest(), CORD_ec_append_cord(), CORD_from_file_eager(), CORD_substr_checked(), CORD_vsprintf(), and String::Body::operator<<().

CORD CORD_from_fn | ( | CORD_fn | fn,
 |  | void * | client_data,
 |  | size_t | len
 | ) |

Definition at line 285 of file cordbscs.c.

References CORD, CORD_fn, FN_HDR, GC_MALLOC_ATOMIC, GC_NEW, OUT_OF_MEMORY, result, and SHORT_LIMIT.

Referenced by CORD_chars(), and CORD_substr_closure().

size_t CORD_len ( CORD x )

Definition at line 321 of file cordbscs.c.

References CORD, and GEN_LEN.

Referenced by CORD_riter(), CORD_str(), CORD_substr(), CORD_to_char_star(), CORD_vsprintf(), ec_len(), String::Languages::invariant(), and String::Body::length().

char CORD_index_access_fn | ( | size_t | i,
 |  | void * | client_data
 | ) |

Definition at line 335 of file cordbscs.c.

References substr_args::sa_cord, and substr_args::sa_index.

Referenced by CORD_block_iter(), and CORD_substr_checked().

char CORD_apply_access_fn | ( | size_t | i,
 |  | void * | client_data
 | ) |

Definition at line 342 of file cordbscs.c.

References CordRep::function, substr_args::sa_cord, and substr_args::sa_index.

Referenced by CORD_block_iter(), and CORD_substr_checked().

CORD CORD_substr_closure | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | n,
 |  | CORD_fn | f
 | ) |

Definition at line 354 of file cordbscs.c.

References CORD, CORD_fn, CORD_from_fn(), GC_NEW, OUT_OF_MEMORY, result, substr_args::sa_cord, substr_args::sa_index, and SUBSTR_HDR.

Referenced by CORD_substr_checked().

CORD CORD_substr_checked | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | n
 | ) |

Definition at line 373 of file cordbscs.c.

References CORD, CORD_apply_access_fn(), CORD_cat(), CORD_index_access_fn(), CORD_IS_STRING, CORD_substr_closure(), GC_MALLOC_ATOMIC, IS_CONCATENATION, IS_SUBSTR, LEFT_LEN, OUT_OF_MEMORY, p, result, substr_args::sa_cord, substr_args::sa_index, and SUBSTR_LIMIT.

Referenced by CORD_substr().

CORD CORD_substr | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | n
 | ) |

Definition at line 458 of file cordbscs.c.

References ABORT, CORD, CORD_len(), and CORD_substr_checked().

Referenced by String::Languages::append(), CORD_str(), CORD_vsprintf(), String::Languages::make_langs(), and String::Body::mid().

int CORD_iter5 | ( | CORD | x,
 |  | size_t | i,
 |  | CORD_iter_fn | f1,
 |  | CORD_batched_iter_fn | f2,
 |  | void * | client_data
 | ) |

Definition at line 475 of file cordbscs.c.

References ABORT, CORD, CORD_batched_iter_fn, CORD_IS_STRING, CORD_iter_fn, CORD_NO_FN, IS_CONCATENATION, LEFT_LEN, p, and result.

Referenced by CORD_chr(), CORD_fill_buf(), CORD_iter(), CORD_put(), String::Body::for_each(), and String::Body::hash_code().

int CORD_block_iter | ( | CORD | x,
 |  | size_t | i,
 |  | CORD_block_iter_fn | fb,
 |  | void * | client_data
 | ) |

Definition at line 521 of file cordbscs.c.

References ABORT, CORD, CORD_apply_access_fn(), CORD_block_iter_fn, CORD_index_access_fn(), CORD_IS_STRING, CordRep::function, IS_CONCATENATION, LEFT_LEN, p, result, and substr_args::sa_cord.

Referenced by CORD_block_count(), CORD_range_contains_chr_greater_then(), and String::Languages::for_each().

int CORD_iter | ( | CORD | x,
 |  | CORD_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 579 of file cordbscs.c.

References CORD, CORD_iter5(), CORD_iter_fn, and CORD_NO_FN.

int CORD_riter4 | ( | CORD | x,
 |  | size_t | i,
 |  | CORD_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 584 of file cordbscs.c.

References ABORT, CORD, CORD_IS_STRING, CORD_iter_fn, IS_CONCATENATION, LEFT_LEN, and p.

Referenced by CORD_rchr(), and CORD_riter().

int CORD_riter | ( | CORD | x,
 |  | CORD_iter_fn | f1,
 |  | void * | client_data
 | ) |

Definition at line 627 of file cordbscs.c.

References CORD, CORD_iter_fn, CORD_len(), and CORD_riter4().

void CORD_init_min_len ( )

Definition at line 664 of file cordbscs.c.

References CORD_max_len, MAX_DEPTH, min_len, and min_len_init.

Referenced by CORD_balance().

void CORD_init_forest | ( | ForestElement * | forest,
 |  | size_t | max_len
 | ) |

Definition at line 683 of file cordbscs.c.

References ABORT, ForestElement::c, MAX_DEPTH, and min_len.

Referenced by CORD_balance().

void CORD_add_forest | ( | ForestElement * | forest,
 |  | CORD | x,
 |  | size_t | len
 | ) |

Definition at line 699 of file cordbscs.c.

References ForestElement::c, CORD, CORD_cat(), CORD_EMPTY, ForestElement::len, and min_len.

Referenced by CORD_balance_insert().

CORD CORD_concat_forest | ( | ForestElement * | forest,
 |  | size_t | expected_len
 | ) |

Definition at line 735 of file cordbscs.c.

References ForestElement::c, CORD, CORD_cat(), and ForestElement::len.

Referenced by CORD_balance().

void CORD_balance_insert | ( | CORD | x,
 |  | size_t | len,
 |  | ForestElement * | forest
 | ) |

Definition at line 754 of file cordbscs.c.

References CORD, CORD_add_forest(), CORD_IS_STRING, DEPTH, IS_CONCATENATION, LEFT_LEN, MAX_DEPTH, and min_len.

Referenced by CORD_balance().

CORD CORD_balance ( CORD x )

Definition at line 775 of file cordbscs.c.

References CORD, CORD_balance_insert(), CORD_concat_forest(), CORD_init_forest(), CORD_init_min_len(), CORD_IS_STRING, LEN, and min_len_init.

Referenced by CORD_cat(), CORD_cat_char_star(), CORD_from_file_eager(), and CORD_vsprintf().

void CORD__extend_path ( register CORD_pos p )

Definition at line 797 of file cordbscs.c.

References CORD, CORD_IS_STRING, CORD_POS_INVALID, GEN_LEN, IS_CONCATENATION, LEFT_LEN, and p.

Referenced by CORD__next(), CORD__prev(), and CORD_set_pos().

char CORD__pos_fetch ( register CORD_pos p )

Definition at line 835 of file cordbscs.c.

References ABORT, CORD, IS_FUNCTION, and p.

void CORD__next ( register CORD_pos p )

Definition at line 846 of file cordbscs.c.

References CORD, CORD__extend_path(), CORD_fn, CORD_IS_STRING, CORD_POS_INVALID, FUNCTION_BUF_SZ, p, and CORD_pe::pe_start_pos.

void CORD__prev ( register CORD_pos p )

Definition at line 898 of file cordbscs.c.

References CORD__extend_path(), CORD_POS_INVALID, p, and CORD_pe::pe_start_pos.

char CORD_pos_fetch ( register CORD_pos p )

Definition at line 933 of file cordbscs.c.

References CORD__pos_fetch(), and p.

void CORD_next ( CORD_pos p )

Definition at line 942 of file cordbscs.c.

References CORD__next(), CORD_Pos::cur_end, CORD_Pos::cur_pos, and p.

void CORD_prev ( CORD_pos p )

Definition at line 951 of file cordbscs.c.

References CORD__prev(), CORD_Pos::cur_end, CORD_Pos::cur_pos, CORD_Pos::cur_start, and p.

size_t CORD_pos_to_index ( CORD_pos p )

Definition at line 960 of file cordbscs.c.

References CORD_Pos::cur_pos, and p.

CORD CORD_pos_to_cord ( CORD_pos p )

Definition at line 965 of file cordbscs.c.

References CORD, p, CORD_Pos::path, and CORD_pe::pe_cord.

int CORD_pos_valid ( CORD_pos p )

Definition at line 970 of file cordbscs.c.

References CORD_POS_INVALID, p, and CORD_Pos::path_len.

void CORD_set_pos | ( | CORD_pos | p,
 |  | CORD | x,
 |  | size_t | i
 | ) |

Definition at line 975 of file cordbscs.c.

References CORD, CORD__extend_path(), CORD_EMPTY, CORD_POS_INVALID, CORD_Pos::cur_pos, p, CORD_Pos::path, CORD_Pos::path_len, CORD_pe::pe_cord, and CORD_pe::pe_start_pos.

Referenced by CORD_cmp(), CORD_fetch(), CORD_ncmp(), CORD_str(), CORD_vsprintf(), and String::Body::set_pos().

Variable Documentation

oom_fn CORD_oom_fn = (oom_fn) 0

Definition at line 33 of file cordbscs.c.

size_t min_len[ MAX_DEPTH ] [static]

Definition at line 652 of file cordbscs.c.

Referenced by CORD_add_forest(), CORD_balance_insert(), CORD_init_forest(), and CORD_init_min_len().

int min_len_init = 0 [static]

Definition at line 654 of file cordbscs.c.

Referenced by CORD_balance(), and CORD_init_min_len().

int CORD_max_len

Definition at line 656 of file cordbscs.c.

Referenced by CORD_init_min_len().


cordbscs.c Source File

cordbscs.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993-1994 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to use or copy this program
00008  * for any purpose,  provided the above notices are retained on all copies.
00009  * Permission to modify the code and to distribute modified code is granted,
00010  * provided the above notices are retained, and a notice that the code was
00011  * modified is included with the above copyright notice.
00012  *
00013  * Author: Hans-J. Boehm (boehm@parc.xerox.com)
00014  */
00015 /* Boehm, October 3, 1994 5:19 pm PDT */
00016 #include "pa_config_includes.h"
00017 # include "gc.h"
00018 # include "cord.h"
00019 # include <stdlib.h>
00020 # include <stdio.h>
00021 # include <string.h>
00022
00023 /* An implementation of the cord primitives.  These are the only    */
00024 /* Functions that understand the representation.  We perform only   */
00025 /* minimal checks on arguments to these functions.  Out of bounds   */
00026 /* arguments to the iteration functions may result in client functions  */
00027 /* invoked on garbage data.  In most cases, client functions should be  */
00028 /* programmed defensively enough that this does not result in memory    */
00029 /* smashes.                             */
00030
00031 typedef void (* oom_fn)(void);
00032
00033 oom_fn CORD_oom_fn = (oom_fn) 0;
00034
00035 # define OUT_OF_MEMORY {  if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
00036               ABORT("Out of memory\n"); }
00037 # define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
00038
00039 typedef unsigned long word;
00040
00041 typedef union {
00042     struct Concatenation {
00043         char null;
00044     char header;
00045     char depth; /* concatenation nesting depth. */
00046     unsigned char left_len;
00047             /* Length of left child if it is sufficiently   */
00048             /* short; 0 otherwise.              */
00049 #       define MAX_LEFT_LEN 255
00050     word len;
00051     CORD left;  /* length(left) > 0 */
00052     CORD right; /* length(right) > 0    */
00053     } concatenation;
00054     struct Function {
00055     char null;
00056     char header;
00057     char depth; /* always 0 */
00058     char left_len;  /* always 0 */
00059     word len;
00060     CORD_fn fn;
00061     void * client_data;
00062     } function;
00063     struct Generic {
00064         char null;
00065     char header;
00066     char depth;
00067     char left_len;
00068     word len;
00069     } generic;
00070     char string[1];
00071 } CordRep;
00072
00073 # define CONCAT_HDR 1
00074
00075 # define FN_HDR 4
00076 # define SUBSTR_HDR 6
00077     /* Substring nodes are a special case of function nodes.    */
00078     /* The client_data field is known to point to a substr_args */
00079     /* structure, and the function is either CORD_apply_access_fn   */
00080     /* or CORD_index_access_fn.                 */
00081
00082 /* The following may be applied only to function and concatenation nodes: */
00083 #define IS_CONCATENATION(s)  (((CordRep *)s)->generic.header == CONCAT_HDR)
00084
00085 #define IS_FUNCTION(s)  ((((CordRep *)s)->generic.header & FN_HDR) != 0)
00086
00087 #define IS_SUBSTR(s) (((CordRep *)s)->generic.header == SUBSTR_HDR)
00088
00089 #define LEN(s) (((CordRep *)s) -> generic.len)
00090 #define DEPTH(s) (((CordRep *)s) -> generic.depth)
00091 #define GEN_LEN(s) (CORD_IS_STRING(s) ? strlen(s) : LEN(s))
00092
00093 #define LEFT_LEN(c) ((c) -> left_len != 0? \
00094                 (c) -> left_len \
00095                 : (CORD_IS_STRING((c) -> left) ? \
00096                     (c) -> len - GEN_LEN((c) -> right) \
00097                     : LEN((c) -> left)))
00098
00099 #define SHORT_LIMIT (sizeof(CordRep) - 1)
00100     /* Cords shorter than this are C strings */
00101
00102 /* paf: using knowledge of interal structure to speedup */
00103 char CORD_nul_func(size_t i, void * client_data);
00104
00105 /* Dump the internal representation of x to stdout, with initial    */
00106 /* indentation level n.                         */
00107 void CORD_dump_inner(CORD x, unsigned n)
00108 {
00109     register size_t i;
00110
00111     for (i = 0; i < (size_t)n; i++) {
00112         fputs("  ", stdout);
00113     }
00114     if (x == 0) {
00115         fputs("NIL\n", stdout);
00116     } else if (CORD_IS_STRING(x)) {
00117         for (i = 0; i <= SHORT_LIMIT*1000; i++) {
00118             if (x[i] == '\0') { putchar('!'); break; }
00119             switch(x[i]){
00120                 case '\n': putchar('|'); break;
00121                 case '\r': putchar('#'); break;
00122                 case '\t': putchar('@'); break;
00123                 default: putchar(x[i]); break;
00124             }
00125         }
00126         if (x[i] != '\0') fputs("...", stdout);
00127         putchar('\n');
00128     } else if (IS_CONCATENATION(x)) {
00129         register struct Concatenation * conc =
00130                     &(((CordRep *)x) -> concatenation);
00131         printf("Concatenation: %p (len: %d, depth: %d)\n",
00132                x, (int)(conc -> len), (int)(conc -> depth));
00133         CORD_dump_inner(conc -> left, n+1);
00134         CORD_dump_inner(conc -> right, n+1);
00135     } else /* function */{
00136         register struct Function * func =
00137                     &(((CordRep *)x) -> function);
00138         if (IS_SUBSTR(x)) printf("(Substring) ");
00139         printf("Function: %p (len: %d): ", x, (int)(func -> len));
00140         for (i = 0; i < 20*1000 && i < func -> len; i++) {
00141             putchar((*(func -> fn))(i, func -> client_data));
00142         }
00143         if (i < func -> len) fputs("...", stdout);
00144         putchar('\n');
00145     }
00146 }
00147
00148 /* Dump the internal representation of x to stdout  */
00149 void CORD_dump(CORD x)
00150 {
00151     CORD_dump_inner(x, 0);
00152     fflush(stdout);
00153 }
00154
00155 CORD CORD_cat_char_star(CORD x, const char*  y, size_t leny)
00156 {
00157     register size_t result_len;
00158     register size_t lenx;
00159     register int depth;
00160
00161     if (x == CORD_EMPTY) return(y);
00162     //if (leny == 0) leny=strlen(y); // PAF
00163     if (y == 0) ABORT("CORD_cat_char_star(,y,) y==0"); // PAF
00164     if (*y == 0) ABORT("CORD_cat_char_star(,y,) y==\"\""); // PAF
00165     if (leny == 0) ABORT("CORD_cat_char_star(,y,) leny==0"); // PAF
00166
00167     if (CORD_IS_STRING(x)) {
00168         lenx = strlen(x);
00169         result_len = lenx + leny;
00170         if (result_len <= SHORT_LIMIT) {
00171             register char * result = GC_MALLOC_ATOMIC(result_len+1);
00172
00173             if (result == 0) OUT_OF_MEMORY;
00174             memcpy(result, x, lenx);
00175             memcpy(result + lenx, y, leny);
00176             result[result_len] = '\0';
00177             return((CORD) result);
00178         } else {
00179             depth = 1;
00180         }
00181     } else {
00182         register CORD right;
00183         register CORD left;
00184         register char * new_right;
00185         register size_t right_len;
00186
00187         lenx = LEN(x);
00188
00189         if (leny <= SHORT_LIMIT/2
00190             && IS_CONCATENATION(x)
00191             && CORD_IS_STRING(right = ((CordRep *)x) -> concatenation.right)) {
00192             /* Merge y into right part of x. */
00193             if (!CORD_IS_STRING(left = ((CordRep *)x) -> concatenation.left)) {
00194                 right_len = lenx - LEN(left);
00195             } else if (((CordRep *)x) -> concatenation.left_len != 0) {
00196                 right_len = lenx - ((CordRep *)x) -> concatenation.left_len;
00197             } else {
00198                 right_len = strlen(right);
00199             }
00200             result_len = right_len + leny;  /* length of new_right */
00201             if (result_len <= SHORT_LIMIT) {
00202                 new_right = GC_MALLOC_ATOMIC(result_len + 1);
00203                 memcpy(new_right, right, right_len);
00204                 memcpy(new_right + right_len, y, leny);
00205                 new_right[result_len] = '\0';
00206                 y = new_right;
00207                 leny = result_len;
00208                 x = left;
00209                 lenx -= right_len;
00210                 /* Now fall through to concatenate the two pieces: */
00211             }
00212             if (CORD_IS_STRING(x)) {
00213                 depth = 1;
00214             } else {
00215                 depth = DEPTH(x) + 1;
00216             }
00217         } else {
00218             depth = DEPTH(x) + 1;
00219         }
00220         result_len = lenx + leny;
00221     }
00222     {
00223       /* The general case; lenx, result_len is known: */
00224         register struct Concatenation * result;
00225
00226         result = GC_NEW(struct Concatenation);
00227         if (result == 0) OUT_OF_MEMORY;
00228         result->header = CONCAT_HDR;
00229         result->depth = depth;
00230         if (lenx <= MAX_LEFT_LEN) result->left_len = lenx;
00231         result->len = result_len;
00232         result->left = x;
00233         result->right = y;
00234         if (depth >= MAX_DEPTH) {
00235             return(CORD_balance((CORD)result));
00236         } else {
00237             return((CORD) result);
00238         }
00239     }
00240 }
00241
00242
00243 CORD CORD_cat(CORD x, CORD y)
00244 {
00245     register size_t result_len;
00246     register int depth;
00247     register size_t lenx;
00248
00249     if (x == CORD_EMPTY) return(y);
00250     if (y == CORD_EMPTY) return(x);
00251     if (CORD_IS_STRING(y)) {
00252         return(CORD_cat_char_star(x, y, strlen(y)));
00253     } else if (CORD_IS_STRING(x)) {
00254         lenx = strlen(x);
00255         depth = DEPTH(y) + 1;
00256     } else {
00257         register int depthy = DEPTH(y);
00258
00259         lenx = LEN(x);
00260         depth = DEPTH(x) + 1;
00261         if (depthy >= depth) depth = depthy + 1;
00262     }
00263     result_len = lenx + LEN(y);
00264     {
00265         register struct Concatenation * result;
00266
00267         result = GC_NEW(struct Concatenation);
00268         if (result == 0) OUT_OF_MEMORY;
00269         result->header = CONCAT_HDR;
00270         result->depth = depth;
00271 //  printf("depth=%d\n", depth);
00272         if (lenx <= MAX_LEFT_LEN) result->left_len = lenx;
00273         result->len = result_len;
00274         result->left = x;
00275         result->right = y;
00276     // PAF@design.ru bug fix:
00277         if (depth >= MAX_DEPTH) {
00278             return(CORD_balance((CORD)result));
00279         } else {
00280             return((CORD) result);
00281         }
00282     }
00283 }
00284
00285 CORD CORD_from_fn(CORD_fn fn, void * client_data, size_t len)
00286 {
00287     if (len <= 0) return(0);
00288     if (len <= SHORT_LIMIT) {
00289         register char * result;
00290         register size_t i;
00291         char buf[SHORT_LIMIT+1];
00292         register char c;
00293
00294         for (i = 0; i < len; i++) {
00295             c = (*fn)(i, client_data);
00296             if (c == '\0') goto gen_case;
00297             buf[i] = c;
00298         }
00299         buf[i] = '\0';
00300         result = GC_MALLOC_ATOMIC(len+1);
00301         if (result == 0) OUT_OF_MEMORY;
00302         strcpy(result, buf);
00303         result[len] = '\0';
00304         return((CORD) result);
00305     }
00306   gen_case:
00307     {
00308         register struct Function * result;
00309
00310         result = GC_NEW(struct Function);
00311         if (result == 0) OUT_OF_MEMORY;
00312         result->header = FN_HDR;
00313         /* depth is already 0 */
00314         result->len = len;
00315         result->fn = fn;
00316         result->client_data = client_data;
00317         return((CORD) result);
00318     }
00319 }
00320
00321 size_t CORD_len(CORD x)
00322 {
00323     if (x == 0) {
00324         return(0);
00325     } else {
00326     return(GEN_LEN(x));
00327     }
00328 }
00329
00330 struct substr_args {
00331     CordRep * sa_cord;
00332     size_t sa_index;
00333 };
00334
00335 char CORD_index_access_fn(size_t i, void * client_data)
00336 {
00337     register struct substr_args *descr = (struct substr_args *)client_data;
00338
00339     return(((char *)(descr->sa_cord))[i + descr->sa_index]);
00340 }
00341
00342 char CORD_apply_access_fn(size_t i, void * client_data)
00343 {
00344     register struct substr_args *descr = (struct substr_args *)client_data;
00345     register struct Function * fn_cord = &(descr->sa_cord->function);
00346
00347     return((*(fn_cord->fn))(i + descr->sa_index, fn_cord->client_data));
00348 }
00349
00350 /* A version of CORD_substr that simply returns a function node, thus   */
00351 /* postponing its work. The fourth argument is a function that may  */
00352 /* be used for efficient access to the ith character.           */
00353 /* Assumes i >= 0 and i + n < length(x).                */
00354 CORD CORD_substr_closure(CORD x, size_t i, size_t n, CORD_fn f)
00355 {
00356     register struct substr_args * sa = GC_NEW(struct substr_args);
00357     CORD result;
00358
00359     if (sa == 0) OUT_OF_MEMORY;
00360     sa->sa_cord = (CordRep *)x;
00361     sa->sa_index = i;
00362     result = CORD_from_fn(f, (void *)sa, n);
00363     ((CordRep *)result) -> function.header = SUBSTR_HDR;
00364     return (result);
00365 }
00366
00367 # define SUBSTR_LIMIT (10 * SHORT_LIMIT)
00368     /* Substrings of function nodes and flat strings shorter than   */
00369     /* this are flat strings.  Othewise we use a functional     */
00370     /* representation, which is significantly slower to access. */
00371
00372 /* A version of CORD_substr that assumes i >= 0, n > 0, and i + n < length(x).*/
00373 CORD CORD_substr_checked(CORD x, size_t i, size_t n)
00374 {
00375     if (CORD_IS_STRING(x)) {
00376         if (n > SUBSTR_LIMIT) {
00377             return(CORD_substr_closure(x, i, n, CORD_index_access_fn));
00378         } else {
00379             register char * result = GC_MALLOC_ATOMIC(n+1);
00380
00381             if (result == 0) OUT_OF_MEMORY;
00382             strncpy(result, x+i, n);
00383             result[n] = '\0';
00384             return(result);
00385         }
00386     } else if (IS_CONCATENATION(x)) {
00387         register struct Concatenation * conc
00388                 = &(((CordRep *)x) -> concatenation);
00389         register size_t left_len;
00390         register size_t right_len;
00391
00392         left_len = LEFT_LEN(conc);
00393         right_len = conc -> len - left_len;
00394         if (i >= left_len) {
00395             if (n == right_len) return(conc -> right);
00396             return(CORD_substr_checked(conc -> right, i - left_len, n));
00397         } else if (i+n <= left_len) {
00398             if (n == left_len) return(conc -> left);
00399             return(CORD_substr_checked(conc -> left, i, n));
00400         } else {
00401             /* Need at least one character from each side. */
00402             register CORD left_part;
00403             register CORD right_part;
00404             register size_t left_part_len = left_len - i;
00405
00406             if (i == 0) {
00407                 left_part = conc -> left;
00408             } else {
00409                 left_part = CORD_substr_checked(conc -> left, i, left_part_len);
00410             }
00411             if (i + n == right_len + left_len) {
00412                  right_part = conc -> right;
00413             } else {
00414                  right_part = CORD_substr_checked(conc -> right, 0,
00415                                       n - left_part_len);
00416             }
00417             return(CORD_cat(left_part, right_part));
00418         }
00419     } else /* function */ {
00420         if (n > SUBSTR_LIMIT) {
00421             if (IS_SUBSTR(x)) {
00422                 /* Avoid nesting substring nodes.   */
00423                 register struct Function * f = &(((CordRep *)x) -> function);
00424                 register struct substr_args *descr =
00425                         (struct substr_args *)(f -> client_data);
00426
00427                 return(CORD_substr_closure((CORD)descr->sa_cord,
00428                                i + descr->sa_index,
00429                                n, f -> fn));
00430             } else {
00431                 return(CORD_substr_closure(x, i, n, CORD_apply_access_fn));
00432             }
00433         } else {
00434             char * result;
00435             register struct Function * f = &(((CordRep *)x) -> function);
00436             char buf[SUBSTR_LIMIT+1];
00437             register char * p = buf;
00438             register char c;
00439             register int j;
00440             register int lim = i + n;
00441
00442             for (j = i; j < lim; j++) {
00443                 c = (*(f -> fn))(j, f -> client_data);
00444                 if (c == '\0') {
00445                     return(CORD_substr_closure(x, i, n, CORD_apply_access_fn));
00446                 }
00447                 *p++ = c;
00448             }
00449             *p = '\0';
00450             result = GC_MALLOC_ATOMIC(n+1);
00451             if (result == 0) OUT_OF_MEMORY;
00452             strcpy(result, buf);
00453             return(result);
00454         }
00455     }
00456 }
00457
00458 CORD CORD_substr(CORD x, size_t i, size_t n)
00459 {
00460     register size_t len = CORD_len(x);
00461
00462     if (i >= len || n <= 0) return(0);
00463         /* n < 0 is impossible in a correct C implementation, but   */
00464         /* quite possible  under SunOS 4.X.             */
00465     if (i + n > len) n = len - i;
00466 #   ifndef __STDC__
00467       if (i < 0) ABORT("CORD_substr: second arg. negative");
00468         /* Possible only if both client and C implementation are buggy. */
00469         /* But empirically this happens frequently.         */
00470 #   endif
00471     return(CORD_substr_checked(x, i, n));
00472 }
00473
00474 /* See cord.h for definition.  We assume i is in range. */
00475 int CORD_iter5(CORD x, size_t i, CORD_iter_fn f1,
00476              CORD_batched_iter_fn f2, void * client_data)
00477 {
00478     int result;
00479     if (x == 0) return(0);
00480     if (CORD_IS_STRING(x)) {
00481         register const char* p = x+i;
00482
00483         if (*p == '\0') ABORT("2nd arg to CORD_iter5 too big");
00484         if (f2 != CORD_NO_FN) {
00485             return((*f2)(p, client_data));
00486         } else {
00487         while (*p) {
00488                 if (result=(*f1)(*p, client_data))
00489                     return result;
00490                 p++;
00491         }
00492         return(0);
00493         }
00494     } else if (IS_CONCATENATION(x)) {
00495         register struct Concatenation * conc = &(((CordRep *)x) -> concatenation);
00496         if (i > 0) {
00497             register size_t left_len = LEFT_LEN(conc);
00498
00499             if (i >= left_len) {
00500                 return(CORD_iter5(conc -> right, i - left_len, f1, f2,
00501                           client_data));
00502             }
00503         }
00504         result=CORD_iter5(conc -> left, i, f1, f2, client_data);
00505         if (result) return result;
00506         return(CORD_iter5(conc -> right, 0, f1, f2, client_data));
00507     } else /* function */ {
00508         register struct Function * f = &(((CordRep *)x) -> function);
00509         register size_t j;
00510         register size_t lim = f -> len;
00511
00512         for (j = i; j < lim; j++) {
00513             if (result=(*f1)((*(f -> fn))(j, f -> client_data), client_data))
00514                 return result;
00515         }
00516         return(0);
00517     }
00518 }
00519
00520 /* See cord.h for definition.  We assume i is in range. */
00521 int CORD_block_iter(CORD x, size_t i, CORD_block_iter_fn fb, void * client_data)
00522 {
00523     int result;
00524     if (x == 0) return(0);
00525     if (CORD_IS_STRING(x)) {
00526         register const char* p = x+i;
00527         const char *b=p;
00528         char bc=*b;
00529         int pc;
00530
00531         if (bc == '\0') ABORT("2nd arg to CORD_iter5 too big");
00532         do {
00533             pc=*++p;
00534             if(pc!=bc) {
00535                 if (result=fb(bc, p-b, client_data))
00536                     return result;
00537                 b=p; bc=pc;
00538             }
00539         } while (pc);
00540         return(0);
00541     } else if (IS_CONCATENATION(x)) {
00542         register struct Concatenation * conc= &(((CordRep *)x) -> concatenation);
00543         if (i > 0) {
00544             register size_t left_len = LEFT_LEN(conc);
00545
00546             if (i >= left_len) {
00547                 return(CORD_block_iter(conc -> right, i - left_len, fb, client_data));
00548             }
00549         }
00550         result=CORD_block_iter(conc -> left, i, fb, client_data);
00551         if (result) return result;
00552         return(CORD_block_iter(conc -> right, 0, fb, client_data));
00553     } else /* function */ {
00554         register struct Function * f = &(((CordRep *)x) -> function);
00555         register size_t lim = f -> len;
00556
00557         if(f->fn == CORD_nul_func ) {
00558             if (result=fb((char)(unsigned long)f -> client_data, f -> len-i, client_data)) return result;
00559         } else if(f->fn == CORD_apply_access_fn) {
00560             register struct substr_args *descr = (struct substr_args *)f->client_data;
00561             register struct Function * fn_cord = &(descr->sa_cord->function);
00562
00563             if(fn_cord->fn == CORD_nul_func ) {
00564                 if (result=fb((char)(unsigned long)fn_cord->client_data, f -> len-i, client_data))
00565                     return result;
00566             } else
00567                 ABORT("CORD_block_iter:CORD_apply_access_fn:unknown_fn should not happen");
00568         } else {
00569             if(f->fn == CORD_index_access_fn)
00570                 ABORT("CORD_block_iter:CORD_index_access_fn should not happen");
00571             ABORT("CORD_block_iter:unknown_fn should not happen");
00572         }
00573     }
00574     return(0);
00575 }
00576
00577
00578 #undef CORD_iter
00579 int CORD_iter(CORD x, CORD_iter_fn f1, void * client_data)
00580 {
00581     return(CORD_iter5(x, 0, f1, CORD_NO_FN, client_data));
00582 }
00583
00584 int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data)
00585 {
00586     if (x == 0) return(0);
00587     if (CORD_IS_STRING(x)) {
00588     register const char* p = x + i;
00589     register char c;
00590
00591     for(;;) {
00592         c = *p;
00593         if (c == '\0') ABORT("2nd arg to CORD_riter4 too big");
00594             if ((*f1)(c, client_data)) return(1);
00595         if (p == x) break;
00596             p--;
00597     }
00598     return(0);
00599     } else if (IS_CONCATENATION(x)) {
00600         register struct Concatenation * conc
00601                 = &(((CordRep *)x) -> concatenation);
00602         register CORD left_part = conc -> left;
00603         register size_t left_len;
00604
00605         left_len = LEFT_LEN(conc);
00606         if (i >= left_len) {
00607             if (CORD_riter4(conc -> right, i - left_len, f1, client_data)) {
00608                 return(1);
00609             }
00610             return(CORD_riter4(left_part, left_len - 1, f1, client_data));
00611         } else {
00612             return(CORD_riter4(left_part, i, f1, client_data));
00613         }
00614     } else /* function */ {
00615         register struct Function * f = &(((CordRep *)x) -> function);
00616         register size_t j;
00617
00618         for (j = i; ; j--) {
00619             if ((*f1)((*(f -> fn))(j, f -> client_data), client_data)) {
00620                 return(1);
00621             }
00622             if (j == 0) return(0);
00623         }
00624     }
00625 }
00626
00627 int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data)
00628 {
00629     return(CORD_riter4(x, CORD_len(x) - 1, f1, client_data));
00630 }
00631
00632 /*
00633  * The following functions are concerned with balancing cords.
00634  * Strategy:
00635  * Scan the cord from left to right, keeping the cord scanned so far
00636  * as a forest of balanced trees of exponentialy decreasing length.
00637  * When a new subtree needs to be added to the forest, we concatenate all
00638  * shorter ones to the new tree in the appropriate order, and then insert
00639  * the result into the forest.
00640  * Crucial invariants:
00641  * 1. The concatenation of the forest (in decreasing order) with the
00642  *     unscanned part of the rope is equal to the rope being balanced.
00643  * 2. All trees in the forest are balanced.
00644  * 3. forest[i] has depth at most i.
00645  */
00646
00647 typedef struct {
00648     CORD c;
00649     size_t len;     /* Actual length of c   */
00650 } ForestElement;
00651
00652 static size_t min_len [ MAX_DEPTH ];
00653
00654 static int min_len_init = 0;
00655
00656 int CORD_max_len;
00657
00658 typedef ForestElement Forest [ MAX_DEPTH ];
00659             /* forest[i].len >= fib(i+1)            */
00660             /* The string is the concatenation  */
00661             /* of the forest in order of DECREASING */
00662             /* indices.             */
00663
00664 void CORD_init_min_len()
00665 {
00666     register int i;
00667     register size_t last, previous, current;
00668
00669     min_len[0] = previous = 1;
00670     min_len[1] = last = 2;
00671     for (i = 2; i < MAX_DEPTH; i++) {
00672         current = last + previous;
00673         if (current < last) /* overflow */ current = last;
00674         min_len[i] = current;
00675         previous = last;
00676         last = current;
00677     }
00678     CORD_max_len = last - 1;
00679     min_len_init = 1;
00680 }
00681
00682
00683 void CORD_init_forest(ForestElement * forest, size_t max_len)
00684 {
00685     register int i;
00686
00687     for (i = 0; i < MAX_DEPTH; i++) {
00688         forest[i].c = 0;
00689         if (min_len[i] > max_len) return;
00690     }
00691     ABORT("Cord too long");
00692 }
00693
00694 /* Add a leaf to the appropriate level in the forest, cleaning      */
00695 /* out lower levels as necessary.                   */
00696 /* Also works if x is a balanced tree of concatenations; however    */
00697 /* in this case an extra concatenation node may be inserted above x;    */
00698 /* This node should not be counted in the statement of the invariants.  */
00699 void CORD_add_forest(ForestElement * forest, CORD x, size_t len)
00700 {
00701     register int i = 0;
00702     register CORD sum = CORD_EMPTY;
00703     register size_t sum_len = 0;
00704
00705     while (len > min_len[i + 1]) {
00706         if (forest[i].c != 0) {
00707             sum = CORD_cat(forest[i].c, sum);
00708             sum_len += forest[i].len;
00709             forest[i].c = 0;
00710         }
00711         i++;
00712     }
00713     /* Sum has depth at most 1 greter than what would be required   */
00714     /* for balance.                         */
00715     sum = CORD_cat(sum, x);
00716     sum_len += len;
00717     /* If x was a leaf, then sum is now balanced.  To see this      */
00718     /* consider the two cases in which forest[i-1] either is or is  */
00719     /* not empty.                           */
00720     while (sum_len >= min_len[i]) {
00721         if (forest[i].c != 0) {
00722             sum = CORD_cat(forest[i].c, sum);
00723             sum_len += forest[i].len;
00724             /* This is again balanced, since sum was balanced, and has  */
00725             /* allowable depth that differs from i by at most 1.    */
00726             forest[i].c = 0;
00727         }
00728         i++;
00729     }
00730     i--;
00731     forest[i].c = sum;
00732     forest[i].len = sum_len;
00733 }
00734
00735 CORD CORD_concat_forest(ForestElement * forest, size_t expected_len)
00736 {
00737     register int i = 0;
00738     CORD sum = 0;
00739     size_t sum_len = 0;
00740
00741     while (sum_len != expected_len) {
00742         if (forest[i].c != 0) {
00743             sum = CORD_cat(forest[i].c, sum);
00744             sum_len += forest[i].len;
00745         }
00746         i++;
00747     }
00748     return(sum);
00749 }
00750
00751 /* Insert the frontier of x into forest.  Balanced subtrees are */
00752 /* treated as leaves.  This potentially adds one to the depth   */
00753 /* of the final tree.                       */
00754 void CORD_balance_insert(CORD x, size_t len, ForestElement * forest)
00755 {
00756     register int depth;
00757
00758     if (CORD_IS_STRING(x)) {
00759         CORD_add_forest(forest, x, len);
00760     } else if (IS_CONCATENATION(x)
00761                && ((depth = DEPTH(x)) >= MAX_DEPTH
00762                    || len < min_len[depth])) {
00763         register struct Concatenation * conc
00764                 = &(((CordRep *)x) -> concatenation);
00765         size_t left_len = LEFT_LEN(conc);
00766
00767         CORD_balance_insert(conc -> left, left_len, forest);
00768         CORD_balance_insert(conc -> right, len - left_len, forest);
00769     } else /* function or balanced */ {
00770         CORD_add_forest(forest, x, len);
00771     }
00772 }
00773
00774
00775 CORD CORD_balance(CORD x)
00776 {
00777     Forest forest;
00778     register size_t len;
00779
00780     if (x == 0) return(0);
00781     if (CORD_IS_STRING(x)) return(x);
00782     if (!min_len_init) CORD_init_min_len();
00783     len = LEN(x);
00784     CORD_init_forest(forest, len);
00785     CORD_balance_insert(x, len, forest);
00786     return(CORD_concat_forest(forest, len));
00787 }
00788
00789
00790 /* Position primitives  */
00791
00792 /* Private routines to deal with the hard cases only: */
00793
00794 /* P contains a prefix of the  path to cur_pos. Extend it to a full */
00795 /* path and set up leaf info.                       */
00796 /* Return 0 if past the end of cord, 1 o.w.             */
00797 void CORD__extend_path(register CORD_pos p)
00798 {
00799      register struct CORD_pe * current_pe = &(p[0].path[p[0].path_len]);
00800      register CORD top = current_pe -> pe_cord;
00801      register size_t pos = p[0].cur_pos;
00802      register size_t top_pos = current_pe -> pe_start_pos;
00803      register size_t top_len = GEN_LEN(top);
00804
00805      /* Fill in the rest of the path. */
00806        while(!CORD_IS_STRING(top) && IS_CONCATENATION(top)) {
00807          register struct Concatenation * conc =
00808                 &(((CordRep *)top) -> concatenation);
00809          register size_t left_len;
00810
00811          left_len = LEFT_LEN(conc);
00812          current_pe++;
00813          if (pos >= top_pos + left_len) {
00814              current_pe -> pe_cord = top = conc -> right;
00815              current_pe -> pe_start_pos = top_pos = top_pos + left_len;
00816              top_len -= left_len;
00817          } else {
00818              current_pe -> pe_cord = top = conc -> left;
00819              current_pe -> pe_start_pos = top_pos;
00820              top_len = left_len;
00821          }
00822          p[0].path_len++;
00823        }
00824      /* Fill in leaf description for fast access. */
00825        if (CORD_IS_STRING(top)) {
00826          p[0].cur_leaf = top;
00827          p[0].cur_start = top_pos;
00828          p[0].cur_end = top_pos + top_len;
00829        } else {
00830          p[0].cur_end = 0;
00831        }
00832        if (pos >= top_pos + top_len) p[0].path_len = CORD_POS_INVALID;
00833 }
00834
00835 char CORD__pos_fetch(register CORD_pos p)
00836 {
00837     /* Leaf is a function node */
00838     struct CORD_pe * pe = &((p)[0].path[(p)[0].path_len]);
00839     CORD leaf = pe -> pe_cord;
00840     register struct Function * f = &(((CordRep *)leaf) -> function);
00841
00842     if (!IS_FUNCTION(leaf)) ABORT("CORD_pos_fetch: bad leaf");
00843     return ((*(f -> fn))(p[0].cur_pos - pe -> pe_start_pos, f -> client_data));
00844 }
00845
00846 void CORD__next(register CORD_pos p)
00847 {
00848     register size_t cur_pos = p[0].cur_pos + 1;
00849     register struct CORD_pe * current_pe = &((p)[0].path[(p)[0].path_len]);
00850     register CORD leaf = current_pe -> pe_cord;
00851
00852     /* Leaf is not a string or we're at end of leaf */
00853     p[0].cur_pos = cur_pos;
00854     if (!CORD_IS_STRING(leaf)) {
00855         /* Function leaf    */
00856         register struct Function * f = &(((CordRep *)leaf) -> function);
00857         register size_t start_pos = current_pe -> pe_start_pos;
00858         register size_t end_pos = start_pos + f -> len;
00859
00860         if (cur_pos < end_pos) {
00861           /* Fill cache and return. */
00862             register size_t i;
00863             register size_t limit = cur_pos + FUNCTION_BUF_SZ;
00864             register CORD_fn fn = f -> fn;
00865             register void * client_data = f -> client_data;
00866
00867             if (limit > end_pos) {
00868                 limit = end_pos;
00869             }
00870             for (i = cur_pos; i < limit; i++) {
00871                 p[0].function_buf[i - cur_pos] =
00872                     (*fn)(i - start_pos, client_data);
00873             }
00874             p[0].cur_start = cur_pos;
00875             p[0].cur_leaf = p[0].function_buf;
00876             p[0].cur_end = limit;
00877             return;
00878         }
00879     }
00880     /* End of leaf  */
00881     /* Pop the stack until we find two concatenation nodes with the     */
00882     /* same start position: this implies we were in left part.      */
00883     {
00884         while (p[0].path_len > 0
00885                && current_pe[0].pe_start_pos != current_pe[-1].pe_start_pos) {
00886             p[0].path_len--;
00887             current_pe--;
00888         }
00889         if (p[0].path_len == 0) {
00890         p[0].path_len = CORD_POS_INVALID;
00891             return;
00892     }
00893     }
00894     p[0].path_len--;
00895     CORD__extend_path(p);
00896 }
00897
00898 void CORD__prev(register CORD_pos p)
00899 {
00900     register struct CORD_pe * pe = &(p[0].path[p[0].path_len]);
00901
00902     if (p[0].cur_pos == 0) {
00903         p[0].path_len = CORD_POS_INVALID;
00904         return;
00905     }
00906     p[0].cur_pos--;
00907     if (p[0].cur_pos >= pe -> pe_start_pos) return;
00908
00909     /* Beginning of leaf    */
00910
00911     /* Pop the stack until we find two concatenation nodes with the     */
00912     /* different start position: this implies we were in right part.    */
00913     {
00914         register struct CORD_pe * current_pe = &((p)[0].path[(p)[0].path_len]);
00915
00916         while (p[0].path_len > 0
00917                && current_pe[0].pe_start_pos == current_pe[-1].pe_start_pos) {
00918             p[0].path_len--;
00919             current_pe--;
00920         }
00921     }
00922     p[0].path_len--;
00923     CORD__extend_path(p);
00924 }
00925
00926 #undef CORD_pos_fetch
00927 #undef CORD_next
00928 #undef CORD_prev
00929 #undef CORD_pos_to_index
00930 #undef CORD_pos_to_cord
00931 #undef CORD_pos_valid
00932
00933 char CORD_pos_fetch(register CORD_pos p)
00934 {
00935     if (p[0].cur_start <= p[0].cur_pos && p[0].cur_pos < p[0].cur_end) {
00936         return(p[0].cur_leaf[p[0].cur_pos - p[0].cur_start]);
00937     } else {
00938         return(CORD__pos_fetch(p));
00939     }
00940 }
00941
00942 void CORD_next(CORD_pos p)
00943 {
00944     if (p[0].cur_pos < p[0].cur_end - 1) {
00945         p[0].cur_pos++;
00946     } else {
00947         CORD__next(p);
00948     }
00949 }
00950
00951 void CORD_prev(CORD_pos p)
00952 {
00953     if (p[0].cur_end != 0 && p[0].cur_pos > p[0].cur_start) {
00954         p[0].cur_pos--;
00955     } else {
00956         CORD__prev(p);
00957     }
00958 }
00959
00960 size_t CORD_pos_to_index(CORD_pos p)
00961 {
00962     return(p[0].cur_pos);
00963 }
00964
00965 CORD CORD_pos_to_cord(CORD_pos p)
00966 {
00967     return(p[0].path[0].pe_cord);
00968 }
00969
00970 int CORD_pos_valid(CORD_pos p)
00971 {
00972     return(p[0].path_len != CORD_POS_INVALID);
00973 }
00974
00975 void CORD_set_pos(CORD_pos p, CORD x, size_t i)
00976 {
00977     if (x == CORD_EMPTY) {
00978         p[0].path_len = CORD_POS_INVALID;
00979         return;
00980     }
00981     p[0].path[0].pe_cord = x;
00982     p[0].path[0].pe_start_pos = 0;
00983     p[0].path_len = 0;
00984     p[0].cur_pos = i;
00985     CORD__extend_path(p);
00986 }


cordprnt.c File Reference

Include dependency graph for cordprnt.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | CONV_SPEC_LEN 50
#define | CONV_RESULT_LEN 50
#define | NONE -1
#define | VARIABLE -2

Functions

int | ec_len (CORD_ec x)
int | extract_conv_spec (CORD_pos source, char *buf, int *width, int *prec, int *left, int *long_arg)
int | CORD_vsprintf (CORD *out, CORD format, va_list args)
int | CORD_sprintf (CORD *out, CORD format,...)
int | CORD_fprintf (FILE *f, CORD format,...)
int | CORD_vfprintf (FILE *f, CORD format, va_list args)
int | CORD_printf (CORD format,...)
int | CORD_vprintf (CORD format, va_list args)

Define Documentation

#define CONV_SPEC_LEN 50

Definition at line 33 of file cordprnt.c.

Referenced by CORD_vsprintf(), and extract_conv_spec().

#define CONV_RESULT_LEN 50

Definition at line 35 of file cordprnt.c.

Referenced by CORD_vsprintf().

#define NONE -1

Definition at line 46 of file cordprnt.c.

Referenced by CORD_vsprintf(), and extract_conv_spec().

#define VARIABLE -2

Definition at line 47 of file cordprnt.c.

Referenced by CORD_vsprintf(), and extract_conv_spec().

Function Documentation

int ec_len ( CORD_ec x ) [static]

Definition at line 40 of file cordprnt.c.

References CORD_len(), CORD_ec_struct::ec_buf, and CORD_ec_struct::ec_bufptr.

Referenced by CORD_vsprintf().

int extract_conv_spec | ( | CORD_pos | source,
 |  | char * | buf,
 |  | int * | width,
 |  | int * | prec,
 |  | int * | left,
 |  | int * | long_arg
 | ) | [static]

Definition at line 57 of file cordprnt.c.

References CONV_SPEC_LEN, CORD_next, CORD_pos_fetch, CORD_pos_valid, NONE, result, and VARIABLE.

Referenced by CORD_vsprintf().

int CORD_vsprintf | ( | CORD * | out,
 |  | CORD | format,
 |  | va_list | args
 | ) |

Definition at line 162 of file cordprnt.c.

References CONV_RESULT_LEN, CONV_SPEC_LEN, CORD, CORD_balance(), CORD_BUFSZ, CORD_cat(), CORD_ec_append, CORD_ec_append_cord(), CORD_ec_flush_buf(), CORD_ec_init, CORD_ec_to_cord, CORD_len(), CORD_next, CORD_pos_fetch, CORD_pos_valid, CORD_set_pos(), CORD_substr(), CORD_ec_struct::ec_buf, CORD_ec_struct::ec_bufptr, ec_len(), extract_conv_spec(), GC_MALLOC_ATOMIC, NONE, result, str, and VARIABLE.

Referenced by CORD_fprintf(), CORD_printf(), CORD_sprintf(), CORD_vfprintf(), and CORD_vprintf().

int CORD_sprintf | ( | CORD * | out,
 |  | CORD | format,
 |  | ... |
 | ) |

Definition at line 342 of file cordprnt.c.

References CORD, CORD_vsprintf(), and result.

int CORD_fprintf | ( | FILE * | f,
 |  | CORD | format,
 |  | ... |
 | ) |

Definition at line 353 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

int CORD_vfprintf | ( | FILE * | f,
 |  | CORD | format,
 |  | va_list | args
 | ) |

Definition at line 366 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

int CORD_printf | ( | CORD | format,
 |  | ... |
 | ) |

Definition at line 376 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.

int CORD_vprintf | ( | CORD | format,
 |  | va_list | args
 | ) |

Definition at line 389 of file cordprnt.c.

References CORD, CORD_put(), CORD_vsprintf(), and result.


cordprnt.c Source File

cordprnt.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993-1994 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to use or copy this program
00008  * for any purpose,  provided the above notices are retained on all copies.
00009  * Permission to modify the code and to distribute modified code is granted,
00010  * provided the above notices are retained, and a notice that the code was
00011  * modified is included with the above copyright notice.
00012  */
00013 /* An sprintf implementation that understands cords.  This is probably  */
00014 /* not terribly portable.  It assumes an ANSI stdarg.h.  It further */
00015 /* assumes that I can make copies of va_list variables, and read    */
00016 /* arguments repeatedly by applyting va_arg to the copies.  This    */
00017 /* could be avoided at some performance cost.               */
00018 /* We also assume that unsigned and signed integers of various kinds    */
00019 /* have the same sizes, and can be cast back and forth.         */
00020 /* We assume that void * and char * have the same size.         */
00021 /* All this cruft is needed because we want to rely on the underlying   */
00022 /* sprintf implementation whenever possible.                */
00023 /* Boehm, September 21, 1995 6:00 pm PDT */
00024
00025 #include "pa_config_includes.h"
00026 #include "cord.h"
00027 #include "ec.h"
00028 #include <stdio.h>
00029 #include <stdarg.h>
00030 #include <string.h>
00031 #include "gc.h"
00032
00033 #define CONV_SPEC_LEN 50    /* Maximum length of a single   */
00034                 /* conversion specification.    */
00035 #define CONV_RESULT_LEN 50  /* Maximum length of any    */
00036                 /* conversion with default  */
00037                 /* width and prec.      */
00038
00039
00040 static int ec_len(CORD_ec x)
00041 {
00042     return(CORD_len(x[0].ec_cord) + (x[0].ec_bufptr - x[0].ec_buf));
00043 }
00044
00045 /* Possible nonumeric precision values. */
00046 # define NONE -1
00047 # define VARIABLE -2
00048 /* Copy the conversion specification from CORD_pos into the buffer buf  */
00049 /* Return negative on error.                        */
00050 /* Source initially points one past the leading %.          */
00051 /* It is left pointing at the conversion type.              */
00052 /* Assign field width and precision to *width and *prec.        */
00053 /* If width or prec is *, VARIABLE is assigned.             */
00054 /* Set *left to 1 if left adjustment flag is present.           */
00055 /* Set *long_arg to 1 if long flag ('l' or 'L') is present, or to   */
00056 /* -1 if 'h' is present.                        */
00057 static int extract_conv_spec(CORD_pos source, char *buf,
00058                  int * width, int *prec, int *left, int * long_arg)
00059 {
00060     register int result = 0;
00061     register int current_number = 0;
00062     register int saw_period = 0;
00063     register int saw_number;
00064     register int chars_so_far = 0;
00065     register char current;
00066
00067     *width = NONE;
00068     buf[chars_so_far++] = '%';
00069     while(CORD_pos_valid(source)) {
00070         if (chars_so_far >= CONV_SPEC_LEN) return(-1);
00071         current = CORD_pos_fetch(source);
00072         buf[chars_so_far++] = current;
00073         switch(current) {
00074       case '*':
00075         saw_number = 1;
00076         current_number = VARIABLE;
00077         break;
00078           case '0':
00079             if (!saw_number) {
00080                 /* Zero fill flag; ignore */
00081                 break;
00082             } /* otherwise fall through: */
00083           case '1':
00084       case '2':
00085       case '3':
00086       case '4':
00087       case '5':
00088           case '6':
00089       case '7':
00090       case '8':
00091       case '9':
00092         saw_number = 1;
00093         current_number *= 10;
00094         current_number += current - '0';
00095         break;
00096       case '.':
00097         saw_period = 1;
00098         if(saw_number) {
00099             *width = current_number;
00100             saw_number = 0;
00101         }
00102         current_number = 0;
00103         break;
00104       case 'l':
00105       case 'L':
00106         *long_arg = 1;
00107         current_number = 0;
00108         break;
00109       case 'h':
00110         *long_arg = -1;
00111         current_number = 0;
00112         break;
00113       case ' ':
00114       case '+':
00115       case '#':
00116         current_number = 0;
00117         break;
00118       case '-':
00119         *left = 1;
00120         current_number = 0;
00121         break;
00122       case 'd':
00123       case 'i':
00124       case 'o':
00125       case 'u':
00126       case 'x':
00127       case 'X':
00128       case 'f':
00129       case 'e':
00130       case 'E':
00131       case 'g':
00132       case 'G':
00133       case 'c':
00134       case 'C':
00135       case 's':
00136       case 'S':
00137       case 'p':
00138       case 'n':
00139       case 'r':
00140         goto done;
00141           default:
00142             return(-1);
00143         }
00144         CORD_next(source);
00145     }
00146     return(-1);
00147   done:
00148     if (saw_number) {
00149         if (saw_period) {
00150             *prec = current_number;
00151         } else {
00152             *prec = NONE;
00153             *width = current_number;
00154         }
00155     } else {
00156         *prec = NONE;
00157     }
00158     buf[chars_so_far] = '\0';
00159     return(result);
00160 }
00161
00162 int CORD_vsprintf(CORD * out, CORD format, va_list args)
00163 {
00164     CORD_ec result;
00165     register int count;
00166     register char current;
00167     CORD_pos pos;
00168     char conv_spec[CONV_SPEC_LEN + 1];
00169
00170     CORD_ec_init(result);
00171     for (CORD_set_pos(pos, format, 0); CORD_pos_valid(pos); CORD_next(pos)) {
00172         current = CORD_pos_fetch(pos);
00173         if (current == '%') {
00174             CORD_next(pos);
00175             if (!CORD_pos_valid(pos)) return(-1);
00176             current = CORD_pos_fetch(pos);
00177             if (current == '%') {
00178                 CORD_ec_append(result, current);
00179             } else {
00180                 int width, prec;
00181                 int left_adj = 0;
00182                 int long_arg = 0;
00183         CORD arg;
00184         size_t len;
00185
00186                 if (extract_conv_spec(pos, conv_spec,
00187                               &width, &prec,
00188                               &left_adj, &long_arg) < 0) {
00189                     return(-1);
00190                 }
00191                 current = CORD_pos_fetch(pos);
00192                 switch(current) {
00193                     case 'n':
00194                         /* Assign length to next arg */
00195                         if (long_arg == 0) {
00196                             int * pos_ptr;
00197                             pos_ptr = va_arg(args, int *);
00198                             *pos_ptr = ec_len(result);
00199                         } else if (long_arg > 0) {
00200                             long * pos_ptr;
00201                             pos_ptr = va_arg(args, long *);
00202                             *pos_ptr = ec_len(result);
00203                         } else {
00204                             short * pos_ptr;
00205                             pos_ptr = va_arg(args, short *);
00206                             *pos_ptr = ec_len(result);
00207                         }
00208                         goto done;
00209                     case 'r':
00210                         /* Append cord and any padding  */
00211                         if (width == VARIABLE) width = va_arg(args, int);
00212                         if (prec == VARIABLE) prec = va_arg(args, int);
00213             arg = va_arg(args, CORD);
00214             len = CORD_len(arg);
00215             if (prec != NONE && len > (size_t)prec) {
00216               if (prec < 0) return(-1);
00217               arg = CORD_substr(arg, 0, prec);
00218               len = prec;
00219             }
00220             if (width != NONE && len < (size_t)width) {
00221               char * blanks = GC_MALLOC_ATOMIC(width-len+1);
00222
00223               memset(blanks, ' ', width-len);
00224               blanks[width-len] = '\0';
00225               if (left_adj) {
00226                 arg = CORD_cat(arg, blanks);
00227               } else {
00228                 arg = CORD_cat(blanks, arg);
00229               }
00230             }
00231             CORD_ec_append_cord(result, arg);
00232                         goto done;
00233             case 'c':
00234             if (width == NONE && prec == NONE) {
00235                 register char c;
00236
00237                 c = (char)va_arg(args, int);
00238                 CORD_ec_append(result, c);
00239                 goto done;
00240             }
00241             break;
00242             case 's':
00243                 if (width == NONE && prec == NONE) {
00244                 char * str = va_arg(args, char *);
00245                 register char c;
00246
00247                 while (c = *str++) {
00248                     CORD_ec_append(result, c);
00249                 }
00250                 goto done;
00251             }
00252             break;
00253                     default:
00254                         break;
00255                 }
00256                 /* Use standard sprintf to perform conversion */
00257                 {
00258                     register char * buf;
00259                     va_list vsprintf_args;
00260                     int max_size = 0;
00261                     int res;
00262 #           ifdef __va_copy
00263                       __va_copy(vsprintf_args, args);
00264 #           else
00265 #             if defined(__GNUC__) /* and probably in other cases */
00266                         va_copy(vsprintf_args, args);
00267 #             else
00268             vsprintf_args = args;
00269 #             endif
00270 #           endif
00271                     if (width == VARIABLE) width = va_arg(args, int);
00272                     if (prec == VARIABLE) prec = va_arg(args, int);
00273                     if (width != NONE) max_size = width;
00274                     if (prec != NONE && prec > max_size) max_size = prec;
00275                     max_size += CONV_RESULT_LEN;
00276                     if (max_size >= CORD_BUFSZ) {
00277                         buf = GC_MALLOC_ATOMIC(max_size + 1);
00278                     } else {
00279                         if (CORD_BUFSZ - (result[0].ec_bufptr-result[0].ec_buf)
00280                             < max_size) {
00281                             CORD_ec_flush_buf(result);
00282                         }
00283                         buf = result[0].ec_bufptr;
00284                     }
00285                     switch(current) {
00286                         case 'd':
00287                         case 'i':
00288                         case 'o':
00289                         case 'u':
00290                         case 'x':
00291                         case 'X':
00292                         case 'c':
00293                             if (long_arg <= 0) {
00294                               (void) va_arg(args, int);
00295                             } else if (long_arg > 0) {
00296                               (void) va_arg(args, long);
00297                             }
00298                             break;
00299                         case 's':
00300                         case 'p':
00301                             (void) va_arg(args, char *);
00302                             break;
00303                         case 'f':
00304                         case 'e':
00305                         case 'E':
00306                         case 'g':
00307                         case 'G':
00308                             (void) va_arg(args, double);
00309                             break;
00310                         default:
00311                             return(-1);
00312                     }
00313                     res = vsprintf(buf, conv_spec, vsprintf_args);
00314                     len = (size_t)res;
00315                     if ((char *)(GC_word)res == buf) {
00316                         /* old style vsprintf */
00317                         len = strlen(buf);
00318                     } else if (res < 0) {
00319                         return(-1);
00320                     }
00321                     if (buf != result[0].ec_bufptr) {
00322                         register char c;
00323
00324             while (c = *buf++) {
00325                 CORD_ec_append(result, c);
00326                 }
00327             } else {
00328                 result[0].ec_bufptr = buf + len;
00329             }
00330                 }
00331               done:;
00332             }
00333         } else {
00334             CORD_ec_append(result, current);
00335         }
00336     }
00337     count = ec_len(result);
00338     *out = CORD_balance(CORD_ec_to_cord(result));
00339     return(count);
00340 }
00341
00342 int CORD_sprintf(CORD * out, CORD format, ...)
00343 {
00344     va_list args;
00345     int result;
00346
00347     va_start(args, format);
00348     result = CORD_vsprintf(out, format, args);
00349     va_end(args);
00350     return(result);
00351 }
00352
00353 int CORD_fprintf(FILE * f, CORD format, ...)
00354 {
00355     va_list args;
00356     int result;
00357     CORD out;
00358
00359     va_start(args, format);
00360     result = CORD_vsprintf(&out, format, args);
00361     va_end(args);
00362     if (result > 0) CORD_put(out, f);
00363     return(result);
00364 }
00365
00366 int CORD_vfprintf(FILE * f, CORD format, va_list args)
00367 {
00368     int result;
00369     CORD out;
00370
00371     result = CORD_vsprintf(&out, format, args);
00372     if (result > 0) CORD_put(out, f);
00373     return(result);
00374 }
00375
00376 int CORD_printf(CORD format, ...)
00377 {
00378     va_list args;
00379     int result;
00380     CORD out;
00381
00382     va_start(args, format);
00383     result = CORD_vsprintf(&out, format, args);
00384     va_end(args);
00385     if (result > 0) CORD_put(out, stdout);
00386     return(result);
00387 }
00388
00389 int CORD_vprintf(CORD format, va_list args)
00390 {
00391     int result;
00392     CORD out;
00393
00394     result = CORD_vsprintf(&out, format, args);
00395     if (result > 0) CORD_put(out, stdout);
00396     return(result);
00397 }


cordxtra.c File Reference

Include dependency graph for cordxtra.c:

Include dependency graph

Go to the source code of this file.

Compounds

struct | CORD_fill_data
struct | chr_data
struct | cache_line
struct | lf_state
struct | refill_data

Defines

#define | I_HIDE_POINTERS
#define | ATOMIC_WRITE(x, y) (x) = (y)
#define | ATOMIC_READ(x) (*(x))
#define | SEEK_SET 0
#define | SEEK_END 2
#define | BUFSZ 2048
#define | OUT_OF_MEMORY
#define | ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
#define | LOG_CACHE_SZ 14
#define | CACHE_SZ (1 << LOG_CACHE_SZ)
#define | LOG_LINE_SZ 9
#define | LINE_SZ (1 << LOG_LINE_SZ)
#define | MOD_CACHE_SZ(n) ((n) & (CACHE_SZ - 1))
#define | DIV_CACHE_SZ(n) ((n) >> LOG_CACHE_SZ)
#define | MOD_LINE_SZ(n) ((n) & (LINE_SZ - 1))
#define | DIV_LINE_SZ(n) ((n) >> LOG_LINE_SZ)
#define | LINE_START(n) ((n) & ~(LINE_SZ - 1))
#define | LAZY_THRESHOLD (128*1024 + 1)

Typedefs

typedef void(* | oom_fn )(void)

Functions

CORD | CORD_cat_char (CORD x, char c)
CORD | CORD_catn (int nargs,...)
int | CORD_fill_proc (char c, void *client_data)
int | CORD_batched_fill_proc (const char *s, void *client_data)
void | CORD_fill_buf (CORD x, size_t i, size_t len, char *buf)
int | CORD_cmp (CORD x, CORD y)
int | CORD_ncmp (CORD x, size_t x_start, CORD y, size_t y_start, size_t len)
char * | CORD_to_char_star (CORD x)
CORD | CORD_from_char_star (const char *s)
const char * | CORD_to_const_char_star (CORD x)
char | CORD_fetch (CORD x, size_t i)
int | CORD_put_proc (char c, void *client_data)
int | CORD_batched_put_proc (const char *s, void *client_data)
int | CORD_put (CORD x, FILE *f)
int | CORD_chr_proc (char c, void *client_data)
int | CORD_rchr_proc (char c, void *client_data)
int | CORD_batched_chr_proc (const char *s, void *client_data)
size_t | CORD_chr (CORD x, size_t i, int c)
size_t | CORD_rchr (CORD x, size_t i, int c)
size_t | CORD_str (CORD x, size_t start, CORD s)
void | CORD_ec_flush_buf (CORD_ec x)
void | CORD_ec_append_cord (CORD_ec x, CORD s)
char | CORD_nul_func (size_t i, void *client_data)
CORD | CORD_chars (char c, size_t i)
CORD | CORD_from_file_eager (FILE *f)
char | refill_cache (client_data) refill_data *client_data

Define Documentation

#define I_HIDE_POINTERS

Definition at line 28 of file cordxtra.c.

#define ATOMIC_WRITE | ( | x,
 |  | y | ) | (x) = (y)

Definition at line 39 of file cordxtra.c.

#define ATOMIC_READ ( x ) (*(x))

Definition at line 40 of file cordxtra.c.

#define SEEK_SET 0

Definition at line 44 of file cordxtra.c.

Referenced by file_read_action(), measure_jpeg(), parse_exif(), parse_IFD_entry(), and parse_IFD_entry_value().

#define SEEK_END 2

Definition at line 47 of file cordxtra.c.

#define BUFSZ 2048

Definition at line 50 of file cordxtra.c.

#define OUT_OF_MEMORY

Value:

{  if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
              ABORT("Out of memory\n"); }

Definition at line 55 of file cordxtra.c.

Referenced by CORD_cat_char(), CORD_from_char_star(), and CORD_to_char_star().

#define ABORT ( msg ) { fprintf(stderr, "%s\n", msg); abort(); }

Definition at line 57 of file cordxtra.c.

#define LOG_CACHE_SZ 14

Definition at line 479 of file cordxtra.c.

#define CACHE_SZ (1 << LOG_CACHE_SZ)

Definition at line 480 of file cordxtra.c.

#define LOG_LINE_SZ 9

Definition at line 481 of file cordxtra.c.

#define LINE_SZ (1 << LOG_LINE_SZ)

Definition at line 482 of file cordxtra.c.

#define MOD_CACHE_SZ ( n ) ((n) & (CACHE_SZ - 1))

Definition at line 496 of file cordxtra.c.

#define DIV_CACHE_SZ ( n ) ((n) >> LOG_CACHE_SZ)

Definition at line 497 of file cordxtra.c.

#define MOD_LINE_SZ ( n ) ((n) & (LINE_SZ - 1))

Definition at line 498 of file cordxtra.c.

#define DIV_LINE_SZ ( n ) ((n) >> LOG_LINE_SZ)

Definition at line 499 of file cordxtra.c.

#define LINE_START ( n ) ((n) & ~(LINE_SZ - 1))

Definition at line 500 of file cordxtra.c.

#define LAZY_THRESHOLD (128*1024 + 1)

Typedef Documentation

typedef void(* oom_fn)(void)

Definition at line 53 of file cordxtra.c.

Function Documentation

CORD CORD_cat_char | ( | CORD | x,
 |  | char | c
 | ) |

Definition at line 59 of file cordxtra.c.

References CORD, CORD_cat(), CORD_cat_char_star(), CORD_nul, GC_MALLOC_ATOMIC, and OUT_OF_MEMORY.

Referenced by String::Body::append().

CORD CORD_catn | ( | int | nargs,
 |  | ... |
 | ) |

Definition at line 71 of file cordxtra.c.

References CORD, CORD_cat(), CORD_EMPTY, and result.

int CORD_fill_proc | ( | char | c,
 |  | void * | client_data
 | ) |

Definition at line 92 of file cordxtra.c.

Referenced by CORD_fill_buf().

int CORD_batched_fill_proc | ( | const char * | s,
 |  | void * | client_data
 | ) |

Definition at line 106 of file cordxtra.c.

Referenced by CORD_fill_buf().

void CORD_fill_buf | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | len,
 |  | char * | buf
 | ) |

Definition at line 127 of file cordxtra.c.

References CORD_fill_data::buf, CORD, CORD_batched_fill_proc(), CORD_fill_proc(), CORD_iter5(), CORD_fill_data::count, and CORD_fill_data::len.

Referenced by CORD_to_char_star().

int CORD_cmp | ( | CORD | x,
 |  | CORD | y
 | ) |

Definition at line 137 of file cordxtra.c.

References CORD, CORD_EMPTY, CORD_IS_STRING, CORD_next, CORD_pos_advance, CORD_pos_chars_left, CORD_pos_cur_char_addr, CORD_pos_fetch, CORD_pos_valid, CORD_set_pos(), and result.

Referenced by String::Body::operator!=(), String::Body::operator<(), String::Body::operator<=(), String::Body::operator==(), String::Body::operator>(), and String::Body::operator>=().

int CORD_ncmp | ( | CORD | x,
 |  | size_t | x_start,
 |  | CORD | y,
 |  | size_t | y_start,
 |  | size_t | len
 | ) |

Definition at line 180 of file cordxtra.c.

References CORD, CORD_next, CORD_pos_advance, CORD_pos_chars_left, CORD_pos_cur_char_addr, CORD_pos_fetch, CORD_pos_valid, CORD_set_pos(), and result.

Referenced by CORD_str(), and String::Body::ncmp().

char* CORD_to_char_star ( CORD x )

Definition at line 225 of file cordxtra.c.

References CORD, CORD_fill_buf(), CORD_len(), GC_MALLOC_ATOMIC, OUT_OF_MEMORY, and result.

Referenced by CORD_str(), CORD_to_const_char_star(), and String::Body::cstrm().

CORD CORD_from_char_star ( const char * s )

Definition at line 236 of file cordxtra.c.

References CORD, GC_MALLOC_ATOMIC, OUT_OF_MEMORY, and result.

const char* CORD_to_const_char_star ( CORD x )

Definition at line 248 of file cordxtra.c.

References CORD, CORD_IS_STRING, and CORD_to_char_star().

Referenced by String::Body::cstr(), String::Body::v(), and String::Languages::v().

char CORD_fetch | ( | CORD | x,
 |  | size_t | i
 | ) |

Definition at line 255 of file cordxtra.c.

References ABORT, CORD, CORD_pos_fetch, CORD_pos_valid, and CORD_set_pos().

Referenced by String::Body::fetch().

int CORD_put_proc | ( | char | c,
 |  | void * | client_data
 | ) |

Definition at line 265 of file cordxtra.c.

Referenced by CORD_put().

int CORD_batched_put_proc | ( | const char * | s,
 |  | void * | client_data
 | ) |

Definition at line 272 of file cordxtra.c.

Referenced by CORD_put().

int CORD_put | ( | CORD | x,
 |  | FILE * | f
 | ) |

Definition at line 280 of file cordxtra.c.

References CORD, CORD_batched_put_proc(), CORD_iter5(), and CORD_put_proc().

Referenced by CORD_fprintf(), CORD_printf(), CORD_vfprintf(), and CORD_vprintf().

int CORD_chr_proc | ( | char | c,
 |  | void * | client_data
 | ) |

Definition at line 294 of file cordxtra.c.

Referenced by CORD_chr().

int CORD_rchr_proc | ( | char | c,
 |  | void * | client_data
 | ) |

Definition at line 303 of file cordxtra.c.

Referenced by CORD_rchr().

int CORD_batched_chr_proc | ( | const char * | s,
 |  | void * | client_data
 | ) |

Definition at line 312 of file cordxtra.c.

Referenced by CORD_chr().

size_t CORD_chr | ( | CORD | x,
 |  | size_t | i,
 |  | int | c
 | ) |

Definition at line 326 of file cordxtra.c.

References CORD, CORD_batched_chr_proc(), CORD_chr_proc(), CORD_iter5(), chr_data::pos, and chr_data::target.

Referenced by String::Body::pos().

size_t CORD_rchr | ( | CORD | x,
 |  | size_t | i,
 |  | int | c
 | ) |

Definition at line 339 of file cordxtra.c.

References CORD, CORD_rchr_proc(), CORD_riter4(), chr_data::pos, and chr_data::target.

size_t CORD_str | ( | CORD | x,
 |  | size_t | start,
 |  | CORD | s
 | ) |

Definition at line 358 of file cordxtra.c.

References CORD, CORD_EMPTY, CORD_IS_STRING, CORD_len(), CORD_ncmp(), CORD_next, CORD_pos_fetch, CORD_set_pos(), CORD_substr(), and CORD_to_char_star().

Referenced by String::Body::pos().

void CORD_ec_flush_buf ( CORD_ec x )

Definition at line 411 of file cordxtra.c.

References CORD_cat_char_star(), CORD_ec_struct::ec_buf, CORD_ec_struct::ec_bufptr, CORD_ec_struct::ec_cord, and GC_MALLOC_ATOMIC.

Referenced by CORD_ec_append_cord(), CORD_from_file_eager(), and CORD_vsprintf().

void CORD_ec_append_cord | ( | CORD_ec | x,
 |  | CORD | s
 | ) |

Definition at line 424 of file cordxtra.c.

References CORD, CORD_cat(), CORD_ec_flush_buf(), and CORD_ec_struct::ec_cord.

Referenced by CORD_vsprintf().

char CORD_nul_func | ( | size_t | i,
 |  | void * | client_data
 | ) |

Definition at line 431 of file cordxtra.c.

Referenced by CORD_chars().

CORD CORD_chars | ( | char | c,
 |  | size_t | i
 | ) |

Definition at line 436 of file cordxtra.c.

References CORD, CORD_from_fn(), and CORD_nul_func().

Referenced by String::Languages::append(), and String::Languages::make_langs().

CORD CORD_from_file_eager ( FILE * f )

Definition at line 441 of file cordxtra.c.

References CORD, CORD_balance(), CORD_cat(), CORD_ec_append, CORD_ec_flush_buf(), CORD_ec_init, CORD_ec_to_cord, CORD_nul, and CORD_ec_struct::ec_cord.

char refill_cache ( client_data ) [static]


cordxtra.c Source File

cordxtra.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993-1994 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to use or copy this program
00008  * for any purpose,  provided the above notices are retained on all copies.
00009  * Permission to modify the code and to distribute modified code is granted,
00010  * provided the above notices are retained, and a notice that the code was
00011  * modified is included with the above copyright notice.
00012  *
00013  * Author: Hans-J. Boehm (boehm@parc.xerox.com)
00014  */
00015 /*
00016  * These are functions on cords that do not need to understand their
00017  * implementation.  They serve also serve as example client code for
00018  * cord_basics.
00019  */
00020 /* Boehm, December 8, 1995 1:53 pm PST */
00021 #include "pa_config_includes.h"
00022 # include <stdio.h>
00023 # include <string.h>
00024 # include <stdlib.h>
00025 # include <stdarg.h>
00026 # include "cord.h"
00027 # include "ec.h"
00028 # define I_HIDE_POINTERS    /* So we get access to allocation lock. */
00029                 /* We use this for lazy file reading,   */
00030                 /* so that we remain independent    */
00031                 /* of the threads primitives.       */
00032 # include "gc.h"
00033
00034 /* For now we assume that pointer reads and writes are atomic,  */
00035 /* i.e. another thread always sees the state before or after    */
00036 /* a write.  This might be false on a Motorola M68K with    */
00037 /* pointers that are not 32-bit aligned.  But there probably    */
00038 /* aren't too many threads packages running on those.       */
00039 # define ATOMIC_WRITE(x,y) (x) = (y)
00040 # define ATOMIC_READ(x) (*(x))
00041
00042 /* The standard says these are in stdio.h, but they aren't always: */
00043 # ifndef SEEK_SET
00044 #   define SEEK_SET 0
00045 # endif
00046 # ifndef SEEK_END
00047 #   define SEEK_END 2
00048 # endif
00049
00050 # define BUFSZ 2048 /* Size of stack allocated buffers when     */
00051             /* we want large buffers.           */
00052
00053 typedef void (* oom_fn)(void);
00054
00055 # define OUT_OF_MEMORY {  if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \
00056               ABORT("Out of memory\n"); }
00057 # define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }
00058
00059 CORD CORD_cat_char(CORD x, char c)
00060 {
00061     register char * string;
00062
00063     if (c == '\0') return(CORD_cat(x, CORD_nul(1)));
00064     string = GC_MALLOC_ATOMIC(2);
00065     if (string == 0) OUT_OF_MEMORY;
00066     string[0] = c;
00067     string[1] = '\0';
00068     return(CORD_cat_char_star(x, string, 1));
00069 }
00070
00071 CORD CORD_catn(int nargs, ...)
00072 {
00073     register CORD result = CORD_EMPTY;
00074     va_list args;
00075     register int i;
00076
00077     va_start(args, nargs);
00078     for (i = 0; i < nargs; i++) {
00079         register CORD next = va_arg(args, CORD);
00080         result = CORD_cat(result, next);
00081     }
00082     va_end(args);
00083     return(result);
00084 }
00085
00086 typedef struct {
00087     size_t len;
00088     size_t count;
00089     char * buf;
00090 } CORD_fill_data;
00091
00092 int CORD_fill_proc(char c, void * client_data)
00093 {
00094     register CORD_fill_data * d = (CORD_fill_data *)client_data;
00095     register size_t count = d -> count;
00096
00097     (d -> buf)[count] = c;
00098     d -> count = ++count;
00099     if (count >= d -> len) {
00100         return(1);
00101     } else {
00102         return(0);
00103     }
00104 }
00105
00106 int CORD_batched_fill_proc(const char*  s, void * client_data)
00107 {
00108     register CORD_fill_data * d = (CORD_fill_data *)client_data;
00109     register size_t count = d -> count;
00110     register size_t max = d -> len;
00111     register char * buf = d -> buf;
00112     register const char*  t = s;
00113
00114     while((buf[count] = *t++) != '\0') {
00115         count++;
00116         if (count >= max) {
00117             d -> count = count;
00118             return(1);
00119         }
00120     }
00121     d -> count = count;
00122     return(0);
00123 }
00124
00125 /* Fill buf with len characters starting at i.              */
00126 /* Assumes len characters are available.                */
00127 void CORD_fill_buf(CORD x, size_t i, size_t len, char * buf)
00128 {
00129     CORD_fill_data fd;
00130
00131     fd.len = len;
00132     fd.buf = buf;
00133     fd.count = 0;
00134     (void)CORD_iter5(x, i, CORD_fill_proc, CORD_batched_fill_proc, &fd);
00135 }
00136
00137 int CORD_cmp(CORD x, CORD y)
00138 {
00139     CORD_pos xpos;
00140     CORD_pos ypos;
00141     register size_t avail, yavail;
00142
00143     if (y == CORD_EMPTY) return(x != CORD_EMPTY);
00144     if (x == CORD_EMPTY) return(-1);
00145     if (CORD_IS_STRING(y) && CORD_IS_STRING(x)) return(strcmp(x,y));
00146     CORD_set_pos(xpos, x, 0);
00147     CORD_set_pos(ypos, y, 0);
00148     for(;;) {
00149         if (!CORD_pos_valid(xpos)) {
00150             if (CORD_pos_valid(ypos)) {
00151                 return(-1);
00152             } else {
00153                 return(0);
00154             }
00155         }
00156         if (!CORD_pos_valid(ypos)) {
00157             return(1);
00158         }
00159         if ((avail = CORD_pos_chars_left(xpos)) <= 0
00160             || (yavail = CORD_pos_chars_left(ypos)) <= 0) {
00161             register char xcurrent = CORD_pos_fetch(xpos);
00162             register char ycurrent = CORD_pos_fetch(ypos);
00163             if (xcurrent != ycurrent) return(xcurrent - ycurrent);
00164             CORD_next(xpos);
00165             CORD_next(ypos);
00166         } else {
00167             /* process as many characters as we can */
00168             register int result;
00169
00170             if (avail > yavail) avail = yavail;
00171             result = strncmp(CORD_pos_cur_char_addr(xpos),
00172                          CORD_pos_cur_char_addr(ypos), avail);
00173             if (result != 0) return(result);
00174             CORD_pos_advance(xpos, avail);
00175             CORD_pos_advance(ypos, avail);
00176         }
00177     }
00178 }
00179
00180 int CORD_ncmp(CORD x, size_t x_start, CORD y, size_t y_start, size_t len)
00181 {
00182     CORD_pos xpos;
00183     CORD_pos ypos;
00184     register size_t count;
00185     register long avail, yavail;
00186
00187     CORD_set_pos(xpos, x, x_start);
00188     CORD_set_pos(ypos, y, y_start);
00189     for(count = 0; count < len;) {
00190         if (!CORD_pos_valid(xpos)) {
00191             if (CORD_pos_valid(ypos)) {
00192                 return(-1);
00193             } else {
00194                 return(0);
00195             }
00196         }
00197         if (!CORD_pos_valid(ypos)) {
00198             return(1);
00199         }
00200         if ((avail = CORD_pos_chars_left(xpos)) <= 0
00201             || (yavail = CORD_pos_chars_left(ypos)) <= 0) {
00202             register char xcurrent = CORD_pos_fetch(xpos);
00203             register char ycurrent = CORD_pos_fetch(ypos);
00204             if (xcurrent != ycurrent) return(xcurrent - ycurrent);
00205             CORD_next(xpos);
00206             CORD_next(ypos);
00207             count++;
00208         } else {
00209             /* process as many characters as we can */
00210             register int result;
00211
00212             if (avail > yavail) avail = yavail;
00213             count += avail;
00214             if (count > len) avail -= (count - len);
00215             result = strncmp(CORD_pos_cur_char_addr(xpos),
00216                          CORD_pos_cur_char_addr(ypos), (size_t)avail);
00217             if (result != 0) return(result);
00218             CORD_pos_advance(xpos, (size_t)avail);
00219             CORD_pos_advance(ypos, (size_t)avail);
00220         }
00221     }
00222     return(0);
00223 }
00224
00225 char * CORD_to_char_star(CORD x)
00226 {
00227     register size_t len = CORD_len(x);
00228     char * result = GC_MALLOC_ATOMIC(len + 1);
00229
00230     if (result == 0) OUT_OF_MEMORY;
00231     CORD_fill_buf(x, 0, len, result);
00232     result[len] = '\0';
00233     return(result);
00234 }
00235
00236 CORD CORD_from_char_star(const char* s)
00237 {
00238     char * result;
00239     size_t len = strlen(s);
00240
00241     if (0 == len) return(CORD_EMPTY);
00242     result = GC_MALLOC_ATOMIC(len + 1);
00243     if (result == 0) OUT_OF_MEMORY;
00244     memcpy(result, s, len+1);
00245     return(result);
00246 }
00247
00248 const char*  CORD_to_const_char_star(CORD x)
00249 {
00250     if (x == 0) return("");
00251     if (CORD_IS_STRING(x)) return((const char* )x);
00252     return(CORD_to_char_star(x));
00253 }
00254
00255 char CORD_fetch(CORD x, size_t i)
00256 {
00257     CORD_pos xpos;
00258
00259     CORD_set_pos(xpos, x, i);
00260     if (!CORD_pos_valid(xpos)) ABORT("bad index?");
00261     return(CORD_pos_fetch(xpos));
00262 }
00263
00264
00265 int CORD_put_proc(char c, void * client_data)
00266 {
00267     register FILE * f = (FILE *)client_data;
00268
00269     return(putc(c, f) == EOF);
00270 }
00271
00272 int CORD_batched_put_proc(const char*  s, void * client_data)
00273 {
00274     register FILE * f = (FILE *)client_data;
00275
00276     return(fputs(s, f) == EOF);
00277 }
00278
00279
00280 int CORD_put(CORD x, FILE * f)
00281 {
00282     if (CORD_iter5(x, 0, CORD_put_proc, CORD_batched_put_proc, f)) {
00283         return(EOF);
00284     } else {
00285         return(1);
00286     }
00287 }
00288
00289 typedef struct {
00290     size_t pos;     /* Current position in the cord */
00291     char target;    /* Character we're looking for  */
00292 } chr_data;
00293
00294 int CORD_chr_proc(char c, void * client_data)
00295 {
00296     register chr_data * d = (chr_data *)client_data;
00297
00298     if (c == d -> target) return(1);
00299     (d -> pos) ++;
00300     return(0);
00301 }
00302
00303 int CORD_rchr_proc(char c, void * client_data)
00304 {
00305     register chr_data * d = (chr_data *)client_data;
00306
00307     if (c == d -> target) return(1);
00308     (d -> pos) --;
00309     return(0);
00310 }
00311
00312 int CORD_batched_chr_proc(const char* s, void * client_data)
00313 {
00314     register chr_data * d = (chr_data *)client_data;
00315     register char * occ = strchr(s, d -> target);
00316
00317     if (occ == 0) {
00318         d -> pos += strlen(s);
00319         return(0);
00320     } else {
00321         d -> pos += occ - s;
00322         return(1);
00323     }
00324 }
00325
00326 size_t CORD_chr(CORD x, size_t i, int c)
00327 {
00328     chr_data d;
00329
00330     d.pos = i;
00331     d.target = c;
00332     if (CORD_iter5(x, i, CORD_chr_proc, CORD_batched_chr_proc, &d)) {
00333         return(d.pos);
00334     } else {
00335         return(CORD_NOT_FOUND);
00336     }
00337 }
00338
00339 size_t CORD_rchr(CORD x, size_t i, int c)
00340 {
00341     chr_data d;
00342
00343     d.pos = i;
00344     d.target = c;
00345     if (CORD_riter4(x, i, CORD_rchr_proc, &d)) {
00346         return(d.pos);
00347     } else {
00348         return(CORD_NOT_FOUND);
00349     }
00350 }
00351
00352 /* Find the first occurrence of s in x at position start or later.  */
00353 /* This uses an asymptotically poor algorithm, which should typically   */
00354 /* perform acceptably.  We compare the first few characters directly,   */
00355 /* and call CORD_ncmp whenever there is a partial match.        */
00356 /* This has the advantage that we allocate very little, or not at all.  */
00357 /* It's very fast if there are few close misses.            */
00358 size_t CORD_str(CORD x, size_t start, CORD s)
00359 {
00360     CORD_pos xpos;
00361     size_t xlen = CORD_len(x);
00362     size_t slen;
00363     register size_t start_len;
00364     const char*  s_start;
00365     unsigned long s_buf = 0;    /* The first few characters of s    */
00366     unsigned long x_buf = 0;    /* Start of candidate substring.    */
00367                     /* Initialized only to make compilers   */
00368                     /* happy.               */
00369     unsigned long mask = 0;
00370     register size_t i;
00371     register size_t match_pos;
00372
00373     if (s == CORD_EMPTY) return(start);
00374     if (CORD_IS_STRING(s)) {
00375         s_start = s;
00376         slen = strlen(s);
00377     } else {
00378         s_start = CORD_to_char_star(CORD_substr(s, 0, sizeof(unsigned long)));
00379         slen = CORD_len(s);
00380     }
00381     if (xlen < start || xlen - start < slen) return(CORD_NOT_FOUND);
00382     start_len = slen;
00383     if (start_len > sizeof(unsigned long)) start_len = sizeof(unsigned long);
00384     CORD_set_pos(xpos, x, start);
00385     for (i = 0; i < start_len; i++) {
00386         mask <<= 8;
00387         mask |= 0xff;
00388         s_buf <<= 8;
00389         s_buf |= (unsigned char)s_start[i];
00390         x_buf <<= 8;
00391         x_buf |= (unsigned char)CORD_pos_fetch(xpos);
00392         CORD_next(xpos);
00393     }
00394     for (match_pos = start; ; match_pos++) {
00395         if ((x_buf & mask) == s_buf) {
00396             if (slen == start_len ||
00397                 CORD_ncmp(x, match_pos + start_len,
00398                       s, start_len, slen - start_len) == 0) {
00399                 return(match_pos);
00400             }
00401         }
00402     if ( match_pos == xlen - slen ) {
00403         return(CORD_NOT_FOUND);
00404     }
00405         x_buf <<= 8;
00406         x_buf |= (unsigned char)CORD_pos_fetch(xpos);
00407         CORD_next(xpos);
00408     }
00409 }
00410
00411 void CORD_ec_flush_buf(CORD_ec x)
00412 {
00413     register size_t len = x[0].ec_bufptr - x[0].ec_buf;
00414     char * s;
00415
00416     if (len == 0) return;
00417     s = GC_MALLOC_ATOMIC(len+1);
00418     memcpy(s, x[0].ec_buf, len);
00419     s[len] = '\0';
00420     x[0].ec_cord = CORD_cat_char_star(x[0].ec_cord, s, len);
00421     x[0].ec_bufptr = x[0].ec_buf;
00422 }
00423
00424 void CORD_ec_append_cord(CORD_ec x, CORD s)
00425 {
00426     CORD_ec_flush_buf(x);
00427     x[0].ec_cord = CORD_cat(x[0].ec_cord, s);
00428 }
00429
00430 /*ARGSUSED*/
00431 char CORD_nul_func(size_t i, void * client_data)
00432 {
00433     return((char)(unsigned long)client_data);
00434 }
00435
00436 CORD CORD_chars(char c, size_t i)
00437 {
00438     return(CORD_from_fn(CORD_nul_func, (void *)(unsigned long)c, i));
00439 }
00440
00441 CORD CORD_from_file_eager(FILE * f)
00442 {
00443     register int c;
00444     CORD_ec ecord;
00445
00446     CORD_ec_init(ecord);
00447     for(;;) {
00448         c = getc(f);
00449         if (c == 0) {
00450           /* Append the right number of NULs    */
00451           /* Note that any string of NULs is rpresented in 4 words, */
00452           /* independent of its length.                 */
00453             register size_t count = 1;
00454
00455             CORD_ec_flush_buf(ecord);
00456             while ((c = getc(f)) == 0) count++;
00457             ecord[0].ec_cord = CORD_cat(ecord[0].ec_cord, CORD_nul(count));
00458         }
00459         if (c == EOF) break;
00460         CORD_ec_append(ecord, c);
00461     }
00462     (void) fclose(f);
00463     return(CORD_balance(CORD_ec_to_cord(ecord)));
00464 }
00465
00466 /* The state maintained for a lazily read file consists primarily   */
00467 /* of a large direct-mapped cache of previously read values.        */
00468 /* We could rely more on stdio buffering.  That would have 2        */
00469 /* disadvantages:                           */
00470 /*      1) Empirically, not all fseek implementations preserve the  */
00471 /*     buffer whenever they could.                  */
00472 /*  2) It would fail if 2 different sections of a long cord     */
00473 /*     were being read alternately.                 */
00474 /* We do use the stdio buffer for read ahead.               */
00475 /* To guarantee thread safety in the presence of atomic pointer     */
00476 /* writes, cache lines are always replaced, and never modified in   */
00477 /* place.                               */
00478
00479 # define LOG_CACHE_SZ 14
00480 # define CACHE_SZ (1 << LOG_CACHE_SZ)
00481 # define LOG_LINE_SZ 9
00482 # define LINE_SZ (1 << LOG_LINE_SZ)
00483
00484 typedef struct {
00485     size_t tag;
00486     char data[LINE_SZ];
00487         /* data[i%LINE_SZ] = ith char in file if tag = i/LINE_SZ    */
00488 } cache_line;
00489
00490 typedef struct {
00491     FILE * lf_file;
00492     size_t lf_current;  /* Current file pointer value */
00493     cache_line * volatile lf_cache[CACHE_SZ/LINE_SZ];
00494 } lf_state;
00495
00496 # define MOD_CACHE_SZ(n) ((n) & (CACHE_SZ - 1))
00497 # define DIV_CACHE_SZ(n) ((n) >> LOG_CACHE_SZ)
00498 # define MOD_LINE_SZ(n) ((n) & (LINE_SZ - 1))
00499 # define DIV_LINE_SZ(n) ((n) >> LOG_LINE_SZ)
00500 # define LINE_START(n) ((n) & ~(LINE_SZ - 1))
00501
00502 typedef struct {
00503     lf_state * state;
00504     size_t file_pos;    /* Position of needed character. */
00505     cache_line * new_cache;
00506 } refill_data;
00507
00508 /* Executed with allocation lock. */
00509 static char refill_cache(client_data)
00510 refill_data * client_data;
00511 {
00512     register lf_state * state = client_data -> state;
00513     register size_t file_pos = client_data -> file_pos;
00514     FILE *f = state -> lf_file;
00515     size_t line_start = LINE_START(file_pos);
00516     size_t line_no = DIV_LINE_SZ(MOD_CACHE_SZ(file_pos));
00517     cache_line * new_cache = client_data -> new_cache;
00518
00519     if (line_start != state -> lf_current
00520         && fseek(f, line_start, SEEK_SET) != 0) {
00521             ABORT("fseek failed");
00522     }
00523     if (fread(new_cache -> data, sizeof(char), LINE_SZ, f)
00524         <= file_pos - line_start) {
00525         ABORT("fread failed");
00526     }
00527     new_cache -> tag = DIV_LINE_SZ(file_pos);
00528     /* Store barrier goes here. */
00529     ATOMIC_WRITE(state -> lf_cache[line_no], new_cache);
00530     state -> lf_current = line_start + LINE_SZ;
00531     return(new_cache->data[MOD_LINE_SZ(file_pos)]);
00532 }
00533
00534 char CORD_lf_func(size_t i, void * client_data)
00535 {
00536     register lf_state * state = (lf_state *)client_data;
00537     register cache_line * volatile * cl_addr =
00538         &(state -> lf_cache[DIV_LINE_SZ(MOD_CACHE_SZ(i))]);
00539     register cache_line * cl = (cache_line *)ATOMIC_READ(cl_addr);
00540
00541     if (cl == 0 || cl -> tag != DIV_LINE_SZ(i)) {
00542         /* Cache miss */
00543         refill_data rd;
00544
00545         rd.state = state;
00546         rd.file_pos =  i;
00547         rd.new_cache = GC_NEW_ATOMIC(cache_line);
00548         if (rd.new_cache == 0) OUT_OF_MEMORY;
00549         return((char)(GC_word)
00550               GC_call_with_alloc_lock((GC_fn_type) refill_cache, &rd));
00551     }
00552     return(cl -> data[MOD_LINE_SZ(i)]);
00553 }
00554
00555 /*ARGSUSED*/
00556 void CORD_lf_close_proc(void * obj, void * client_data)
00557 {
00558     if (fclose(((lf_state *)obj) -> lf_file) != 0) {
00559         ABORT("CORD_lf_close_proc: fclose failed");
00560     }
00561 }
00562
00563 #ifndef PA_DEBUG_DISABLE_GC
00564 CORD CORD_from_file_lazy_inner(FILE * f, size_t len)
00565 {
00566     register lf_state * state = GC_NEW(lf_state);
00567     register int i;
00568
00569     if (state == 0) OUT_OF_MEMORY;
00570     if (len != 0) {
00571     /* Dummy read to force buffer allocation.   */
00572     /* This greatly increases the probability   */
00573     /* of avoiding deadlock if buffer allocation    */
00574     /* is redirected to GC_malloc and the       */
00575     /* world is multithreaded.          */
00576     char buf[1];
00577
00578     (void) fread(buf, 1, 1, f);
00579     rewind(f);
00580     }
00581     state -> lf_file = f;
00582     for (i = 0; i < CACHE_SZ/LINE_SZ; i++) {
00583         state -> lf_cache[i] = 0;
00584     }
00585     state -> lf_current = 0;
00586     GC_REGISTER_FINALIZER(state, CORD_lf_close_proc, 0, 0, 0);
00587     return(CORD_from_fn(CORD_lf_func, state, len));
00588 }
00589
00590 CORD CORD_from_file_lazy(FILE * f)
00591 {
00592     register long len;
00593
00594     if (fseek(f, 0l, SEEK_END) != 0) {
00595         ABORT("Bad fd argument - fseek failed");
00596     }
00597     if ((len = ftell(f)) < 0) {
00598         ABORT("Bad fd argument - ftell failed");
00599     }
00600     rewind(f);
00601     return(CORD_from_file_lazy_inner(f, (size_t)len));
00602 }
00603
00604 # define LAZY_THRESHOLD (128*1024 + 1)
00605
00606 CORD CORD_from_file(FILE * f)
00607 {
00608     register long len;
00609
00610     if (fseek(f, 0l, SEEK_END) != 0) {
00611         ABORT("Bad fd argument - fseek failed");
00612     }
00613     if ((len = ftell(f)) < 0) {
00614         ABORT("Bad fd argument - ftell failed");
00615     }
00616     rewind(f);
00617     if (len < LAZY_THRESHOLD) {
00618         return(CORD_from_file_eager(f));
00619     } else {
00620         return(CORD_from_file_lazy_inner(f, (size_t)len));
00621     }
00622 }
00623 #endif


date.C File Reference

Parser: date parser class. More...

Include dependency graph for date.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MDate
class | Date_calendar_table_template_columns

Defines

#define | WDFILL(size, value)

Functions

DECLARE_CLASS_VAR (date, new MDate, 0)
Table date_calendar_table_template (new Date_calendar_table_template_columns)
void | _now (Request &r, MethodParams &params)
int | to_tm_year (int iyear)
shrinked range: 1970/1/1 to 2038/1/1. More...

tm | cstr_to_time_t (char *cstr)
void | _create (Request &r, MethodParams &params)
void | _sql_string (Request &r, MethodParams &)
void | _roll (Request &r, MethodParams &params)
Table & | fill_month_days (Request &r, MethodParams &params, bool rus)
Table & | fill_week_days (Request &r, MethodParams &params, bool rus)
void | _calendar (Request &r, MethodParams &params)
void | _unix_timestamp (Request &r, MethodParams &params)

Variables

const char *const | IDENT_DATE_C = "$Date: 2005/12/09 07:18:07 $"

Detailed Description

Parser: date parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file date.C.

Define Documentation

#define WDFILL | ( | size,
 |  | value | )

Value:

{ \
            char *buf=new(PointerFreeGC) char[size+1]; \
            *row+=new String(buf, sprintf(buf, "%0"#size"d", value)); \
        }

Function Documentation

DECLARE_CLASS_VAR | ( | date | ,
 |  | new | MDate,
 |  | 0 |
 | ) |

Table date_calendar_table_template ( new Date_calendar_table_template_columns )

void _now | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 53 of file date.C.

References MethodParams::as_double(), Array< Value * >::count(), GET_SELF, SECS_PER_DAY, and VDate::set_time().

Referenced by MDate::MDate().

int to_tm_year ( int iyear ) [static]

shrinked range: 1970/1/1 to 2038/1/1.

Definition at line 64 of file date.C.

Referenced by _create(), and cstr_to_time_t().

tm cstr_to_time_t ( char * cstr )

Definition at line 75 of file date.C.

References lsplit(), pa_atoi(), and to_tm_year().

Referenced by _create(), and parse_IFD_entry_formatted_value().

void _create | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 118 of file date.C.

References String::as_double(), MethodParams::as_int(), Array< Value * >::count(), cstr_to_time_t(), String::cstrm(), GET_SELF, SECS_PER_DAY, VDate::set_time(), and to_tm_year().

Referenced by MDate::MDate().

void _sql_string | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 151 of file date.C.

References VDate::get_localtime(), GET_SELF, size, and Request::write_assign_lang().

Referenced by MDate::MDate().

void _roll | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 160 of file date.C.

References MethodParams::as_int(), MethodParams::as_string(), GET_SELF, VDate::get_time(), offset, VDate::set_time(), and VDate::set_tz().

Referenced by MDate::MDate().

Table& fill_month_days | ( | Request & | r,
 |  | MethodParams & | params,
 |  | bool | rus
 | ) | [static]

Definition at line 242 of file date.C.

References String::append_know_length(), ArrayString, MethodParams::as_int(), Array< ArrayString * >::element_type, getMonthDays(), String::L_CLEAN, result, snprintf, and VDate::week_no().

Referenced by _calendar().

Table& fill_week_days | ( | Request & | r,
 |  | MethodParams & | params,
 |  | bool | rus
 | ) | [static]

Definition at line 312 of file date.C.

References ArrayString, MethodParams::as_int(), Table::columns_type, Array< ArrayString * >::element_type, result, and SECS_PER_DAY.

Referenced by _calendar().

void _calendar | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 361 of file date.C.

References MethodParams::as_string(), Array< Value * >::count(), fill_month_days(), fill_week_days(), and Request::write_no_lang().

Referenced by MDate::MDate().

void _unix_timestamp | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 382 of file date.C.

References MethodParams::as_int(), Array< Value * >::count(), GET_SELF, VDate::get_time(), VDate::set_time(), and Request::write_no_lang().

Referenced by MDate::MDate().

Variable Documentation

const char* const IDENT_DATE_C = "$Date: 2005/12/09 07:18:07 $" [static]

Definition at line 8 of file date.C.


date.C Source File

date.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_DATE_C="$Date: 2005/12/09 07:18:07 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vdouble.h"
00015 #include "pa_vdate.h"
00016 #include "pa_vtable.h"
00017
00018 // class
00019
00020 class MDate: public Methoded {
00021 public: // VStateless_class
00022     Value* create_new_value(Pool&, HashStringValue&) { return new VDate(0); }
00023
00024 public:
00025     MDate();
00026 public: // Methoded
00027     bool used_directly() { return true; }
00028 };
00029
00030 // global variable
00031
00032 DECLARE_CLASS_VAR(date, new MDate, 0);
00033
00034 // helpers
00035
00036 class Date_calendar_table_template_columns: public ArrayString {
00037 public:
00038     Date_calendar_table_template_columns(): ArrayString(6+2) {
00039         for(int i=0; i<=6; i++) {
00040             char *cname=new(PointerFreeGC) char[1/*strlen("6")*/+1/*terminating 0*/];
00041             *this+=new String(cname, sprintf(cname, "%d", i)); // .i column name
00042         }
00043         *this+=new String("week");
00044         *this+=new String("year");
00045     }
00046 };
00047
00048
00049 Table date_calendar_table_template(new Date_calendar_table_template_columns);
00050
00051 // methods
00052
00053 static void _now(Request& r, MethodParams& params) {
00054     VDate& vdate=GET_SELF(r, VDate);
00055
00056     time_t t=time(0);
00057     if(params.count()==1) // ^now(offset)
00058         t+=(time_t)round(params.as_double(0, "offset must be double", r)*SECS_PER_DAY);
00059
00060     vdate.set_time(t);
00061 }
00062
00064 static int to_tm_year(int iyear) {
00065     if(iyear<1970 || iyear>2038)
00066         throw Exception(0,
00067             0,
00068             "year '%d' is out of valid range", iyear);
00069     return iyear-1900;
00070 }
00071
00072 // 2002-04-25 18:14:00
00073 // 18:14:00
00074 // 2002:04:25 [+maybe time]
00075 /*not static, used in image.C*/ tm cstr_to_time_t(char *cstr) {
00076     if( !cstr || !*cstr )
00077         throw Exception(0,
00078             0,
00079             "empty string is not valid datetime");
00080
00081     char *cur=cstr;
00082     char date_delim=isdigit((unsigned char)cur[0])&&isdigit((unsigned char)cur[1])&&isdigit((unsigned char)cur[2])&&isdigit((unsigned char)cur[3])&&cur[4]==':'?':'
00083         :'-';
00084     const char* year=lsplit(&cur, date_delim);
00085     const char* month=lsplit(&cur, date_delim);
00086     const char* mday=lsplit(&cur, ' ');
00087     if(!month)
00088         cur=cstr;
00089     const char* hour=lsplit(&cur, ':');
00090     const char* min=lsplit(&cur, ':');
00091     const char* sec=lsplit(&cur, '.');
00092     const char* msec=cur;
00093
00094     tm tmIn;  memset(&tmIn, 0, sizeof(tmIn));
00095     tmIn.tm_isdst=-1;
00096     if(!month)
00097         if(min) {
00098             year=mday=0; // HH:MM
00099             time_t t=time(0);
00100             tm *tmNow=localtime(&t);
00101             tmIn.tm_year=tmNow->tm_year;
00102             tmIn.tm_mon=tmNow->tm_mon;
00103             tmIn.tm_mday=tmNow->tm_mday;
00104             goto date_part_set;
00105         } else
00106             hour=min=sec=msec=0; // not YYYY- & not HH: = just YYYY
00107     tmIn.tm_year=to_tm_year(pa_atoi(year));
00108     tmIn.tm_mon=month?pa_atoi(month)-1:0;
00109     tmIn.tm_mday=mday?pa_atoi(mday):1;
00110 date_part_set:
00111     tmIn.tm_hour=hour?pa_atoi(hour):0;
00112     tmIn.tm_min=min?pa_atoi(min):0;
00113     tmIn.tm_sec=sec?pa_atoi(sec):0;
00114     //tmIn.tm_[msec<<no such, waits reimplementation of the class]=f(msec);
00115     return tmIn;
00116 }
00117
00118 static void _create(Request& r, MethodParams& params) {
00119     VDate& vdate=GET_SELF(r, VDate);
00120
00121     if(params.count()==1) {
00122         // ^create[2002-04-25 18:14:00]
00123         // ^create[18:14:00]
00124         if(const String* sdate=params[0].get_string())
00125             vdate.set_time(cstr_to_time_t(sdate->cstrm()));
00126         else { // ^create(float days)
00127             time_t t=(time_t)round(params.as_double(0, "float days must be double", r)*SECS_PER_DAY);
00128             if(t<0 || !localtime(&t))
00129                 throw Exception(0,
00130                     0,
00131                     "invalid datetime");
00132             vdate.set_time(t);
00133         }
00134     } else if(params.count()>=2) { // ^create(y;m;d[;h[;m[;s]]])
00135         tm tmIn; memset(&tmIn, 0, sizeof(tmIn));
00136         tmIn.tm_isdst=-1;
00137         tmIn.tm_year=to_tm_year(params.as_int(0, "year must be int", r));
00138         tmIn.tm_mon=params.as_int(1, "month must be int", r)-1;
00139         tmIn.tm_mday=params.count()>2?params.as_int(2, "mday must be int", r):1;
00140         int savedHour=0;
00141         if(params.count()>3) savedHour=tmIn.tm_hour=params.as_int(3, "hour must be int", r);
00142         if(params.count()>4) tmIn.tm_min=params.as_int(4, "minutes must be int", r);
00143         if(params.count()>5) tmIn.tm_sec=params.as_int(5, "seconds must be int", r);
00144         vdate.set_time(tmIn);
00145     } else
00146         throw Exception("parser.runtime",
00147             0,
00148             "invalid params count, must be 1 or >=2");
00149 }
00150
00151 static void _sql_string(Request& r, MethodParams&) {
00152     VDate& vdate=GET_SELF(r, VDate);
00153     int size=1+ 4+1+2+1+2 +1+ 2+1+2+1+2 +1 +1;
00154     char *buf=new(PointerFreeGC) char[size];
00155     size=strftime(buf, size, "%Y-%m-%d %H:%M:%S", &vdate.get_localtime());
00156
00157     r.write_assign_lang(String(buf, size));
00158 }
00159
00160 static void _roll(Request& r, MethodParams& params) {
00161     VDate& vdate=GET_SELF(r, VDate);
00162
00163     const String& what=params.as_string(0, "'what' must be string");
00164     int oyear=0;
00165     int omonth=0;
00166     int oday=0;
00167     int *offset;
00168     if(what=="year") offset=&oyear;
00169     else if(what=="month") offset=&omonth;
00170     else if(what=="day") offset=&oday;
00171     else if(what=="TZ") {
00172         const String& argument_tz=params.as_string(1, "'TZ' must be string");
00173         vdate.set_tz(&argument_tz);
00174         return;
00175     } else
00176         throw Exception("parser.runtime",
00177             &what,
00178             "must be year|month|day|TZ");
00179
00180     *offset=params.as_int(1, "offset must be int", r);
00181
00182     time_t self_time=vdate.get_time();
00183     tm tmIn=*localtime(&self_time);
00184     tm tmSaved=tmIn;
00185     int adjust_day=0;
00186     time_t t_changed_date;
00187     while(true) {
00188         tmIn.tm_year+=oyear;
00189         tmIn.tm_mon+=omonth;
00190         tmIn.tm_mday+=oday+adjust_day;
00191         tmIn.tm_hour=24/2;
00192         tmIn.tm_min=0;
00193         tmIn.tm_sec=0;
00194         int saved_mon=(tmIn.tm_mon+12*100)%12; // crossing year boundary backwards
00195         t_changed_date=mktime/*normalizetime*/(&tmIn);
00196         if(t_changed_date<0)
00197             throw Exception(0,
00198                 0,
00199                 "bad resulting time (rolled out of valid date range)");
00200         if(oday==0 && tmIn.tm_mon!=saved_mon/*but it changed*/) {
00201             if(adjust_day <= -3/*31->28 max, so never, but...*/)
00202                 throw Exception(0,
00203                     0,
00204                     "bad resulting time (day hole still with %d day adjustment)", adjust_day );
00205
00206             tmIn=tmSaved; // restoring
00207             --adjust_day; //retrying with prev day
00208         } else
00209             break;
00210     }
00211
00212     tm *tmOut=localtime(&t_changed_date);
00213     if(!tmOut)
00214         throw Exception(0,
00215             0,
00216             "bad resulting time (seconds from epoch=%d)", t_changed_date);
00217
00218     tmOut->tm_hour=tmSaved.tm_hour;
00219     tmOut->tm_min=tmSaved.tm_min;
00220     tmOut->tm_sec=tmSaved.tm_sec;
00221     tmOut->tm_isdst=-1;
00222     {
00223         time_t t_changed_time=mktime/*normalizetime*/(tmOut);
00224         /*autofix: in msk timezone last sunday of march hour hole: [2am->3am)
00225         if(
00226             tmOut->tm_hour!=tmSaved.tm_hour
00227             ||tmOut->tm_min!=tmSaved.tm_min)
00228             throw Exception(0,
00229                 0,
00230                 "bad resulting time (hour hole)");
00231         */
00232
00233         if(t_changed_time<0)
00234             throw Exception(0,
00235                 0,
00236                 "bad resulting time (after reconstruction)");
00237
00238         vdate.set_time(t_changed_time);
00239     }
00240 }
00241
00242 static Table& fill_month_days(Request& r, MethodParams& params, bool rus){
00243     Table::Action_options table_options;
00244     Table& result=*new Table(date_calendar_table_template, table_options);
00245
00246     int year=params.as_int(1, "year must be int", r);
00247     int month=max(1, min(params.as_int(2, "month must be int", r), 12)) -1;
00248
00249     tm tmIn;
00250     memset(&tmIn, 0, sizeof(tmIn));
00251     tmIn.tm_mday=1;
00252     tmIn.tm_mon=month;
00253     tmIn.tm_year=year-1900;
00254
00255     time_t t=mktime(&tmIn);
00256     if(t<0)
00257         throw Exception(0,
00258             0,
00259             "invalid date");
00260     tm *tmOut=localtime(&t);
00261
00262     int weekDay1=tmOut->tm_wday;
00263     if(rus)
00264         weekDay1=weekDay1?weekDay1-1:6; //sunday last
00265     int monthDays=getMonthDays(year, month);
00266
00267     for(int _day=1-weekDay1; _day<=monthDays;) {
00268         Table::element_type row(new ArrayString(7));
00269         // calculating year week no [1..54]
00270         char *weekno_buf=0; // surely would be assigned to, but to calm down compiler
00271         size_t weekno_size=0; // same
00272         int weekyear=0; // same
00273         // 0..6 week days-cells fill with month days
00274         for(int wday=0; wday<7; wday++, _day++) {
00275             String* cell=new String;
00276             if(_day>=1 && _day<=monthDays) {
00277                 char *buf=new(PointerFreeGC) char[2+1];
00278                 cell->append_know_length(buf, sprintf(buf, "%02d", _day), String::L_CLEAN);
00279             }
00280             *row+=cell;
00281
00282             if(wday==(rus?3:4)/*thursday*/) {
00283                 tm tms;
00284                 memset(&tms, 0, sizeof(tmIn));
00285                 tms.tm_mday=_day;
00286                 tms.tm_mon=month;
00287                 tms.tm_year=year-1900;
00288
00289                 /*normalize*/mktime(&tms);
00290                 weekyear=tms.tm_year+1900;
00291
00292                 const int weekno_buf_size=2+1/*for stupid snprintfs*/ +1;
00293
00294                 weekno_buf=new(PointerFreeGC) char[weekno_buf_size];
00295                 weekno_size=snprintf(weekno_buf, weekno_buf_size, "%02d", VDate::week_no(tms));
00296             }
00297
00298         }
00299         // appending year week no
00300         *row+=new String(weekno_buf, weekno_size);
00301         // appending year week year
00302         {
00303             char* buf=new(PointerFreeGC) char[4+1];
00304             *row+=new String(buf, sprintf(buf, "%02d", weekyear));
00305         }
00306         result+=row;
00307     }
00308
00309     return result;
00310 }
00311
00312 static Table& fill_week_days(Request& r, MethodParams& params, bool rus){
00313     Table::columns_type columns(new ArrayString(4));
00314     *columns+=new String("year");
00315     *columns+=new String("month");
00316     *columns+=new String("day");
00317     *columns+=new String("weekday");
00318     Table& result=*new Table(columns);
00319
00320     int year=params.as_int(1, "year must be int", r);
00321     int month=max(1, min(params.as_int(2, "month must be int", r), 12)) -1;
00322     int day=params.as_int(3, "day must be int", r);
00323
00324     tm tmIn;
00325     memset(&tmIn, 0, sizeof(tmIn));
00326     tmIn.tm_hour=18;
00327     tmIn.tm_mday=day;
00328     tmIn.tm_mon=month;
00329     tmIn.tm_year=year-1900;
00330
00331     time_t t=mktime(&tmIn);
00332     if(t<0)
00333         throw Exception(0,
00334             0,
00335             "invalid date");
00336     tm *tmOut=localtime(&t);
00337
00338     int baseWeekDay=tmOut->tm_wday;
00339     if(rus)
00340         baseWeekDay=baseWeekDay?baseWeekDay-1:6; //sunday last
00341
00342     t-=baseWeekDay*SECS_PER_DAY;
00343
00344     for(int curWeekDay=0; curWeekDay<7; curWeekDay++, t+=SECS_PER_DAY) {
00345         tm *tmOut=localtime(&t);
00346         Table::element_type row(new ArrayString(4));
00347 #define WDFILL(size, value) { \
00348             char *buf=new(PointerFreeGC) char[size+1]; \
00349             *row+=new String(buf, sprintf(buf, "%0"#size"d", value)); \
00350         }
00351         WDFILL(4, 1900+tmOut->tm_year);
00352         WDFILL(2, 1+tmOut->tm_mon);
00353         WDFILL(2, tmOut->tm_mday);
00354         WDFILL(2, tmOut->tm_wday);
00355         result+=row;
00356     }
00357
00358     return result;
00359 }
00360
00361 static void _calendar(Request& r, MethodParams& params) {
00362     const String& what=params.as_string(0, "format must be strig");
00363     bool rus=false;
00364     if(what=="rus")
00365         rus=true;
00366     else if(what=="eng")
00367         rus=false;
00368     else
00369         throw Exception("parser.runtime",
00370             &what,
00371             "must be rus|eng");
00372
00373     Table* table;
00374     if(params.count()==1+2)
00375         table=&fill_month_days(r, params, rus);
00376     else // 1+3
00377         table=&fill_week_days(r, params, rus);
00378
00379     r.write_no_lang(*new VTable(table));
00380 }
00381
00382 static void _unix_timestamp(Request& r, MethodParams& params) {
00383     VDate& vdate=GET_SELF(r, VDate);
00384
00385     if(params.count()==0) {
00386         // ^date.unix-timestamp[]
00387         r.write_no_lang(*new VInt((int)vdate.get_time()));
00388     } else {
00389         if(vdate.get_time())
00390             throw Exception(0,
00391                 0,
00392                 "date object already constructed");
00393
00394         // ^unix-timestamp(time_t)
00395         time_t t=(time_t)params.as_int(0, "Unix timestamp must be integer", r);
00396
00397         vdate.set_time(t);
00398     }
00399 }
00400
00401
00402 // constructor
00403
00404 MDate::MDate(): Methoded("date") {
00405     // ^now[]
00406     add_native_method("now", Method::CT_DYNAMIC, _now, 0, 1);
00407
00408     // ^create(float days)
00409     add_native_method("create", Method::CT_DYNAMIC, _create, 1, 6);
00410     // old name for compatibility with <= v1.17 2002/2/18 12:13:42 paf
00411     add_native_method("set", Method::CT_DYNAMIC, _create, 1, 6);
00412
00413     // ^sql-string[]
00414     add_native_method("sql-string", Method::CT_DYNAMIC, _sql_string, 0, 0);
00415
00416     // ^roll(year|month|day;+/- 1)
00417     add_native_method("roll", Method::CT_DYNAMIC, _roll, 2, 2);
00418
00419     // ^date:calendar[month|montheng;year;month]  = table
00420     // ^date:calendar[week|weekeng;year;month;day] = table
00421     add_native_method("calendar", Method::CT_STATIC, _calendar, 3, 4);
00422
00423
00424     // ^unix-timestamp[]
00425     add_native_method("unix-timestamp", Method::CT_DYNAMIC, _unix_timestamp, 0, 1);
00426 }


dftables.c File Reference

Include dependency graph for dftables.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | DFTABLES

Functions

int | main (void)

Define Documentation

#define DFTABLES

Definition at line 49 of file dftables.c.

Function Documentation

int main ( void )

Definition at line 53 of file dftables.c.

References cbit_length, ctype_digit, ctype_letter, ctype_meta, ctype_space, ctype_word, ctype_xdigit, and pcre_maketables().


dftables.c Source File

dftables.c

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005 /*
00006 PCRE is a library of functions to support regular expressions whose syntax
00007 and semantics are as close as possible to those of the Perl 5 language.
00008
00009 Written by: Philip Hazel <ph10@cam.ac.uk>
00010
00011            Copyright (c) 1997-1999 University of Cambridge
00012
00013 -----------------------------------------------------------------------------
00014 Permission is granted to anyone to use this software for any purpose on any
00015 computer system, and to redistribute it freely, subject to the following
00016 restrictions:
00017
00018 1. This software is distributed in the hope that it will be useful,
00019    but WITHOUT ANY WARRANTY; without even the implied warranty of
00020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00021
00022 2. The origin of this software must not be misrepresented, either by
00023    explicit claim or by omission.
00024
00025 3. Altered versions must be plainly marked as such, and must not be
00026    misrepresented as being the original software.
00027
00028 4. If PCRE is embedded in any software that is released under the GNU
00029    General Purpose Licence (GPL), then the terms of that licence shall
00030    supersede any condition above with which it is incompatible.
00031 -----------------------------------------------------------------------------
00032
00033 See the file Tech.Notes for some information on the internals.
00034 */
00035
00036
00037 /* This is a support program to generate the file chartables.c, containing
00038 character tables of various kinds. They are built according to the default C
00039 locale and used as the default tables by PCRE. Now that pcre_maketables is
00040 a function visible to the outside world, we make use of its code from here in
00041 order to be consistent. */
00042
00043 #include <ctype.h>
00044 #include <stdio.h>
00045 #include <string.h>
00046
00047 #include "internal.h"
00048
00049 #define DFTABLES          /* maketables.c notices this */
00050 #include "maketables.c"
00051
00052
00053 int main(void)
00054 {
00055 int i;
00056 unsigned const char *tables;
00057     tables = pcre_maketables();
00058
00059 printf(
00060   "/*************************************************\n"
00061   "*      Perl-Compatible Regular Expressions       *\n"
00062   "*************************************************/\n\n"
00063   "/* This file is automatically written by the dftables auxiliary \n"
00064   "program. If you edit it by hand, you might like to edit the Makefile to \n"
00065   "prevent its ever being regenerated.\n\n"
00066   "This file is #included in the compilation of pcre.c to build the default\n"
00067   "character tables which are used when no tables are passed to the compile\n"
00068   "function. */\n\n"
00069   "unsigned char pcre_default_tables[] = {\n\n"
00070   "/* This table is a lower casing table. */\n\n");
00071
00072 printf("  ");
00073 for (i = 0; i < 256; i++)
00074   {
00075   if ((i & 7) == 0 && i != 0) printf("\n  ");
00076   printf("%3d", *tables++);
00077   if (i != 255) printf(",");
00078   }
00079 printf(",\n\n");
00080
00081 printf("/* This table is a case flipping table. */\n\n");
00082
00083 printf("  ");
00084 for (i = 0; i < 256; i++)
00085   {
00086   if ((i & 7) == 0 && i != 0) printf("\n  ");
00087   printf("%3d", *tables++);
00088   if (i != 255) printf(",");
00089   }
00090 printf(",\n\n");
00091
00092 printf(
00093   "/* This table contains bit maps for digits, 'word' chars, and white\n"
00094   "space. Each map is 32 bytes long and the bits run from the least\n"
00095   "significant end of each byte. */\n\n");
00096
00097 printf("  ");
00098 for (i = 0; i < cbit_length; i++)
00099   {
00100   if ((i & 7) == 0 && i != 0)
00101     {
00102     if ((i & 31) == 0) printf("\n");
00103     printf("\n  ");
00104     }
00105   printf("0x%02x", *tables++);
00106   if (i != cbit_length - 1) printf(",");
00107   }
00108 printf(" ,\n\n");
00109
00110 printf(
00111   "/* This table identifies various classes of character by individual bits:\n"
00112   "  0x%02x   white space character\n"
00113   "  0x%02x   letter\n"
00114   "  0x%02x   decimal digit\n"
00115   "  0x%02x   hexadecimal digit\n"
00116   "  0x%02x   alphanumeric or '_'\n"
00117   "  0x%02x   regular expression metacharacter or binary zero\n*/\n\n",
00118   ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word,
00119   ctype_meta);
00120
00121 printf("  ");
00122 for (i = 0; i < 256; i++)
00123   {
00124   if ((i & 7) == 0 && i != 0)
00125     {
00126     printf(" /* ");
00127     if (isprint(i-8)) printf(" %c -", i-8);
00128       else printf("%3d-", i-8);
00129     if (isprint(i-1)) printf(" %c ", i-1);
00130       else printf("%3d", i-1);
00131     printf(" */\n  ");
00132     }
00133   printf("0x%02x", *tables++);
00134   if (i != 255) printf(",");
00135   }
00136
00137 printf("};/* ");
00138 if (isprint(i-8)) printf(" %c -", i-8);
00139   else printf("%3d-", i-8);
00140 if (isprint(i-1)) printf(" %c ", i-1);
00141   else printf("%3d", i-1);
00142 printf(" */\n\n/* End of chartables.c */\n");
00143
00144 return 0;
00145 }
00146
00147 /* End of dftables.c */


double.C File Reference

Parser: double parser class. More...

Include dependency graph for double.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MDouble

Typedefs

typedef void(* | vdouble_op_func_ptr )(VDouble &vdouble, double param)

Functions

void | _string_format (Request &r, MethodParams &)
DECLARE_CLASS_VAR (double, new MDouble, 0)
void | _int (Request &r, MethodParams &params)
void | _double (Request &r, MethodParams &params)
void | __inc (VDouble &vdouble, double param)
void | __dec (VDouble &vdouble, double param)
void | __mul (VDouble &vdouble, double param)
void | __div (VDouble &vdouble, double param)
void | __mod (VDouble &vdouble, double param)
void | vdouble_op (Request &r, MethodParams &params, vdouble_op_func_ptr func)
void | _inc (Request &r, MethodParams &params)
void | _dec (Request &r, MethodParams &params)
void | _mul (Request &r, MethodParams &params)
void | _div (Request &r, MethodParams &params)
void | _mod (Request &r, MethodParams &params)
const String * | sql_result_string (Request &r, MethodParams &params, HashStringValue *&options, Value *&default_code)
void | _sql (Request &r, MethodParams &params)

Variables

const char *const | IDENT_DOUBLE_C = "$Date: 2005/08/26 11:12:45 $"

Detailed Description

Parser: double parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file double.C.

Typedef Documentation

typedef void(* vdouble_op_func_ptr)(VDouble& vdouble, double param)

Definition at line 54 of file double.C.

Referenced by vdouble_op().

Function Documentation

void _string_format | ( | Request & | r,
 |  | MethodParams & |
 | ) |

Definition at line 91 of file string.C.

Referenced by MString::MString().

DECLARE_CLASS_VAR | ( | double | ,
 |  | new | MDouble,
 |  | 0 |
 | ) |

void _int | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 36 of file double.C.

References VDouble::as_int(), MethodParams::as_int(), Array< Value * >::count(), GET_SELF, and Request::write_no_lang().

Referenced by MDouble::MDouble().

void _double | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 45 of file double.C.

References VDouble::as_double(), MethodParams::as_double(), Array< Value * >::count(), GET_SELF, and Request::write_no_lang().

Referenced by MDouble::MDouble().

void __inc | ( | VDouble & | vdouble,
 |  | double | param
 | ) | [static]

Definition at line 56 of file double.C.

References VDouble::inc().

Referenced by _inc().

void __dec | ( | VDouble & | vdouble,
 |  | double | param
 | ) | [static]

Definition at line 57 of file double.C.

References VDouble::inc().

Referenced by _dec().

void __mul | ( | VDouble & | vdouble,
 |  | double | param
 | ) | [static]

Definition at line 58 of file double.C.

References VDouble::mul().

Referenced by _mul().

void __div | ( | VDouble & | vdouble,
 |  | double | param
 | ) | [static]

Definition at line 59 of file double.C.

References VDouble::div().

Referenced by _div().

void __mod | ( | VDouble & | vdouble,
 |  | double | param
 | ) | [static]

Definition at line 60 of file double.C.

References VDouble::mod().

Referenced by _mod().

void vdouble_op | ( | Request & | r,
 |  | MethodParams & | params,
 |  | vdouble_op_func_ptr | func
 | ) | [static]

Definition at line 62 of file double.C.

References MethodParams::as_double(), Array< Value * >::count(), func, GET_SELF, and vdouble_op_func_ptr.

Referenced by _dec(), _div(), _inc(), _mod(), and _mul().

void _inc | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 70 of file double.C.

References __inc(), and vdouble_op().

Referenced by MDouble::MDouble().

void _dec | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 71 of file double.C.

References __dec(), and vdouble_op().

Referenced by MDouble::MDouble().

void _mul | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 72 of file double.C.

References __mul(), and vdouble_op().

Referenced by MDouble::MDouble().

void _div | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 73 of file double.C.

References __div(), and vdouble_op().

Referenced by MDouble::MDouble().

void _mod | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 74 of file double.C.

References __mod(), and vdouble_op().

Referenced by MDouble::MDouble().

const String* sql_result_string | ( | Request & | r,
 |  | MethodParams & | params,
 |  | HashStringValue *& | options,
 |  | Value *& | default_code
 | ) |

Definition at line 422 of file string.C.

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 81 of file double.C.

References Value::as_double(), String::as_double(), Request::process_to_value(), sql_result_string(), val, and Request::write_no_lang().

Referenced by MDouble::MDouble().

Variable Documentation

const char* const IDENT_DOUBLE_C = "$Date: 2005/08/26 11:12:45 $" [static]

Definition at line 8 of file double.C.


double.C Source File

double.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_DOUBLE_C="$Date: 2005/08/26 11:12:45 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vdouble.h"
00015 #include "pa_vint.h"
00016
00017 // externs
00018
00019 void _string_format(Request& r, MethodParams&);
00020
00021 // class
00022
00023 class MDouble: public Methoded {
00024 public:
00025     MDouble();
00026 public: // Methoded
00027     bool used_directly() { return true; }
00028 };
00029
00030 // global variable
00031
00032 DECLARE_CLASS_VAR(double, new MDouble, 0);
00033
00034 // methods
00035
00036 static void _int(Request& r, MethodParams& params) {
00037     // just checking (default) syntax validity, never really using it  here, just for string.int compatibility
00038     if(params.count()>0)
00039         params.as_int(0, "default must be int", r);
00040
00041     VDouble& vdouble=GET_SELF(r, VDouble);
00042     r.write_no_lang(*new VInt(vdouble.as_int()));
00043 }
00044
00045 static void _double(Request& r, MethodParams& params) {
00046     // just checking (default) syntax validity, never really using it  here, just for string.doube compatibility
00047     if(params.count()>0)
00048         params.as_double(0, "default must be double", r);
00049
00050     VDouble& vdouble=GET_SELF(r, VDouble);
00051     r.write_no_lang(*new VDouble(vdouble.as_double()));
00052 }
00053
00054 typedef void (*vdouble_op_func_ptr)(VDouble& vdouble, double param);
00055
00056 static void __inc(VDouble& vdouble, double param) { vdouble.inc(param); }
00057 static void __dec(VDouble& vdouble, double param) { vdouble.inc(-param); }
00058 static void __mul(VDouble& vdouble, double param) { vdouble.mul(param); }
00059 static void __div(VDouble& vdouble, double param) { vdouble.div(param); }
00060 static void __mod(VDouble& vdouble, double param) { vdouble.mod((int)param); }
00061
00062 static void vdouble_op(Request& r, MethodParams& params,
00063                        vdouble_op_func_ptr func) {
00064     VDouble& vdouble=GET_SELF(r, VDouble);
00065     double param=params.count()?
00066             params.as_double(0, "param must be double", r):1/*used in inc/dec*/;
00067     (*func)(vdouble, param);
00068 }
00069
00070 static void _inc(Request& r, MethodParams& params) { vdouble_op(r, params, &__inc); }
00071 static void _dec(Request& r, MethodParams& params) { vdouble_op(r, params, &__dec); }
00072 static void _mul(Request& r, MethodParams& params) { vdouble_op(r, params, &__mul); }
00073 static void _div(Request& r, MethodParams& params) { vdouble_op(r, params, &__div); }
00074 static void _mod(Request& r, MethodParams& params) { vdouble_op(r, params, &__mod); }
00075
00076 // from string.C
00077 extern
00078 const String* sql_result_string(Request& r, MethodParams& params,
00079                 HashStringValue*& options, Value*& default_code);
00080
00081 static void _sql(Request& r, MethodParams& params) {
00082     double val;
00083     HashStringValue* options;
00084     Value* default_code;
00085     if(const String* string=sql_result_string(r, params, options, default_code))
00086         val=string->as_double();
00087     else
00088         if(default_code)
00089             val=r.process_to_value(*default_code).as_double();
00090         else {
00091             throw Exception("parser.runtime",
00092                 0,
00093                 "produced no result, but no default option specified");
00094         }
00095     r.write_no_lang(*new VDouble(val));
00096 }
00097
00098 // constructor
00099
00100 MDouble::MDouble(): Methoded("double") {
00101     // ^double.int[]
00102     add_native_method("int", Method::CT_DYNAMIC, _int, 0, 1);
00103
00104     // ^double.double[]
00105     add_native_method("double", Method::CT_DYNAMIC, _double, 0, 1);
00106
00107     // ^double.inc[]
00108     // ^double.inc[offset]
00109     add_native_method("inc", Method::CT_DYNAMIC, _inc, 0, 1);
00110     // ^double.dec[]
00111     // ^double.dec[offset]
00112     add_native_method("dec", Method::CT_DYNAMIC, _dec, 0, 1);
00113     // ^double.mul[k]
00114     add_native_method("mul", Method::CT_DYNAMIC, _mul, 1, 1);
00115     // ^double.div[d]
00116     add_native_method("div", Method::CT_DYNAMIC, _div, 1, 1);
00117     // ^double.mod[offset]
00118     add_native_method("mod", Method::CT_DYNAMIC, _mod, 1, 1);
00119
00120     // ^double.format{format}
00121     add_native_method("format", Method::CT_DYNAMIC, _string_format, 1, 1);
00122
00123     // ^sql[query]
00124     // ^sql[query][$.limit(1) $.offset(2) $.default(0.0)]
00125     add_native_method("sql", Method::CT_STATIC, _sql, 1, 2);
00126 }


ec.h File Reference

Include dependency graph for ec.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | CORD_ec_struct

Defines

#define | CORD_BUFSZ 128
#define | CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord)
#define | CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf)
#define | CORD_ec_append(x, c)

Typedefs

typedef CORD_ec_struct | CORD_ec [1]

Functions

void | CORD_ec_flush_buf (CORD_ec x)
void | CORD_ec_append_cord (CORD_ec x, CORD s)

Define Documentation

#define CORD_BUFSZ 128

Definition at line 34 of file ec.h.

Referenced by CORD_vsprintf().

#define CORD_ec_to_cord ( x ) (CORD_ec_flush_buf(x), (x)[0].ec_cord)

Definition at line 52 of file ec.h.

Referenced by CORD_from_file_eager(), CORD_vsprintf(), and String::cstr_to_string_body().

#define CORD_ec_init ( x ) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf)

Definition at line 55 of file ec.h.

Referenced by CORD_from_file_eager(), CORD_vsprintf(), and String::cstr_to_string_body().

#define CORD_ec_append | ( | x,
 |  | c | )

Value:

{  \
    if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \
        CORD_ec_flush_buf(x); \
    } \
    *((x)[0].ec_bufptr)++ = (c); \
    }

Definition at line 58 of file ec.h.

Referenced by CORD_from_file_eager(), CORD_vsprintf(), and ec_append().

Typedef Documentation

typedef struct CORD_ec_struct CORD_ec[1]

Function Documentation

void CORD_ec_flush_buf ( CORD_ec x )

Definition at line 411 of file cordxtra.c.

References CORD_cat_char_star(), CORD_ec_struct::ec_buf, CORD_ec_struct::ec_bufptr, CORD_ec_struct::ec_cord, and GC_MALLOC_ATOMIC.

Referenced by CORD_ec_append_cord(), CORD_from_file_eager(), and CORD_vsprintf().

void CORD_ec_append_cord | ( | CORD_ec | x,
 |  | CORD | s
 | ) |

Definition at line 424 of file cordxtra.c.

References CORD, CORD_cat(), CORD_ec_flush_buf(), and CORD_ec_struct::ec_cord.

Referenced by CORD_vsprintf().


ec.h Source File

ec.h

Go to the documentation of this file.
00001 # ifndef EC_H
00002 # define EC_H
00003
00004 # ifndef CORD_H
00005 #  include "cord.h"
00006 # endif
00007
00008 /* Extensible cords are strings that may be destructively appended to.  */
00009 /* They allow fast construction of cords from characters that are   */
00010 /* being read from a stream.                        */
00011 /*
00012  * A client might look like:
00013  *
00014  *  {
00015  *      CORD_ec x;
00016  *      CORD result;
00017  *      char c;
00018  *      FILE *f;
00019  *
00020  *      ...
00021  *      CORD_ec_init(x);
00022  *      while(...) {
00023  *      c = getc(f);
00024  *      ...
00025  *      CORD_ec_append(x, c);
00026  *      }
00027  *      result = CORD_balance(CORD_ec_to_cord(x));
00028  *
00029  * If a C string is desired as the final result, the call to CORD_balance
00030  * may be replaced by a call to CORD_to_char_star.
00031  */
00032
00033 # ifndef CORD_BUFSZ
00034 #   define CORD_BUFSZ 128
00035 # endif
00036
00037 typedef struct CORD_ec_struct {
00038     CORD ec_cord;
00039     char * ec_bufptr;
00040     char ec_buf[CORD_BUFSZ+1];
00041 } CORD_ec[1];
00042
00043 /* This structure represents the concatenation of ec_cord with      */
00044 /* ec_buf[0 ... (ec_bufptr-ec_buf-1)]                   */
00045
00046 /* Flush the buffer part of the extended chord into ec_cord.    */
00047 /* Note that this is almost the only real function, and it is   */
00048 /* implemented in 6 lines in cordxtra.c             */
00049 void CORD_ec_flush_buf(CORD_ec x);
00050
00051 /* Convert an extensible cord to a cord. */
00052 # define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord)
00053
00054 /* Initialize an extensible cord. */
00055 # define CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf)
00056
00057 /* Append a character to an extensible cord.    */
00058 # define CORD_ec_append(x, c) \
00059     {  \
00060     if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \
00061         CORD_ec_flush_buf(x); \
00062     } \
00063     *((x)[0].ec_bufptr)++ = (c); \
00064     }
00065
00066 /* Append a cord to an extensible cord.  Structure remains shared with  */
00067 /* original.                                */
00068 void CORD_ec_append_cord(CORD_ec x, CORD s);
00069
00070 # endif /* EC_H */


exception.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


execute.C File Reference

Parser: executor part of request class. More...

Include dependency graph for execute.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_EXECUTE_C = "$Date: 2005/11/24 14:00:34 $"

Detailed Description

Parser: executor part of request class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file execute.C.

Variable Documentation

const char* const IDENT_EXECUTE_C = "$Date: 2005/11/24 14:00:34 $" [static]

Definition at line 8 of file execute.C.


execute.C Source File

execute.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_EXECUTE_C="$Date: 2005/11/24 14:00:34 $";
00009
00010 #include "pa_opcode.h"
00011 #include "pa_array.h"
00012 #include "pa_request.h"
00013 #include "pa_vstring.h"
00014 #include "pa_vhash.h"
00015 #include "pa_vvoid.h"
00016 #include "pa_vcode_frame.h"
00017 #include "pa_vmethod_frame.h"
00018 #include "pa_vobject.h"
00019 #include "pa_vdouble.h"
00020 #include "pa_vbool.h"
00021 #include "pa_vtable.h"
00022 #include "pa_vfile.h"
00023 #include "pa_vimage.h"
00024 #include "pa_wwrapper.h"
00025
00026 //#define DEBUG_EXECUTE
00027
00028 #ifdef DEBUG_EXECUTE
00029 char *opcode_name[]={
00030     // literals
00031     "VALUE",  "CURLY_CODE__STORE_PARAM",  "EXPR_CODE__STORE_PARAM",
00032     "NESTED_CODE",
00033
00034     // actions
00035     "WITH_ROOT",    "WITH_SELF",    "WITH_READ",    "WITH_WRITE",
00036     "GET_CLASS",
00037     "CONSTRUCT_VALUE", "CONSTRUCT_EXPR", "CURLY_CODE__CONSTRUCT",
00038     "WRITE_VALUE",  "WRITE_EXPR_RESULT",  "STRING__WRITE",
00039     "GET_ELEMENT_OR_OPERATOR", "GET_ELEMENT",   "GET_ELEMENT__WRITE",
00040     "OBJECT_POOL",  "STRING_POOL",
00041     "STORE_PARAM",
00042     "PREPARE_TO_CONSTRUCT_OBJECT",  "PREPARE_TO_EXPRESSION",
00043     "CALL", "CALL__WRITE",
00044
00045     // expression ops: unary
00046     "NEG", "INV", "NOT", "DEF", "IN", "FEXISTS", "DEXISTS",
00047     // expression ops: binary
00048     "SUB", "ADD", "MUL", "DIV", "MOD", "INTDIV",
00049     "BIN_SL", "BIN_SR",
00050     "BIN_AND", "BIN_OR", "BIN_XOR",
00051     "LOG_AND", "LOG_OR", "LOG_XOR",
00052     "NUM_LT", "NUM_GT", "NUM_LE", "NUM_GE", "NUM_EQ", "NUM_NE",
00053     "STR_LT", "STR_GT", "STR_LE", "STR_GE", "STR_EQ", "STR_NE",
00054     "IS"
00055 };
00056
00057 void va_debug_printf(SAPI_Info& sapi_info, const char* fmt,va_list args) {
00058     char buf[MAX_STRING];
00059     vsnprintf(buf, MAX_STRING, fmt, args);
00060     SAPI::log(sapi_info, "%s", buf);
00061 }
00062
00063 void debug_printf(SAPI_Info& sapi_info, const char* fmt, ...) {
00064     va_list args;
00065     va_start(args, fmt);
00066     va_debug_printf(sapi_info, fmt, args);
00067     va_end(args);
00068 }
00069
00070 void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) {
00071     Array_iterator<Operation> i(ops);
00072     while(i.has_next()) {
00073         OPCODE opcode=i.next().code;
00074
00075         if(opcode==OP_VALUE || opcode==OP_STRING__WRITE) {
00076             Operation::Origin origin=i.next().origin;
00077             Value& value=*i.next().value;
00078             debug_printf(sapi_info,
00079                 "%*s%s"
00080                 " \"%s\" %s",
00081                 level*4, "", opcode_name[opcode],
00082                 value.get_string()->cstr(), value.type());
00083             continue;
00084         }
00085         debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[opcode]);
00086
00087         switch(opcode) {
00088         case OP_CURLY_CODE__STORE_PARAM:
00089         case OP_EXPR_CODE__STORE_PARAM:
00090         case OP_CURLY_CODE__CONSTRUCT:
00091         case OP_NESTED_CODE:
00092         case OP_OBJECT_POOL:
00093         case OP_STRING_POOL:
00094         case OP_CALL:
00095         case OP_CALL__WRITE:
00096             if(ArrayOperation* local_ops=i.next().ops)
00097                 debug_dump(sapi_info, level+1, *local_ops);
00098         }
00099     }
00100 }
00101 #endif
00102
00103 // Request
00104
00105 void Request::execute(ArrayOperation& ops) {
00106     register Stack<StackItem>& stack=this->stack; // helps a lot on MSVC: 'esi'
00107
00108     const String* debug_name=0;  Operation::Origin debug_origin={0, 0, 0};
00109     try{
00110 #ifdef DEBUG_EXECUTE
00111     debug_printf(sapi_info, "source----------------------------\n");
00112     debug_dump(sapi_info, 0, ops);
00113     debug_printf(sapi_info, "execution-------------------------\n");
00114 #endif
00115     for(Array_iterator<Operation> i(ops); i.has_next(); ) {
00116         if(get_interrupted()) {
00117             set_interrupted(false);
00118             throw Exception("parser.interrupted",
00119                 0,
00120                 "execution stopped");
00121         }
00122         OPCODE opcode=i.next().code;
00123
00124 #ifdef DEBUG_EXECUTE
00125         debug_printf(sapi_info, "%d:%s", stack.top_index()+1, opcode_name[opcode]);
00126 #endif
00127
00128         switch(opcode) {
00129         // param in next instruction
00130         case OP_VALUE:
00131             {
00132                 debug_origin=i.next().origin;
00133                 Value& value=*i.next().value;
00134 #ifdef DEBUG_EXECUTE
00135                 debug_printf(sapi_info, " \"%s\" %s", value.get_string()->cstr(), value.type());
00136 #endif
00137                 stack.push(value);
00138                 break;
00139             }
00140         case OP_GET_CLASS:
00141             {
00142                 // maybe they do ^class:method[] call, remember the fact
00143                 wcontext->set_somebody_entered_some_class();
00144
00145                 const String& name=stack.pop().string();
00146                 Value* value=classes().get(name);
00147                 if(!value)
00148                     throw Exception("parser.runtime",
00149                         &name,
00150                         "class is undefined");
00151
00152                 stack.push(*value);
00153                 break;
00154             }
00155
00156         // OP_WITH
00157         case OP_WITH_ROOT:
00158             {
00159                 stack.push(*method_frame);
00160                 break;
00161             }
00162         case OP_WITH_SELF:
00163             {
00164                 stack.push(get_self());
00165                 break;
00166             }
00167         case OP_WITH_READ:
00168             {
00169                 stack.push(*rcontext);
00170                 break;
00171             }
00172         case OP_WITH_WRITE:
00173             {
00174                 if(wcontext==method_frame)
00175                     throw Exception("parser.runtime",
00176                         0,
00177                         "$.name outside of $name[...]");
00178
00179                 stack.push(*wcontext);
00180                 break;
00181             }
00182
00183         // OTHER ACTIONS BUT WITHs
00184         case OP_CONSTRUCT_VALUE:
00185             {
00186                 Value& value=stack.pop().value();
00187                 const String& name=stack.pop().string();  debug_name=&name;
00188                 Value& ncontext=stack.pop().value();
00189                 put_element(ncontext, name, value);
00190
00191                 break;
00192             }
00193         case OP_CONSTRUCT_EXPR:
00194             {
00195                 // see OP_PREPARE_TO_EXPRESSION
00196                 wcontext->set_in_expression(false);
00197
00198                 Value& expr=stack.pop().value();
00199                 const String& name=stack.pop().string();  debug_name=&name;
00200                 Value& ncontext=stack.pop().value();
00201                 Value& value=expr.as_expr_result();
00202                 put_element(ncontext, name, value);
00203                 break;
00204             }
00205         case OP_CURLY_CODE__CONSTRUCT:
00206             {
00207                 ArrayOperation& local_ops=*i.next().ops;
00208 #ifdef DEBUG_EXECUTE
00209                 debug_printf(sapi_info, " (%d)\n", local_ops.count());
00210                 debug_dump(sapi_info, 1, local_ops);
00211 #endif
00212                 Value& value=*new VJunction(
00213                     get_self(), 0,
00214                     method_frame,
00215                     rcontext,
00216                     wcontext,
00217                     &local_ops);
00218
00219                 const String& name=stack.pop().string();  debug_name=&name;
00220                 Value& ncontext=stack.pop().value();
00221                 if(const VJunction* vjunction=ncontext.put_element(ncontext, name, &value, false))
00222                     if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT)
00223                         throw Exception("parser.runtime",
00224                             0,
00225                             "property value can not be code, use [] or () brackets");
00226
00227                 break;
00228             }
00229         case OP_NESTED_CODE:
00230             {
00231                 ArrayOperation& local_ops=*i.next().ops;
00232 #ifdef DEBUG_EXECUTE
00233                 debug_printf(sapi_info, " (%d)\n", local_ops.count());
00234                 debug_dump(sapi_info, 1, local_ops);
00235 #endif
00236                 stack.push(local_ops);
00237                 break;
00238             }
00239         case OP_WRITE_VALUE:
00240             {
00241                 Value& value=stack.pop().value();
00242                 write_assign_lang(value);
00243                 break;
00244             }
00245         case OP_WRITE_EXPR_RESULT:
00246             {
00247                 Value& value=stack.pop().value();
00248                 write_no_lang(value.as_expr_result());
00249
00250                 // must be after write(result) and
00251                 // see OP_PREPARE_TO_EXPRESSION
00252                 wcontext->set_in_expression(false);
00253                 break;
00254             }
00255         case OP_STRING__WRITE:
00256             {
00257                 i.next(); // ignore origin
00258                 Value* value=i.next().value;
00259 #ifdef DEBUG_EXECUTE
00260                 debug_printf(sapi_info, " \"%s\"", value->get_string()->cstr());
00261 #endif
00262                 write_no_lang(*value->get_string());
00263                 break;
00264             }
00265
00266         case OP_GET_ELEMENT_OR_OPERATOR:
00267             {
00268                 const String& name=stack.pop().string();  debug_name=&name;
00269                 Value& ncontext=stack.pop().value();
00270                 Value& value=get_element(ncontext, name, true);
00271                 stack.push(value);
00272                 break;
00273             }
00274         case OP_GET_ELEMENT:
00275             {
00276                 const String& name=stack.pop().string();  debug_name=&name;
00277                 Value& ncontext=stack.pop().value();
00278                 Value& value=get_element(ncontext, name, false);
00279                 stack.push(value);
00280                 break;
00281             }
00282
00283         case OP_GET_ELEMENT__WRITE:
00284             {
00285                 const String& name=stack.pop().string();  debug_name=&name;
00286                 Value& ncontext=stack.pop().value();
00287                 Value& value=get_element(ncontext, name, false);
00288                 write_assign_lang(value);
00289                 break;
00290             }
00291
00292
00293         case OP_OBJECT_POOL:
00294             {
00295                 ArrayOperation& local_ops=*i.next().ops;
00296
00297                 WContext *saved_wcontext=wcontext;
00298                 String::Language saved_lang=flang;
00299                 flang=String::L_PASS_APPENDED;
00300                 WWrapper local(0/*empty*/, wcontext);
00301                 wcontext=&local;
00302
00303                 execute(local_ops);
00304
00305                 stack.push(wcontext->result().as_value());
00306                 flang=saved_lang;
00307                 wcontext=saved_wcontext;
00308                 break;
00309             }
00310
00311         case OP_STRING_POOL:
00312             {
00313                 ArrayOperation& local_ops=*i.next().ops;
00314
00315                 WContext *saved_wcontext=wcontext;
00316                 WWrapper local(0 /*empty*/, wcontext);
00317                 wcontext=&local;
00318
00319                 execute(local_ops);
00320
00321                 Value* value;
00322                 // from "$a $b" part of expression taking only string value,
00323                 // ignoring any other content of wcontext
00324                 if(const String* string=wcontext->get_string())
00325                     value=new VString(*string);
00326                 else
00327                     value=new VVoid;
00328                 stack.push(*value);
00329
00330                 wcontext=saved_wcontext;
00331                 break;
00332             }
00333
00334         // CALL
00335         case OP_STORE_PARAM:
00336             {
00337                 Value& value=stack.pop().value();
00338                 VMethodFrame& frame=stack.top_value().method_frame();
00339                 // this op is executed from CALL local_ops only, so may skip the check "method_frame_to_fill==0"
00340                 frame.store_param(value);
00341                 break;
00342             }
00343         case OP_CURLY_CODE__STORE_PARAM:
00344         case OP_EXPR_CODE__STORE_PARAM:
00345             {
00346                 // code
00347                 ArrayOperation& local_ops=*i.next().ops;
00348                 VMethodFrame& frame=stack.top_value().method_frame();
00349 #ifdef DEBUG_EXECUTE
00350                 debug_printf(sapi_info, " (%d)\n", local_ops.count());
00351                 debug_dump(sapi_info, 1, local_ops);
00352 #endif
00353                 // when they evaluate expression parameter,
00354                 // the object expression result
00355                 // does not need to be written into calling frame
00356                 // it must go into any expressions using that parameter
00357                 // hence, we zero junction.wcontext here, and later
00358                 // in .process we would test that field
00359                 // in decision "which wwrapper to use"
00360                 Value& value=*new VJunction(
00361                     get_self(), 0,
00362                     method_frame,
00363                     rcontext,
00364                     opcode==OP_EXPR_CODE__STORE_PARAM?0:wcontext,
00365                     &local_ops);
00366                 // store param
00367                 // this op is executed from CALL local_ops only, so can not check method_frame_to_fill==0
00368                 frame.store_param(value);
00369                 break;
00370             }
00371
00372         case OP_PREPARE_TO_CONSTRUCT_OBJECT:
00373             {
00374                 wcontext->set_constructing(true);
00375                 break;
00376             }
00377
00378         case OP_PREPARE_TO_EXPRESSION:
00379             {
00380                 wcontext->set_in_expression(true);
00381                 break;
00382             }
00383
00384         case OP_CALL:
00385         case OP_CALL__WRITE:
00386             {
00387                 //is_debug_junction=true;
00388                 ArrayOperation* local_ops=i.next().ops;
00389 #ifdef DEBUG_EXECUTE
00390                 debug_printf(sapi_info, " (%d)\n", local_ops?local_ops->count():0);
00391                 if(local_ops)
00392                     debug_dump(sapi_info, 1, *local_ops);
00393
00394                 debug_printf(sapi_info, "->\n");
00395 #endif
00396                 Value& value=stack.pop().value();
00397
00398                 Junction* junction=value.get_junction();
00399                 if(!junction) {
00400                     if(value.is("void"))
00401                         throw Exception("parser.runtime",
00402                             0,
00403                             "undefined method");
00404                     else
00405                         throw Exception("parser.runtime",
00406                             0,
00407                             "is '%s', not a method or junction, can not call it",
00408                                 value.type());
00409                 }
00410                 /* no check needed, code compiled the way that that's impossible
00411                 // check:
00412                 //  that this is method-junction, not a code-junction
00413                 // [disabling these contstructions:]
00414                 // $junction{code}
00415                 //  ^junction[]
00416                 if(!junction->method)
00417                     throw Exception("parser.runtime",
00418
00419                         "is '%s', it is code junction, can not call it",
00420                             value.type());
00421                 */
00422
00423                 VMethodFrame frame(*junction, method_frame/*caller*/);
00424                 if(local_ops){ // store param code goes here
00425                     stack.push(frame); // argument for *STORE_PARAM ops
00426                     execute(*local_ops);
00427                     stack.pop().value();
00428                 }
00429                 frame.fill_unspecified_params();
00430                 VMethodFrame *saved_method_frame=method_frame;
00431                 Value* saved_rcontext=rcontext;
00432                 WContext *saved_wcontext=wcontext;
00433
00434                 VStateless_class& called_class=*frame.junction.self.get_class();
00435                 Value* new_self;
00436                 if(wcontext->get_constructing()) {
00437                     wcontext->set_constructing(false);
00438                     new_self=&get_self();
00439                     if(frame.junction.method->call_type!=Method::CT_STATIC) {
00440                         // this is a constructor call
00441
00442                         HashStringValue& new_object_fields=*new HashStringValue();
00443                         if(Value* value=called_class.create_new_value(fpool, new_object_fields)) {
00444                             // some stateless_class creatable derivates
00445                             new_self=value;
00446                         } else
00447                             throw Exception("parser.runtime",
00448                                 0, //&frame.name(),
00449                                 "is not a constructor, system class '%s' can be constructed only implicitly",
00450                                     called_class.name().cstr());
00451
00452                         frame.write(*new_self,
00453                             String::L_CLEAN  // not used, always an object, not string
00454                         );
00455                     } else
00456                         throw Exception("parser.runtime",
00457                             0, //&frame.name(),
00458                             "method is static and can not be used as constructor");
00459                 } else
00460                     new_self=&frame.junction.self;
00461
00462                 frame.set_self(*new_self);
00463
00464                 // see OP_PREPARE_TO_EXPRESSION
00465                 frame.set_in_expression(wcontext->get_in_expression());
00466
00467                 rcontext=wcontext=&frame;
00468                 {
00469                     const Method& method=*frame.junction.method;
00470                     Method::Call_type call_type=
00471                         &called_class==new_self ? Method::CT_STATIC : Method::CT_DYNAMIC;
00472                     if(
00473                         method.call_type==Method::CT_ANY ||
00474                         method.call_type==call_type) { // allowed call type?
00475                         method_frame=&frame;
00476                         if(method.native_code) { // native code?
00477                             method.check_actual_numbered_params(
00478                                 frame.junction.self,
00479                                 /*frame.name(), */frame.numbered_params());
00480                             method.native_code(
00481                                 *this,
00482                                 *frame.numbered_params()); // execute it
00483                         } else // parser code, execute it
00484                             recoursion_checked_execute(*method.parser_code);
00485                     } else
00486                         throw Exception("parser.runtime",
00487                             0, //&frame.name(),
00488                             "is not allowed to be called %s",
00489                                 call_type==Method::CT_STATIC?"statically":"dynamically");
00490
00491                 }
00492                 StringOrValue result=wcontext->result();
00493
00494                 wcontext=saved_wcontext;
00495                 rcontext=saved_rcontext;
00496                 method_frame=saved_method_frame;
00497
00498                 if(opcode==OP_CALL__WRITE) {
00499                     write_assign_lang(result);
00500                 } else { // OP_CALL
00501                     stack.push(result.as_value());
00502                 }
00503
00504 #ifdef DEBUG_EXECUTE
00505                 debug_printf(sapi_info, "<-returned");
00506 #endif
00507                 //is_debug_junction=false;
00508                 break;
00509             }
00510
00511         // expression ops: unary
00512         case OP_NEG:
00513             {
00514                 Value& a=stack.pop().value();
00515                 Value& value=*new VDouble(-a.as_double());
00516                 stack.push(value);
00517                 break;
00518             }
00519         case OP_INV:
00520             {
00521                 Value& a=stack.pop().value();
00522                 Value& value=*new VDouble(~a.as_int());
00523                 stack.push(value);
00524                 break;
00525             }
00526         case OP_NOT:
00527             {
00528                 Value& a=stack.pop().value();
00529                 Value& value=*new VBool(!a.as_bool());
00530                 stack.push(value);
00531                 break;
00532             }
00533         case OP_DEF:
00534             {
00535                 Value& a=stack.pop().value();
00536                 Value& value=*new VBool(a.is_defined());
00537                 stack.push(value);
00538                 break;
00539             }
00540         case OP_IN:
00541             {
00542                 Value& a=stack.pop().value();
00543                 const String& path=a.as_string();
00544                 Value& value=*new VBool(request_info.uri && *request_info.uri && path.this_starts(request_info.uri));
00545                 stack.push(value);
00546                 break;
00547             }
00548         case OP_FEXISTS:
00549             {
00550                 Value& a=stack.pop().value();
00551                 Value& value=*new VBool(file_exist(absolute(a.as_string())));
00552                 stack.push(value);
00553                 break;
00554             }
00555         case OP_DEXISTS:
00556             {
00557                 Value& a=stack.pop().value();
00558                 Value& value=*new VBool(dir_exists(absolute(a.as_string())));
00559                 stack.push(value);
00560                 break;
00561             }
00562
00563         // expression ops: binary
00564         case OP_SUB:
00565             {
00566                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00567                 Value& value=*new VDouble(a.as_double() - b.as_double());
00568                 stack.push(value);
00569                 break;
00570             }
00571         case OP_ADD:
00572             {
00573                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00574                 Value& value=*new VDouble(a.as_double() + b.as_double());
00575                 stack.push(value);
00576                 break;
00577             }
00578         case OP_MUL:
00579             {
00580                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00581                 Value& value=*new VDouble(a.as_double() * b.as_double());
00582                 stack.push(value);
00583                 break;
00584             }
00585         case OP_DIV:
00586             {
00587                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00588
00589                 double a_double=a.as_double();
00590                 double b_double=b.as_double();
00591
00592                 if(b_double == 0) {
00593                     //const String* problem_source=b.as_string();
00594                     throw Exception("number.zerodivision",
00595                         0, //problem_source,
00596                         "Division by zero");
00597                 }
00598
00599                 Value& value=*new VDouble(a_double / b_double);
00600                 stack.push(value);
00601                 break;
00602             }
00603         case OP_MOD:
00604             {
00605                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00606
00607                 double a_double=a.as_double();
00608                 double b_double=b.as_double();
00609
00610                 if(b_double == 0) {
00611                     //const String* problem_source=b.as_string();
00612                     throw Exception("number.zerodivision",
00613                         0, //problem_source,
00614                         "Modulus by zero");
00615                 }
00616
00617                 Value& value=*new VDouble(fmod(a_double, b_double));
00618                 stack.push(value);
00619                 break;
00620             }
00621         case OP_INTDIV:
00622             {
00623                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00624
00625                 int a_int=a.as_int();
00626                 int b_int=b.as_int();
00627
00628                 if(b_int == 0) {
00629                     //const String* problem_source=b.as_string();
00630                     throw Exception("number.zerodivision",
00631                         0, //problem_source,
00632                         "Division by zero");
00633                 }
00634
00635                 Value& value=*new VInt(a_int / b_int);
00636                 stack.push(value);
00637                 break;
00638             }
00639         case OP_BIN_SL:
00640             {
00641                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00642                 Value& value=*new VInt(
00643                     a.as_int() <<
00644                     b.as_int());
00645                 stack.push(value);
00646                 break;
00647             }
00648         case OP_BIN_SR:
00649             {
00650                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00651                 Value& value=*new VInt(
00652                     a.as_int() >>
00653                     b.as_int());
00654                 stack.push(value);
00655                 break;
00656             }
00657         case OP_BIN_AND:
00658             {
00659                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00660                 Value& value=*new VInt(
00661                     a.as_int() &
00662                     b.as_int());
00663                 stack.push(value);
00664                 break;
00665             }
00666         case OP_BIN_OR:
00667             {
00668                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00669                 Value& value=*new VInt(
00670                     a.as_int() |
00671                     b.as_int());
00672                 stack.push(value);
00673                 break;
00674             }
00675         case OP_BIN_XOR:
00676             {
00677                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00678                 Value& value=*new VInt(
00679                     a.as_int() ^
00680                     b.as_int());
00681                 stack.push(value);
00682                 break;
00683             }
00684         case OP_LOG_AND:
00685             {
00686                 ArrayOperation& local_ops=stack.pop().ops();  Value& a=stack.pop().value();
00687                 bool result;
00688                 if(a.as_bool()) {
00689                     execute(local_ops);
00690                     Value& b=stack.pop().value();
00691                     result=b.as_bool();
00692                 } else
00693                     result=false;
00694                 Value& value=*new VBool(result);
00695                 stack.push(value);
00696                 break;
00697             }
00698         case OP_LOG_OR:
00699             {
00700                 ArrayOperation& local_ops=stack.pop().ops();  Value& a=stack.pop().value();
00701                 bool result;
00702                 if(a.as_bool())
00703                     result=true;
00704                 else {
00705                     execute(local_ops);
00706                     Value& b=stack.pop().value();
00707                     result=b.as_bool();
00708                 }
00709                 Value& value=*new VBool(result);
00710                 stack.push(value);
00711                 break;
00712             }
00713         case OP_LOG_XOR:
00714             {
00715                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00716                 Value& value=*new VBool(a.as_bool() ^ b.as_bool());
00717                 stack.push(value);
00718                 break;
00719             }
00720         case OP_NUM_LT:
00721             {
00722                 volatile double b_double=stack.pop().value().as_double();
00723                 volatile double a_double=stack.pop().value().as_double();
00724                 Value& value=*new VBool(a_double<b_double);
00725                 stack.push(value);
00726                 break;
00727             }
00728         case OP_NUM_GT:
00729             {
00730                 volatile double b_double=stack.pop().value().as_double();
00731                 volatile double a_double=stack.pop().value().as_double();
00732                 Value& value=*new VBool(a_double>b_double);
00733                 stack.push(value);
00734                 break;
00735             }
00736         case OP_NUM_LE:
00737             {
00738                 volatile double b_double=stack.pop().value().as_double();
00739                 volatile double a_double=stack.pop().value().as_double();
00740                 Value& value=*new VBool(a_double<=b_double);
00741                 stack.push(value);
00742                 break;
00743             }
00744         case OP_NUM_GE:
00745             {
00746                 volatile double b_double=stack.pop().value().as_double();
00747                 volatile double a_double=stack.pop().value().as_double();
00748                 Value& value=*new VBool(a_double>=b_double);
00749                 stack.push(value);
00750                 break;
00751             }
00752         case OP_NUM_EQ:
00753             {
00754                 volatile double b_double=stack.pop().value().as_double();
00755                 volatile double a_double=stack.pop().value().as_double();
00756                 Value& value=*new VBool(a_double==b_double);
00757                 stack.push(value);
00758                 break;
00759             }
00760         case OP_NUM_NE:
00761             {
00762                 volatile double b_double=stack.pop().value().as_double();
00763                 volatile double a_double=stack.pop().value().as_double();
00764                 Value& value=*new VBool(a_double!=b_double);
00765                 stack.push(value);
00766                 break;
00767             }
00768         case OP_STR_LT:
00769             {
00770                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00771                 Value& value=*new VBool(a.as_string() < b.as_string());
00772                 stack.push(value);
00773                 break;
00774             }
00775         case OP_STR_GT:
00776             {
00777                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00778                 Value& value=*new VBool(a.as_string() > b.as_string());
00779                 stack.push(value);
00780                 break;
00781             }
00782         case OP_STR_LE:
00783             {
00784                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00785                 Value& value=*new VBool(a.as_string() <= b.as_string());
00786                 stack.push(value);
00787                 break;
00788             }
00789         case OP_STR_GE:
00790             {
00791                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00792                 Value& value=*new VBool(a.as_string() >= b.as_string());
00793                 stack.push(value);
00794                 break;
00795             }
00796         case OP_STR_EQ:
00797             {
00798                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00799                 Value& value=*new VBool(a.as_string() == b.as_string());
00800                 stack.push(value);
00801                 break;
00802             }
00803         case OP_STR_NE:
00804             {
00805                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00806                 Value& value=*new VBool(a.as_string() != b.as_string());
00807                 stack.push(value);
00808                 break;
00809             }
00810         case OP_IS:
00811             {
00812                 Value& b=stack.pop().value();  Value& a=stack.pop().value();
00813                 Value& value=*new VBool(a.is(b.as_string().cstr()));
00814                 stack.push(value);
00815                 break;
00816             }
00817
00818         default:
00819             throw Exception(0,
00820                 0,
00821                 "invalid opcode %d", opcode);
00822         }
00823     }
00824     } catch(const Exception&) {
00825         // record it to stack trace
00826         if(debug_name)
00827             exception_trace.push(Trace(debug_name, debug_origin));
00828         rethrow;
00829     }
00830 }
00831
00836 Value& Request::get_element(Value& ncontext, const String& name, bool can_call_operator) {
00837     Value* value=0;
00838     if(can_call_operator) {
00839         if(Method* method=main_class.get_method(name)) // looking operator of that name FIRST
00840             value=new VJunction(main_class, method);
00841     }
00842     if(!value) {
00843         if(!wcontext->get_constructing() // not constructing
00844             && wcontext->get_somebody_entered_some_class() ) // ^class:method
00845             if(VStateless_class *called_class=ncontext.get_class())
00846                 if(VStateless_class *read_class=rcontext->get_class())
00847                     if(read_class->derived_from(*called_class)) // current derived from called
00848                         if(Value* base=get_self().base()) { // doing DYNAMIC call
00849                             Temp_derived temp_derived(*base, 0); // temporarily prevent go-back-down virtual calls
00850                             value=base->get_element(name, *base, false); // virtual-up lookup starting from parent
00851                             goto value_ready;
00852                         }
00853     }
00854     if(!value)
00855         value=ncontext.get_element(name, ncontext, false);
00856
00857     if(value && wcontext->get_constructing())
00858         if(Junction* junction=value->get_junction()) {
00859             if(junction->self.get_class()!=&ncontext)
00860                 throw Exception("parser.runtime",
00861                     &name,
00862                     "constructor must be declared in class '%s'",
00863                         ncontext.get_class()->name_cstr());
00864         }
00865
00866 value_ready:
00867     if(value)
00868         value=&process_to_value(*value); // process possible code-junction
00869     else
00870         value=new VVoid;
00871
00872     return *value;
00873 }
00874
00875 void Request::put_element(Value& ncontext, const String& name, Value& value) {
00876     // put_element can return property-setting-junction
00877     if(const VJunction* vjunction=ncontext.put_element(ncontext, name, &value, false))
00878         if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) {
00879             const Junction& junction=vjunction->junction();
00880             // process it
00881             ArrayString* params_names=junction.method->params_names;
00882             int param_count=params_names? params_names->count(): 0;
00883             if(param_count!=1)
00884                 throw Exception("parser.runtime",
00885                     0,
00886                     "setter method must have ONE parameter (has %d parameters)", param_count);
00887
00888             VMethodFrame frame(junction, method_frame/*caller*/);
00889             frame.store_param(value);
00890
00891             frame.set_self(frame.junction.self);
00892
00893             VMethodFrame *saved_method_frame=method_frame;
00894             Value* saved_rcontext=rcontext;
00895             WContext *saved_wcontext=wcontext;
00896
00897             rcontext=wcontext=&frame;
00898             method_frame=&frame;
00899
00900             // prevent non-string writes for better error reporting [setters are not expected to return anything]
00901             wcontext->write(*method_frame);
00902
00903             recoursion_checked_execute(*frame.junction.method->parser_code); // parser code, execute it
00904             // we don't need it StringOrValue result=wcontext->result();
00905
00906             method_frame=saved_method_frame;
00907             wcontext=saved_wcontext;
00908             rcontext=saved_rcontext;
00909         }
00910 }
00911
00923 StringOrValue Request::process(Value& input_value, bool intercept_string) {
00924     Junction* junction=input_value.get_junction();
00925     if(junction) {
00926         if(junction->is_getter) { // is it a getter-junction?
00927             // process it
00928
00929             VMethodFrame frame(*junction, method_frame/*caller*/);
00930             if(junction->method->params_names)
00931                 throw Exception("parser.runtime",
00932                     0,
00933                     "getter method must have no parameters");
00934
00935             frame.set_self(frame.junction.self);
00936
00937             VMethodFrame *saved_method_frame=method_frame;
00938             Value* saved_rcontext=rcontext;
00939             WContext *saved_wcontext=wcontext;
00940
00941             rcontext=wcontext=&frame;
00942             method_frame=&frame;
00943
00944             recoursion_checked_execute(*frame.junction.method->parser_code); // parser code, execute it
00945             StringOrValue result=wcontext->result();
00946
00947             method_frame=saved_method_frame;
00948             wcontext=saved_wcontext;
00949             rcontext=saved_rcontext;
00950
00951             return result;
00952         }
00953
00954         if(junction->code) { // is it a code-junction?
00955             // process it
00956             StringOrValue result;
00957 #ifdef DEBUG_EXECUTE
00958             debug_printf(sapi_info, "ja->\n");
00959 #endif
00960
00961             if(!junction->method_frame)
00962                 throw Exception("parser.runtime",
00963                 0,
00964                 "junction used outside of context");
00965
00966             VMethodFrame *saved_method_frame=method_frame;
00967             Value* saved_rcontext=rcontext;
00968             WContext *saved_wcontext=wcontext;
00969
00970             method_frame=junction->method_frame;
00971             rcontext=junction->rcontext;
00972
00973             // for expression method params
00974             // wcontext is set 0
00975             // using the fact in decision "which wwrapper to use"
00976             bool using_code_frame=intercept_string && junction->wcontext;
00977             if(using_code_frame) {
00978                 // almost plain wwrapper about junction wcontext,
00979                 // BUT intercepts string writes
00980                 VCodeFrame local(*junction->wcontext, junction->wcontext);
00981                 wcontext=&local;
00982
00983                 // execute it
00984                 recoursion_checked_execute(*junction->code);
00985
00986                 // CodeFrame soul:
00987                 //   string writes were intercepted
00988                 //   returning them as the result of getting code-junction
00989                 result.set_string(*wcontext->get_string());
00990             } else {
00991                 // plain wwrapper
00992                 WWrapper local(0/*empty*/, wcontext);
00993                 wcontext=&local;
00994
00995                 // execute it
00996                 recoursion_checked_execute(*junction->code);
00997
00998                 result=wcontext->result();
00999             }
01000
01001             wcontext=saved_wcontext;
01002             rcontext=saved_rcontext;
01003             method_frame=saved_method_frame;
01004
01005 #ifdef DEBUG_EXECUTE
01006             debug_printf(sapi_info, "<-ja returned");
01007 #endif
01008             return result;
01009         }
01010
01011         // it is then method-junction, do not explode it
01012         // just return it as we do for usual objects
01013     }
01014
01015     return input_value;
01016 }
01017
01018 StringOrValue Request::execute_method(VMethodFrame& amethod_frame, const Method& method) {
01019     VMethodFrame *saved_method_frame=method_frame;
01020     Value* saved_rcontext=rcontext;
01021     WContext *saved_wcontext=wcontext;
01022
01023     // initialize contexts
01024     rcontext=wcontext=method_frame=&amethod_frame;
01025
01026     // execute!
01027     execute(*method.parser_code);
01028
01029     // result
01030     StringOrValue result=wcontext->result();
01031
01032     wcontext=saved_wcontext;
01033     rcontext=saved_rcontext;
01034     method_frame=saved_method_frame;
01035
01036     // return
01037     return result;
01038 }
01039
01040 const String* Request::execute_method(Value& aself,
01041                       const Method& method, VString* optional_param,
01042                       bool do_return_string) {
01043     VMethodFrame *saved_method_frame=method_frame;
01044     Value* saved_rcontext=rcontext;
01045     WContext *saved_wcontext=wcontext;
01046
01047     Junction local_junction(aself, &method);
01048     VMethodFrame local_frame(local_junction, method_frame/*caller*/);
01049     if(optional_param && local_frame.can_store_param()) {
01050         local_frame.store_param(*optional_param);
01051         local_frame.fill_unspecified_params();
01052     }
01053     local_frame.set_self(aself);
01054     rcontext=wcontext=method_frame=&local_frame;
01055
01056     // prevent non-string writes for better error reporting
01057     if(do_return_string)
01058         wcontext->write(local_frame);
01059
01060     // execute!
01061     execute(*method.parser_code);
01062
01063     // result
01064     const String* result=0;
01065     if(do_return_string)
01066         result=&wcontext->result().as_string();
01067
01068     wcontext=saved_wcontext;
01069     rcontext=saved_rcontext;
01070     method_frame=saved_method_frame;
01071
01072     return result;
01073 }
01074
01075 Request::Execute_nonvirtual_method_result
01076 Request::execute_nonvirtual_method(VStateless_class& aclass,
01077                    const String& method_name, VString* optional_param,
01078                    bool do_return_string) {
01079     Execute_nonvirtual_method_result result;
01080     result.method=aclass.get_method(method_name);
01081     if(result.method)
01082         result.string=execute_method(aclass, *result.method, optional_param,
01083             do_return_string);
01084     return result;
01085 }
01086
01087 const String* Request::execute_virtual_method(Value& aself,
01088                           const String& method_name) {
01089     if(Value* value=aself.get_element(method_name, aself, false))
01090         if(Junction* junction=value->get_junction())
01091             if(const Method *method=junction->method)
01092                 return execute_method(aself, *method, 0/*no params*/, true);
01093
01094     return 0;
01095 }


executor.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


file.C File Reference

Parser: file parser class. More...

Include dependency graph for file.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MFile

Defines

#define | TEXT_MODE_NAME "text"
#define | BINARY_MODE_NAME "binary"
#define | STDIN_EXEC_PARAM_NAME "stdin"
#define | CHARSET_EXEC_PARAM_NAME "charset"
#define | NAME_NAME "name"
#define | ECSTR(name, value_cstr)

Functions

DECLARE_CLASS_VAR (file, new MFile, 0)
const String::Body | adate_name ("adate")
const String::Body | mdate_name ("mdate")
const String::Body | cdate_name ("cdate")
bool | is_text_mode (const String &mode)
void | _save (Request &r, MethodParams &params)
void | _delete (Request &r, MethodParams &params)
void | _move (Request &r, MethodParams &params)
void | _load_pass_param (HashStringValue::key_type key, HashStringValue::value_type value, HashStringValue *dest)
void | _load (Request &r, MethodParams &params)
void | _create (Request &r, MethodParams &params)
void | _stat (Request &r, MethodParams &params)
bool | is_safe_env_key (const char *key)
void | append_env_pair (HashStringValue::key_type akey, HashStringValue::value_type avalue, Append_env_pair_info *info)
void | pass_cgi_header_attribute (ArrayString::element_type astring, Pass_cgi_header_attribute_info *info)
void | _exec_cgi (Request &r, MethodParams &params, bool cgi)
void | _exec (Request &r, MethodParams &params)
void | _cgi (Request &r, MethodParams &params)
void | _list (Request &r, MethodParams &params)
void | lock_execute_body (int, void *ainfo)
void | _lock (Request &r, MethodParams &params)
int | lastposafter (const String &s, size_t after, const char *substr, size_t substr_size, bool beforelast=false)
void | _find (Request &r, MethodParams &params)
void | _dirname (Request &r, MethodParams &params)
void | _basename (Request &r, MethodParams &params)
void | _justname (Request &r, MethodParams &params)
void | _justext (Request &r, MethodParams &params)
void | _fullpath (Request &r, MethodParams &params)
void | _sql_string (Request &r, MethodParams &)
void | _sql (Request &r, MethodParams &params)
void | _base64 (Request &r, MethodParams &params)

Variables

const char *const | IDENT_FILE_C = "$Date: 2005/11/24 14:00:34 $"
String sql_limit_name
String sql_offset_name
const char * | suexec_safe_env_lst []
from apache-1.3|src|support|suexec.c. More...

Detailed Description

Parser: file parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file file.C.

Define Documentation

#define TEXT_MODE_NAME "text"

Definition at line 31 of file file.C.

Referenced by is_text_mode().

#define BINARY_MODE_NAME "binary"

Definition at line 32 of file file.C.

Referenced by is_text_mode().

#define STDIN_EXEC_PARAM_NAME "stdin"

Definition at line 33 of file file.C.

Referenced by _exec_cgi(), and append_env_pair().

#define CHARSET_EXEC_PARAM_NAME "charset"

Definition at line 34 of file file.C.

Referenced by _exec_cgi(), and append_env_pair().

#define NAME_NAME "name"

Definition at line 36 of file file.C.

Referenced by _sql().

#define ECSTR | ( | name,
 |  | value_cstr | )

Value:

if(value_cstr) \
            env.put( \
                String::Body(#name), \
                String::Body(value_cstr, 0)); \

Function Documentation

DECLARE_CLASS_VAR | ( | file | ,
 |  | new | MFile,
 |  | 0 |
 | ) |

const String::Body adate_name ( "adate" ) [static]

const String::Body mdate_name ( "mdate" ) [static]

const String::Body cdate_name ( "cdate" ) [static]

bool is_text_mode ( const String & mode ) [static]

Definition at line 116 of file file.C.

References BINARY_MODE_NAME, mode, and TEXT_MODE_NAME.

Referenced by _create(), _load(), and _save().

void _save | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 126 of file file.C.

References Request::absolute(), MethodParams::as_no_junction(), Value::as_string(), GET_SELF, and is_text_mode().

Referenced by MFile::MFile().

void _delete | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 135 of file file.C.

References Request::absolute(), MethodParams::as_no_junction(), Value::as_string(), and file_delete().

Referenced by MFile::MFile().

void _move | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 142 of file file.C.

References Request::absolute(), MethodParams::as_no_junction(), Value::as_string(), and file_move().

Referenced by MFile::MFile().

void _load_pass_param | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | HashStringValue * | dest
 | ) | [static]

Definition at line 152 of file file.C.

References Hash< const String::Body, Value * >::put(), and value.

Referenced by _load().

void _load | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 158 of file file.C.

References _load_pass_param(), Request::absolute(), Value::as_int(), MethodParams::as_no_junction(), MethodParams::as_string(), Value::as_string(), Request::charsets, Array< Value * >::count(), String::cstr(), VFile::fields(), file, file_read(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), GET_SELF, HashStringValue, File_read_result::headers, is_text_mode(), String::L_FILE_SPEC, File_read_result::length, Request::mime_type_of(), offset, Request::process_to_value(), VFile::set(), and File_read_result::str.

Referenced by MFile::MFile().

void _create | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 205 of file file.C.

References Request::absolute(), MethodParams::as_no_junction(), MethodParams::as_string(), Value::as_string(), String::cstr(), GET_SELF, is_text_mode(), String::L_FILE_SPEC, String::L_UNSPECIFIED, Request::mime_type_of(), and VFile::set().

Referenced by MFile::MFile().

void _stat | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 224 of file file.C.

References Request::absolute(), MethodParams::as_no_junction(), Value::as_string(), String::cstr(), VFile::fields(), file_stat(), GET_SELF, String::L_FILE_SPEC, Request::mime_type_of(), Hash< const String::Body, Value * >::put(), VFile::set(), and size.

Referenced by MFile::MFile().

bool is_safe_env_key ( const char * key ) [static]

Definition at line 244 of file file.C.

References suexec_safe_env_lst.

Referenced by append_env_pair().

void append_env_pair | ( | HashStringValue::key_type | akey,
 |  | HashStringValue::value_type | avalue,
 |  | Append_env_pair_info * | info
 | ) | [static]

Definition at line 267 of file file.C.

References CHARSET_EXEC_PARAM_NAME, is_safe_env_key(), String::L_TAINTED, String::L_UNSPECIFIED, and STDIN_EXEC_PARAM_NAME.

Referenced by _exec_cgi().

void pass_cgi_header_attribute | ( | ArrayString::element_type | astring,
 |  | Pass_cgi_header_attribute_info * | info
 | ) | [static]

Definition at line 290 of file file.C.

References String::CC_UPPER, STRING_NOT_FOUND, and value.

Referenced by _exec_cgi().

void _exec_cgi | ( | Request & | r,
 |  | MethodParams & | params,
 |  | bool | cgi
 | ) | [static]

Todo:
fix `` in perl - they produced flipping consoles and no output to perl

Definition at line 304 of file file.C.

References Request::absolute(), String::append(), append_env_pair(), String::append_know_length(), MethodParams::as_no_junction(), MethodParams::as_string(), Value::as_string(), String::CC_UPPER, String::change_case(), CHARSET_EXEC_PARAM_NAME, Request::charsets, Request_info::content_length, Request_info::content_type, Array< Value * >::count(), String::cstr(), Request_info::document_root, SAPI::environment(), PA_exec_result::err, VFile::fields(), Array< const String * >::for_each(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), GET_SELF, String::L_CLEAN, String::L_TAINTED, String::length(), MAX_NUMBER, Request_info::method, String::mid(), PA_exec_result::out, pa_exec(), pa_strdup(), pass_cgi_header_attribute(), Request_info::path_translated, String::pos(), Hash< const String::Body, Value * >::put(), Hash< K, V >::put(), Request_info::query_string, Request::request_info, Request::sapi_info, VFile::set(), snprintf, Request_charsets::source(), String::split(), PA_exec_result::status, STDIN_EXEC_PARAM_NAME, STRING_NOT_FOUND, Charset::transcode(), uint, Request_info::uri, VFile::value_ptr(), and VFile::value_size().

Referenced by _cgi(), and _exec().

void _exec | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 479 of file file.C.

References _exec_cgi().

Referenced by MFile::MFile().

void _cgi | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 482 of file file.C.

References _exec_cgi().

Referenced by MFile::MFile().

void _list | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 486 of file file.C.

References Request::absolute(), MethodParams::as_no_junction(), Value::as_string(), Request::charsets, Table::columns_type, Array< Value * >::count(), String::cstr(), Array< ArrayString * >::element_type, String::L_FILE_SPEC, String::length(), LOAD_DIR, String::mid(), pa_strdup(), pcre, pcre_compile(), PCRE_DOTALL, PCRE_ERROR_NOMATCH, pcre_exec(), PCRE_EXTRA, pcre_free, Charset::pcre_tables, Request_charsets::source(), and Request::write_no_lang().

Referenced by MFile::MFile().

void lock_execute_body | ( | int | ,
 |  | void * | ainfo
 | ) | [static]

Definition at line 559 of file file.C.

Referenced by _lock().

void _lock | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 564 of file file.C.

References Request::absolute(), MethodParams::as_junction(), MethodParams::as_string(), file_write_action_under_lock(), and lock_execute_body().

Referenced by MFile::MFile().

int lastposafter | ( | const String & | s,
 |  | size_t | after,
 |  | const char * | substr,
 |  | size_t | substr_size,
 |  | bool | beforelast = false
 | ) | [static]

Definition at line 574 of file file.C.

References String::length(), String::pos(), size, and STRING_NOT_FOUND.

Referenced by _basename(), _dirname(), _find(), _justext(), and _justname().

void _find | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 589 of file file.C.

References Request::absolute(), MethodParams::as_junction(), MethodParams::as_no_junction(), Value::as_string(), Array< Value * >::count(), dirname, file_exist(), String::first_char(), lastposafter(), String::length(), String::mid(), Request::process(), Request::relative(), Request::request_info, Request_info::uri, Request::write_assign_lang(), and Request::write_pass_lang().

Referenced by MFile::MFile().

void _dirname | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 626 of file file.C.

References MethodParams::as_string(), lastposafter(), String::mid(), and Request::write_assign_lang().

Referenced by MFile::MFile().

void _basename | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 637 of file file.C.

References MethodParams::as_string(), lastposafter(), String::length(), String::mid(), and Request::write_assign_lang().

Referenced by MFile::MFile().

void _justname | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 644 of file file.C.

References MethodParams::as_string(), lastposafter(), String::length(), String::mid(), and Request::write_assign_lang().

Referenced by MFile::MFile().

void _justext | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 651 of file file.C.

References MethodParams::as_string(), lastposafter(), String::length(), String::mid(), and Request::write_assign_lang().

Referenced by MFile::MFile().

void _fullpath | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 659 of file file.C.

References Request::absolute(), MethodParams::as_string(), Request_info::document_root, String::first_char(), String::length(), String::mid(), Request::request_info, result, and Request::write_assign_lang().

Referenced by MFile::MFile().

void _sql_string | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 679 of file file.C.

References Request::connection(), GET_SELF, SQL_Connection::quote(), VFile::value_ptr(), VFile::value_size(), and Request::write_assign_lang().

Referenced by MFile::MFile().

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 739 of file file.C.

References MethodParams::as_junction(), MethodParams::as_no_junction(), Value::as_string(), Request::connection(), CONTENT_TYPE_NAME, Hash< const String::Body, Value * >::count(), Array< Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), Value::get_hash(), GET_SELF, String::L_SQL, String::L_UNSPECIFIED, Request::mime_type_of(), NAME_NAME, Request::process_to_string(), SQL_Connection::query(), and VFile::set().

Referenced by MFile::MFile().

void _base64 | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 790 of file file.C.

References MethodParams::as_string(), Array< Value * >::count(), String::cstr(), GET_SELF, pa_base64_decode(), pa_base64_encode(), VFile::set(), VFile::value_ptr(), VFile::value_size(), and Request::write_assign_lang().

Referenced by MFile::MFile().

Variable Documentation

const char* const IDENT_FILE_C = "$Date: 2005/11/24 14:00:34 $" [static]

Definition at line 8 of file file.C.

String sql_limit_name

Definition at line 40 of file file.C.

String sql_offset_name

Definition at line 41 of file file.C.

const char* suexec_safe_env_lst[] [static]

from apache-1.3|src|support|suexec.c.

Definition at line 65 of file file.C.

Referenced by is_safe_env_key().


file.C Source File

file.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_FILE_C="$Date: 2005/11/24 14:00:34 $";
00009
00010 #include "pa_config_includes.h"
00011
00012 #include "pcre.h"
00013
00014 #include "classes.h"
00015 #include "pa_vmethod_frame.h"
00016
00017 #include "pa_request.h"
00018 #include "pa_vfile.h"
00019 #include "pa_table.h"
00020 #include "pa_vint.h"
00021 #include "pa_exec.h"
00022 #include "pa_vdate.h"
00023 #include "pa_dir.h"
00024 #include "pa_vtable.h"
00025 #include "pa_charset.h"
00026 #include "pa_charsets.h"
00027 #include "pa_sql_connection.h"
00028
00029 // defines
00030
00031 #define TEXT_MODE_NAME "text"
00032 #define BINARY_MODE_NAME "binary"
00033 #define STDIN_EXEC_PARAM_NAME "stdin"
00034 #define CHARSET_EXEC_PARAM_NAME "charset"
00035
00036 #define NAME_NAME "name"
00037
00038 // externs
00039
00040 extern String sql_limit_name;
00041 extern String sql_offset_name;
00042
00043 // class
00044
00045 class MFile: public Methoded {
00046 public: // VStateless_class
00047
00048     Value* create_new_value(Pool&, HashStringValue&) { return new VFile(); }
00049
00050 public: // Methoded
00051     bool used_directly() { return true; }
00052
00053 public:
00054     MFile();
00055
00056 };
00057
00058 // global variable
00059
00060 DECLARE_CLASS_VAR(file, new MFile, 0);
00061
00062 // consts
00063
00065 static const char* suexec_safe_env_lst[]={
00066     "AUTH_TYPE",
00067     "CONTENT_LENGTH",
00068     "CONTENT_TYPE",
00069     "DATE_GMT",
00070     "DATE_LOCAL",
00071     "DOCUMENT_NAME",
00072     "DOCUMENT_PATH_INFO",
00073     "DOCUMENT_ROOT",
00074     "DOCUMENT_URI",
00075     "FILEPATH_INFO",
00076     "GATEWAY_INTERFACE",
00077     "LAST_MODIFIED",
00078     "PATH_INFO",
00079     "PATH_TRANSLATED",
00080     "QUERY_STRING",
00081     "QUERY_STRING_UNESCAPED",
00082     "REMOTE_ADDR",
00083     "REMOTE_HOST",
00084     "REMOTE_IDENT",
00085     "REMOTE_PORT",
00086     "REMOTE_USER",
00087     "REDIRECT_QUERY_STRING",
00088     "REDIRECT_STATUS",
00089     "REDIRECT_URL",
00090     "REQUEST_METHOD",
00091     "REQUEST_URI",
00092     "SCRIPT_FILENAME",
00093     "SCRIPT_NAME",
00094     "SCRIPT_URI",
00095     "SCRIPT_URL",
00096     "SERVER_ADMIN",
00097     "SERVER_NAME",
00098     "SERVER_ADDR",
00099     "SERVER_PORT",
00100     "SERVER_PROTOCOL",
00101     "SERVER_SOFTWARE",
00102     "UNIQUE_ID",
00103     "USER_NAME",
00104     "TZ",
00105     NULL
00106 };
00107
00108 // statics
00109
00110 static const String::Body adate_name("adate");
00111 static const String::Body mdate_name("mdate");
00112 static const String::Body cdate_name("cdate");
00113
00114 // methods
00115
00116 static bool is_text_mode(const String& mode) {
00117     if(mode==TEXT_MODE_NAME)
00118         return true;
00119     if(mode==BINARY_MODE_NAME)
00120         return false;
00121     throw Exception("parser.runtime",
00122         &mode,
00123         "is invalid mode, must be either '"TEXT_MODE_NAME"' or '"BINARY_MODE_NAME"'");
00124 }
00125
00126 static void _save(Request& r, MethodParams& params) {
00127     Value& vmode_name=params. as_no_junction(0, "mode must not be code");
00128     Value& vfile_name=params.as_no_junction(1, "file name must not be code");
00129
00130     // save
00131     GET_SELF(r, VFile).save(r.absolute(vfile_name.as_string()),
00132         is_text_mode(vmode_name.as_string()));
00133 }
00134
00135 static void _delete(Request& r, MethodParams& params) {
00136     Value& vfile_name=params.as_no_junction(0, "file name must not be code");
00137
00138     // unlink
00139     file_delete(r.absolute(vfile_name.as_string()));
00140 }
00141
00142 static void _move(Request& r, MethodParams& params) {
00143     Value& vfrom_file_name=params.as_no_junction(0, "from file name must not be code");
00144     Value& vto_file_name=params.as_no_junction(1, "to file name must not be code");
00145
00146     // move
00147     file_move(
00148         r.absolute(vfrom_file_name.as_string()),
00149         r.absolute(vto_file_name.as_string()));
00150 }
00151
00152 static void _load_pass_param(
00153                  HashStringValue::key_type key,
00154                  HashStringValue::value_type value,
00155                  HashStringValue *dest) {
00156     dest->put(key, value);
00157 }
00158 static void _load(Request& r, MethodParams& params) {
00159     Value& vmode_name=params. as_no_junction(0, "mode must not be code");
00160     const String& lfile_name=r.absolute(params.as_no_junction(1, "file name must not be code").as_string());
00161     Value* third_param=params.count()>2?&params.as_no_junction(2, "filename or options must not be code")
00162         :0;
00163     HashStringValue* third_param_hash=third_param?third_param->get_hash():0;
00164     size_t alt_filename_param_index=2;
00165     if(third_param_hash)
00166         alt_filename_param_index++;
00167
00168     HashStringValue* options=third_param_hash;
00169     size_t offset=0;
00170     size_t limit=0;
00171     if(options) {
00172         options=new HashStringValue(*options);
00173         if(Value *voffset=(Value *)options->get(sql_offset_name)) {
00174             offset=r.process_to_value(*voffset).as_int();
00175         }
00176         if(Value *vlimit=(Value *)options->get(sql_limit_name)) {
00177             limit=r.process_to_value(*vlimit).as_int();
00178         }
00179         // no check on options count here, see file_read
00180     }
00181     File_read_result file=file_read(r.charsets, lfile_name,
00182         is_text_mode(vmode_name.as_string()),
00183         options, true, 0, offset, limit
00184     );
00185
00186     const char *user_file_name=params.count()>alt_filename_param_index?
00187         params.as_string(alt_filename_param_index, "filename must be string").cstr()
00188         :lfile_name.cstr(String::L_FILE_SPEC);
00189
00190     Value* vcontent_type=0;
00191     if(file.headers)
00192     {
00193         if(Value* remote_content_type=file.headers->get("CONTENT-TYPE"))
00194             vcontent_type=new VString(*new String(remote_content_type->as_string().cstr()));
00195     }
00196     if(!vcontent_type)
00197         vcontent_type=new VString(r.mime_type_of(user_file_name));
00198
00199     VFile& self=GET_SELF(r, VFile);
00200     self.set(true/*tainted*/, file.str, file.length, user_file_name, vcontent_type);
00201     if(file.headers)
00202         file.headers->for_each(_load_pass_param, &self.fields());
00203 }
00204
00205 static void _create(Request& r, MethodParams& params) {
00206     Value& vmode_name=params. as_no_junction(0, "mode must not be code");
00207     if(!is_text_mode(vmode_name.as_string()))
00208         throw Exception("parser.runtime",
00209             0,
00210             "only text mode is currently supported");
00211
00212     const char* user_file_name_cstr=r.absolute(
00213         params.as_no_junction(1, "file name must not be code").as_string()).cstr(String::L_FILE_SPEC);
00214
00215     const String& content=params.as_string(2, "content must be string");
00216     const char* content_cstr=content.cstr(String::L_UNSPECIFIED); // explode content, honor tainting changes
00217
00218     VString* vcontent_type=new VString(r.mime_type_of(user_file_name_cstr));
00219
00220     VFile& self=GET_SELF(r, VFile);
00221     self.set(true/*tainted*/, content_cstr, strlen(content_cstr), user_file_name_cstr, vcontent_type);
00222 }
00223
00224 static void _stat(Request& r, MethodParams& params) {
00225     Value& vfile_name=params.as_no_junction(0, "file name must not be code");
00226
00227     const String& lfile_name=vfile_name.as_string();
00228
00229     size_t size;
00230     time_t atime, mtime, ctime;
00231     file_stat(r.absolute(lfile_name),
00232         size,
00233         atime, mtime, ctime);
00234
00235     VFile& self=GET_SELF(r, VFile);
00236     self.set(true/*tainted*/, 0/*no bytes*/, size);
00237     HashStringValue& ff=self.fields();
00238     ff.put(adate_name, new VDate(atime));
00239     ff.put(mdate_name, new VDate(mtime));
00240     ff.put(cdate_name, new VDate(ctime));
00241     ff.put(content_type_name, new VString(r.mime_type_of(lfile_name.cstr(String::L_FILE_SPEC))));
00242 }
00243
00244 static bool is_safe_env_key(const char* key) {
00245     for(const char* validator=key; *validator; validator++) {
00246         char c=*validator;
00247         if(!(c>='A' && c<='Z' || c>='0' && c<='9' || c=='_' || c=='-'))
00248             return false;
00249     }
00250     if(strncasecmp(key, "HTTP_", 5)==0)
00251         return true;
00252     if(strncasecmp(key, "CGI_", 4)==0)
00253         return true;
00254     for(int i=0; suexec_safe_env_lst[i]; i++) {
00255         if(strcasecmp(key, suexec_safe_env_lst[i])==0)
00256             return true;
00257     }
00258     return false;
00259 }
00260 #ifndef DOXYGEN
00261 struct Append_env_pair_info {
00262     Request_charsets* charsets;
00263     HashStringString* env;
00264     Value* vstdin;
00265 };
00266 #endif
00267 static void append_env_pair(
00268                 HashStringValue::key_type akey,
00269                 HashStringValue::value_type avalue,
00270                 Append_env_pair_info *info) {
00271     if(akey==STDIN_EXEC_PARAM_NAME) {
00272         info->vstdin=avalue;
00273     } else if(akey==CHARSET_EXEC_PARAM_NAME) {
00274         // ignore, already processed
00275     } else {
00276         if(!is_safe_env_key(akey.cstr()))
00277             throw Exception("parser.runtime",
00278                 new String(akey, String::L_TAINTED),
00279                 "not safe environment variable");
00280         info->env->put(akey, avalue->as_string().cstr_to_string_body(String::L_UNSPECIFIED, 0, info->charsets));
00281     }
00282 }
00283 #ifndef DOXYGEN
00284 struct Pass_cgi_header_attribute_info {
00285     Charset* charset;
00286     HashStringValue* fields;
00287     Value* content_type;
00288 };
00289 #endif
00290 static void pass_cgi_header_attribute(
00291                       ArrayString::element_type astring,
00292                       Pass_cgi_header_attribute_info* info) {
00293     size_t colon_pos=astring->pos(':');
00294     if(colon_pos!=STRING_NOT_FOUND) {
00295         const String& key=astring->mid(0, colon_pos).change_case(
00296             *info->charset, String::CC_UPPER);
00297         Value* value=new VString(astring->mid(colon_pos+1, astring->length()).trim());
00298         info->fields->put(key, value);
00299         if(key=="CONTENT-TYPE")
00300             info->content_type=value;
00301     }
00302 }
00304 static void _exec_cgi(Request& r, MethodParams& params,
00305                       bool cgi) {
00306
00307     Value& vfile_name=params.as_no_junction(0, "file name must not be code");
00308
00309     const String& script_name=r.absolute(vfile_name.as_string());
00310
00311     HashStringString env;
00312     #define ECSTR(name, value_cstr) \
00313         if(value_cstr) \
00314             env.put( \
00315                 String::Body(#name), \
00316                 String::Body(value_cstr, 0)); \
00317     // passing SAPI::environment
00318     if(const char *const *pairs=SAPI::environment(r.sapi_info)) {
00319         while(const char* pair=*pairs++)
00320             if(const char* eq_at=strchr(pair, '='))
00321                 if(eq_at[1]) // has value
00322                     env.put(
00323                         pa_strdup(pair, eq_at-pair),
00324                         pa_strdup(eq_at+1, 0));
00325     }
00326
00327     // const
00328     ECSTR(GATEWAY_INTERFACE, "CGI/1.1");
00329     // from Request.info
00330     ECSTR(DOCUMENT_ROOT, r.request_info.document_root);
00331     ECSTR(PATH_TRANSLATED, r.request_info.path_translated);
00332     ECSTR(REQUEST_METHOD, r.request_info.method);
00333     ECSTR(QUERY_STRING, r.request_info.query_string);
00334     ECSTR(REQUEST_URI, r.request_info.uri);
00335     ECSTR(CONTENT_TYPE, r.request_info.content_type);
00336     char content_length_cstr[MAX_NUMBER];
00337     snprintf(content_length_cstr, MAX_NUMBER, "%u", r.request_info.content_length);
00338     //String content_length(content_length_cstr);
00339     ECSTR(CONTENT_LENGTH, content_length_cstr);
00340     // SCRIPT_*
00341     env.put(String::Body("SCRIPT_NAME"), script_name);
00342     //env.put(String::Body("SCRIPT_FILENAME"), ??&script_name);
00343
00344     bool stdin_specified=false;
00345     // environment & stdin from param
00346     String *in=new String();
00347     Charset *charset=0; // default script works raw_in 'source' charset = no transcoding needed
00348     if(params.count()>1) {
00349         Value& venv=params.as_no_junction(1, "env must not be code");
00350         if(HashStringValue* user_env=venv.get_hash()) {
00351             // $.charset  [previewing to handle URI pieces]
00352             if(Value* vcharset=user_env->get(CHARSET_EXEC_PARAM_NAME))
00353                 charset=&charsets.get(vcharset->as_string()
00354                     .change_case(r.charsets.source(), String::CC_UPPER));
00355
00356             // $.others
00357             Append_env_pair_info info={&r.charsets, &env, 0};
00358             {
00359                 // influence URLencoding of tainted pieces to String::L_URI lang
00360                 // main target -- $.QUERY_STRING
00361                 Temp_client_charset temp(r.charsets, charset? *charset: r.charsets.source());
00362                 user_env->for_each(append_env_pair, &info);
00363             }
00364             // $.stdin
00365             if(info.vstdin) {
00366                 stdin_specified=true;
00367                 if(const String* sstdin=info.vstdin->get_string()) {
00368                     in->append(*sstdin, String::L_CLEAN, true);
00369                 } else
00370                     if(VFile* vfile=static_cast<VFile *>(info.vstdin->as("file", false)))
00371                         in->append_know_length((const char* )vfile->value_ptr(), vfile->value_size(), String::L_TAINTED);
00372                     else
00373                         throw Exception("parser.runtime",
00374                             0,
00375                             STDIN_EXEC_PARAM_NAME " parameter must be string or file");
00376             }
00377         }
00378     }
00379
00380     // argv from params
00381     ArrayString argv;
00382     if(params.count()>2) {
00383         for(size_t i=2; i<params.count(); i++)
00384             argv+=&params.as_string(i, "parameter must be string");
00385     }
00386
00387     // transcode if necessary
00388     if(charset) {
00389         Charset::transcode(env, r.charsets.source(), *charset);
00390         Charset::transcode(argv, r.charsets.source(), *charset);
00391         in=&Charset::transcode(*in, r.charsets.source(), *charset);
00392     }
00393     // @todo
00394     // ifdef WIN32 do  OEM->ANSI transcode on some(.cmd?) programs to
00395     // match silent conversion in OS
00396
00397     // exec!
00398     PA_exec_result execution=
00399         pa_exec(false/*forced_allow*/, script_name, &env, argv, *in);
00400
00401     String *real_out=&execution.out;
00402     String *real_err=&execution.err;
00403     // transcode if necessary
00404     if(charset) {
00405         real_out=&Charset::transcode(*real_out, *charset, r.charsets.source());
00406         real_err=&Charset::transcode(*real_err, *charset, r.charsets.source());
00407     }
00408
00409     VFile& self=GET_SELF(r, VFile);
00410
00411     const String* body=real_out; // ^file:exec
00412     const char* eol_marker=0; size_t eol_marker_size;
00413     const String* header=0;
00414     if(cgi) { // ^file:cgi
00415         // construct with 'out' body and header
00416         size_t dos_pos=real_out->pos("\r\n\r\n", 4);
00417         size_t unix_pos=real_out->pos("\n\n", 2);
00418
00419         bool unix_header_break;
00420         switch((dos_pos!=STRING_NOT_FOUND?10:00) + (unix_pos!=STRING_NOT_FOUND?01:00)) {
00421         case 10: // dos
00422             unix_header_break=false;
00423             break;
00424         case 01: // unix
00425             unix_header_break=true;
00426             break;
00427         case 11: // dos & unix
00428             unix_header_break=unix_pos<dos_pos;
00429             break;
00430         default: // 00
00431             unix_header_break=false; // calm down, compiler
00432             throw Exception(0,
00433                 0,
00434                 "output does not contain CGI header; "
00435                 "exit status=%d; stdoutsize=%u; stdout: \"%s\"; stderrsize=%u; stderr: \"%s\"",
00436                     execution.status,
00437                     (uint)real_out->length(), real_out->cstr(),
00438                     (uint)real_err->length(), real_err->cstr());
00439             break; //never reached
00440         }
00441
00442         int header_break_pos;
00443         if(unix_header_break) {
00444             header_break_pos=unix_pos;
00445             eol_marker="\n"; eol_marker_size=1;
00446         } else {
00447             header_break_pos=dos_pos;
00448             eol_marker="\r\n"; eol_marker_size=2;
00449         }
00450
00451         header=&real_out->mid(0, header_break_pos);
00452         body=&real_out->mid(header_break_pos+eol_marker_size*2, real_out->length());
00453     }
00454     // body
00455     self.set(false/*not tainted*/, body->cstr(), body->length());
00456
00457     // $fields << header
00458     if(header && eol_marker) {
00459         ArrayString rows;
00460         size_t pos_after=0;
00461         header->split(rows, pos_after, eol_marker);
00462         Pass_cgi_header_attribute_info info={0, 0, 0};
00463         info.charset=&r.charsets.source();
00464         info.fields=&self.fields();
00465         rows.for_each(pass_cgi_header_attribute, &info);
00466         if(info.content_type)
00467             self.fields().put(content_type_name, info.content_type);
00468     }
00469
00470     // $status
00471     self.fields().put(file_status_name, new VInt(execution.status));
00472
00473     // $stderr
00474     if(real_err->length())
00475         self.fields().put(
00476             String::Body("stderr"),
00477             new VString(*real_err));
00478 }
00479 static void _exec(Request& r, MethodParams& params) {
00480     _exec_cgi(r, params, false);
00481 }
00482 static void _cgi(Request& r, MethodParams& params) {
00483     _exec_cgi(r, params, true);
00484 }
00485
00486 static void _list(Request& r, MethodParams& params) {
00487     Value& relative_path=params.as_no_junction(0, "path must not be code");
00488
00489     const String* regexp;
00490     pcre *regexp_code;
00491     const int ovecsize=(1/*match*/)*3;
00492     int ovector[ovecsize];
00493     if(params.count()>1) {
00494         regexp=&params.as_no_junction(1, "regexp must not be code").as_string();
00495
00496         const char* pattern=regexp->cstr();
00497         const char* errptr;
00498         int erroffset;
00499         regexp_code=pcre_compile(pattern, PCRE_EXTRA | PCRE_DOTALL,
00500             &errptr, &erroffset,
00501             r.charsets.source().pcre_tables);
00502
00503         if(!regexp_code)
00504             throw Exception(0,
00505                 &regexp->mid(erroffset, regexp->length()),
00506                 "regular expression syntax error - %s", errptr);
00507     } else {
00508         regexp=0; // not used, just to calm down compiler
00509         regexp_code=0;
00510     }
00511
00512
00513     const char* absolute_path_cstr=r.absolute(relative_path.as_string()).cstr(String::L_FILE_SPEC);
00514
00515     Table::columns_type columns(new ArrayString);
00516     *columns+=new String("name");
00517     Table& table=*new Table(columns);
00518
00519     LOAD_DIR(absolute_path_cstr,
00520         const char* file_name_cstr=ffblk.ff_name;
00521         size_t file_name_size=strlen(file_name_cstr);
00522         bool suits=true;
00523         if(regexp_code) {
00524             int exec_result=pcre_exec(regexp_code, 0,
00525                 ffblk.ff_name, file_name_size, 0,
00526                 0, ovector, ovecsize);
00527
00528             if(exec_result==PCRE_ERROR_NOMATCH)
00529                 suits=false;
00530             else if(exec_result<0) {
00531                 (*pcre_free)(regexp_code);
00532                 throw Exception(0,
00533                     regexp,
00534                     "regular expression execute (%d)",
00535                         exec_result);
00536             }
00537         }
00538
00539         if(suits) {
00540             Table::element_type row(new ArrayString);
00541             *row+=new String(pa_strdup(file_name_cstr, file_name_size), file_name_size, true);
00542             table+=row;
00543         }
00544     );
00545
00546     if(regexp_code)
00547         pcre_free(regexp_code);
00548
00549     // write out result
00550     r.write_no_lang(*new VTable(&table));
00551 }
00552
00553 #ifndef DOXYGEN
00554 struct Lock_execute_body_info {
00555     Request* r;
00556     Value* body_code;
00557 };
00558 #endif
00559 static void lock_execute_body(int , void *ainfo) {
00560     Lock_execute_body_info& info=*static_cast<Lock_execute_body_info *>(ainfo);
00561     // execute body
00562     info.r->write_assign_lang(info.r->process(*info.body_code));
00563 };
00564 static void _lock(Request& r, MethodParams& params) {
00565     const String& file_spec=r.absolute(params.as_string(0, "file name must be string"));
00566     Lock_execute_body_info info={
00567         &r,
00568         &params.as_junction(1, "body must be code")
00569     };
00570
00571     file_write_action_under_lock(file_spec, "lock", lock_execute_body, &info);
00572 }
00573
00574 static int lastposafter(const String& s, size_t after, const char* substr, size_t substr_size, bool beforelast=false) {
00575     size_t size=0; // just to calm down compiler
00576     if(beforelast)
00577         size=s.length();
00578     size_t at;
00579     while((at=s.pos(String::Body(substr, substr_size), after))!=STRING_NOT_FOUND) {
00580         size_t newafter=at+substr_size/*skip substr*/;
00581         if(beforelast && newafter==size)
00582             break;
00583         after=newafter;
00584     }
00585
00586     return after;
00587 }
00588
00589 static void _find(Request& r, MethodParams& params) {
00590     const String& file_name=params.as_no_junction(0, "file name must not be code").as_string();
00591     const String* file_spec;
00592     if(file_name.first_char()=='/')
00593         file_spec=&file_name;
00594     else
00595         file_spec=&r.relative(r.request_info.uri, file_name);
00596
00597     // easy way
00598     if(file_exist(r.absolute(*file_spec))) {
00599         r.write_assign_lang(*file_spec);
00600         return;
00601     }
00602
00603     // monkey way
00604     int after_base_slash=lastposafter(*file_spec, 0, "/", 1);
00605     const String* dirname=&file_spec->mid(0, after_base_slash);
00606     const String& basename=file_spec->mid(after_base_slash, file_spec->length());
00607
00608     int after_monkey_slash;
00609     while((after_monkey_slash=lastposafter(*dirname, 0, "/", 1, true))>0) {
00610         String test_name;
00611         test_name<<*(dirname=&dirname->mid(0, after_monkey_slash));
00612         test_name<<basename;
00613         if(file_exist(r.absolute(test_name))) {
00614             r.write_assign_lang(test_name);
00615             return;
00616         }
00617     }
00618
00619     // no way, not found
00620     if(params.count()==2) {
00621         Value& not_found_code=params.as_junction(1, "not-found param must be code");
00622         r.write_pass_lang(r.process(not_found_code));
00623     }
00624 }
00625
00626 static void _dirname(Request& r, MethodParams& params) {
00627     const String& file_spec=params.as_string(0, "file name must be string");
00628     // /a/some.tar.gz > /a
00629     // /a/b/ > /a
00630     int afterslash=lastposafter(file_spec, 0, "/", 1, true);
00631     if(afterslash>0)
00632         r.write_assign_lang(file_spec.mid(0, afterslash==1?1:afterslash-1));
00633     else
00634         r.write_assign_lang(String(".", 1));
00635 }
00636
00637 static void _basename(Request& r, MethodParams& params) {
00638     const String& file_spec=params.as_string(0, "file name must be string");
00639     // /a/some.tar.gz > some.tar.gz
00640     int afterslash=lastposafter(file_spec, 0, "/", 1);
00641     r.write_assign_lang(file_spec.mid(afterslash, file_spec.length()));
00642 }
00643
00644 static void _justname(Request& r, MethodParams& params) {
00645     const String& file_spec=params.as_string(0, "file name must be string");
00646     // /a/some.tar.gz > some.tar
00647     int afterslash=lastposafter(file_spec, 0, "/", 1);
00648     int afterdot=lastposafter(file_spec, afterslash, ".", 1);
00649     r.write_assign_lang(file_spec.mid(afterslash, afterdot!=afterslash?afterdot-1:file_spec.length()));
00650 }
00651 static void _justext(Request& r, MethodParams& params) {
00652     const String& file_spec=params.as_string(0, "file name must be string");
00653     // /a/some.tar.gz > gz
00654     int afterdot=lastposafter(file_spec, 0, ".", 1);
00655     if(afterdot>0)
00656         r.write_assign_lang(file_spec.mid(afterdot, file_spec.length()));
00657 }
00658
00659 static void _fullpath(Request& r, MethodParams& params) {
00660     const String& file_spec=params.as_string(0, "file name must be string");
00661     const String* result;
00662     if(file_spec.first_char()=='/')
00663         result=&file_spec;
00664     else {
00665         // /some/page.html: ^file:fullpath[a.gif] => /some/a.gif
00666         const String& full_disk_path=r.absolute(file_spec);
00667         size_t document_root_length=strlen(r.request_info.document_root);
00668
00669         if(document_root_length>0) {
00670             char last_char=r.request_info.document_root[document_root_length-1];
00671             if(last_char == '/' || last_char == '\\')
00672                 --document_root_length;
00673         }
00674         result=&full_disk_path.mid(document_root_length,  full_disk_path.length());
00675     }
00676     r.write_assign_lang(*result);
00677 }
00678
00679 static void _sql_string(Request& r, MethodParams&) {
00680     VFile& self=GET_SELF(r, VFile);
00681
00682     const char *quoted=r.connection()->quote(self.value_ptr(), self.value_size());
00683     r.write_assign_lang(*new String(quoted));
00684 }
00685
00686 #ifndef DOXYGEN
00687 class File_sql_event_handlers: public SQL_Driver_query_event_handlers {
00688     const String& statement_string; const char* statement_cstr;
00689     int got_columns;
00690     int got_cells;
00691 public:
00692     String::C value;
00693     const String* user_file_name;
00694     const String* user_content_type;
00695 public:
00696     File_sql_event_handlers(
00697         const String& astatement_string, const char* astatement_cstr):
00698         statement_string(astatement_string), statement_cstr(astatement_cstr),
00699         got_columns(0),
00700         got_cells(0),
00701         user_file_name(0),
00702         user_content_type(0) {}
00703
00704     bool add_column(SQL_Error& error, const char* /*str*/, size_t /*length*/) {
00705         if(got_columns++==3) {
00706             error=SQL_Error("parser.runtime", "result must contain not more then 3 columns");
00707             return true;
00708         }
00709         return false;
00710     }
00711     bool before_rows(SQL_Error& /*error*/ ) { /* ignore */ return false; }
00712     bool add_row(SQL_Error& /*error*/) { /* ignore */ return false; }
00713     bool add_row_cell(SQL_Error& error, const char* str, size_t length) {
00714         try {
00715             switch(got_cells++) {
00716                 case 0:
00717                     value=String::C(str, length);
00718                     break;
00719                 case 1:
00720                     if(!user_file_name) // user not specified?
00721                         user_file_name=new String(str, length, true);
00722                     break;
00723                 case 2:
00724                     if(!user_content_type) // user not specified?
00725                         user_content_type=new String(str, length, true);
00726                     break;
00727                 default:
00728                     error=SQL_Error("parser.runtime", "result must not contain more then one row, three rows");
00729                     return true;
00730             }
00731             return false;
00732         } catch(...) {
00733             error=SQL_Error("exception occured in File_sql_event_handlers::add_row_cell");
00734             return true;
00735         }
00736     }
00737 };
00738 #endif
00739 static void _sql(Request& r, MethodParams& params) {
00740     Value& statement=params.as_junction(0, "statement must be code");
00741
00742     Temp_lang temp_lang(r, String::L_SQL);
00743     const String& statement_string=r.process_to_string(statement);
00744     const char* statement_cstr=
00745         statement_string.cstr(String::L_UNSPECIFIED, r.connection());
00746     File_sql_event_handlers handlers(statement_string, statement_cstr);
00747
00748     if(params.count()>1)
00749         if(HashStringValue* options=
00750             params.as_no_junction(1, "param must not be code").get_hash()) {
00751             int valid_options=0;
00752             if(Value* vfilename=options->get(NAME_NAME)) {
00753                 valid_options++;
00754                 handlers.user_file_name=&vfilename->as_string();
00755             }
00756             if(Value* vcontent_type=options->get(CONTENT_TYPE_NAME)) {
00757                 valid_options++;
00758                 handlers.user_content_type=&vcontent_type->as_string();
00759             }
00760             if(valid_options!=options->count())
00761                 throw Exception("parser.runtime",
00762                     0,
00763                     "called with invalid option");
00764         }
00765
00766
00767     r.connection()->query(
00768         statement_cstr,
00769         0, 0,
00770         0, 0,
00771         handlers,
00772         statement_string);
00773
00774     if(!handlers.value)
00775         throw Exception("parser.runtime",
00776             0,
00777             "produced no result");
00778
00779     const char* user_file_name_cstr=handlers.user_file_name? handlers.user_file_name->cstr(): 0;
00780
00781     VString* vcontent_type=handlers.user_content_type?
00782         new VString(*handlers.user_content_type)
00783         : user_file_name_cstr?
00784             new VString(r.mime_type_of(user_file_name_cstr))
00785             : 0;
00786     VFile& self=GET_SELF(r, VFile);
00787     self.set(true/*tainted*/, handlers.value.str, handlers.value.length, user_file_name_cstr, vcontent_type);
00788 }
00789
00790 static void _base64(Request& r, MethodParams& params) {
00791     VFile& self=GET_SELF(r, VFile);
00792     if(params.count()) {
00793         // decode
00794         const char* cstr=params.as_string(0, "parameter must be string").cstr();
00795         char* decoded_cstr=0;
00796         size_t decoded_size=0;
00797         pa_base64_decode(cstr, strlen(cstr), decoded_cstr, decoded_size);
00798         if(decoded_cstr && decoded_size)
00799             self.set(true/*tainted*/, decoded_cstr, decoded_size);
00800     } else {
00801         // encode
00802         const char* encoded=pa_base64_encode(self.value_ptr(), self.value_size());
00803         r.write_assign_lang(*new String(encoded, 0, true/*once ?param=base64(something) was needed*/));
00804     }
00805 }
00806
00807 // constructor
00808
00809 MFile::MFile(): Methoded("file") {
00810     // ^create[text;user-name;string]
00811     // ^create[binary;user-name;SOMEDAY SOMETHING]
00812     add_native_method("create", Method::CT_DYNAMIC, _create, 3, 3);
00813
00814     // ^save[mode;file-name]
00815     add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2);
00816
00817     // ^delete[file-name]
00818     add_native_method("delete", Method::CT_STATIC, _delete, 1, 1);
00819
00820     // ^move[from-file-name;to-file-name]
00821     add_native_method("move", Method::CT_STATIC, _move, 2, 2);
00822
00823     // ^load[mode;disk-name]
00824     // ^load[mode;disk-name;user-name]
00825     add_native_method("load", Method::CT_DYNAMIC, _load, 2, 3);
00826
00827     // ^stat[disk-name]
00828     add_native_method("stat", Method::CT_DYNAMIC, _stat, 1, 1);
00829
00830     // ^cgi[file-name]
00831     // ^cgi[file-name;env hash]
00832     // ^cgi[file-name;env hash;1cmd;2line;3ar;4g;5s]
00833     add_native_method("cgi", Method::CT_DYNAMIC, _cgi, 1, 2+50);
00834
00835     // ^exec[file-name]
00836     // ^exec[file-name;env hash]
00837     // ^exec[file-name;env hash;1cmd;2line;3ar;4g;5s]
00838     add_native_method("exec", Method::CT_DYNAMIC, _exec, 1, 2+50);
00839
00840     // ^file:list[path]
00841     // ^file:list[path][regexp]
00842     add_native_method("list", Method::CT_STATIC, _list, 1, 2);
00843
00844     // ^file:lock[path]{code}
00845     add_native_method("lock", Method::CT_STATIC, _lock, 2, 2);
00846
00847     // ^find[file-name]
00848     // ^find[file-name]{when-not-found}
00849     add_native_method("find", Method::CT_STATIC, _find, 1, 2);
00850
00851     // ^file:dirname[/a/some.tar.gz]=/a
00852     // ^file:dirname[/a/b/]=/a
00853     add_native_method("dirname", Method::CT_STATIC, _dirname, 1, 1);
00854     // ^file:basename[/a/some.tar.gz]=some.tar.gz
00855     add_native_method("basename", Method::CT_STATIC, _basename, 1, 1);
00856     // ^file:justname[/a/some.tar.gz]=some.tar
00857     add_native_method("justname", Method::CT_STATIC, _justname, 1, 1);
00858     // ^file:justext[/a/some.tar.gz]=gz
00859     add_native_method("justext", Method::CT_STATIC, _justext, 1, 1);
00860     // /some/page.html: ^file:fullpath[a.gif] => /some/a.gif
00861     add_native_method("fullpath", Method::CT_STATIC, _fullpath, 1, 1);
00862
00863     // ^file.sql-string[]
00864     add_native_method("sql-string", Method::CT_DYNAMIC, _sql_string, 0, 0);
00865
00866     // ^file::sql[[alt_name]]{}
00867     add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2);
00868
00869     // ^file.base64[] << encode
00870     // ^file::base64[string] << decode
00871     add_native_method("base64", Method::CT_DYNAMIC, _base64, 0, 1);
00872 }


form.C File Reference

Parser: form parser class. More...

Include dependency graph for form.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MForm

Defines

#define | LIMITS_NAME "LIMITS"
#define | MAX_POST_SIZE_NAME "post_max_size"

Functions

DECLARE_CLASS_VAR (form, 0, new MForm)
const String | max_post_size_name (MAX_POST_SIZE_NAME)
const String | limits_name (LIMITS_NAME)

Variables

const char *const | IDENT_FORM_C = "$Date: 2005/08/09 08:14:47 $"
const size_t | MAX_POST_SIZE_DEFAULT = 10*0x400*0x400
$LIMITS.max_post_size default 10M. More...

Detailed Description

Parser: form parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file form.C.

Define Documentation

#define LIMITS_NAME "LIMITS"

Definition at line 39 of file form.C.

Referenced by MForm::configure_admin().

#define MAX_POST_SIZE_NAME "post_max_size"

Definition at line 40 of file form.C.

Referenced by MForm::configure_admin().

Function Documentation

DECLARE_CLASS_VAR | ( | form | ,
 |  | 0 | ,
 |  | new | MForm
 | ) |

const String max_post_size_name ( MAX_POST_SIZE_NAME ) [static]

const String limits_name ( LIMITS_NAME ) [static]

Variable Documentation

const char* const IDENT_FORM_C = "$Date: 2005/08/09 08:14:47 $" [static]

Definition at line 8 of file form.C.

const size_t MAX_POST_SIZE_DEFAULT = 10*0x400*0x400

$LIMITS.max_post_size default 10M.

Definition at line 17 of file form.C.

Referenced by MForm::configure_admin().


form.C Source File

form.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_FORM_C="$Date: 2005/08/09 08:14:47 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vform.h"
00015
00017 const size_t MAX_POST_SIZE_DEFAULT=10*0x400*0x400;
00018
00019 // class
00020
00021 class MForm : public Methoded {
00022 public: // Methoded
00023
00024     bool used_directly() { return false; }
00025     void configure_admin(Request& r);
00026
00027 public:
00028
00029     MForm(): Methoded("form") {}
00030
00031 };
00032
00033 // global variable
00034
00035 DECLARE_CLASS_VAR(form, 0/*fictive*/, new MForm);
00036
00037 // defines for statics
00038
00039 #define LIMITS_NAME "LIMITS"
00040 #define MAX_POST_SIZE_NAME "post_max_size"
00041
00042 // statics
00043
00044 static const String max_post_size_name(MAX_POST_SIZE_NAME);
00045 static const String limits_name(LIMITS_NAME);
00046
00047 // methods
00048
00049 // constructor & configurator
00050
00051 void MForm::configure_admin(Request& r) {
00052
00053     Value* limits=r.main_class.get_element(limits_name, r.main_class, false);
00054     if(r.request_info.method && StrEqNc(r.request_info.method, "post", true)) {
00055         // $limits.max_post_size default 10M
00056         Value* element=limits?limits->get_element(max_post_size_name, *limits, false)
00057             :0;
00058         size_t value=element?(size_t)element->as_double():0;
00059         size_t max_post_size=value?value:MAX_POST_SIZE_DEFAULT;
00060
00061         if(r.request_info.content_length>max_post_size)
00062             throw Exception("parser.runtime",
00063                 0,
00064                 "posted content_length(%u) > $"LIMITS_NAME"."MAX_POST_SIZE_NAME"(%u)",
00065                     r.request_info.content_length, max_post_size);
00066
00067         // read POST data
00068         if(r.request_info.content_length) {
00069             char *post_data=new(PointerFreeGC) char[r.request_info.content_length+1/*terminating zero*/];
00070             size_t post_size=SAPI::read_post(r.sapi_info,
00071                     post_data, r.request_info.content_length);
00072             post_data[post_size]=0; // terminating zero
00073             r.request_info.post_data=post_data;
00074             r.request_info.post_size=post_size;
00075         } else {
00076             r.request_info.post_data=0;
00077             r.request_info.post_size=0;
00078         }
00079         if(r.request_info.post_size!=r.request_info.content_length)
00080             throw Exception(0,
00081                 0,
00082                 "post_size(%u) != content_length(%u)",
00083                     r.request_info.post_size, r.request_info.content_length);
00084     }
00085 }


gc.h File Reference

Include dependency graph for gc.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | __GC
#define | GC_API extern
#define | GC_PROTO(args) ()
#define | GC_CONST
#define | GC_TIME_UNLIMITED 999999
#define | GC_PROTECTS_POINTER_HEAP 1
#define | GC_PROTECTS_PTRFREE_HEAP 2
#define | GC_PROTECTS_STATIC_DATA 4
#define | GC_PROTECTS_STACK 8
#define | GC_PROTECTS_NONE 0
#define | GC_EXTRAS __FILE__, __LINE__
#define | GC_EXTRA_PARAMS GC_CONST char * s, int i
#define | GC_MALLOC(sz) GC_malloc(sz)
#define | GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
#define | GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
#define | GC_REALLOC(old, sz) GC_realloc(old, sz)
#define | GC_FREE(p) GC_free(p)
#define | GC_REGISTER_FINALIZER(p, f, d, of, od) GC_register_finalizer(p, f, d, of, od)
#define | GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) GC_register_finalizer_ignore_self(p, f, d, of, od)
#define | GC_REGISTER_FINALIZER_NO_ORDER(p, f, d, of, od) GC_register_finalizer_no_order(p, f, d, of, od)
#define | GC_MALLOC_STUBBORN(sz) GC_malloc_stubborn(sz)
#define | GC_CHANGE_STUBBORN(p) GC_change_stubborn(p)
#define | GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p)
#define | GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) GC_general_register_disappearing_link(link, obj)
#define | GC_REGISTER_DISPLACEMENT(n) GC_register_displacement(n)
#define | GC_NEW(t) (t *)GC_MALLOC(sizeof (t))
#define | GC_NEW_ATOMIC(t) (t *)GC_MALLOC_ATOMIC(sizeof (t))
#define | GC_NEW_STUBBORN(t) (t *)GC_MALLOC_STUBBORN(sizeof (t))
#define | GC_NEW_UNCOLLECTABLE(t) (t *)GC_MALLOC_UNCOLLECTABLE(sizeof (t))
#define | GC_PTR_ADD3(x, n, type_of_result) ((x)+(n))
#define | GC_PTR_ADD(x, n) ((x)+(n))
#define | GC_PRE_INCR3(x, n, type_of_result) ((x) += (n))
#define | GC_PRE_INCR(x, n) ((x) += (n))
#define | GC_POST_INCR2(x, n, type_of_result) ((x)++)
#define | GC_POST_INCR(x, n) ((x)++)
#define | GC_PTR_STORE(p, q) *((p) = (q))
#define | GC_INIT()

Typedefs

typedef char * | GC_PTR
typedef unsigned long | GC_word
typedef long | GC_signed_word
typedef int GC_stop_func | GC_PROTO ((void))

Functions

GC_API GC_PTR GC_oom_fn | GC_PROTO ((size_t bytes_requested))
GC_API void GC_init | GC_PROTO ((void))
GC_API GC_PTR GC_malloc | GC_PROTO ((size_t size_in_bytes))
GC_API void GC_free | GC_PROTO ((GC_PTR object_addr))
GC_API void GC_change_stubborn | GC_PROTO ((GC_PTR))
GC_API GC_PTR GC_base | GC_PROTO ((GC_PTR displaced_pointer))
GC_API GC_PTR GC_realloc | GC_PROTO ((GC_PTR old_object, size_t new_size_in_bytes))
GC_API int GC_expand_hp | GC_PROTO ((size_t number_of_bytes))
GC_API void GC_set_max_heap_size | GC_PROTO ((GC_word n))
GC_API void GC_exclude_static_roots | GC_PROTO ((GC_PTR start, GC_PTR finish))
GC_API void GC_add_roots | GC_PROTO ((char *low_address, char *high_address_plus_1))
GC_API int GC_try_to_collect | GC_PROTO ((GC_stop_func stop_func))
GC_API GC_PTR GC_malloc_ignore_off_page | GC_PROTO ((size_t lb))
GC_API GC_PTR GC_debug_malloc | GC_PROTO ((size_t size_in_bytes, GC_EXTRA_PARAMS))
GC_API GC_PTR GC_debug_realloc | GC_PROTO ((GC_PTR old_object, size_t new_size_in_bytes, GC_EXTRA_PARAMS))
GC_API GC_PTR GC_debug_realloc_replacement | GC_PROTO ((GC_PTR object_addr, size_t size_in_bytes))
GC_API void GC_register_finalizer | GC_PROTO ((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, GC_finalization_proc *ofn, GC_PTR *ocd))
GC_API int GC_register_disappearing_link | GC_PROTO ((GC_PTR *))
GC_API int GC_general_register_disappearing_link | GC_PROTO ((GC_PTR *, GC_PTR obj))
GC_API GC_PTR GC_make_closure | GC_PROTO ((GC_finalization_proc fn, GC_PTR data))
GC_API void GC_debug_invoke_finalizer | GC_PROTO ((GC_PTR obj, GC_PTR data))
GC_API GC_warn_proc GC_set_warn_proc | GC_PROTO ((GC_warn_proc p))
GC_API GC_PTR GC_call_with_alloc_lock | GC_PROTO ((GC_fn_type fn, GC_PTR client_data))
GC_API GC_PTR GC_same_obj | GC_PROTO ((GC_PTR p, GC_PTR q))
GC_API GC_PTR GC_pre_incr | GC_PROTO ((GC_PTR *p, size_t how_much))
GC_API GC_PTR GC_is_visible | GC_PROTO ((GC_PTR p))
GC_API GC_PTR GC_is_valid_displacement | GC_PROTO ((GC_PTR p))

Variables

GC_API GC_word | GC_gc_no
GC_API int | GC_parallel
GC_API int | GC_find_leak
GC_API int | GC_all_interior_pointers
GC_API int | GC_quiet
GC_API int | GC_finalize_on_demand
GC_API int | GC_java_finalization
GC_API void(* | GC_finalizer_notifier )()
GC_API int | GC_dont_gc
GC_API int | GC_dont_expand
GC_API int | GC_use_entire_heap
GC_API int | GC_full_freq
GC_API GC_word | GC_non_gc_bytes
GC_API int | GC_no_dls
GC_API GC_word | GC_free_space_divisor
GC_API GC_word | GC_max_retries
GC_API char * | GC_stackbottom
GC_API int | GC_dont_precollect
GC_API unsigned long | GC_time_limit

Define Documentation

#define __GC

Definition at line 92 of file gc.h.

#define GC_API extern

Definition at line 127 of file gc.h.

#define GC_PROTO ( args ) ()

Definition at line 135 of file gc.h.

#define GC_CONST

Definition at line 137 of file gc.h.

#define GC_TIME_UNLIMITED 999999

Definition at line 319 of file gc.h.

#define GC_PROTECTS_POINTER_HEAP 1

Definition at line 497 of file gc.h.

#define GC_PROTECTS_PTRFREE_HEAP 2

Definition at line 498 of file gc.h.

#define GC_PROTECTS_STATIC_DATA 4

Definition at line 499 of file gc.h.

#define GC_PROTECTS_STACK 8

Definition at line 500 of file gc.h.

#define GC_PROTECTS_NONE 0

Definition at line 502 of file gc.h.

#define GC_EXTRAS __FILE__, __LINE__

Definition at line 540 of file gc.h.

#define GC_EXTRA_PARAMS GC_CONST char * s, int i

Definition at line 541 of file gc.h.

#define GC_MALLOC ( sz ) GC_malloc(sz)

Definition at line 597 of file gc.h.

Referenced by pa_gc_malloc().

#define GC_MALLOC_ATOMIC ( sz ) GC_malloc_atomic(sz)

Definition at line 598 of file gc.h.

Referenced by CORD_cat_char(), CORD_cat_char_star(), CORD_ec_flush_buf(), CORD_from_char_star(), CORD_from_fn(), CORD_substr_checked(), CORD_to_char_star(), CORD_vsprintf(), and pa_gc_malloc_atomic().

#define GC_MALLOC_UNCOLLECTABLE ( sz ) GC_malloc_uncollectable(sz)

Definition at line 599 of file gc.h.

#define GC_REALLOC | ( | old,
 |  | sz | ) | GC_realloc(old, sz)

Definition at line 600 of file gc.h.

Referenced by pa_gc_realloc().

#define GC_FREE ( p ) GC_free(p)

Definition at line 601 of file gc.h.

Referenced by pa_gc_free().

#define GC_REGISTER_FINALIZER | ( | p,
 |  | f,
 |  | d,
 |  | of,
 |  | od | ) | GC_register_finalizer(p, f, d, of, od)

Definition at line 602 of file gc.h.

#define GC_REGISTER_FINALIZER_IGNORE_SELF | ( | p,
 |  | f,
 |  | d,
 |  | of,
 |  | od | ) | GC_register_finalizer_ignore_self(p, f, d, of, od)

Definition at line 604 of file gc.h.

Referenced by PA_Cleaned::~PA_Cleaned().

#define GC_REGISTER_FINALIZER_NO_ORDER | ( | p,
 |  | f,
 |  | d,
 |  | of,
 |  | od | ) | GC_register_finalizer_no_order(p, f, d, of, od)

Definition at line 606 of file gc.h.

#define GC_MALLOC_STUBBORN ( sz ) GC_malloc_stubborn(sz)

Definition at line 608 of file gc.h.

#define GC_CHANGE_STUBBORN ( p ) GC_change_stubborn(p)

Definition at line 609 of file gc.h.

#define GC_END_STUBBORN_CHANGE ( p ) GC_end_stubborn_change(p)

Definition at line 610 of file gc.h.

#define GC_GENERAL_REGISTER_DISAPPEARING_LINK | ( | link,
 |  | obj | ) | GC_general_register_disappearing_link(link, obj)

Definition at line 611 of file gc.h.

#define GC_REGISTER_DISPLACEMENT ( n ) GC_register_displacement(n)

Definition at line 613 of file gc.h.

#define GC_NEW ( t ) (t *)GC_MALLOC(sizeof (t))

Definition at line 619 of file gc.h.

Referenced by CORD_cat(), CORD_cat_char_star(), CORD_from_fn(), and CORD_substr_closure().

#define GC_NEW_ATOMIC ( t ) (t *)GC_MALLOC_ATOMIC(sizeof (t))

Definition at line 620 of file gc.h.

#define GC_NEW_STUBBORN ( t ) (t *)GC_MALLOC_STUBBORN(sizeof (t))

Definition at line 621 of file gc.h.

#define GC_NEW_UNCOLLECTABLE ( t ) (t *)GC_MALLOC_UNCOLLECTABLE(sizeof (t))

Definition at line 622 of file gc.h.

#define GC_PTR_ADD3 | ( | x,
 |  | n,
 |  | type_of_result | ) | ((x)+(n))

Definition at line 853 of file gc.h.

#define GC_PTR_ADD | ( | x,
 |  | n | ) | ((x)+(n))

Definition at line 854 of file gc.h.

#define GC_PRE_INCR3 | ( | x,
 |  | n,
 |  | type_of_result | ) | ((x) += (n))

Definition at line 855 of file gc.h.

#define GC_PRE_INCR | ( | x,
 |  | n | ) | ((x) += (n))

Definition at line 856 of file gc.h.

#define GC_POST_INCR2 | ( | x,
 |  | n,
 |  | type_of_result | ) | ((x)++)

Definition at line 857 of file gc.h.

#define GC_POST_INCR | ( | x,
 |  | n | ) | ((x)++)

Definition at line 858 of file gc.h.

#define GC_PTR_STORE | ( | p,
 |  | q | ) | *((p) = (q))

Definition at line 871 of file gc.h.

#define GC_INIT ( )

Definition at line 960 of file gc.h.

Typedef Documentation

typedef char* GC_PTR

Definition at line 136 of file gc.h.

typedef unsigned long GC_word

Definition at line 153 of file gc.h.

typedef long GC_signed_word

Definition at line 154 of file gc.h.

GC_API void GC_is_visible_print_proc GC_PROTO

Definition at line 463 of file gc.h.

Function Documentation

GC_API GC_PTR GC_oom_fn GC_PROTO ( (size_t bytes_requested) )

GC_API void GC_init GC_PROTO ( (void) )

GC_API GC_PTR GC_malloc GC_PROTO ( (size_t size_in_bytes) )

GC_API void GC_free GC_PROTO ( (GC_PTR object_addr) )

GC_API void GC_change_stubborn GC_PROTO ( (GC_PTR) )

GC_API GC_PTR GC_base GC_PROTO ( (GC_PTR displaced_pointer) )

GC_API GC_PTR GC_realloc GC_PROTO ( (GC_PTR old_object, size_t new_size_in_bytes) )

GC_API int GC_expand_hp GC_PROTO ( (size_t number_of_bytes) )

GC_API void GC_set_max_heap_size GC_PROTO ( (GC_word n) )

GC_API void GC_exclude_static_roots GC_PROTO ( (GC_PTR start, GC_PTR finish) )

GC_API void GC_add_roots GC_PROTO ( (char *low_address, char *high_address_plus_1) )

GC_API int GC_try_to_collect GC_PROTO ( (GC_stop_func stop_func) )

GC_API GC_PTR GC_malloc_ignore_off_page GC_PROTO ( (size_t lb) )

GC_API GC_PTR GC_debug_malloc GC_PROTO ( (size_t size_in_bytes, GC_EXTRA_PARAMS) )

GC_API GC_PTR GC_debug_realloc GC_PROTO ( (GC_PTR old_object, size_t new_size_in_bytes, GC_EXTRA_PARAMS) )

GC_API GC_PTR GC_debug_realloc_replacement GC_PROTO ( (GC_PTR object_addr, size_t size_in_bytes) )

GC_API void GC_register_finalizer GC_PROTO ( (GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, GC_finalization_proc *ofn, GC_PTR *ocd) )

GC_API int GC_register_disappearing_link GC_PROTO ( (GC_PTR *) )

GC_API int GC_general_register_disappearing_link GC_PROTO ( (GC_PTR *, GC_PTR obj) )

GC_API GC_PTR GC_make_closure GC_PROTO ( (GC_finalization_proc fn, GC_PTR data) )

GC_API void GC_debug_invoke_finalizer GC_PROTO ( (GC_PTR obj, GC_PTR data) )

GC_API GC_warn_proc GC_set_warn_proc GC_PROTO ( (GC_warn_proc p) )

GC_API GC_PTR GC_call_with_alloc_lock GC_PROTO ( (GC_fn_type fn, GC_PTR client_data) )

GC_API GC_PTR GC_same_obj GC_PROTO ( (GC_PTR p, GC_PTR q) )

GC_API GC_PTR GC_pre_incr GC_PROTO ( (GC_PTR *p, size_t how_much) )

GC_API GC_PTR GC_is_visible GC_PROTO ( (GC_PTR p) )

GC_API GC_PTR GC_is_valid_displacement GC_PROTO ( (GC_PTR p) )

Variable Documentation

GC_API GC_word GC_gc_no

Definition at line 158 of file gc.h.

GC_API int GC_parallel

Definition at line 161 of file gc.h.

GC_API int GC_find_leak

Definition at line 183 of file gc.h.

GC_API int GC_all_interior_pointers

Definition at line 189 of file gc.h.

GC_API int GC_quiet

Definition at line 201 of file gc.h.

GC_API int GC_finalize_on_demand

Definition at line 206 of file gc.h.

GC_API int GC_java_finalization

Definition at line 213 of file gc.h.

Referenced by main().

GC_API void(* GC_finalizer_notifier)()

Definition at line 220 of file gc.h.

GC_API int GC_dont_gc

Definition at line 229 of file gc.h.

Referenced by _compact(), main(), and real_parser_handler().

GC_API int GC_dont_expand

Definition at line 232 of file gc.h.

GC_API int GC_use_entire_heap

Definition at line 236 of file gc.h.

GC_API int GC_full_freq

Definition at line 247 of file gc.h.

GC_API GC_word GC_non_gc_bytes

Definition at line 257 of file gc.h.

GC_API int GC_no_dls

Definition at line 263 of file gc.h.

GC_API GC_word GC_free_space_divisor

Definition at line 271 of file gc.h.

GC_API GC_word GC_max_retries

Definition at line 284 of file gc.h.

GC_API char* GC_stackbottom

Definition at line 290 of file gc.h.

GC_API int GC_dont_precollect

Definition at line 302 of file gc.h.

GC_API unsigned long GC_time_limit

Definition at line 310 of file gc.h.


gc.h Source File

gc.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
00003  * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
00004  * Copyright 1996-1999 by Silicon Graphics.  All rights reserved.
00005  * Copyright 1999 by Hewlett-Packard Company.  All rights reserved.
00006  *
00007  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00008  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00009  *
00010  * Permission is hereby granted to use or copy this program
00011  * for any purpose,  provided the above notices are retained on all copies.
00012  * Permission to modify the code and to distribute modified code is granted,
00013  * provided the above notices are retained, and a notice that the code was
00014  * modified is included with the above copyright notice.
00015  */
00016
00017 /*
00018  * Note that this defines a large number of tuning hooks, which can
00019  * safely be ignored in nearly all cases.  For normal use it suffices
00020  * to call only GC_MALLOC and perhaps GC_REALLOC.
00021  * For better performance, also look at GC_MALLOC_ATOMIC, and
00022  * GC_enable_incremental.  If you need an action to be performed
00023  * immediately before an object is collected, look at GC_register_finalizer.
00024  * If you are using Solaris threads, look at the end of this file.
00025  * Everything else is best ignored unless you encounter performance
00026  * problems.
00027  */
00028
00029 #ifndef _GC_H
00030
00031 # define _GC_H
00032
00033 /*
00034  * Some tests for old macros.  These violate our namespace rules and will
00035  * disappear shortly.  Use the GC_ names.
00036  */
00037 #if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS)
00038 # define GC_SOLARIS_THREADS
00039 #endif
00040 #if defined(_SOLARIS_PTHREADS)
00041 # define GC_SOLARIS_PTHREADS
00042 #endif
00043 #if defined(IRIX_THREADS)
00044 # define GC_IRIX_THREADS
00045 #endif
00046 #if defined(DGUX_THREADS)
00047 # if !defined(GC_DGUX386_THREADS)
00048 #  define GC_DGUX386_THREADS
00049 # endif
00050 #endif
00051 #if defined(HPUX_THREADS)
00052 # define GC_HPUX_THREADS
00053 #endif
00054 #if defined(OSF1_THREADS)
00055 # define GC_OSF1_THREADS
00056 #endif
00057 #if defined(LINUX_THREADS)
00058 # define GC_LINUX_THREADS
00059 #endif
00060 #if defined(WIN32_THREADS)
00061 # define GC_WIN32_THREADS
00062 #endif
00063 #if defined(USE_LD_WRAP)
00064 # define GC_USE_LD_WRAP
00065 #endif
00066
00067 #if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \
00068                      || defined(GC_SOLARIS_PTHREADS) \
00069                  || defined(GC_HPUX_THREADS) \
00070                  || defined(GC_LINUX_THREADS))
00071 # define _REENTRANT
00072     /* Better late than never.  This fails if system headers that   */
00073     /* depend on this were previously included.         */
00074 #endif
00075
00076 #if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
00077 # define _POSIX4A_DRAFT10_SOURCE 1
00078 #endif
00079
00080 #if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
00081 #   define GC_SOLARIS_THREADS
00082 #endif
00083
00084 # if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
00085     defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
00086     defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
00087     defined(GC_DGUX386_THREADS) || \
00088         (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
00089 #   define GC_PTHREADS
00090 # endif
00091
00092 # define __GC
00093 # include <stddef.h>
00094 # ifdef _WIN32_WCE
00095 /* Yet more kluges for WinCE */
00096 #   include <stdlib.h>      /* size_t is defined here */
00097     typedef long ptrdiff_t; /* ptrdiff_t is not defined */
00098 # endif
00099
00100 #if defined(__MINGW32__) && defined(_DLL) && !defined(GC_NOT_DLL)
00101 # ifdef GC_BUILD
00102 #   define GC_API __declspec(dllexport)
00103 # else
00104 #   define GC_API __declspec(dllimport)
00105 # endif
00106 #endif
00107
00108 #if (defined(__DMC__) || defined(_MSC_VER)) \
00109         && (defined(_DLL) && !defined(GC_NOT_DLL) \
00110                 || defined(GC_DLL))
00111 # ifdef GC_BUILD
00112 #   define GC_API extern __declspec(dllexport)
00113 # else
00114 #   define GC_API __declspec(dllimport)
00115 # endif
00116 #endif
00117
00118 #if defined(__WATCOMC__) && defined(GC_DLL)
00119 # ifdef GC_BUILD
00120 #   define GC_API extern __declspec(dllexport)
00121 # else
00122 #   define GC_API extern __declspec(dllimport)
00123 # endif
00124 #endif
00125
00126 #ifndef GC_API
00127 #define GC_API extern
00128 #endif
00129
00130 # if defined(__STDC__) || defined(__cplusplus)
00131 #   define GC_PROTO(args) args
00132     typedef void * GC_PTR;
00133 #   define GC_CONST const
00134 # else
00135 #   define GC_PROTO(args) ()
00136     typedef char * GC_PTR;
00137 #   define GC_CONST
00138 #  endif
00139
00140 # ifdef __cplusplus
00141     extern "C" {
00142 # endif
00143
00144
00145 /* Define word and signed_word to be unsigned and signed types of the   */
00146 /* size as char * or void *.  There seems to be no way to do this   */
00147 /* even semi-portably.  The following is probably no better/worse   */
00148 /* than almost anything else.                       */
00149 /* The ANSI standard suggests that size_t and ptr_diff_t might be   */
00150 /* better choices.  But those appear to have incorrect definitions  */
00151 /* on may systems.  Notably "typedef int size_t" seems to be both   */
00152 /* frequent and WRONG.                          */
00153 typedef unsigned long GC_word;
00154 typedef long GC_signed_word;
00155
00156 /* Public read-only variables */
00157
00158 GC_API GC_word GC_gc_no;/* Counter incremented per collection.      */
00159             /* Includes empty GCs at startup.       */
00160
00161 GC_API int GC_parallel; /* GC is parallelized for performance on    */
00162             /* multiprocessors.  Currently set only     */
00163             /* implicitly if collector is built with    */
00164             /* -DPARALLEL_MARK and if either:       */
00165             /*  Env variable GC_NPROC is set to > 1, or */
00166             /*  GC_NPROC is not set and this is an MP.  */
00167             /* If GC_parallel is set, incremental       */
00168             /* collection is only partially functional, */
00169             /* and may not be desirable.            */
00170
00171
00172 /* Public R/W variables */
00173
00174 GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requested));
00175             /* When there is insufficient memory to satisfy */
00176             /* an allocation request, we return     */
00177             /* (*GC_oom_fn)().  By default this just    */
00178             /* returns 0.                   */
00179             /* If it returns, it must return 0 or a valid   */
00180             /* pointer to a previously allocated heap   */
00181             /* object.                  */
00182
00183 GC_API int GC_find_leak;
00184             /* Do not actually garbage collect, but simply  */
00185             /* report inaccessible memory that was not  */
00186             /* deallocated with GC_free.  Initial value */
00187             /* is determined by FIND_LEAK macro.        */
00188
00189 GC_API int GC_all_interior_pointers;
00190             /* Arrange for pointers to object interiors to  */
00191             /* be recognized as valid.  May not be changed  */
00192             /* after GC initialization.         */
00193             /* Initial value is determined by       */
00194             /* -DALL_INTERIOR_POINTERS.         */
00195             /* Unless DONT_ADD_BYTE_AT_END is defined, this */
00196             /* also affects whether sizes are increased by  */
00197             /* at least a byte to allow "off the end"   */
00198             /* pointer recognition.             */
00199             /* MUST BE 0 or 1.              */
00200
00201 GC_API int GC_quiet;    /* Disable statistics output.  Only matters if  */
00202             /* collector has been compiled with statistics  */
00203             /* enabled.  This involves a performance cost,  */
00204             /* and is thus not the default.         */
00205
00206 GC_API int GC_finalize_on_demand;
00207             /* If nonzero, finalizers will only be run in   */
00208             /* response to an explicit GC_invoke_finalizers */
00209             /* call.  The default is determined by whether  */
00210             /* the FINALIZE_ON_DEMAND macro is defined  */
00211             /* when the collector is built.         */
00212
00213 GC_API int GC_java_finalization;
00214             /* Mark objects reachable from finalizable  */
00215             /* objects in a separate postpass.  This makes  */
00216             /* it a bit safer to use non-topologically- */
00217             /* ordered finalization.  Default value is  */
00218             /* determined by JAVA_FINALIZATION macro.   */
00219
00220 GC_API void (* GC_finalizer_notifier)();
00221             /* Invoked by the collector when there are  */
00222             /* objects to be finalized.  Invoked at most    */
00223             /* once per GC cycle.  Never invoked unless     */
00224             /* GC_finalize_on_demand is set.        */
00225             /* Typically this will notify a finalization    */
00226             /* thread, which will call GC_invoke_finalizers */
00227             /* in response.                 */
00228
00229 GC_API int GC_dont_gc;  /* Dont collect unless explicitly requested, e.g. */
00230             /* because it's not safe.             */
00231
00232 GC_API int GC_dont_expand;
00233             /* Dont expand heap unless explicitly requested */
00234             /* or forced to.                */
00235
00236 GC_API int GC_use_entire_heap;
00237         /* Causes the nonincremental collector to use the   */
00238         /* entire heap before collecting.  This was the only    */
00239         /* option for GC versions < 5.0.  This sometimes    */
00240         /* results in more large block fragmentation, since */
00241         /* very larg blocks will tend to get broken up      */
00242         /* during each GC cycle.  It is likely to result in a   */
00243         /* larger working set, but lower collection     */
00244         /* frequencies, and hence fewer instructions executed   */
00245         /* in the collector.                    */
00246
00247 GC_API int GC_full_freq;    /* Number of partial collections between    */
00248                 /* full collections.  Matters only if   */
00249                 /* GC_incremental is set.           */
00250                 /* Full collections are also triggered if   */
00251                 /* the collector detects a substantial  */
00252                 /* increase in the number of in-use heap    */
00253                 /* blocks.  Values in the tens are now  */
00254                 /* perfectly reasonable, unlike for     */
00255                 /* earlier GC versions.         */
00256
00257 GC_API GC_word GC_non_gc_bytes;
00258             /* Bytes not considered candidates for collection. */
00259             /* Used only to control scheduling of collections. */
00260             /* Updated by GC_malloc_uncollectable and GC_free. */
00261             /* Wizards only.                   */
00262
00263 GC_API int GC_no_dls;
00264             /* Don't register dynamic library data segments. */
00265             /* Wizards only.  Should be used only if the     */
00266             /* application explicitly registers all roots.   */
00267             /* In Microsoft Windows environments, this will  */
00268             /* usually also prevent registration of the  */
00269             /* main data segment as part of the root set.    */
00270
00271 GC_API GC_word GC_free_space_divisor;
00272             /* We try to make sure that we allocate at  */
00273             /* least N/GC_free_space_divisor bytes between  */
00274             /* collections, where N is the heap size plus   */
00275             /* a rough estimate of the root set size.   */
00276             /* Initially, GC_free_space_divisor = 4.    */
00277             /* Increasing its value will use less space */
00278             /* but more collection time.  Decreasing it */
00279             /* will appreciably decrease collection time    */
00280             /* at the expense of space.         */
00281             /* GC_free_space_divisor = 1 will effectively   */
00282             /* disable collections.             */
00283
00284 GC_API GC_word GC_max_retries;
00285             /* The maximum number of GCs attempted before   */
00286             /* reporting out of memory after heap       */
00287             /* expansion fails.  Initially 0.       */
00288
00289
00290 GC_API char *GC_stackbottom;    /* Cool end of user stack.      */
00291                 /* May be set in the client prior to    */
00292                 /* calling any GC_ routines.  This  */
00293                 /* avoids some overhead, and        */
00294                 /* potentially some signals that can    */
00295                 /* confuse debuggers.  Otherwise the    */
00296                 /* collector attempts to set it     */
00297                 /* automatically.           */
00298                 /* For multithreaded code, this is the  */
00299                 /* cold end of the stack for the    */
00300                 /* primordial thread.           */
00301
00302 GC_API int GC_dont_precollect;  /* Don't collect as part of         */
00303                 /* initialization.  Should be set only  */
00304                 /* if the client wants a chance to  */
00305                 /* manually initialize the root set */
00306                 /* before the first collection.     */
00307                 /* Interferes with blacklisting.    */
00308                 /* Wizards only.            */
00309
00310 GC_API unsigned long GC_time_limit;
00311                 /* If incremental collection is enabled, */
00312                 /* We try to terminate collections   */
00313                 /* after this many milliseconds.  Not a  */
00314                 /* hard time bound.  Setting this to     */
00315                 /* GC_TIME_UNLIMITED will essentially    */
00316                 /* disable incremental collection while  */
00317                 /* leaving generational collection   */
00318                 /* enabled.              */
00319 #   define GC_TIME_UNLIMITED 999999
00320                 /* Setting GC_time_limit to this value   */
00321                 /* will disable the "pause time exceeded"*/
00322                 /* tests.                */
00323
00324 /* Public procedures */
00325
00326 /* Initialize the collector.  This is only required when using thread-local
00327  * allocation, since unlike the regular allocation routines, GC_local_malloc
00328  * is not self-initializing.  If you use GC_local_malloc you should arrange
00329  * to call this somehow (e.g. from a constructor) before doing any allocation.
00330  */
00331 GC_API void GC_init GC_PROTO((void));
00332
00333 /*
00334  * general purpose allocation routines, with roughly malloc calling conv.
00335  * The atomic versions promise that no relevant pointers are contained
00336  * in the object.  The nonatomic versions guarantee that the new object
00337  * is cleared.  GC_malloc_stubborn promises that no changes to the object
00338  * will occur after GC_end_stubborn_change has been called on the
00339  * result of GC_malloc_stubborn. GC_malloc_uncollectable allocates an object
00340  * that is scanned for pointers to collectable objects, but is not itself
00341  * collectable.  The object is scanned even if it does not appear to
00342  * be reachable.  GC_malloc_uncollectable and GC_free called on the resulting
00343  * object implicitly update GC_non_gc_bytes appropriately.
00344  *
00345  * Note that the GC_malloc_stubborn support is stubbed out by default
00346  * starting in 6.0.  GC_malloc_stubborn is an alias for GC_malloc unless
00347  * the collector is built with STUBBORN_ALLOC defined.
00348  */
00349 GC_API GC_PTR GC_malloc GC_PROTO((size_t size_in_bytes));
00350 GC_API GC_PTR GC_malloc_atomic GC_PROTO((size_t size_in_bytes));
00351 GC_API GC_PTR GC_malloc_uncollectable GC_PROTO((size_t size_in_bytes));
00352 GC_API GC_PTR GC_malloc_stubborn GC_PROTO((size_t size_in_bytes));
00353
00354 /* The following is only defined if the library has been suitably   */
00355 /* compiled:                                */
00356 GC_API GC_PTR GC_malloc_atomic_uncollectable GC_PROTO((size_t size_in_bytes));
00357
00358 /* Explicitly deallocate an object.  Dangerous if used incorrectly.     */
00359 /* Requires a pointer to the base of an object.             */
00360 /* If the argument is stubborn, it should not be changeable when freed. */
00361 /* An object should not be enable for finalization when it is       */
00362 /* explicitly deallocated.                      */
00363 /* GC_free(0) is a no-op, as required by ANSI C for free.       */
00364 GC_API void GC_free GC_PROTO((GC_PTR object_addr));
00365
00366 /*
00367  * Stubborn objects may be changed only if the collector is explicitly informed.
00368  * The collector is implicitly informed of coming change when such
00369  * an object is first allocated.  The following routines inform the
00370  * collector that an object will no longer be changed, or that it will
00371  * once again be changed.  Only nonNIL pointer stores into the object
00372  * are considered to be changes.  The argument to GC_end_stubborn_change
00373  * must be exacly the value returned by GC_malloc_stubborn or passed to
00374  * GC_change_stubborn.  (In the second case it may be an interior pointer
00375  * within 512 bytes of the beginning of the objects.)
00376  * There is a performance penalty for allowing more than
00377  * one stubborn object to be changed at once, but it is acceptable to
00378  * do so.  The same applies to dropping stubborn objects that are still
00379  * changeable.
00380  */
00381 GC_API void GC_change_stubborn GC_PROTO((GC_PTR));
00382 GC_API void GC_end_stubborn_change GC_PROTO((GC_PTR));
00383
00384 /* Return a pointer to the base (lowest address) of an object given */
00385 /* a pointer to a location within the object.               */
00386 /* I.e. map an interior pointer to the corresponding bas pointer.   */
00387 /* Note that with debugging allocation, this returns a pointer to the   */
00388 /* actual base of the object, i.e. the debug information, not to    */
00389 /* the base of the user object.                     */
00390 /* Return 0 if displaced_pointer doesn't point to within a valid    */
00391 /* object.                              */
00392 GC_API GC_PTR GC_base GC_PROTO((GC_PTR displaced_pointer));
00393
00394 /* Given a pointer to the base of an object, return its size in bytes.  */
00395 /* The returned size may be slightly larger than what was originally    */
00396 /* requested.                               */
00397 GC_API size_t GC_size GC_PROTO((GC_PTR object_addr));
00398
00399 /* For compatibility with C library.  This is occasionally faster than  */
00400 /* a malloc followed by a bcopy.  But if you rely on that, either here  */
00401 /* or with the standard C library, your code is broken.  In my      */
00402 /* opinion, it shouldn't have been invented, but now we're stuck. -HB   */
00403 /* The resulting object has the same kind as the original.      */
00404 /* If the argument is stubborn, the result will have changes enabled.   */
00405 /* It is an error to have changes enabled for the original object.  */
00406 /* Follows ANSI comventions for NULL old_object.            */
00407 GC_API GC_PTR GC_realloc
00408     GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes));
00409
00410 /* Explicitly increase the heap size.   */
00411 /* Returns 0 on failure, 1 on success.  */
00412 GC_API int GC_expand_hp GC_PROTO((size_t number_of_bytes));
00413
00414 /* Limit the heap size to n bytes.  Useful when you're debugging,   */
00415 /* especially on systems that don't handle running out of memory well.  */
00416 /* n == 0 ==> unbounded.  This is the default.              */
00417 GC_API void GC_set_max_heap_size GC_PROTO((GC_word n));
00418
00419 /* Inform the collector that a certain section of statically allocated  */
00420 /* memory contains no pointers to garbage collected memory.  Thus it    */
00421 /* need not be scanned.  This is sometimes important if the application */
00422 /* maps large read/write files into the address space, which could be   */
00423 /* mistaken for dynamic library data segments on some systems.      */
00424 GC_API void GC_exclude_static_roots GC_PROTO((GC_PTR start, GC_PTR finish));
00425
00426 /* Clear the set of root segments.  Wizards only. */
00427 GC_API void GC_clear_roots GC_PROTO((void));
00428
00429 /* Add a root segment.  Wizards only. */
00430 GC_API void GC_add_roots GC_PROTO((char * low_address,
00431                    char * high_address_plus_1));
00432
00433 /* Add a displacement to the set of those considered valid by the   */
00434 /* collector.  GC_register_displacement(n) means that if p was returned */
00435 /* by GC_malloc, then (char *)p + n will be considered to be a valid    */
00436 /* pointer to n.  N must be small and less than the size of p.      */
00437 /* (All pointers to the interior of objects from the stack are      */
00438 /* considered valid in any case.  This applies to heap objects and  */
00439 /* static data.)                            */
00440 /* Preferably, this should be called before any other GC procedures.    */
00441 /* Calling it later adds to the probability of excess memory        */
00442 /* retention.                               */
00443 /* This is a no-op if the collector was compiled with recognition of    */
00444 /* arbitrary interior pointers enabled, which is now the default.   */
00445 GC_API void GC_register_displacement GC_PROTO((GC_word n));
00446
00447 /* The following version should be used if any debugging allocation is  */
00448 /* being done.                              */
00449 GC_API void GC_debug_register_displacement GC_PROTO((GC_word n));
00450
00451 /* Explicitly trigger a full, world-stop collection.    */
00452 GC_API void GC_gcollect GC_PROTO((void));
00453
00454 /* Trigger a full world-stopped collection.  Abort the collection if    */
00455 /* and when stop_func returns a nonzero value.  Stop_func will be   */
00456 /* called frequently, and should be reasonably fast.  This works even   */
00457 /* if virtual dirty bits, and hence incremental collection is not   */
00458 /* available for this architecture.  Collections can be aborted faster  */
00459 /* than normal pause times for incremental collection.  However,    */
00460 /* aborted collections do no useful work; the next collection needs */
00461 /* to start from the beginning.                     */
00462 /* Return 0 if the collection was aborted, 1 if it succeeded.       */
00463 typedef int (* GC_stop_func) GC_PROTO((void));
00464 GC_API int GC_try_to_collect GC_PROTO((GC_stop_func stop_func));
00465
00466 /* Return the number of bytes in the heap.  Excludes collector private  */
00467 /* data structures.  Includes empty blocks and fragmentation loss.  */
00468 /* Includes some pages that were allocated but never written.       */
00469 GC_API size_t GC_get_heap_size GC_PROTO((void));
00470
00471 /* Return a lower bound on the number of free bytes in the heap.    */
00472 GC_API size_t GC_get_free_bytes GC_PROTO((void));
00473
00474 /* Return the number of bytes allocated since the last collection.  */
00475 GC_API size_t GC_get_bytes_since_gc GC_PROTO((void));
00476
00477 /* Return the total number of bytes allocated in this process.      */
00478 /* Never decreases.                         */
00479 GC_API size_t GC_get_total_bytes GC_PROTO((void));
00480
00481 /* Enable incremental/generational collection.  */
00482 /* Not advisable unless dirty bits are      */
00483 /* available or most heap objects are       */
00484 /* pointerfree(atomic) or immutable.        */
00485 /* Don't use in leak finding mode.      */
00486 /* Ignored if GC_dont_gc is true.       */
00487 /* Only the generational piece of this is   */
00488 /* functional if GC_parallel is TRUE        */
00489 /* or if GC_time_limit is GC_TIME_UNLIMITED.    */
00490 /* Causes GC_local_gcj_malloc() to revert to    */
00491 /* locked allocation.  Must be called       */
00492 /* before any GC_local_gcj_malloc() calls.  */
00493 GC_API void GC_enable_incremental GC_PROTO((void));
00494
00495 /* Does incremental mode write-protect pages?  Returns zero or  */
00496 /* more of the following, or'ed together:           */
00497 #define GC_PROTECTS_POINTER_HEAP  1 /* May protect non-atomic objs. */
00498 #define GC_PROTECTS_PTRFREE_HEAP  2
00499 #define GC_PROTECTS_STATIC_DATA   4 /* Curently never.          */
00500 #define GC_PROTECTS_STACK     8 /* Probably impractical.        */
00501
00502 #define GC_PROTECTS_NONE 0
00503 GC_API int GC_incremental_protection_needs GC_PROTO((void));
00504
00505 /* Perform some garbage collection work, if appropriate.    */
00506 /* Return 0 if there is no more work to be done.        */
00507 /* Typically performs an amount of work corresponding roughly   */
00508 /* to marking from one page.  May do more work if further   */
00509 /* progress requires it, e.g. if incremental collection is  */
00510 /* disabled.  It is reasonable to call this in a wait loop  */
00511 /* until it returns 0.                      */
00512 GC_API int GC_collect_a_little GC_PROTO((void));
00513
00514 /* Allocate an object of size lb bytes.  The client guarantees that */
00515 /* as long as the object is live, it will be referenced by a pointer    */
00516 /* that points to somewhere within the first 256 bytes of the object.   */
00517 /* (This should normally be declared volatile to prevent the compiler   */
00518 /* from invalidating this assertion.)  This routine is only useful  */
00519 /* if a large array is being allocated.  It reduces the chance of   */
00520 /* accidentally retaining such an array as a result of scanning an  */
00521 /* integer that happens to be an address inside the array.  (Actually,  */
00522 /* it reduces the chance of the allocator not finding space for such    */
00523 /* an array, since it will try hard to avoid introducing such a false   */
00524 /* reference.)  On a SunOS 4.X or MS Windows system this is recommended */
00525 /* for arrays likely to be larger than 100K or so.  For other systems,  */
00526 /* or if the collector is not configured to recognize all interior  */
00527 /* pointers, the threshold is normally much higher.         */
00528 GC_API GC_PTR GC_malloc_ignore_off_page GC_PROTO((size_t lb));
00529 GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
00530
00531 #if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
00532 #   define GC_ADD_CALLER
00533 #   define GC_RETURN_ADDR (GC_word)__return_address
00534 #endif
00535
00536 #ifdef GC_ADD_CALLER
00537 #  define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
00538 #  define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * s, int i
00539 #else
00540 #  define GC_EXTRAS __FILE__, __LINE__
00541 #  define GC_EXTRA_PARAMS GC_CONST char * s, int i
00542 #endif
00543
00544 /* Debugging (annotated) allocation.  GC_gcollect will check        */
00545 /* objects allocated in this way for overwrites, etc.           */
00546 GC_API GC_PTR GC_debug_malloc
00547     GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
00548 GC_API GC_PTR GC_debug_malloc_atomic
00549     GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
00550 GC_API GC_PTR GC_debug_malloc_uncollectable
00551     GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
00552 GC_API GC_PTR GC_debug_malloc_stubborn
00553     GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
00554 GC_API void GC_debug_free GC_PROTO((GC_PTR object_addr));
00555 GC_API GC_PTR GC_debug_realloc
00556     GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes,
00557           GC_EXTRA_PARAMS));
00558 GC_API void GC_debug_change_stubborn GC_PROTO((GC_PTR));
00559 GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_PTR));
00560
00561 /* Routines that allocate objects with debug information (like the  */
00562 /* above), but just fill in dummy file and line number information. */
00563 /* Thus they can serve as drop-in malloc/realloc replacements.  This    */
00564 /* can be useful for two reasons:                   */
00565 /* 1) It allows the collector to be built with DBG_HDRS_ALL defined */
00566 /*    even if some allocation calls come from 3rd party libraries   */
00567 /*    that can't be recompiled.                     */
00568 /* 2) On some platforms, the file and line information is redundant,    */
00569 /*    since it can be reconstructed from a stack trace.  On such    */
00570 /*    platforms it may be more convenient not to recompile, e.g. for    */
00571 /*    leak detection.  This can be accomplished by instructing the  */
00572 /*    linker to replace malloc/realloc with these.          */
00573 GC_API GC_PTR GC_debug_malloc_replacement GC_PROTO((size_t size_in_bytes));
00574 GC_API GC_PTR GC_debug_realloc_replacement
00575           GC_PROTO((GC_PTR object_addr, size_t size_in_bytes));
00576
00577 # ifdef GC_DEBUG
00578 #   define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS)
00579 #   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
00580 #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_debug_malloc_uncollectable(sz, \
00581                             GC_EXTRAS)
00582 #   define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS)
00583 #   define GC_FREE(p) GC_debug_free(p)
00584 #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
00585     GC_debug_register_finalizer(p, f, d, of, od)
00586 #   define GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) \
00587     GC_debug_register_finalizer_ignore_self(p, f, d, of, od)
00588 #   define GC_REGISTER_FINALIZER_NO_ORDER(p, f, d, of, od) \
00589     GC_debug_register_finalizer_no_order(p, f, d, of, od)
00590 #   define GC_MALLOC_STUBBORN(sz) GC_debug_malloc_stubborn(sz, GC_EXTRAS);
00591 #   define GC_CHANGE_STUBBORN(p) GC_debug_change_stubborn(p)
00592 #   define GC_END_STUBBORN_CHANGE(p) GC_debug_end_stubborn_change(p)
00593 #   define GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) \
00594     GC_general_register_disappearing_link(link, GC_base(obj))
00595 #   define GC_REGISTER_DISPLACEMENT(n) GC_debug_register_displacement(n)
00596 # else
00597 #   define GC_MALLOC(sz) GC_malloc(sz)
00598 #   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
00599 #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
00600 #   define GC_REALLOC(old, sz) GC_realloc(old, sz)
00601 #   define GC_FREE(p) GC_free(p)
00602 #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
00603     GC_register_finalizer(p, f, d, of, od)
00604 #   define GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) \
00605     GC_register_finalizer_ignore_self(p, f, d, of, od)
00606 #   define GC_REGISTER_FINALIZER_NO_ORDER(p, f, d, of, od) \
00607     GC_register_finalizer_no_order(p, f, d, of, od)
00608 #   define GC_MALLOC_STUBBORN(sz) GC_malloc_stubborn(sz)
00609 #   define GC_CHANGE_STUBBORN(p) GC_change_stubborn(p)
00610 #   define GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p)
00611 #   define GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) \
00612     GC_general_register_disappearing_link(link, obj)
00613 #   define GC_REGISTER_DISPLACEMENT(n) GC_register_displacement(n)
00614 # endif
00615 /* The following are included because they are often convenient, and    */
00616 /* reduce the chance for a misspecifed size argument.  But calls may    */
00617 /* expand to something syntactically incorrect if t is a complicated    */
00618 /* type expression.                             */
00619 # define GC_NEW(t) (t *)GC_MALLOC(sizeof (t))
00620 # define GC_NEW_ATOMIC(t) (t *)GC_MALLOC_ATOMIC(sizeof (t))
00621 # define GC_NEW_STUBBORN(t) (t *)GC_MALLOC_STUBBORN(sizeof (t))
00622 # define GC_NEW_UNCOLLECTABLE(t) (t *)GC_MALLOC_UNCOLLECTABLE(sizeof (t))
00623
00624 /* Finalization.  Some of these primitives are grossly unsafe.      */
00625 /* The idea is to make them both cheap, and sufficient to build     */
00626 /* a safer layer, closer to PCedar finalization.            */
00627 /* The interface represents my conclusions from a long discussion   */
00628 /* with Alan Demers, Dan Greene, Carl Hauser, Barry Hayes,      */
00629 /* Christian Jacobi, and Russ Atkinson.  It's not perfect, and      */
00630 /* probably nobody else agrees with it.     Hans-J. Boehm  3/13/92  */
00631 typedef void (*GC_finalization_proc)
00632     GC_PROTO((GC_PTR obj, GC_PTR client_data));
00633
00634 GC_API void GC_register_finalizer
00635         GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
00636           GC_finalization_proc *ofn, GC_PTR *ocd));
00637 GC_API void GC_debug_register_finalizer
00638         GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
00639           GC_finalization_proc *ofn, GC_PTR *ocd));
00640     /* When obj is no longer accessible, invoke     */
00641     /* (*fn)(obj, cd).  If a and b are inaccessible, and    */
00642     /* a points to b (after disappearing links have been    */
00643     /* made to disappear), then only a will be      */
00644     /* finalized.  (If this does not create any new     */
00645     /* pointers to b, then b will be finalized after the    */
00646     /* next collection.)  Any finalizable object that   */
00647     /* is reachable from itself by following one or more    */
00648     /* pointers will not be finalized (or collected).   */
00649     /* Thus cycles involving finalizable objects should */
00650     /* be avoided, or broken by disappearing links.     */
00651     /* All but the last finalizer registered for an object  */
00652     /* is ignored.                      */
00653     /* Finalization may be removed by passing 0 as fn.  */
00654     /* Finalizers are implicitly unregistered just before   */
00655     /* they are invoked.                    */
00656     /* The old finalizer and client data are stored in  */
00657     /* *ofn and *ocd.                   */
00658     /* Fn is never invoked on an accessible object,     */
00659     /* provided hidden pointers are converted to real   */
00660     /* pointers only if the allocation lock is held, and    */
00661     /* such conversions are not performed by finalization   */
00662     /* routines.                        */
00663     /* If GC_register_finalizer is aborted as a result of   */
00664     /* a signal, the object may be left with no     */
00665     /* finalization, even if neither the old nor new    */
00666     /* finalizer were NULL.                 */
00667     /* Obj should be the nonNULL starting address of an     */
00668     /* object allocated by GC_malloc or friends.        */
00669     /* Note that any garbage collectable object referenced  */
00670     /* by cd will be considered accessible until the    */
00671     /* finalizer is invoked.                */
00672
00673 /* Another versions of the above follow.  It ignores        */
00674 /* self-cycles, i.e. pointers from a finalizable object to  */
00675 /* itself.  There is a stylistic argument that this is wrong,   */
00676 /* but it's unavoidable for C++, since the compiler may     */
00677 /* silently introduce these.  It's also benign in that specific */
00678 /* case.  And it helps if finalizable objects are split to  */
00679 /* avoid cycles.                        */
00680 /* Note that cd will still be viewed as accessible, even if it  */
00681 /* refers to the object itself.                 */
00682 GC_API void GC_register_finalizer_ignore_self
00683     GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
00684           GC_finalization_proc *ofn, GC_PTR *ocd));
00685 GC_API void GC_debug_register_finalizer_ignore_self
00686     GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
00687           GC_finalization_proc *ofn, GC_PTR *ocd));
00688
00689 /* Another version of the above.  It ignores all cycles.        */
00690 /* It should probably only be used by Java implementations.     */
00691 /* Note that cd will still be viewed as accessible, even if it  */
00692 /* refers to the object itself.                 */
00693 GC_API void GC_register_finalizer_no_order
00694     GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
00695           GC_finalization_proc *ofn, GC_PTR *ocd));
00696 GC_API void GC_debug_register_finalizer_no_order
00697     GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
00698           GC_finalization_proc *ofn, GC_PTR *ocd));
00699
00700
00701 /* The following routine may be used to break cycles between    */
00702 /* finalizable objects, thus causing cyclic finalizable     */
00703 /* objects to be finalized in the correct order.  Standard  */
00704 /* use involves calling GC_register_disappearing_link(&p),  */
00705 /* where p is a pointer that is not followed by finalization    */
00706 /* code, and should not be considered in determining        */
00707 /* finalization order.                      */
00708 GC_API int GC_register_disappearing_link GC_PROTO((GC_PTR * /* link */));
00709     /* Link should point to a field of a heap allocated     */
00710     /* object obj.  *link will be cleared when obj is   */
00711     /* found to be inaccessible.  This happens BEFORE any   */
00712     /* finalization code is invoked, and BEFORE any     */
00713     /* decisions about finalization order are made.     */
00714     /* This is useful in telling the finalizer that     */
00715     /* some pointers are not essential for proper       */
00716     /* finalization.  This may avoid finalization cycles.   */
00717     /* Note that obj may be resurrected by another      */
00718     /* finalizer, and thus the clearing of *link may    */
00719     /* be visible to non-finalization code.         */
00720     /* There's an argument that an arbitrary action should  */
00721     /* be allowed here, instead of just clearing a pointer. */
00722     /* But this causes problems if that action alters, or   */
00723     /* examines connectivity.               */
00724     /* Returns 1 if link was already registered, 0      */
00725     /* otherwise.                       */
00726     /* Only exists for backward compatibility.  See below:  */
00727
00728 GC_API int GC_general_register_disappearing_link
00729     GC_PROTO((GC_PTR * /* link */, GC_PTR obj));
00730     /* A slight generalization of the above. *link is   */
00731     /* cleared when obj first becomes inaccessible.  This   */
00732     /* can be used to implement weak pointers easily and    */
00733     /* safely. Typically link will point to a location  */
00734     /* holding a disguised pointer to obj.  (A pointer  */
00735     /* inside an "atomic" object is effectively         */
00736     /* disguised.)   In this way soft           */
00737     /* pointers are broken before any object        */
00738     /* reachable from them are finalized.  Each link    */
00739     /* May be registered only once, i.e. with one obj   */
00740     /* value.  This was added after a long email discussion */
00741     /* with John Ellis.                 */
00742     /* Obj must be a pointer to the first word of an object */
00743     /* we allocated.  It is unsafe to explicitly deallocate */
00744     /* the object containing link.  Explicitly deallocating */
00745     /* obj may or may not cause link to eventually be   */
00746     /* cleared.                     */
00747 GC_API int GC_unregister_disappearing_link GC_PROTO((GC_PTR * /* link */));
00748     /* Returns 0 if link was not actually registered.   */
00749     /* Undoes a registration by either of the above two */
00750     /* routines.                        */
00751
00752 /* Auxiliary fns to make finalization work correctly with displaced */
00753 /* pointers introduced by the debugging allocators.         */
00754 GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
00755 GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
00756
00757 /* Returns !=0  if GC_invoke_finalizers has something to do.        */
00758 GC_API int GC_should_invoke_finalizers GC_PROTO((void));
00759
00760 GC_API int GC_invoke_finalizers GC_PROTO((void));
00761     /* Run finalizers for all objects that are ready to */
00762     /* be finalized.  Return the number of finalizers   */
00763     /* that were run.  Normally this is also called     */
00764     /* implicitly during some allocations.  If      */
00765     /* GC-finalize_on_demand is nonzero, it must be called  */
00766     /* explicitly.                      */
00767
00768 /* GC_set_warn_proc can be used to redirect or filter warning messages. */
00769 /* p may not be a NULL pointer.                     */
00770 typedef void (*GC_warn_proc) GC_PROTO((char *msg, GC_word arg));
00771 GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p));
00772     /* Returns old warning procedure.   */
00773
00774 /* The following is intended to be used by a higher level   */
00775 /* (e.g. Java-like) finalization facility.  It is expected  */
00776 /* that finalization code will arrange for hidden pointers to   */
00777 /* disappear.  Otherwise objects can be accessed after they */
00778 /* have been collected.                     */
00779 /* Note that putting pointers in atomic objects or in       */
00780 /* nonpointer slots of "typed" objects is equivalent to     */
00781 /* disguising them in this way, and may have other advantages.  */
00782 # if defined(I_HIDE_POINTERS) || defined(GC_I_HIDE_POINTERS)
00783     typedef GC_word GC_hidden_pointer;
00784 #   define HIDE_POINTER(p) (~(GC_hidden_pointer)(p))
00785 #   define REVEAL_POINTER(p) ((GC_PTR)(HIDE_POINTER(p)))
00786     /* Converting a hidden pointer to a real pointer requires verifying */
00787     /* that the object still exists.  This involves acquiring the   */
00788     /* allocator lock to avoid a race with the collector.       */
00789 # endif /* I_HIDE_POINTERS */
00790
00791 typedef GC_PTR (*GC_fn_type) GC_PROTO((GC_PTR client_data));
00792 GC_API GC_PTR GC_call_with_alloc_lock
00793             GC_PROTO((GC_fn_type fn, GC_PTR client_data));
00794
00795 /* The following routines are primarily intended for use with a     */
00796 /* preprocessor which inserts calls to check C pointer arithmetic.  */
00797
00798 /* Check that p and q point to the same object.         */
00799 /* Fail conspicuously if they don't.                */
00800 /* Returns the first argument.                  */
00801 /* Succeeds if neither p nor q points to the heap.      */
00802 /* May succeed if both p and q point to between heap objects.   */
00803 GC_API GC_PTR GC_same_obj GC_PROTO((GC_PTR p, GC_PTR q));
00804
00805 /* Checked pointer pre- and post- increment operations.  Note that  */
00806 /* the second argument is in units of bytes, not multiples of the   */
00807 /* object size.  This should either be invoked from a macro, or the */
00808 /* call should be automatically generated.              */
00809 GC_API GC_PTR GC_pre_incr GC_PROTO((GC_PTR *p, size_t how_much));
00810 GC_API GC_PTR GC_post_incr GC_PROTO((GC_PTR *p, size_t how_much));
00811
00812 /* Check that p is visible                      */
00813 /* to the collector as a possibly pointer containing location.      */
00814 /* If it isn't fail conspicuously.                  */
00815 /* Returns the argument in all cases.  May erroneously succeed      */
00816 /* in hard cases.  (This is intended for debugging use with     */
00817 /* untyped allocations.  The idea is that it should be possible, though */
00818 /* slow, to add such a call to all indirect pointer stores.)        */
00819 /* Currently useless for multithreaded worlds.              */
00820 GC_API GC_PTR GC_is_visible GC_PROTO((GC_PTR p));
00821
00822 /* Check that if p is a pointer to a heap page, then it points to   */
00823 /* a valid displacement within a heap object.               */
00824 /* Fail conspicuously if this property does not hold.           */
00825 /* Uninteresting with GC_all_interior_pointers.             */
00826 /* Always returns its argument.                     */
00827 GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR p));
00828
00829 /* Safer, but slow, pointer addition.  Probably useful mainly with  */
00830 /* a preprocessor.  Useful only for heap pointers.          */
00831 #ifdef GC_DEBUG
00832 #   define GC_PTR_ADD3(x, n, type_of_result) \
00833     ((type_of_result)GC_same_obj((x)+(n), (x)))
00834 #   define GC_PRE_INCR3(x, n, type_of_result) \
00835     ((type_of_result)GC_pre_incr(&(x), (n)*sizeof(*x))
00836 #   define GC_POST_INCR2(x, type_of_result) \
00837     ((type_of_result)GC_post_incr(&(x), sizeof(*x))
00838 #   ifdef __GNUC__
00839 #       define GC_PTR_ADD(x, n) \
00840         GC_PTR_ADD3(x, n, typeof(x))
00841 #       define GC_PRE_INCR(x, n) \
00842         GC_PRE_INCR3(x, n, typeof(x))
00843 #       define GC_POST_INCR(x, n) \
00844         GC_POST_INCR3(x, typeof(x))
00845 #   else
00846     /* We can't do this right without typeof, which ANSI    */
00847     /* decided was not sufficiently useful.  Repeatedly */
00848     /* mentioning the arguments seems too dangerous to be   */
00849     /* useful.  So does not casting the result.     */
00850 #       define GC_PTR_ADD(x, n) ((x)+(n))
00851 #   endif
00852 #else   /* !GC_DEBUG */
00853 #   define GC_PTR_ADD3(x, n, type_of_result) ((x)+(n))
00854 #   define GC_PTR_ADD(x, n) ((x)+(n))
00855 #   define GC_PRE_INCR3(x, n, type_of_result) ((x) += (n))
00856 #   define GC_PRE_INCR(x, n) ((x) += (n))
00857 #   define GC_POST_INCR2(x, n, type_of_result) ((x)++)
00858 #   define GC_POST_INCR(x, n) ((x)++)
00859 #endif
00860
00861 /* Safer assignment of a pointer to a nonstack location.    */
00862 #ifdef GC_DEBUG
00863 # ifdef __STDC__
00864 #   define GC_PTR_STORE(p, q) \
00865     (*(void **)GC_is_visible(p) = GC_is_valid_displacement(q))
00866 # else
00867 #   define GC_PTR_STORE(p, q) \
00868     (*(char **)GC_is_visible(p) = GC_is_valid_displacement(q))
00869 # endif
00870 #else /* !GC_DEBUG */
00871 #   define GC_PTR_STORE(p, q) *((p) = (q))
00872 #endif
00873
00874 /* Fynctions called to report pointer checking errors */
00875 GC_API void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR p, GC_PTR q));
00876
00877 GC_API void (*GC_is_valid_displacement_print_proc)
00878     GC_PROTO((GC_PTR p));
00879
00880 GC_API void (*GC_is_visible_print_proc)
00881     GC_PROTO((GC_PTR p));
00882
00883
00884 /* For pthread support, we generally need to intercept a number of  */
00885 /* thread library calls.  We do that here by macro defining them.   */
00886
00887 #if !defined(GC_USE_LD_WRAP) && \
00888     (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS))
00889 # include "gc_pthread_redirects.h"
00890 #endif
00891
00892 # if defined(PCR) || defined(GC_SOLARIS_THREADS) || \
00893      defined(GC_PTHREADS) || defined(GC_WIN32_THREADS)
00894     /* Any flavor of threads except SRC_M3. */
00895 /* This returns a list of objects, linked through their first       */
00896 /* word.  Its use can greatly reduce lock contention problems, since    */
00897 /* the allocation lock can be acquired and released many fewer times.   */
00898 /* lb must be large enough to hold the pointer field.           */
00899 /* It is used internally by gc_local_alloc.h, which provides a simpler  */
00900 /* programming interface on Linux.                  */
00901 GC_PTR GC_malloc_many(size_t lb);
00902 #define GC_NEXT(p) (*(GC_PTR *)(p))     /* Retrieve the next element    */
00903                     /* in returned list.        */
00904 extern void GC_thr_init();  /* Needed for Solaris/X86   */
00905
00906 #endif /* THREADS && !SRC_M3 */
00907
00908 #if defined(GC_WIN32_THREADS)
00909 # include <windows.h>
00910 # include <winbase.h>
00911
00912   /*
00913    * All threads must be created using GC_CreateThread, so that they will be
00914    * recorded in the thread table.  For backwards compatibility, this is not
00915    * technically true if the GC is built as a dynamic library, since it can
00916    * and does then use DllMain to keep track of thread creations.  But new code
00917    * should be built to call GC_CreateThread.
00918    */
00919   HANDLE WINAPI GC_CreateThread(
00920       LPSECURITY_ATTRIBUTES lpThreadAttributes,
00921       DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
00922       LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );
00923
00924 # if defined(_WIN32_WCE)
00925   /*
00926    * win32_threads.c implements the real WinMain, which will start a new thread
00927    * to call GC_WinMain after initializing the garbage collector.
00928    */
00929   int WINAPI GC_WinMain(
00930       HINSTANCE hInstance,
00931       HINSTANCE hPrevInstance,
00932       LPWSTR lpCmdLine,
00933       int nCmdShow );
00934
00935 #  ifndef GC_BUILD
00936 #    define WinMain GC_WinMain
00937 #    define CreateThread GC_CreateThread
00938 #  endif
00939 # endif /* defined(_WIN32_WCE) */
00940
00941 #endif /* defined(GC_WIN32_THREADS) */
00942
00943 /*
00944  * If you are planning on putting
00945  * the collector in a SunOS 5 dynamic library, you need to call GC_INIT()
00946  * from the statically loaded program section.
00947  * This circumvents a Solaris 2.X (X<=4) linker bug.
00948  */
00949 #if defined(sparc) || defined(__sparc)
00950 #   define GC_INIT() { extern end, etext; \
00951                GC_noop(&end, &etext); }
00952 #else
00953 # if defined(__CYGWIN32__) && defined(GC_USE_DLL) || defined (_AIX)
00954     /*
00955      * Similarly gnu-win32 DLLs need explicit initialization from
00956      * the main program, as does AIX.
00957      */
00958 #   define GC_INIT() { GC_add_roots(DATASTART, DATAEND); }
00959 # else
00960 #   define GC_INIT()
00961 # endif
00962 #endif
00963
00964 #if !defined(_WIN32_WCE) \
00965     && ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
00966         || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__))
00967   /* win32S may not free all resources on process exit.  */
00968   /* This explicitly deallocates the heap.       */
00969     GC_API void GC_win32_free_heap ();
00970 #endif
00971
00972 #if ( defined(_AMIGA) && !defined(GC_AMIGA_MAKINGLIB) )
00973   /* Allocation really goes through GC_amiga_allocwrapper_do */
00974 # include "gc_amiga_redirects.h"
00975 #endif
00976
00977 #if defined(GC_REDIRECT_TO_LOCAL) && !defined(GC_LOCAL_ALLOC_H)
00978 #  include  "gc_local_alloc.h"
00979 #endif
00980
00981 #ifdef __cplusplus
00982     }  /* end of extern "C" */
00983 #endif
00984
00985 #endif /* _GC_H */


get.c File Reference

Include dependency graph for get.c:

Include dependency graph

Go to the source code of this file.

Functions

int | pcre_copy_substring (const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size)
int | pcre_get_substring_list (const char *subject, int *ovector, int stringcount, const char ***listptr)
int | pcre_get_substring (const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr)

Function Documentation

int pcre_copy_substring | ( | const char * | subject,
 |  | int * | ovector,
 |  | int | stringcount,
 |  | int | stringnumber,
 |  | char * | buffer,
 |  | int | size
 | ) |

Definition at line 75 of file get.c.

References PCRE_ERROR_NOMEMORY, PCRE_ERROR_NOSUBSTRING, and size.

int pcre_get_substring_list | ( | const char * | subject,
 |  | int * | ovector,
 |  | int | stringcount,
 |  | const char *** | listptr
 | ) |

Definition at line 113 of file get.c.

References p, PCRE_ERROR_NOMEMORY, and size.

int pcre_get_substring | ( | const char * | subject,
 |  | int * | ovector,
 |  | int | stringcount,
 |  | int | stringnumber,
 |  | const char ** | stringptr
 | ) |

Definition at line 172 of file get.c.

References PCRE_ERROR_NOMEMORY, and PCRE_ERROR_NOSUBSTRING.


get.c Source File

get.c

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005 /*
00006 This is a library of functions to support regular expressions whose syntax
00007 and semantics are as close as possible to those of the Perl 5 language. See
00008 the file Tech.Notes for some information on the internals.
00009
00010 Written by: Philip Hazel <ph10@cam.ac.uk>
00011
00012            Copyright (c) 1997-1999 University of Cambridge
00013
00014 -----------------------------------------------------------------------------
00015 Permission is granted to anyone to use this software for any purpose on any
00016 computer system, and to redistribute it freely, subject to the following
00017 restrictions:
00018
00019 1. This software is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022
00023 2. The origin of this software must not be misrepresented, either by
00024    explicit claim or by omission.
00025
00026 3. Altered versions must be plainly marked as such, and must not be
00027    misrepresented as being the original software.
00028
00029 4. If PCRE is embedded in any software that is released under the GNU
00030    General Purpose Licence (GPL), then the terms of that licence shall
00031    supersede any condition above with which it is incompatible.
00032 -----------------------------------------------------------------------------
00033 */
00034
00035 /* This module contains some convenience functions for extracting substrings
00036 from the subject string after a regex match has succeeded. The original idea
00037 for these functions came from Scott Wimer <scottw@cgibuilder.com>. */
00038
00039
00040 /* Include the internals header, which itself includes Standard C headers plus
00041 the external pcre header. */
00042
00043 #include "internal.h"
00044
00045
00046
00047 /*************************************************
00048 *      Copy captured string to given buffer      *
00049 *************************************************/
00050
00051 /* This function copies a single captured substring into a given buffer.
00052 Note that we use memcpy() rather than strncpy() in case there are binary zeros
00053 in the string.
00054
00055 Arguments:
00056   subject        the subject string that was matched
00057   ovector        pointer to the offsets table
00058   stringcount    the number of substrings that were captured
00059                    (i.e. the yield of the pcre_exec call, unless
00060                    that was zero, in which case it should be 1/3
00061                    of the offset table size)
00062   stringnumber   the number of the required substring
00063   buffer         where to put the substring
00064   size           the size of the buffer
00065
00066 Returns:         if successful:
00067                    the length of the copied string, not including the zero
00068                    that is put on the end; can be zero
00069                  if not successful:
00070                    PCRE_ERROR_NOMEMORY (-6) buffer too small
00071                    PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
00072 */
00073
00074 int
00075 pcre_copy_substring(const char *subject, int *ovector, int stringcount,
00076   int stringnumber, char *buffer, int size)
00077 {
00078 int yield;
00079 if (stringnumber < 0 || stringnumber >= stringcount)
00080   return PCRE_ERROR_NOSUBSTRING;
00081 stringnumber *= 2;
00082 yield = ovector[stringnumber+1] - ovector[stringnumber];
00083 if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
00084 memcpy(buffer, subject + ovector[stringnumber], yield);
00085 buffer[yield] = 0;
00086 return yield;
00087 }
00088
00089
00090
00091 /*************************************************
00092 *      Copy all captured strings to new store    *
00093 *************************************************/
00094
00095 /* This function gets one chunk of store and builds a list of pointers and all
00096 of the captured substrings in it. A NULL pointer is put on the end of the list.
00097
00098 Arguments:
00099   subject        the subject string that was matched
00100   ovector        pointer to the offsets table
00101   stringcount    the number of substrings that were captured
00102                    (i.e. the yield of the pcre_exec call, unless
00103                    that was zero, in which case it should be 1/3
00104                    of the offset table size)
00105   listptr        set to point to the list of pointers
00106
00107 Returns:         if successful: 0
00108                  if not successful:
00109                    PCRE_ERROR_NOMEMORY (-6) failed to get store
00110 */
00111
00112 int
00113 pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
00114   const char ***listptr)
00115 {
00116 int i;
00117 int size = sizeof(char *);
00118 int double_count = stringcount * 2;
00119 char **stringlist;
00120 char *p;
00121
00122 for (i = 0; i < double_count; i += 2)
00123   size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
00124
00125 stringlist = (char **)(pcre_malloc)(size);
00126 if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
00127
00128 *listptr = (const char **)stringlist;
00129 p = (char *)(stringlist + stringcount + 1);
00130
00131 for (i = 0; i < double_count; i += 2)
00132   {
00133   int len = ovector[i+1] - ovector[i];
00134   memcpy(p, subject + ovector[i], len);
00135   *stringlist++ = p;
00136   p += len;
00137   *p++ = 0;
00138   }
00139
00140 *stringlist = NULL;
00141 return 0;
00142 }
00143
00144
00145
00146 /*************************************************
00147 *      Copy captured string to new store         *
00148 *************************************************/
00149
00150 /* This function copies a single captured substring into a piece of new
00151 store
00152
00153 Arguments:
00154   subject        the subject string that was matched
00155   ovector        pointer to the offsets table
00156   stringcount    the number of substrings that were captured
00157                    (i.e. the yield of the pcre_exec call, unless
00158                    that was zero, in which case it should be 1/3
00159                    of the offset table size)
00160   stringnumber   the number of the required substring
00161   stringptr      where to put a pointer to the substring
00162
00163 Returns:         if successful:
00164                    the length of the string, not including the zero that
00165                    is put on the end; can be zero
00166                  if not successful:
00167                    PCRE_ERROR_NOMEMORY (-6) failed to get store
00168                    PCRE_ERROR_NOSUBSTRING (-7) substring not present
00169 */
00170
00171 int
00172 pcre_get_substring(const char *subject, int *ovector, int stringcount,
00173   int stringnumber, const char **stringptr)
00174 {
00175 int yield;
00176 char *substring;
00177 if (stringnumber < 0 || stringnumber >= stringcount)
00178   return PCRE_ERROR_NOSUBSTRING;
00179 stringnumber *= 2;
00180 yield = ovector[stringnumber+1] - ovector[stringnumber];
00181 substring = (char *)(pcre_malloc)(yield + 1);
00182 if (substring == NULL) return PCRE_ERROR_NOMEMORY;
00183 memcpy(substring, subject + ovector[stringnumber], yield);
00184 substring[yield] = 0;
00185 *stringptr = substring;
00186 return yield;
00187 }
00188
00189 /* End of get.c */


getopt.c File Reference

Include dependency graph for getopt.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | OPTERRCOLON (1)
#define | OPTERRNF (2)
#define | OPTERRARG (3)

Functions

int | optiserr (int, char *const *argv, int oint, const char *, int optchr, int err)
int | getopt (int argc, char *const *argv, const char *optstr)

Variables

char * | optarg
int | optind = 1
int | opterr = 1
int | optopt

Define Documentation

#define OPTERRCOLON (1)

Definition at line 8 of file getopt.c.

Referenced by getopt(), and optiserr().

#define OPTERRNF (2)

Definition at line 9 of file getopt.c.

Referenced by getopt(), and optiserr().

#define OPTERRARG (3)

Definition at line 10 of file getopt.c.

Referenced by getopt(), and optiserr().

Function Documentation

int optiserr | ( | int | ,
 |  | char *const * | argv,
 |  | int | oint,
 |  | const char * | ,
 |  | int | optchr,
 |  | int | err
 | ) | [static]

Definition at line 18 of file getopt.c.

References OPTERRARG, OPTERRCOLON, OPTERRNF, and optopt.

Referenced by getopt().

int getopt | ( | int | argc,
 |  | char *const * | argv,
 |  | const char * | optstr
 | ) |

Definition at line 47 of file getopt.c.

References assert, optarg, OPTERRARG, OPTERRCOLON, OPTERRNF, optind, and optiserr().

Referenced by main().

Variable Documentation

char* optarg

Definition at line 12 of file getopt.c.

Referenced by getopt().

int optind = 1

Definition at line 13 of file getopt.c.

Referenced by getopt().

int opterr = 1

Definition at line 14 of file getopt.c.

int optopt

Definition at line 15 of file getopt.c.

Referenced by optiserr().


getopt.c Source File

getopt.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <assert.h>
00004 #include <stdlib.h>
00005
00006 #ifdef WIN32
00007
00008 #define OPTERRCOLON (1)
00009 #define OPTERRNF (2)
00010 #define OPTERRARG (3)
00011
00012 char *optarg;
00013 int optind = 1;
00014 int opterr = 1;
00015 int optopt;
00016
00017 static int
00018 optiserr(int /*argc*/, char * const *argv, int oint, const char* /*optstr*/,
00019          int optchr, int err)
00020 {
00021     if(opterr)
00022     {
00023         fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
00024         switch(err)
00025         {
00026         case OPTERRCOLON:
00027             fprintf(stderr, ": in flags\n");
00028             break;
00029         case OPTERRNF:
00030             fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
00031             break;
00032         case OPTERRARG:
00033             fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
00034             break;
00035         default:
00036             fprintf(stderr, "unknown\n");
00037             break;
00038         }
00039     }
00040     optopt = argv[oint][optchr];
00041     return('?');
00042 }
00043
00044
00045
00046 int
00047 getopt(int argc, char* const *argv, const char* optstr)
00048 {
00049     static int optchr = 0;
00050     static int dash = 0; /* have already seen the - */
00051
00052     char *cp;
00053
00054     if(optind >= argc)
00055         return(EOF);
00056     if(!dash && (argv[optind][0] !=  '-'))
00057         return(EOF);
00058     if(!dash && (argv[optind][0] ==  '-') && !argv[optind][1])
00059     {
00060         /*
00061          * use to specify stdin. Need to let pgm process this and
00062          * the following args
00063          */
00064         return(EOF);
00065     }
00066     if((argv[optind][0] == '-') && (argv[optind][1] == '-'))
00067     {
00068         /* -- indicates end of args */
00069         optind++;
00070         return(EOF);
00071     }
00072     if(!dash)
00073     {
00074         assert((argv[optind][0] == '-') && argv[optind][1]);
00075         dash = 1;
00076         optchr = 1;
00077     }
00078
00079     /* Check if the guy tries to do a -: kind of flag */
00080     assert(dash);
00081     if(argv[optind][optchr] == ':')
00082     {
00083         dash = 0;
00084         optind++;
00085         return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRCOLON));
00086     }
00087     if(!(cp = strchr(optstr, argv[optind][optchr])))
00088     {
00089         int errind = optind;
00090         int errchr = optchr;
00091
00092         if(!argv[optind][optchr+1])
00093         {
00094             dash = 0;
00095             optind++;
00096         }
00097         else
00098             optchr++;
00099         return(optiserr(argc, argv, errind, optstr, errchr, OPTERRNF));
00100     }
00101     if(cp[1] == ':')
00102     {
00103         dash = 0;
00104         optind++;
00105         if(optind == argc)
00106             return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRARG));
00107         optarg = argv[optind++];
00108         return(*cp);
00109     }
00110     else
00111     {
00112         if(!argv[optind][optchr+1])
00113         {
00114             dash = 0;
00115             optind++;
00116         }
00117         else
00118             optchr++;
00119         return(*cp);
00120     }
00121     assert(0);
00122     return(0);
00123 }
00124
00125 #endif /* WIN32 */
00126
00127 #ifdef TESTGETOPT
00128 int
00129  main (int argc, char **argv)
00130  {
00131       int c;
00132       extern char *optarg;
00133       extern int optind;
00134       int aflg = 0;
00135       int bflg = 0;
00136       int errflg = 0;
00137       char *ofile = NULL;
00138
00139       while ((c = getopt(argc, argv, "abo:")) != EOF)
00140            switch (c) {
00141            case 'a':
00142                 if (bflg)
00143                      errflg++;
00144                 else
00145                      aflg++;
00146                 break;
00147            case 'b':
00148                 if (aflg)
00149                      errflg++;
00150                 else
00151                      bflg++;
00152                 break;
00153            case 'o':
00154                 ofile = optarg;
00155                 (void)printf("ofile = %s\n", ofile);
00156                 break;
00157            case '?':
00158                 errflg++;
00159            }
00160       if (errflg) {
00161            (void)fprintf(stderr,
00162                 "usage: cmd [-a|-b] [-o <filename>] files...\n");
00163            exit (2);
00164       }
00165       for ( ; optind < argc; optind++)
00166            (void)printf("%s\n", argv[optind]);
00167       return 0;
00168  }
00169
00170 #endif /* TESTGETOPT */


getopt.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

int | getopt (int argc, char *const *argv, const char *optstr)

Variables

char * | optarg
int | optind
int | opterr
int | optopt

Function Documentation

int getopt | ( | int | argc,
 |  | char *const * | argv,
 |  | const char * | optstr
 | ) |

Definition at line 47 of file getopt.c.

References assert, optarg, OPTERRARG, OPTERRCOLON, OPTERRNF, optind, and optiserr().

Referenced by main().

Variable Documentation

char* optarg

Definition at line 4 of file getopt.h.

Referenced by getopt().

int optind

Definition at line 5 of file getopt.h.

Referenced by getopt().

int opterr

Definition at line 6 of file getopt.h.

int optopt

Definition at line 7 of file getopt.h.

Referenced by optiserr().


getopt.h Source File

getopt.h

Go to the documentation of this file.
00001 #ifndef GETOPT_H
00002 #define GETOPT_H
00003
00004 extern char *optarg;
00005 extern int optind;
00006 extern int opterr;
00007 extern int optopt;
00008 int getopt(int argc, char* const *argv, const char* optstr);
00009
00010 #endif


gif.C File Reference

Parser: image manipulations impl1. More...

Include dependency graph for gif.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | styledSet

Functions

int | gdCompareInt (const void *a, const void *b)

Variables

const char *const | IDENT_GIF_C = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: image manipulations impl1.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) based on: gd

Written by Tom Boutell, 5/94. Copyright 1994, Cold Spring Harbor Labs. Permission granted to use this code in any fashion provided that this notice is retained and any alterations are labeled as such. It is requested, but not required, that you share extensions to this module with us so that we can incorporate them into new versions.

Definition in file gif.C.

Define Documentation

#define styledSet

Value:

{ \
        if (lineStyle) { \
            if(!lineStyle[styleStep]) \
                styleStep = 0; \
            on=lineStyle[styleStep++]!=' '; \
        } \
        if (on) { \
            SetPixel(x, y, color); \
        } \
    }

Definition at line 169 of file gif.C.

Referenced by gdImage::Line().

Function Documentation

int gdCompareInt | ( | const void * | a,
 |  | const void * | b
 | ) | [static]

Definition at line 806 of file gif.C.

Referenced by gdImage::FilledPolygon(), and gdImage::FilledPolygonReplaceColor().

Variable Documentation

const char* const IDENT_GIF_C = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 17 of file gif.C.


gif.C Source File

gif.C

Go to the documentation of this file.
00001
00017 static const char * const IDENT_GIF_C="$Date: 2005/08/09 08:14:50 $";
00018
00019 #include "gif.h"
00020
00021 #include "mtables.h"
00022 //#include "pa_common.h"
00023
00024 //static void BrushApply(int x, int y);
00025 //static void TileApply(int x, int y);
00026
00027 void gdImage::Create(int asx, int asy) {
00028     sx = asx;
00029     sy = asy;
00030
00031     int i;
00032     pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx);
00033     polyInts = 0;
00034     polyAllocated = 0;
00035     lineWidth = 1;
00036     for (i=0; (i<asx); i++)
00037         pixels[i] = (unsigned char *) malloc_atomic(asy);
00038     colorsTotal = 0;
00039     transparent = (-1);
00040     interlace = 0;
00041 }
00042
00043 int gdImage::ColorClosest(int r, int g, int b, int tolerance)
00044 {
00045     int i;
00046     long rd, gd, bd;
00047     int ct = (-1);
00048     long mindist = 0;
00049     for (i=0; (i<(colorsTotal)); i++) {
00050         long dist;
00051         if (open[i]) {
00052             continue;
00053         }
00054         rd = (red[i] - r);
00055         gd = (green[i] - g);
00056         bd = (blue[i] - b);
00057         dist = rd * rd + gd * gd + bd * bd;
00058         if ((i == 0) || (dist < mindist+tolerance)) {
00059             mindist = dist;
00060             ct = i;
00061         }
00062     }
00063     return mindist<tolerance?ct:-1;
00064 }
00065
00066 int gdImage::ColorExact(int r, int g, int b)
00067 {
00068     int i;
00069     for (i=0; (i<(colorsTotal)); i++) {
00070         if (open[i]) {
00071             continue;
00072         }
00073         if ((red[i] == r) &&
00074             (green[i] == g) &&
00075             (blue[i] == b)) {
00076             return i;
00077         }
00078     }
00079     return -1;
00080 }
00081
00082 int gdImage::ColorAllocate(int r, int g, int b)
00083 {
00084     int i;
00085     int ct = (-1);
00086     for (i=0; (i<(colorsTotal)); i++) {
00087         if (open[i]) {
00088             ct = i;
00089             break;
00090         }
00091     }
00092     if (ct == (-1)) {
00093         ct = colorsTotal;
00094         if (ct == gdMaxColors) {
00095             return -1;
00096         }
00097         colorsTotal++;
00098     }
00099     red[ct] = r;
00100     green[ct] = g;
00101     blue[ct] = b;
00102     open[ct] = 0;
00103     return ct;
00104 }
00105
00106 int gdImage::ColorRGB(int r, int g, int b){
00107     int idx=ColorExact(r,g,b);
00108     return idx<0 ? ColorAllocate(r,g,b) : idx;
00109 }
00110
00111 int gdImage::Color(unsigned int rgb){
00112     unsigned int b=rgb, g=b>>8, r=g>>8;
00113     return ColorRGB(r & 0xFF,g & 0xFF,b & 0xFF);
00114 }
00115 unsigned int gdImage::DecodeColor(int color) {
00116     if(color<0)
00117         return color;
00118     return (((red[color]<<8) + green[color])<<8)+blue[color];
00119 }
00120
00121 void gdImage::ColorDeallocate(int color)
00122 {
00123     /* Mark it open. */
00124     open[color] = 1;
00125 }
00126
00127 void gdImage::SetColorTransparent(int color)
00128 {
00129     transparent = color;
00130 }
00131
00132
00133 void gdImage::SetPixel(int x, int y, int color)
00134 {
00135 //paf   int p;
00136
00137     switch (lineWidth){
00138         case 1: {
00139         DoSetPixel(x, y,color);
00140         return;
00141         }
00142         case 2: {
00143         DoSetPixel(x, y-1,color);
00144         DoSetPixel(x-1, y,color);
00145         DoSetPixel(x, y,color);
00146         DoSetPixel(x+1, y,color);
00147         DoSetPixel(x, y+1,color);
00148         return;
00149         }
00150         default:{
00151         int i,j;
00152         for (i=-1;i<=1;i++) DoSetPixel(x+i, y-2,color);
00153         for (j=-1;j<=1;j++) for (i=-2;i<=2;i++) DoSetPixel(x+i, y+j,color);
00154         for (i=-1;i<=1;i++) DoSetPixel(x+i, y+2,color);
00155         return;
00156         }
00157     }
00158 }
00159
00160 int gdImage::GetPixel(int x, int y)
00161 {
00162     return BoundsSafe(x, y) ? pixels[x][y]:-1;
00163 }
00164
00165 /* Bresenham as presented in Foley & Van Dam */
00166
00167 /* As above, plus dashing */
00168
00169 #define styledSet \
00170     { \
00171         if (lineStyle) { \
00172             if(!lineStyle[styleStep]) \
00173                 styleStep = 0; \
00174             on=lineStyle[styleStep++]!=' '; \
00175         } \
00176         if (on) { \
00177             SetPixel(x, y, color); \
00178         } \
00179     }
00180
00181 void gdImage::Line(int x1, int y1, int x2, int y2, int color)
00182 {
00183     int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
00184     int styleStep = 0;
00185     int on = 1;
00186     dx = abs(x2-x1);
00187     dy = abs(y2-y1);
00188     if (dy <= dx) {
00189         d = 2*dy - dx;
00190         incr1 = 2*dy;
00191         incr2 = 2 * (dy - dx);
00192         if (x1 > x2) {
00193             x = x2;
00194             y = y2;
00195             ydirflag = (-1);
00196             xend = x1;
00197         } else {
00198             x = x1;
00199             y = y1;
00200             ydirflag = 1;
00201             xend = x2;
00202         }
00203         styledSet;
00204         if (((y2 - y1) * ydirflag) > 0) {
00205             while (x < xend) {
00206                 x++;
00207                 if (d <0) {
00208                     d+=incr1;
00209                 } else {
00210                     y++;
00211                     d+=incr2;
00212                 }
00213                 styledSet;
00214             }
00215         } else {
00216             while (x < xend) {
00217                 x++;
00218                 if (d <0) {
00219                     d+=incr1;
00220                 } else {
00221                     y--;
00222                     d+=incr2;
00223                 }
00224                 styledSet;
00225             }
00226         }
00227     } else {
00228         d = 2*dx - dy;
00229         incr1 = 2*dx;
00230         incr2 = 2 * (dx - dy);
00231         if (y1 > y2) {
00232             y = y2;
00233             x = x2;
00234             yend = y1;
00235             xdirflag = (-1);
00236         } else {
00237             y = y1;
00238             x = x1;
00239             yend = y2;
00240             xdirflag = 1;
00241         }
00242         styledSet;
00243         if (((x2 - x1) * xdirflag) > 0) {
00244             while (y < yend) {
00245                 y++;
00246                 if (d <0) {
00247                     d+=incr1;
00248                 } else {
00249                     x++;
00250                     d+=incr2;
00251                 }
00252                 styledSet;
00253             }
00254         } else {
00255             while (y < yend) {
00256                 y++;
00257                 if (d <0) {
00258                     d+=incr1;
00259                 } else {
00260                     x--;
00261                     d+=incr2;
00262                 }
00263                 styledSet;
00264             }
00265         }
00266     }
00267 }
00268
00269 /* s and e are integers modulo 360 (degrees), with 0 degrees
00270   being the rightmost extreme and degrees changing clockwise.
00271   cx and cy are the center in pixels; w and h are the horizontal
00272   and vertical diameter in pixels. Nice interface, but slow, since
00273   I don't yet use Bresenham (I'm using an inefficient but
00274   simple solution with too much work going on in it; generalizing
00275   Bresenham to ellipses and partial arcs of ellipses is non-trivial,
00276   at least for me) and there are other inefficiencies (small circles
00277   do far too much work). */
00278
00279 void gdImage::Arc(int cx, int cy, int w, int h, int s, int e, int color)
00280 {
00281 #if 0
00282     if(s==0 && e==360) { // full
00283         if(w==h) { // circle?
00284             /* Bresenham octant code, which I should use eventually */
00285             int x, y, d;
00286             x = 0;
00287             y = w/2;
00288             d = 3-w;
00289             while (x <= y) {
00290                 SetPixel(cx+x, cy+y, color);
00291                 SetPixel(cx+x, cy-y, color);
00292                 SetPixel(cx-x, cy+y, color);
00293                 SetPixel(cx-x, cy-y, color);
00294                 SetPixel(cx+y, cy+x, color);
00295                 SetPixel(cx+y, cy-x, color);
00296                 SetPixel(cx-y, cy+x, color);
00297                 SetPixel(cx-y, cy-x, color);
00298                 if (d < 0) {
00299                     d += 4 * x + 6;
00300                 } else {
00301                     d += 4 * (x - y) + 10;
00302                     y--;
00303                 }
00304                 x++;
00305             }
00306         } else { // full ellipse
00307             w/=2;
00308             h/=2;
00309             int elx, ely;
00310             long aa, aa2, bb, bb2, d, dx, dy;
00311
00312             elx = 0; ely = h; aa = (long)w * w; aa2 = 2 * aa;
00313             bb = (long)h * h; bb2 = 2 * bb;
00314             d = bb - aa * h + aa/4; dx = 0; dy = aa2 * h;
00315             SetPixel(cx, cy - ely, color); SetPixel(cx, cy + ely, color);
00316             SetPixel(cx - w, cy, color); SetPixel(cx + w, cy, color);
00317
00318             while (dx < dy)
00319             {
00320                 if (d > 0) { ely--; dy-=aa2; d-=dy;}
00321                 elx++; dx+=bb2; d+=bb+dx;
00322                 SetPixel(cx + elx, cy + ely, color);
00323                 SetPixel(cx - elx, cy + ely, color);
00324                 SetPixel(cx + elx, cy - ely, color);
00325                 SetPixel(cx - elx, cy - ely, color);
00326             };
00327             d+=(3 * (aa - bb)/2 - (dx + dy))/2;
00328             while (ely > 0)
00329             {
00330                 if (d < 0) {elx++; dx+=bb2; d+=bb + dx;}
00331                 ely--; dy-=aa2; d+=aa - dy;
00332                 SetPixel(cx + elx, cy + ely, color);
00333                 SetPixel(cx - elx, cy + ely, color);
00334                 SetPixel(cx + elx, cy - ely, color);
00335                 SetPixel(cx - elx, cy - ely, color);
00336             };
00337         }
00338     } else {
00339 #endif
00340         int i;
00341         int lx = 0, ly = 0;
00342         int w2, h2;
00343         w2 = w/2;
00344         h2 = h/2;
00345         while (e < s) e += 360;
00346         // paf
00347         while(s<0) s+=360;
00348         while(s>360) s-=360;
00349         while(e<0) e+=360;
00350         while(e>360) e-=360;
00351         for (i=s; (i <= e); i++) {
00352             int x, y;
00353             x = ((long)cost[i] * (long)w2 / costScale) + cx;
00354             y = ((long)sint[i] * (long)h2 / sintScale) + cy;
00355             if (i != s) {
00356                 Line(lx, ly, x, y, color);
00357             }
00358             lx = x;
00359             ly = y;
00360         }
00361 #if 0
00362     }
00363 #endif
00364 }
00365
00366 /*
00367
00368 // http://firststeps.narod.ru/cgi/18.html
00369
00370 int CGIScreen::Ellipse(int exc, int eyc, int ea, int eb , unsigned char Color)
00371 {
00372   int elx, ely;
00373   long aa, aa2, bb, bb2, d, dx, dy;
00374
00375   elx = 0; ely = eb; aa = (long)ea * ea; aa2 = 2 * aa;
00376   bb = (long)eb * eb; bb2 = 2 * bb;
00377   d = bb - aa * eb + aa/4; dx = 0; dy = aa2 * eb;
00378   PutPixel(exc, eyc - ely, Color); PutPixel(exc, eyc + ely, Color);
00379   PutPixel(exc - ea, eyc, Color); PutPixel(exc + ea, eyc, Color);
00380
00381   while (dx < dy)
00382   {
00383     if (d > 0) { ely--; dy-=aa2; d-=dy;}
00384     elx++; dx+=bb2; d+=bb+dx;
00385     PutPixel(exc + elx, eyc + ely, Color);
00386     PutPixel(exc - elx, eyc + ely, Color);
00387     PutPixel(exc + elx, eyc - ely, Color);
00388     PutPixel(exc - elx, eyc - ely, Color);
00389   };
00390   d+=(3 * (aa - bb)/2 - (dx + dy))/2;
00391   while (ely > 0)
00392   {
00393     if (d < 0) {elx++; dx+=bb2; d+=bb + dx;}
00394     ely--; dy-=aa2; d+=aa - dy;
00395     PutPixel(exc + elx, eyc + ely, Color);
00396     PutPixel(exc - elx, eyc + ely, Color);
00397     PutPixel(exc + elx, eyc - ely, Color);
00398     PutPixel(exc - elx, eyc - ely, Color);
00399   };
00400   return 0;
00401 };
00402
00403 */
00404
00405
00406 void gdImage::Sector(int cx, int cy, int w, int h, int s, int e, int color)
00407 {
00408     int i;
00409     int lx = 0, ly = 0;
00410     int w2, h2;
00411     w2 = w/2;
00412     h2 = h/2;
00413     while (e < s) e += 360;
00414     // paf
00415     while(s<0) s+=360;
00416     while(s>360) s-=360;
00417     while(e<0) e+=360;
00418     while(e>360) e-=360;
00419     for (i=s; (i <= e); i++) {
00420         int x, y;
00421         x = ((long)cost[i] * (long)w2 / costScale) + cx;
00422         y = ((long)sint[i] * (long)h2 / sintScale) + cy;
00423         if(i==s || i==e)
00424             Line(cx, cy, x, y, color);
00425         if (i != s) {
00426             Line(lx, ly, x, y, color);
00427         }
00428         lx = x;
00429         ly = y;
00430     }
00431 }
00432
00433
00434
00435 void gdImage::FillToBorder(int x, int y, int border, int color)
00436 {
00437     if(!BoundsSafe(x, y)) //PAF
00438         return;
00439
00440     int lastBorder;
00441     /* Seek left */
00442     int leftLimit, rightLimit;
00443     int i;
00444     leftLimit = (-1);
00445     if (border < 0) {
00446         /* Refuse to fill to a non-solid border */
00447         return;
00448     }
00449     for (i = x; (i >= 0); i--) {
00450         if (GetPixel(i, y) == border) {
00451             break;
00452         }
00453         SetPixel(i, y, color);
00454         leftLimit = i;
00455     }
00456     if (leftLimit == (-1)) {
00457         return;
00458     }
00459     /* Seek right */
00460     rightLimit = x;
00461     for (i = (x+1); (i < sx); i++) {
00462         if (GetPixel(i, y) == border) {
00463             break;
00464         }
00465         SetPixel(i, y, color);
00466         rightLimit = i;
00467     }
00468     /* Look at lines above and below and start paints */
00469     /* Above */
00470     if (y > 0) {
00471         lastBorder = 1;
00472         for (i = leftLimit; (i <= rightLimit); i++) {
00473             int c;
00474             c = GetPixel(i, y-1);
00475             if (lastBorder) {
00476                 if ((c != border) && (c != color)) {
00477                     FillToBorder(i, y-1,
00478                         border, color);
00479                     lastBorder = 0;
00480                 }
00481             } else if ((c == border) || (c == color)) {
00482                 lastBorder = 1;
00483             }
00484         }
00485     }
00486     /* Below */
00487     if (y < ((sy) - 1)) {
00488         lastBorder = 1;
00489         for (i = leftLimit; (i <= rightLimit); i++) {
00490             int c;
00491             c = GetPixel(i, y+1);
00492             if (lastBorder) {
00493                 if ((c != border) && (c != color)) {
00494                     FillToBorder(i, y+1,
00495                         border, color);
00496                     lastBorder = 0;
00497                 }
00498             } else if ((c == border) || (c == color)) {
00499                 lastBorder = 1;
00500             }
00501         }
00502     }
00503 }
00504
00505 void gdImage::Fill(int x, int y, int color)
00506 {
00507     if(!BoundsSafe(x, y)) //PAF
00508         return;
00509
00510     int lastBorder;
00511     int old;
00512     int leftLimit, rightLimit;
00513     int i;
00514     old = GetPixel(x, y);
00515     if (old == color) {
00516         /* Nothing to be done */
00517         return;
00518     }
00519     /* Seek left */
00520     leftLimit = (-1);
00521     for (i = x; (i >= 0); i--) {
00522         if (GetPixel(i, y) != old) {
00523             break;
00524         }
00525         DoSetPixel(i, y, color); // PAF, was SetPixel
00526         leftLimit = i;
00527     }
00528     if (leftLimit == (-1)) {
00529         return;
00530     }
00531     /* Seek right */
00532     rightLimit = x;
00533     for (i = (x+1); (i < sx); i++) {
00534         if (GetPixel(i, y) != old) {
00535             break;
00536         }
00537         DoSetPixel(i, y, color); // PAF, was SetPixel
00538         rightLimit = i;
00539     }
00540     /* Look at lines above and below and start paints */
00541     /* Above */
00542     if (y > 0) {
00543         lastBorder = 1;
00544         for (i = leftLimit; (i <= rightLimit); i++) {
00545             int c;
00546             c = GetPixel(i, y-1);
00547             if (lastBorder) {
00548                 if (c == old) {
00549                     Fill(i, y-1, color);
00550                     lastBorder = 0;
00551                 }
00552             } else if (c != old) {
00553                 lastBorder = 1;
00554             }
00555         }
00556     }
00557     /* Below */
00558     if (y < ((sy) - 1)) {
00559         lastBorder = 1;
00560         for (i = leftLimit; (i <= rightLimit); i++) {
00561             int c;
00562             c = GetPixel(i, y+1);
00563             if (lastBorder) {
00564                 if (c == old) {
00565                     Fill(i, y+1, color);
00566                     lastBorder = 0;
00567                 }
00568             } else if (c != old) {
00569                 lastBorder = 1;
00570             }
00571         }
00572     }
00573 }
00574
00575 void gdImage::Rectangle(int x1, int y1, int x2, int y2, int color)
00576 {
00577     Line(x1, y1, x2, y1, color);
00578     Line(x1, y2, x2, y2, color);
00579     Line(x1, y1, x1, y2, color);
00580     Line(x2, y1, x2, y2, color);
00581 }
00582
00583 void gdImage::FilledRectangle(int x1, int y1, int x2, int y2, int color)
00584 {
00585     if(x1>x2) {
00586         int t=x1;
00587         x1=x2;
00588         x2=t;
00589     }
00590     if(y1>y2) {
00591         int t=y1;
00592         y1=y2;
00593         y2=t;
00594     }
00595     int x, y;
00596
00597     for (y=y1; (y<=y2); y++)
00598         for (x=x1; (x<=x2); x++)
00599             SetPixel(x, y, color);
00600 }
00601
00602 void gdImage::Copy(gdImage& dst, int dstX, int dstY, int srcX, int srcY, int w, int h)
00603 {
00604     int c;
00605     int x, y;
00606     int tox, toy;
00607     int i;
00608     int colorMap[gdMaxColors];
00609     for (i=0; (i<gdMaxColors); i++) {
00610         colorMap[i] = (-1);
00611     }
00612     toy = dstY;
00613     for (y=srcY; (y < (srcY + h)); y++) {
00614         tox = dstX;
00615         for (x=srcX; (x < (srcX + w)); x++) {
00616             int nc;
00617             c = GetPixel(x, y);
00618             /* Added 7/24/95: support transparent copies */
00619             if (GetTransparent() == c) {
00620                 tox++;
00621                 continue;
00622             }
00623             /* Have we established a mapping for this color? */
00624             if (colorMap[c] == (-1)) {
00625                 /* If it's the same image, mapping is trivial */
00626                 if (&dst == this) {
00627                     nc = c;
00628                 } else {
00629                     /* First look for an exact match */
00630                     nc = dst.ColorExact(
00631                         red[c], green[c],
00632                         blue[c]);
00633                 }
00634                 if (nc == (-1)) {
00635                     /* No, so try to allocate it */
00636                     nc = dst.ColorAllocate(
00637                         red[c], green[c],
00638                         blue[c]);
00639                     /* If we're out of colors, go for the
00640                         closest color */
00641                     if (nc == (-1)) {
00642                         nc = dst.ColorClosest(
00643                             red[c], green[c],
00644                             blue[c]);
00645                     }
00646                 }
00647                 colorMap[c] = nc;
00648             }
00649             dst.SetPixel(tox, toy, colorMap[c]);
00650             tox++;
00651         }
00652         toy++;
00653     }
00654 }
00655
00656 void gdImage::CopyResampled(gdImage& dst,
00657               int dstX, int dstY,
00658               int /*srcX*/, int /*srcY*/,
00659               int dstW, int dstH,
00660               int srcW, int srcH,
00661               int tolerance)
00662 {
00663     gdImage& src=*this;
00664     int x, y;
00665     int srcTransparent=src.GetTransparent();
00666     int dstTransparent=dst.GetTransparent();
00667     for (y = dstY; (y < dstY + dstH); y++) {
00668         for (x = dstX; (x < dstX + dstW); x++) {
00669             int pd = dst.GetPixel (x, y);
00670             /* Added 7/24/95: support transparent copies */
00671             /* fixed by paf 20030116, another fix below */
00672             if (pd == dstTransparent)
00673                 continue;
00674
00675             double sy1, sy2, sx1, sx2;
00676             double sx, sy;
00677             double spixels = 0;
00678             double red = 0.0, green = 0.0, blue = 0.0;
00679             bool transparent=true;
00680             sy1 = ((double) y - (double) dstY) * (double) srcH /
00681                 (double) dstH;
00682             sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH /
00683                 (double) dstH;
00684             sy = sy1;
00685             do
00686             {
00687                 double yportion;
00688                 if (floor (sy) == floor (sy1))
00689                 {
00690                     yportion = 1.0 - (sy - floor (sy));
00691                     if (yportion > sy2 - sy1)
00692                     {
00693                         yportion = sy2 - sy1;
00694                     }
00695                     sy = floor (sy);
00696                 }
00697                 else if (sy == floor (sy2))
00698                 {
00699                     yportion = sy2 - floor (sy2);
00700                 }
00701                 else
00702                 {
00703                     yportion = 1.0;
00704                 }
00705                 sx1 = ((double) x - (double) dstX) * (double) srcW /
00706                     dstW;
00707                 sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW /
00708                     dstW;
00709                 sx = sx1;
00710                 do
00711                 {
00712                     double xportion;
00713                     double pcontribution;
00714                     int p;
00715                     if (floor (sx) == floor (sx1))
00716                     {
00717                         xportion = 1.0 - (sx - floor (sx));
00718                         if (xportion > sx2 - sx1)
00719                         {
00720                             xportion = sx2 - sx1;
00721                         }
00722                         sx = floor (sx);
00723                     }
00724                     else if (sx == floor (sx2))
00725                     {
00726                         xportion = sx2 - floor (sx2);
00727                     }
00728                     else
00729                     {
00730                         xportion = 1.0;
00731                     }
00732                     pcontribution = xportion * yportion;
00733                     p = src.GetPixel (
00734                         (int) sx,
00735                         (int) sy);
00736                     // fix added 20020116 by paf to support transparent src
00737                     if (p!=srcTransparent) {
00738                         transparent = false;
00739                         red += Red (p) * pcontribution;
00740                         green += Green (p) * pcontribution;
00741                         blue += Blue (p) * pcontribution;
00742                     }
00743                     spixels += xportion * yportion;
00744                     sx += 1.0;
00745                 } while (sx < sx2);
00746                 sy += 1.0;
00747             } while (sy < sy2);
00748
00749             if(transparent)
00750                 continue;
00751
00752             if (spixels != 0.0) {
00753                 red /= spixels;
00754                 green /= spixels;
00755                 blue /= spixels;
00756             }
00757             /* Clamping to allow for rounding errors above */
00758             if (red > 255.0)
00759                 red = 255.0;
00760             if (green > 255.0)
00761                 green = 255.0;
00762             if (blue > 255.0)
00763                 blue = 255.0;
00764
00765             red=round(red);
00766             green=round(green);
00767             blue=round(blue);
00768             /* First look for an exact match */
00769             int nc = dst.ColorExact((int)red, (int)green, (int)blue);
00770             if (nc == (-1)) {
00771                 /* No, so go for the closest color with high tolerance */
00772                 nc = dst.ColorClosest((int)red, (int)green, (int)blue,  tolerance);
00773                 if (nc == (-1)) {
00774                     /* Not found with even high tolerance, so try to allocate it */
00775                     nc = dst.ColorAllocate((int)red, (int)green, (int)blue);
00776
00777                     /* If we're out of colors, go for the closest color */
00778                     if (nc == (-1))
00779                         nc = dst.ColorClosest((int)red, (int)green, (int)blue);
00780                 }
00781             }
00782             dst.SetPixel(x, y, nc);
00783         }
00784     }
00785 }
00786
00787 void gdImage::Polygon(Point *p, int n, int c, bool closed)
00788 {
00789     int i;
00790     int lx, ly;
00791     if (!n) {
00792         return;
00793     }
00794     lx = p->x;
00795     ly = p->y;
00796     if(closed)
00797         Line(lx, ly, p[n-1].x, p[n-1].y, c);
00798     for (i=1; (i < n); i++) {
00799         p++;
00800         Line(lx, ly, p->x, p->y, c);
00801         lx = p->x;
00802         ly = p->y;
00803     }
00804 }
00805
00806 static int gdCompareInt(const void *a, const void *b)
00807 {
00808     return (*(const int *)a) - (*(const int *)b);
00809 }
00810
00811
00812
00813 void gdImage::FilledPolygon(Point *p, int n, int c)
00814 {
00815     int i;
00816     int y;
00817     int y1, y2;
00818     int ints;
00819     if (!n) {
00820         return;
00821     }
00822     if (!polyAllocated) {
00823         polyInts = (int *) malloc(sizeof(int) * n);
00824         polyAllocated = n;
00825     }
00826     if (polyAllocated < n) {
00827         while (polyAllocated < n) {
00828             polyAllocated *= 2;
00829         }
00830         polyInts = (int *) realloc(polyInts,
00831             sizeof(int) * polyAllocated);
00832     }
00833     y1 = p[0].y;
00834     y2 = p[0].y;
00835     for (i=1; (i < n); i++) {
00836         if (p[i].y < y1) {
00837             y1 = p[i].y;
00838         }
00839         if (p[i].y > y2) {
00840             y2 = p[i].y;
00841         }
00842     }
00843     for (y=y1; (y <= y2); y++) {
00844         int interLast = 0;
00845         int dirLast = 0;
00846         int interFirst = 1;
00847         ints = 0;
00848         for (i=0; (i <= n); i++) {
00849             int x1, x2;
00850             int y1, y2;
00851             int dir;
00852             int ind1, ind2;
00853             int lastInd1 = 0;
00854             if ((i == n) || (!i)) {
00855                 ind1 = n-1;
00856                 ind2 = 0;
00857             } else {
00858                 ind1 = i-1;
00859                 ind2 = i;
00860             }
00861             y1 = p[ind1].y;
00862             y2 = p[ind2].y;
00863             if (y1 < y2) {
00864                 y1 = p[ind1].y;
00865                 y2 = p[ind2].y;
00866                 x1 = p[ind1].x;
00867                 x2 = p[ind2].x;
00868                 dir = -1;
00869             } else if (y1 > y2) {
00870                 y2 = p[ind1].y;
00871                 y1 = p[ind2].y;
00872                 x2 = p[ind1].x;
00873                 x1 = p[ind2].x;
00874                 dir = 1;
00875             } else {
00876                 /* Horizontal; just draw it */
00877                 Line(
00878                     p[ind1].x, y1,
00879                     p[ind2].x, y1,
00880                     c);
00881                 continue;
00882             }
00883             if ((y >= y1) && (y <= y2)) {
00884                 int inter =
00885                     (y-y1) * (x2-x1) / (y2-y1) + x1;
00886                 /* Only count intersections once
00887                     except at maxima and minima. Also,
00888                     if two consecutive intersections are
00889                     endpoints of the same horizontal line
00890                     that is not at a maxima or minima,
00891                     discard the leftmost of the two. */
00892                 if (!interFirst) {
00893                     if ((p[ind1].y == p[lastInd1].y) &&
00894                         (p[ind1].x != p[lastInd1].x)) {
00895                         if (dir == dirLast) {
00896                             if (inter > interLast) {
00897                                 /* Replace the old one */
00898                                 polyInts[ints] = inter;
00899                             } else {
00900                                 /* Discard this one */
00901                             }
00902                             continue;
00903                         }
00904                     }
00905                     if (inter == interLast) {
00906                         if (dir == dirLast) {
00907                             continue;
00908                         }
00909                     }
00910                 }
00911                 if (i > 0) {
00912                     polyInts[ints++] = inter;
00913                 }
00914                 lastInd1 = i;
00915                 dirLast = dir;
00916                 interLast = inter;
00917                 interFirst = 0;
00918             }
00919         }
00920         qsort(polyInts, ints, sizeof(int), gdCompareInt);
00921         for (i=0; (i < (ints-1)); i+=2)
00922             Line(polyInts[i], y, polyInts[i+1], y, c);
00923     }
00924 }
00925
00926 //001005paf this used in drawing straight lines in gdImage::FilledPolygonReplaceColor
00927 void gdImage::LineReplaceColor(int x1, int y1, int x2, int y2, int a, int b) {
00928     if(y1!=y2)
00929         return;
00930
00931     for(int x=x1; x<=x2; x++)
00932         if(BoundsSafe(x, y1)) {
00933             unsigned char *pixel=&pixels[x][y1];
00934             if(*pixel==a)
00935                 *pixel=b;
00936         }
00937 }
00938
00939 void gdImage::FilledPolygonReplaceColor(Point *p, int n, int a, int b)
00940 {
00941     int i;
00942     int y;
00943     int y1, y2;
00944     int ints;
00945     if (!n) {
00946         return;
00947     }
00948     if (!polyAllocated) {
00949         polyInts = (int *) malloc(sizeof(int) * n);
00950         polyAllocated = n;
00951     }
00952     if (polyAllocated < n) {
00953         while (polyAllocated < n) {
00954             polyAllocated *= 2;
00955         }
00956         polyInts = (int *) realloc(polyInts,
00957             sizeof(int) * polyAllocated);
00958     }
00959     y1 = p[0].y;
00960     y2 = p[0].y;
00961     for (i=1; (i < n); i++) {
00962         if (p[i].y < y1) {
00963             y1 = p[i].y;
00964         }
00965         if (p[i].y > y2) {
00966             y2 = p[i].y;
00967         }
00968     }
00969     for (y=y1; (y <= y2); y++) {
00970         int interLast = 0;
00971         int dirLast = 0;
00972         int interFirst = 1;
00973         ints = 0;
00974         for (i=0; (i <= n); i++) {
00975             int x1, x2;
00976             int y1, y2;
00977             int dir;
00978             int ind1, ind2;
00979             int lastInd1 = 0;
00980             if ((i == n) || (!i)) {
00981                 ind1 = n-1;
00982                 ind2 = 0;
00983             } else {
00984                 ind1 = i-1;
00985                 ind2 = i;
00986             }
00987             y1 = p[ind1].y;
00988             y2 = p[ind2].y;
00989             if (y1 < y2) {
00990                 y1 = p[ind1].y;
00991                 y2 = p[ind2].y;
00992                 x1 = p[ind1].x;
00993                 x2 = p[ind2].x;
00994                 dir = -1;
00995             } else if (y1 > y2) {
00996                 y2 = p[ind1].y;
00997                 y1 = p[ind2].y;
00998                 x2 = p[ind1].x;
00999                 x1 = p[ind2].x;
01000                 dir = 1;
01001             } else {
01002                 /* Horizontal; just draw it */
01003                 LineReplaceColor(
01004                     p[ind1].x, y1,
01005                     p[ind2].x, y1,
01006                     a,b);
01007                 continue;
01008             }
01009             if ((y >= y1) && (y <= y2)) {
01010                 int inter =
01011                     (y-y1) * (x2-x1) / (y2-y1) + x1;
01012                 /* Only count intersections once
01013                     except at maxima and minima. Also,
01014                     if two consecutive intersections are
01015                     endpoints of the same horizontal line
01016                     that is not at a maxima or minima,
01017                     discard the leftmost of the two. */
01018                 if (!interFirst) {
01019                     if ((p[ind1].y == p[lastInd1].y) &&
01020                         (p[ind1].x != p[lastInd1].x)) {
01021                         if (dir == dirLast) {
01022                             if (inter > interLast) {
01023                                 /* Replace the old one */
01024                                 polyInts[ints] = inter;
01025                             } else {
01026                                 /* Discard this one */
01027                             }
01028                             continue;
01029                         }
01030                     }
01031                     if (inter == interLast) {
01032                         if (dir == dirLast) {
01033                             continue;
01034                         }
01035                     }
01036                 }
01037                 if (i > 0) {
01038                     polyInts[ints++] = inter;
01039                 }
01040                 lastInd1 = i;
01041                 dirLast = dir;
01042                 interLast = inter;
01043                 interFirst = 0;
01044             }
01045         }
01046         qsort(polyInts, ints, sizeof(int), gdCompareInt);
01047         for (i=0; (i < (ints-1)); i+=2) {
01048             LineReplaceColor(polyInts[i], y,
01049                 polyInts[i+1], y, a,b);
01050         }
01051     }
01052 }
01053
01054 void gdImage::SetInterlace(int interlaceArg)
01055 {
01056     interlace = interlaceArg;
01057 }
01058
01059 void gdImage::SetLineWidth(int width)
01060 {
01061     lineWidth=width;
01062 }
01063
01064 void gdImage::SetLineStyle(const char* alineStyle)
01065 {
01066     lineStyle=alineStyle;
01067 }
01068


gif.h File Reference

Parser: image manipulations decls. More...

Include dependency graph for gif.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | gdBuf
class | gdGrowingBuf
class | gdImage
Image type. More...

struct | Point
Point type for use in polygon drawing. More...

class | gdGifEncoder
used by gdImage::Gif to produce buffer with bytes in GIF format. More...

Defines

#define | gdMaxColors 0x100
#define | HSIZE 5003

Variables

const char *const | IDENT_GIF_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: image manipulations decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) based on: gd.h: declarations file for the gifdraw module.

Written by Tom Boutell, 5/94. Copyright 1994, Cold Spring Harbor Labs. Permission granted to use this code in any fashion provided that this notice is retained and any alterations are labeled as such. It is requested, but not required, that you share extensions to this module with us so that we can incorporate them into new versions.

Definition in file gif.h.

Define Documentation

#define gdMaxColors 0x100

Definition at line 28 of file gif.h.

Referenced by gdImage::ColorAllocate(), gdImage::Copy(), and gdImage::ReadImage().

#define HSIZE 5003

Definition at line 29 of file gif.h.

Referenced by gdGifEncoder::gdGifEncoder().

Variable Documentation

const char* const IDENT_GIF_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 21 of file gif.h.


gif.h Source File

gif.h

Go to the documentation of this file.
00001
00018 #ifndef GIF_H
00019 #define GIF_H
00020
00021 static const char * const IDENT_GIF_H="$Date: 2005/08/09 08:14:50 $";
00022
00023 #include "pa_config_includes.h"
00024
00025
00026 #include "pa_memory.h"
00027
00028 #define gdMaxColors 0x100
00029 #define HSIZE  5003            /* 80% occupancy */
00030
00031 struct gdBuf {
00032     void *ptr;
00033     size_t size;
00034
00035     gdBuf(void *aptr, size_t asize): ptr(aptr), size(asize) {}
00036 };
00037
00038 class gdGrowingBuf: PA_Object {
00039     unsigned char *fptr;
00040     size_t fallocated;
00041     size_t fused;
00042
00043     void expand(size_t delta) {
00044         size_t new_allocated=fallocated+delta;
00045         fptr=(unsigned char*)realloc(fptr, new_allocated);
00046         fallocated=new_allocated;
00047     }
00048 public:
00049     operator gdBuf() { return gdBuf(fptr, fused); }
00050
00051     gdGrowingBuf(): fptr(0), fallocated(0), fused(0) {}
00052
00053     void append(unsigned char *abuf, size_t asize) {
00054         ssize_t delta=asize-(fallocated-fused);
00055         if(delta>0)
00056             expand(delta+100);
00057
00058         memcpy(&fptr[fused], abuf, asize);
00059         fused+=asize;
00060     }
00061 };
00062
00069 class gdImage: public PA_Object {
00070
00071 public:
00072
00074
00075     void Create(int asx, int asy);
00076     bool CreateFromGif(FILE *fd);
00077     void SetPixel(int x, int y, int color);
00078     int GetPixel(int x, int y);
00079     void Line(int x1, int y1, int x2, int y2, int color);
00080     void StyledLine(int x1, int y1, int x2, int y2, int color, const char* lineStyle);
00081     void Rectangle(int x1, int y1, int x2, int y2, int color);
00082     void LineReplaceColor(int x1, int y1, int x2, int y2, int a, int b);
00083     void FilledRectangle(int x1, int y1, int x2, int y2, int color);
00085
00087     struct Point {
00088         int x, y;
00089     };
00090
00091     void Polygon(Point *p, int n, int c, bool closed=true);
00092     void FilledPolygon(Point *p, int n, int c);
00093     void FilledPolygonReplaceColor(Point *p, int n, int a, int b);
00094
00095     int ColorAllocate(int r, int g, int b);
00096     int ColorClosest(int r, int g, int b, int tolerance=0);
00097     int ColorExact(int r, int g, int b);
00098     int ColorRGB(int r, int g, int b);
00099     int Color(unsigned int rgb);
00100     unsigned int DecodeColor(int color);
00101     void ColorDeallocate(int color);
00102     void SetColorTransparent(int color);
00103
00104     int BoundsSafe(int x, int y);
00105     void DoSetPixel(int x, int y, int color);
00106
00107     gdBuf Gif();
00108     void Arc(int cx, int cy, int w, int h, int s, int e, int color);
00109     void Sector(int cx, int cy, int w, int h, int s, int e, int color);
00110     void FillToBorder(int x, int y, int border, int color);
00111     void Fill(int x, int y, int color);
00112     void Copy(gdImage& dst, int dstX, int dstY, int srcX, int srcY, int w, int h);
00113     void CopyResampled(gdImage& dst, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH, int tolerance);
00114     void SetLineWidth(int width);
00115     void SetLineStyle(const char* aLineStyle);
00116     void SetInterlace(int interlaceArg); /* On or off(1 or 0) */
00117
00118 public:
00119
00121
00122     int SX() { return sx; }
00123     int SY() { return sy; }
00124     int ColorsTotal() { return colorsTotal; }
00125     int Red(int c) { return red[c]; }
00126     int Green(int c) { return green[c]; }
00127     int Blue(int c) { return blue[c]; }
00128     int GetTransparent() { return transparent; }
00129     int GetInterlaced() { return interlace; }
00131
00132 private:
00133
00134     unsigned char ** pixels;
00135     int sx;
00136     int sy;
00137     int colorsTotal;
00138     int red[gdMaxColors];
00139     int green[gdMaxColors];
00140     int blue[gdMaxColors];
00141     int open[gdMaxColors];
00142     int transparent;
00143     int *polyInts;
00144     int polyAllocated;
00145     int lineWidth; const char* lineStyle;
00146     int interlace;
00147
00148 private: // read gif
00149
00150     int GetDataBlock(FILE *fd, unsigned char *buf);
00151     int LWZReadByte(FILE *fd, int flag, int input_code_size);
00152     void ReadImage(FILE *fd, int len, int height, unsigned char(*cmap)[256], int interlace, int ignore);
00153     int DoExtension(FILE *fd, int label, int *Transparent);
00154     int GetCode(FILE *fd, int code_size, int flag);
00155
00156 private: // read gif
00157
00158     int ZeroDataBlock;
00159
00160 };
00161
00163 class gdGifEncoder: public PA_Object {
00164 public:
00165
00166     gdGifEncoder(gdImage& aim);
00167
00168     gdBuf encode(
00169         int GWidth, int GHeight,
00170         int GInterlace, int Background,
00171         int Transparent, int BitsPerPixel,
00172         int *Red, int *Green, int *Blue);
00173
00174 private:
00175
00177     typedef int             code_int;
00178 #ifdef SIGNED_COMPARE_SLOW
00179     typedef unsigned long int count_int;
00180     typedef unsigned short int count_short;
00181 #else
00182     typedef long int          count_int;
00183 #endif
00184
00185 private:
00186
00187     void Putbyte(unsigned char c);
00188     void Putword(int w);
00189     void Write(void *buf, size_t size);
00190
00191     void prepare_encoder(void);
00192     void BumpPixel(void);
00193     int GIFNextPixel();
00194     void compress(int init_bits);
00195     void output(code_int code);
00196     void cl_block(void);
00197     void cl_hash(count_int hsize);
00198     void char_init(void);
00199     void char_out(int c);
00200     void flush_char(void);
00201
00202 private:
00203
00204     gdImage& im;
00205     gdGrowingBuf buf;
00206
00207     int Width, Height;
00208     int curx, cury;
00209     long CountDown;
00210     int Pass;
00211     int Interlace;
00212
00213     int g_init_bits;
00214
00215     int ClearCode;
00216     int EOFCode;
00217
00218     int n_bits;                        /* number of bits/code */
00219     int maxbits;                /* user settable max # bits/code */
00220
00221     code_int maxcode;                  /* maximum code, given n_bits */
00222     code_int maxmaxcode; /* should NEVER generate this code */
00223
00224     count_int htab [HSIZE];
00225     unsigned short codetab [HSIZE];
00226     code_int hsize;                 /* for dynamic table sizing */
00227
00228     code_int free_ent;                  /* first unused entry */
00229
00230     /*
00231     * block compression parameters -- after all codes are used up,
00232     * and compression rate changes, start over.
00233     */
00234     int clear_flg;
00235
00236     int offset;
00237     long int in_count;            /* length of input */
00238     long int out_count;           /* # of codes output(for debugging) */
00239
00240     unsigned long cur_accum;
00241     int cur_bits;
00242
00243     /*
00244      * Number of characters so far in this 'packet'
00245      */
00246     int a_count;
00247
00248     /*
00249      * Define the storage for the packet accumulator
00250      */
00251     char accum[ 256 ];
00252
00253 };
00254
00255 inline int gdImage::BoundsSafe(int x, int y){
00256     return(!(((y < 0) ||(y >= sy)) ||((x < 0) ||(x >= sx))));
00257 }
00258
00259 inline /*paf int*/void gdImage::DoSetPixel(int x, int y, int color){
00260     if(BoundsSafe(x, y)) pixels[x][y] = (unsigned char)color;
00261 }
00262
00263 #endif


gifio.C File Reference

Parser: image manipulations impl2. More...

Include dependency graph for gifio.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | TRUE 1
#define | FALSE 0
#define | GIFBITS 12
#define | MAXCODE(n_bits) (((code_int) 1 <<(n_bits)) - 1)
#define | HashTabOf(i) htab[i]
#define | CodeTabOf(i) codetab[i]
#define | tab_prefixof(i) CodeTabOf(i)
#define | tab_suffixof(i) ((char_type*)(htab))[i]
#define | de_stack ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
#define | MAXCOLORMAPSIZE 256
#define | CM_RED 0
#define | CM_GREEN 1
#define | CM_BLUE 2
#define | MAX_LWZ_BITS 12
#define | INTERLACE 0x40
#define | LOCALCOLORMAP 0x80
#define | BitSet(byte, bit) (((byte) &(bit)) ==(bit))
#define | ReadOK(file, buffer, len) (fread(buffer, len, 1, file) != 0)
#define | LM_to_uint(a, b) (((b)<<8)|(a))

Typedefs

typedef unsigned char | char_type

Functions

int | colorstobpp (int colors)
int | ReadColorMap (FILE *fd, int number, unsigned char(*buffer)[256])
Graphic Control Extension struct. More...

Variables

const char *const | IDENT_GIFIO_C = "$Date: 2005/08/09 08:14:50 $"
unsigned long | masks []

Detailed Description

Parser: image manipulations impl2.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

based on: gd

Written by Tom Boutell, 5/94. Copyright 1994, Cold Spring Harbor Labs. Permission granted to use this code in any fashion provided that this notice is retained and any alterations are labeled as such. It is requested, but not required, that you share extensions to this module with us so that we can incorporate them into new versions.

based on:

Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A Lempel-Zim compression based on "compress".

Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>

Copyright(C) 1989 by Jef Poskanzer.

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. This software is provided "as is" without express or implied warranty.

The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated.

Definition in file gifio.C.

Define Documentation

#define TRUE 1

Definition at line 89 of file gifio.C.

Referenced by gdImage::GetCode(), gdImage::LWZReadByte(), ReadColorMap(), and gdImage::ReadImage().

#define FALSE 0

Definition at line 92 of file gifio.C.

Referenced by gdImage::CreateFromGif(), gdImage::DoExtension(), gdImage::GetCode(), gdImage::LWZReadByte(), ReadColorMap(), and gdImage::ReadImage().

#define GIFBITS 12

Definition at line 365 of file gifio.C.

Referenced by gdGifEncoder::gdGifEncoder().

#define MAXCODE ( n_bits ) (((code_int) 1 <<(n_bits)) - 1)

Definition at line 390 of file gifio.C.

Referenced by gdGifEncoder::compress(), and gdGifEncoder::output().

#define HashTabOf ( i ) htab[i]

Definition at line 393 of file gifio.C.

Referenced by gdGifEncoder::compress().

#define CodeTabOf ( i ) codetab[i]

Definition at line 394 of file gifio.C.

Referenced by gdGifEncoder::compress().

#define tab_prefixof ( i ) CodeTabOf(i)

Definition at line 404 of file gifio.C.

#define tab_suffixof ( i ) ((char_type*)(htab))[i]

Definition at line 405 of file gifio.C.

#define de_stack ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))

Definition at line 406 of file gifio.C.

#define MAXCOLORMAPSIZE 256

Definition at line 726 of file gifio.C.

Referenced by gdImage::CreateFromGif().

#define CM_RED 0

Definition at line 735 of file gifio.C.

Referenced by ReadColorMap(), and gdImage::ReadImage().

#define CM_GREEN 1

Definition at line 736 of file gifio.C.

Referenced by ReadColorMap(), and gdImage::ReadImage().

#define CM_BLUE 2

Definition at line 737 of file gifio.C.

Referenced by ReadColorMap(), and gdImage::ReadImage().

#define MAX_LWZ_BITS 12

Definition at line 739 of file gifio.C.

Referenced by gdImage::LWZReadByte().

#define INTERLACE 0x40

Definition at line 741 of file gifio.C.

Referenced by gdImage::CreateFromGif().

#define LOCALCOLORMAP 0x80

Definition at line 742 of file gifio.C.

Referenced by gdImage::CreateFromGif().

#define BitSet | ( | byte,
 |  | bit | ) | (((byte) &(bit)) ==(bit))

Definition at line 743 of file gifio.C.

Referenced by gdImage::CreateFromGif().

#define ReadOK | ( | file,
 |  | buffer,
 |  | len | ) | (fread(buffer, len, 1, file) != 0)

Definition at line 745 of file gifio.C.

Referenced by gdImage::CreateFromGif(), gdImage::GetDataBlock(), ReadColorMap(), and gdImage::ReadImage().

#define LM_to_uint | ( | a,
 |  | b | ) | (((b)<<8)|(a))

Definition at line 747 of file gifio.C.

Referenced by gdImage::CreateFromGif(), and gdImage::DoExtension().

Typedef Documentation

typedef unsigned char char_type

Definition at line 370 of file gifio.C.

Function Documentation

int colorstobpp ( int colors ) [static]

Definition at line 56 of file gifio.C.

Referenced by gdImage::Gif().

int ReadColorMap | ( | FILE * | fd,
 |  | int | number,
 |  | unsigned char * | buffer[256]
 | ) | [static]

Graphic Control Extension struct.

Definition at line 886 of file gifio.C.

References CM_BLUE, CM_GREEN, CM_RED, FALSE, ReadOK, and TRUE.

Referenced by gdImage::CreateFromGif().

Variable Documentation

const char* const IDENT_GIFIO_C = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 38 of file gifio.C.

unsigned long masks[] [static]

Initial value:

 { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
    0x001F, 0x003F, 0x007F, 0x00FF,
    0x01FF, 0x03FF, 0x07FF, 0x0FFF,
    0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }

Definition at line 536 of file gifio.C.

Referenced by gdGifEncoder::output().


gifio.C Source File

gifio.C

Go to the documentation of this file.
00001
00038 static const char * const IDENT_GIFIO_C="$Date: 2005/08/09 08:14:50 $";
00039
00040 #include "gif.h"
00041
00042 static int colorstobpp(int colors);
00043
00044 gdBuf gdImage::Gif()
00045 {
00046     int BitsPerPixel = colorstobpp(colorsTotal);
00047     /* Clear any old values in statics strewn through the GIF code */
00048     gdGifEncoder encoder(*this);
00049     /* All set, let's do it. */
00050     return encoder.encode(
00051         sx, sy, interlace, 0, transparent, BitsPerPixel,
00052         red, green, blue);
00053 }
00054
00055 static int
00056 colorstobpp(int colors)
00057 {
00058     int bpp = 0;
00059
00060     if( colors <= 2 )
00061         bpp = 1;
00062     else if( colors <= 4 )
00063         bpp = 2;
00064     else if( colors <= 8 )
00065         bpp = 3;
00066     else if( colors <= 16 )
00067         bpp = 4;
00068     else if( colors <= 32 )
00069         bpp = 5;
00070     else if( colors <= 64 )
00071         bpp = 6;
00072     else if( colors <= 128 )
00073         bpp = 7;
00074     else if( colors <= 256 )
00075         bpp = 8;
00076     return bpp;
00077 }
00078
00079 /*****************************************************************************
00080 *
00081 * GIFENCODE.C    - GIF Image compression interface
00082 *
00083 * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
00084 *            BitsPerPixel, Red, Green, Blue, gdGifEncoder::Ptr )
00085 *
00086 *****************************************************************************/
00087
00088 #ifndef TRUE
00089 #define TRUE 1
00090 #endif
00091 #ifndef FALSE
00092 #define FALSE 0
00093 #endif
00094
00095 /*
00096 * Bump the 'curx' and 'cury' to point to the next pixel
00097 */
00098 void
00099 gdGifEncoder::BumpPixel(void)
00100 {
00101 /*
00102 * Bump the current X position
00103     */
00104     ++curx;
00105
00106     /*
00107     * If we are at the end of a scan line, set curx back to the beginning
00108     * If we are interlaced, bump the cury to the appropriate spot,
00109     * otherwise, just increment it.
00110     */
00111     if( curx == Width ) {
00112         curx = 0;
00113
00114         if( !Interlace )
00115             ++cury;
00116         else {
00117             switch( Pass ) {
00118
00119             case 0:
00120                 cury += 8;
00121                 if( cury >= Height ) {
00122                     ++Pass;
00123                     cury = 4;
00124                 }
00125                 break;
00126
00127             case 1:
00128                 cury += 8;
00129                 if( cury >= Height ) {
00130                     ++Pass;
00131                     cury = 2;
00132                 }
00133                 break;
00134
00135             case 2:
00136                 cury += 4;
00137                 if( cury >= Height ) {
00138                     ++Pass;
00139                     cury = 1;
00140                 }
00141                 break;
00142
00143             case 3:
00144                 cury += 2;
00145                 break;
00146             }
00147         }
00148     }
00149 }
00150
00151 /*
00152 * Return the next pixel from the image
00153 */
00154 int
00155 gdGifEncoder::GIFNextPixel()
00156 {
00157     int r;
00158
00159     if( CountDown == 0 )
00160         return EOF;
00161
00162     --CountDown;
00163
00164     r = im.GetPixel(curx, cury);
00165
00166     BumpPixel();
00167
00168     return r;
00169 }
00170
00171 /* public */
00172
00173 gdBuf
00174 gdGifEncoder::encode(int GWidth, int GHeight,
00175                      int GInterlace, int Background, int Transparent, int BitsPerPixel,
00176                      int *Red, int *Green, int *Blue)
00177 {
00178     int B;
00179     int RWidth, RHeight;
00180     int LeftOfs, TopOfs;
00181     int Resolution;
00182     int ColorMapSize;
00183     int InitCodeSize;
00184     int i;
00185
00186     Interlace = GInterlace;
00187
00188     ColorMapSize = 1 << BitsPerPixel;
00189
00190     RWidth = Width = GWidth;
00191     RHeight = Height = GHeight;
00192     LeftOfs = TopOfs = 0;
00193
00194     Resolution = BitsPerPixel;
00195
00196     /*
00197     * Calculate number of bits we are expecting
00198     */
00199     CountDown =(long)Width *(long)Height;
00200
00201     /*
00202     * Indicate which pass we are on(if interlace)
00203     */
00204     Pass = 0;
00205
00206     /*
00207     * The initial code size
00208     */
00209     if( BitsPerPixel <= 1 )
00210         InitCodeSize = 2;
00211     else
00212         InitCodeSize = BitsPerPixel;
00213
00214         /*
00215         * Set up the current x and y position
00216     */
00217     curx = cury = 0;
00218
00219     /*
00220     * Write the Magic header
00221     */
00222     Putbyte('G');Putbyte('I');Putbyte('F');
00223     Putbyte('8');Putbyte(Transparent < 0?'7':'9');Putbyte('a');
00224
00225     /*
00226     * Write out the screen width and height
00227     */
00228     Putword( RWidth);
00229     Putword( RHeight);
00230
00231     /*
00232     * Indicate that there is a global colour map
00233     */
00234     B = 0x80;       /* Yes, there is a color map */
00235
00236                     /*
00237                     * OR in the resolution
00238     */
00239     B |=(Resolution - 1) << 5;
00240
00241     /*
00242     * OR in the Bits per Pixel
00243     */
00244     B |=(BitsPerPixel - 1);
00245
00246     /*
00247     * Write it out
00248     */
00249     Putbyte(B);
00250
00251     /*
00252     * Write out the Background colour
00253     */
00254     Putbyte(Background);
00255
00256     /*
00257     * Byte of 0's(future expansion)
00258     */
00259     Putbyte(0);
00260
00261     /*
00262     * Write out the Global Colour Map
00263     */
00264     for( i=0; i<ColorMapSize; ++i ) {
00265         Putbyte( Red[i]);
00266         Putbyte( Green[i]);
00267         Putbyte( Blue[i]);
00268     }
00269
00270     /*
00271     * Write out extension for transparent colour index, if necessary.
00272     */
00273     if( Transparent >= 0 ) {
00274         Putbyte( '!');
00275         Putbyte( 0xf9);
00276         Putbyte( 4);
00277         Putbyte( 1);
00278         Putbyte( 0);
00279         Putbyte( 0);
00280         Putbyte((unsigned char) Transparent);
00281         Putbyte( 0);
00282     }
00283
00284     /*
00285     * Write an Image separator
00286     */
00287     Putbyte( ',');
00288
00289     /*
00290     * Write the Image header
00291     */
00292
00293     Putword( LeftOfs);
00294     Putword( TopOfs);
00295     Putword( Width);
00296     Putword( Height);
00297
00298     /*
00299     * Write out whether or not the image is interlaced
00300     */
00301     if( Interlace )
00302         Putbyte( 0x40);
00303     else
00304         Putbyte( 0x00);
00305
00306         /*
00307         * Write out the initial code size
00308     */
00309     Putbyte( InitCodeSize);
00310
00311     /*
00312     * Go and actually compress the data
00313     */
00314     compress( InitCodeSize+1 );
00315
00316     /*
00317     * Write out a Zero-length packet(to end the series)
00318     */
00319     Putbyte( 0);
00320
00321     /*
00322     * Write the GIF file terminator
00323     */
00324     Putbyte( ';');
00325
00326     return buf;
00327 }
00328
00329 /*
00330 * Write out a byte to the GIF file
00331 */
00332 void
00333 gdGifEncoder::Putbyte(unsigned char c) {
00334     buf.append(&c, 1);
00335 }
00336 /*
00337 * Write out a word to the GIF file
00338 */
00339 void
00340 gdGifEncoder::Putword(int w)
00341 {
00342     unsigned char b0=w & 0xff;
00343     unsigned char b1=w >> 8;
00344     buf.append(&b0, 1);
00345     buf.append(&b1, 1);
00346 }
00347
00348 void gdGifEncoder::Write(void *abuf, size_t size) {
00349     buf.append((unsigned char*)abuf, size);
00350 }
00351
00352 /***************************************************************************
00353 *
00354 *  GIFCOMPR.C       - GIF Image compression routines
00355 *
00356 *  Lempel-Ziv compression based on 'compress'.  GIF modifications by
00357 *  David Rowley(mgardi@watdcsu.waterloo.edu)
00358 *
00359 ***************************************************************************/
00360
00361 /*
00362 * General DEFINEs
00363 */
00364
00365 #define GIFBITS    12
00366
00367 #ifdef NO_UCHAR
00368 typedef char   char_type;
00369 #else
00370 typedef        unsigned char   char_type;
00371 #endif
00372
00373 /*
00374 *
00375 * GIF Image compression - modified 'compress'
00376 *
00377 * Based on: compress.c - File compression ala IEEE Computer, June 1984.
00378 *
00379 * By Authors:  Spencer W. Thomas     (decvax!harpo!utah-cs!utah-gr!thomas)
00380 *              Jim McKie             (decvax!mcvax!jim)
00381 *              Steve Davies          (decvax!vax135!petsd!peora!srd)
00382 *              Ken Turkowski         (decvax!decwrl!turtlevax!ken)
00383 *              James A. Woods        (decvax!ihnp4!ames!jaw)
00384 *              Joe Orost             (decvax!vax135!petsd!joe)
00385 *
00386 */
00387 #ifdef COMPATIBLE               /* But wrong! */
00388 # define MAXCODE(n_bits)      ((code_int) 1 <<(n_bits) - 1)
00389 #else
00390 # define MAXCODE(n_bits)      (((code_int) 1 <<(n_bits)) - 1)
00391 #endif
00392
00393 #define HashTabOf(i)       htab[i]
00394 #define CodeTabOf(i)    codetab[i]
00395 /*
00396 * To save much memory, we overlay the table used by compress() with those
00397 * used by decompress().  The tab_prefix table is the same size and type
00398 * as the codetab.  The tab_suffix table needs 2**GIFBITS characters.  We
00399 * get this from the beginning of htab.  The output stack uses the rest
00400 * of htab, and contains characters.  There is plenty of room for any
00401 * possible stack(stack used to be 8000 characters).
00402 */
00403
00404 #define tab_prefixof(i) CodeTabOf(i)
00405 #define tab_suffixof(i)      ((char_type*)(htab))[i]
00406 #define de_stack             ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
00407
00408 /*
00409 * compress stdin to stdout
00410 *
00411 * Algorithm:  use open addressing double hashing(no chaining) on the
00412 * prefix code / next character combination.  We do a variant of Knuth's
00413 * algorithm D(vol. 3, sec. 6.4) along with G. Knott's relatively-prime
00414 * secondary probe.  Here, the modular division first probe is gives way
00415 * to a faster exclusive-or manipulation.  Also do block compression with
00416 * an adaptive reset, whereby the code table is cleared when the compression
00417 * ratio decreases, but after the table fills.  The variable-length output
00418 * codes are re-sized at this point, and a special CLEAR code is generated
00419 * for the decompressor.  Late addition:  construct the table according to
00420 * file size for noticeable speed improvement on small files.  Please direct
00421 * questions about this implementation to ames!jaw.
00422 */
00423
00424 void
00425 gdGifEncoder::compress(int init_bits)
00426 {
00427     register long fcode;
00428     register code_int i /* = 0 */;
00429     register int c;
00430     register code_int ent;
00431     register code_int disp;
00432     register code_int hsize_reg;
00433     register int hshift;
00434
00435     /*
00436     * Set up the globals:  g_init_bits - initial number of bits
00437     *                      g_outfile   - pointer to output file
00438     */
00439     g_init_bits = init_bits;
00440
00441     /*
00442     * Set up the necessary values
00443     */
00444     offset = 0;
00445     out_count = 0;
00446     clear_flg = 0;
00447     in_count = 1;
00448     maxcode = MAXCODE(n_bits = g_init_bits);
00449
00450     ClearCode =(1 <<(init_bits - 1));
00451     EOFCode = ClearCode + 1;
00452     free_ent = ClearCode + 2;
00453
00454     char_init();
00455
00456     ent = GIFNextPixel( );
00457
00458     hshift = 0;
00459     for( fcode =(long) hsize;  fcode < 65536L; fcode *= 2L )
00460         ++hshift;
00461     hshift = 8 - hshift;                /* set hash code range bound */
00462
00463     hsize_reg = hsize;
00464     cl_hash((count_int) hsize_reg);            /* clear hash table */
00465
00466     output((code_int)ClearCode );
00467
00468 #ifdef SIGNED_COMPARE_SLOW
00469     while((c = GIFNextPixel( )) !=(unsigned) EOF ) {
00470 #else
00471     while((c = GIFNextPixel( )) != EOF ) {  /* } */
00472 #endif
00473
00474     ++in_count;
00475
00476     fcode =(long)(((long) c << maxbits) + ent);
00477     i =(((code_int)c << hshift) ^ ent);    /* xor hashing */
00478
00479     if( HashTabOf(i) == fcode ) {
00480         ent = CodeTabOf(i);
00481         continue;
00482     } else if((long)HashTabOf(i) < 0 )      /* empty slot */
00483         goto nomatch;
00484     disp = hsize_reg - i;           /* secondary hash(after G. Knott) */
00485     if( i == 0 )
00486         disp = 1;
00487 probe:
00488     if((i -= disp) < 0 )
00489         i += hsize_reg;
00490
00491     if( HashTabOf(i) == fcode ) {
00492         ent = CodeTabOf(i);
00493         continue;
00494     }
00495     if((long)HashTabOf(i) > 0 )
00496         goto probe;
00497 nomatch:
00498     output((code_int) ent );
00499     ++out_count;
00500     ent = c;
00501 #ifdef SIGNED_COMPARE_SLOW
00502     if((unsigned) free_ent <(unsigned) maxmaxcode) {
00503 #else
00504         if( free_ent < maxmaxcode ) {  /* } */
00505 #endif
00506             CodeTabOf(i) = free_ent++; /* code -> hashtable */
00507             HashTabOf(i) = fcode;
00508         } else
00509             cl_block();
00510     }
00511     /*
00512     * Put out the final code.
00513     */
00514     output((code_int)ent );
00515     ++out_count;
00516     output((code_int) EOFCode );
00517 }
00518
00519 /*****************************************************************
00520 * TAG( output )
00521 *
00522 * Output the given code.
00523 * Inputs:
00524 *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
00525 *              that n_bits =<(long)wordsize - 1.
00526 * Outputs:
00527 *      Outputs code to the file.
00528 * Assumptions:
00529 *      Chars are 8 bits long.
00530 * Algorithm:
00531 *      Maintain a GIFBITS character long buffer(so that 8 codes will
00532 * fit in it exactly).  Use the VAX insv instruction to insert each
00533 * code in turn.  When the buffer fills up empty it and start over.
00534 */
00535
00536 static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
00537     0x001F, 0x003F, 0x007F, 0x00FF,
00538     0x01FF, 0x03FF, 0x07FF, 0x0FFF,
00539     0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
00540
00541 void
00542     gdGifEncoder::output(code_int code)
00543 {
00544     cur_accum &= masks[ cur_bits ];
00545
00546     if( cur_bits > 0 )
00547         cur_accum |=((long)code << cur_bits);
00548     else
00549         cur_accum = code;
00550
00551     cur_bits += n_bits;
00552
00553     while( cur_bits >= 8 ) {
00554         char_out((unsigned int)(cur_accum & 0xff) );
00555         cur_accum >>= 8;
00556         cur_bits -= 8;
00557     }
00558
00559     /*
00560     * If the next entry is going to be too big for the code size,
00561     * then increase it, if possible.
00562     */
00563     if( free_ent > maxcode || clear_flg ) {
00564
00565         if( clear_flg ) {
00566
00567             maxcode = MAXCODE(n_bits = g_init_bits);
00568             clear_flg = 0;
00569
00570         } else {
00571
00572             ++n_bits;
00573             if( n_bits == maxbits )
00574                 maxcode = maxmaxcode;
00575             else
00576                 maxcode = MAXCODE(n_bits);
00577         }
00578     }
00579
00580     if( code == EOFCode ) {
00581     /*
00582     * At EOF, write the rest of the buffer.
00583         */
00584         while( cur_bits > 0 ) {
00585             char_out((unsigned int)(cur_accum & 0xff) );
00586             cur_accum >>= 8;
00587             cur_bits -= 8;
00588         }
00589
00590         flush_char();
00591             }
00592 }
00593
00594 /*
00595 * Clear out the hash table
00596 */
00597 void
00598     gdGifEncoder::cl_block(void)             /* table clear for block compress */
00599 {
00600
00601     cl_hash((count_int) hsize );
00602     free_ent = ClearCode + 2;
00603     clear_flg = 1;
00604
00605     output((code_int)ClearCode );
00606 }
00607
00608 void
00609     gdGifEncoder::cl_hash(count_int hsize)          /* reset code table */
00610
00611 {
00612
00613     register count_int *htab_p = htab+hsize;
00614
00615     register long i;
00616     register long m1 = -1;
00617
00618     i = hsize - 16;
00619     do {                            /* might use Sys V memset(3) here */
00620         *(htab_p-16) = m1;
00621         *(htab_p-15) = m1;
00622         *(htab_p-14) = m1;
00623         *(htab_p-13) = m1;
00624         *(htab_p-12) = m1;
00625         *(htab_p-11) = m1;
00626         *(htab_p-10) = m1;
00627         *(htab_p-9) = m1;
00628         *(htab_p-8) = m1;
00629         *(htab_p-7) = m1;
00630         *(htab_p-6) = m1;
00631         *(htab_p-5) = m1;
00632         *(htab_p-4) = m1;
00633         *(htab_p-3) = m1;
00634         *(htab_p-2) = m1;
00635         *(htab_p-1) = m1;
00636         htab_p -= 16;
00637     } while((i -= 16) >= 0);
00638
00639     for( i += 16; i > 0; --i )
00640         *--htab_p = m1;
00641 }
00642
00643 /******************************************************************************
00644 *
00645 * GIF Specific routines
00646 *
00647 ******************************************************************************/
00648
00649 /*
00650 * Set up the 'byte output' routine
00651 */
00652 void
00653     gdGifEncoder::char_init(void)
00654 {
00655     a_count = 0;
00656 }
00657
00658 /*
00659 * Add a character to the end of the current packet, and if it is 254
00660 * characters, flush the packet to disk.
00661 */
00662 void
00663     gdGifEncoder::char_out(int c)
00664 {
00665     accum[ a_count++ ] = c;
00666     if( a_count >= 254 )
00667         flush_char();
00668 }
00669
00670 /*
00671 * Flush the packet to disk, and reset the accumulator
00672 */
00673 void
00674     gdGifEncoder::flush_char(void)
00675 {
00676     if( a_count > 0 ) {
00677         Putbyte( a_count );
00678         Write( accum, a_count);
00679         a_count = 0;
00680     }
00681 }
00682
00683 gdGifEncoder::gdGifEncoder(gdImage& aim):
00684     im(aim) {
00685     /* Some of these are properly initialized later. What I'm doing
00686     here is making sure code that depends on C's initialization
00687     of statics doesn't break when the code gets called more
00688     than once. */
00689     Width = 0;
00690     Height = 0;
00691     curx = 0;
00692     cury = 0;
00693     CountDown = 0;
00694     Pass = 0;
00695     Interlace = 0;
00696     a_count = 0;
00697     cur_accum = 0;
00698     cur_bits = 0;
00699     g_init_bits = 0;
00700     ClearCode = 0;
00701     EOFCode = 0;
00702     free_ent = 0;
00703     clear_flg = 0;
00704     offset = 0;
00705     in_count = 1;
00706     out_count = 0;
00707     hsize = HSIZE;
00708     n_bits = 0;
00709     maxbits = GIFBITS;
00710     maxcode = 0;
00711     maxmaxcode =(code_int)1 << GIFBITS;
00712 }
00713
00714
00715 /* +-------------------------------------------------------------------+ */
00716 /* | Copyright 1990, 1991, 1993, David Koblas.(koblas@netcom.com)    | */
00717 /* |   Permission to use, copy, modify, and distribute this software   | */
00718 /* |   and its documentation for any purpose and without fee is hereby | */
00719 /* |   granted, provided that the above copyright notice appear in all | */
00720 /* |   copies and that both that copyright notice and this permission  | */
00721 /* |   notice appear in supporting documentation.  This software is    | */
00722 /* |   provided "as is" without express or implied warranty.           | */
00723 /* +-------------------------------------------------------------------+ */
00724
00725
00726 #define        MAXCOLORMAPSIZE         256
00727
00728 #ifndef TRUE
00729 #define        TRUE    1
00730 #endif
00731 #ifndef FALSE
00732 #define        FALSE   0
00733 #endif
00734
00735 #define CM_RED         0
00736 #define CM_GREEN       1
00737 #define CM_BLUE                2
00738
00739 #define        MAX_LWZ_BITS            12
00740
00741 #define INTERLACE              0x40
00742 #define LOCALCOLORMAP  0x80
00743 #define BitSet(byte, bit)    (((byte) &(bit)) ==(bit))
00744
00745 #define        ReadOK(file,buffer,len)(fread(buffer, len, 1, file) != 0)
00746
00747 #define LM_to_uint(a,b)                      (((b)<<8)|(a))
00748
00749     /* We may eventually want to use this information, but def it out for now */
00750 #if 0
00751     struct GifScreen {
00752         unsigned int    Width;
00753         unsigned int    Height;
00754         unsigned char   ColorMap[3][MAXCOLORMAPSIZE];
00755         unsigned int    BitPixel;
00756         unsigned int    ColorResolution;
00757         unsigned int    Background;
00758         unsigned int    AspectRatio;
00759     };
00760 #endif
00761
00763 #ifndef DOXYGEN
00764 struct Gif89 {
00765     int     transparent;
00766     int     delayTime;
00767     int     inputFlag;
00768     int     disposal;
00769 };
00770 #endif
00771 static int ReadColorMap(FILE *fd, int number, unsigned char(*buffer)[256]);
00772
00773 bool gdImage::CreateFromGif(FILE *fd)
00774 {
00775     int imageNumber;
00776     int BitPixel;
00777     int ColorResolution;
00778     int Background;
00779     int AspectRatio;
00780     int Transparent =(-1);
00781     unsigned char   buf[16];
00782     unsigned char   c;
00783     unsigned char   ColorMap[3][MAXCOLORMAPSIZE];
00784     unsigned char   localColorMap[3][MAXCOLORMAPSIZE];
00785     int             imw, imh;
00786     int             useGlobalColormap;
00787     int             bitPixel;
00788     int             imageCount = 0;
00789     char            version[4];
00790     ZeroDataBlock = FALSE;
00791
00792     imageNumber = 1;
00793     if(! ReadOK(fd,buf,6)) {
00794         return false;
00795     }
00796     if(strncmp((char *)buf,"GIF",3) != 0) {
00797         return false;
00798     }
00799     strncpy(version,(char *)buf + 3, 3);
00800     version[3] = '\0';
00801
00802     if((strcmp(version, "87a") != 0) &&(strcmp(version, "89a") != 0)) {
00803         return false;
00804     }
00805     if(! ReadOK(fd,buf,7)) {
00806         return false;
00807     }
00808     BitPixel        = 2<<(buf[4]&0x07);
00809     ColorResolution =(int)(((buf[4]&0x70)>>3)+1);
00810     Background      = buf[5];
00811     AspectRatio     = buf[6];
00812
00813     if(BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */
00814         if(ReadColorMap(fd, BitPixel, ColorMap)) {
00815             return false;
00816         }
00817     }
00818     for(;;) {
00819         if(! ReadOK(fd,&c,1)) {
00820             return false;
00821         }
00822         if(c == ';') {         /* GIF terminator */
00823             int i;
00824             if(imageCount < imageNumber) {
00825                 return false;
00826             }
00827             /* Check for open colors at the end, so
00828             we can reduce colorsTotal and ultimately
00829             BitsPerPixel */
00830             for(i=((colorsTotal-1));(i>=0); i--) {
00831                 if(open[i]) {
00832                     colorsTotal--;
00833                 } else {
00834                     break;
00835                 }
00836             }
00837             return true;
00838         }
00839
00840         if(c == '!') {         /* Extension */
00841             if(! ReadOK(fd,&c,1)) {
00842                 return false;
00843             }
00844             DoExtension(fd, c, &Transparent);
00845             continue;
00846         }
00847
00848         if(c != ',') {         /* Not a valid start character */
00849             continue;
00850         }
00851
00852         ++imageCount;
00853
00854         if(! ReadOK(fd,buf,9)) {
00855             return false;
00856         }
00857
00858         useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
00859
00860         bitPixel = 1<<((buf[8]&0x07)+1);
00861
00862         imw = LM_to_uint(buf[4],buf[5]);
00863         imh = LM_to_uint(buf[6],buf[7]);
00864         Create(imw, imh);
00865         interlace = BitSet(buf[8], INTERLACE);
00866         if(! useGlobalColormap) {
00867             if(ReadColorMap(fd, bitPixel, localColorMap)) {
00868                 return false;
00869             }
00870             ReadImage(fd, imw, imh, localColorMap,
00871                 BitSet(buf[8], INTERLACE),
00872                 imageCount != imageNumber);
00873         } else {
00874             ReadImage(fd, imw, imh,
00875                 ColorMap,
00876                 BitSet(buf[8], INTERLACE),
00877                 imageCount != imageNumber);
00878         }
00879         if(Transparent !=(-1)) {
00880             SetColorTransparent(Transparent);
00881         }
00882     }
00883 }
00884
00885 static int
00886 ReadColorMap(FILE *fd, int number, unsigned char(*buffer)[256])
00887 {
00888     int             i;
00889     unsigned char   rgb[3];
00890
00891
00892     for(i = 0; i < number; ++i) {
00893         if(! ReadOK(fd, rgb, sizeof(rgb))) {
00894             return TRUE;
00895         }
00896         buffer[CM_RED][i] = rgb[0] ;
00897         buffer[CM_GREEN][i] = rgb[1] ;
00898         buffer[CM_BLUE][i] = rgb[2] ;
00899     }
00900
00901
00902     return FALSE;
00903 }
00904
00905 int gdImage::DoExtension(FILE *fd, int label, int *Transparent)
00906 {
00907     static unsigned char     buf[256];
00908
00909     switch(label) {
00910     case 0xf9: {             /* Graphic Control Extension */
00911         (void) GetDataBlock(fd,(unsigned char*) buf);
00912         Gif89 gif89 = { -1, -1, -1, 0 }; // PAF:huh?
00913         gif89.disposal    =(buf[0] >> 2) & 0x7;
00914         gif89.inputFlag   =(buf[0] >> 1) & 0x1;
00915         gif89.delayTime   = LM_to_uint(buf[1],buf[2]);
00916         if((buf[0] & 0x1) != 0)
00917             *Transparent = buf[3];
00918
00919         while(GetDataBlock(fd,(unsigned char*) buf) != 0)
00920             ;
00921         return FALSE;
00922                }
00923     default:
00924         break;
00925     }
00926     while(GetDataBlock(fd,(unsigned char*) buf) != 0)
00927         ;
00928
00929     return FALSE;
00930 }
00931
00932 int
00933 gdImage::GetDataBlock(FILE *fd, unsigned char *buf)
00934 {
00935     unsigned char   count;
00936
00937     if(! ReadOK(fd,&count,1)) {
00938         return -1;
00939     }
00940
00941     ZeroDataBlock = count == 0;
00942
00943     if((count != 0) &&(! ReadOK(fd, buf, count))) {
00944         return -1;
00945     }
00946
00947     return count;
00948 }
00949
00950 int gdImage::GetCode(FILE *fd, int code_size, int flag)
00951 {
00952     static unsigned char    buf[280];
00953     static int              curbit, lastbit, done, last_byte;
00954     int                     i, j, ret;
00955     unsigned char           count;
00956
00957     if(flag) {
00958         curbit = 0;
00959         lastbit = 0;
00960         done = FALSE;
00961         return 0;
00962     }
00963
00964     if((curbit+code_size) >= lastbit) {
00965         if(done) {
00966             if(curbit >= lastbit) {
00967                 /* Oh well */
00968             }
00969             return -1;
00970         }
00971         buf[0] = buf[last_byte-2];
00972         buf[1] = buf[last_byte-1];
00973
00974         if((count = GetDataBlock(fd, &buf[2])) == 0)
00975             done = TRUE;
00976
00977         last_byte = 2 + count;
00978         curbit =(curbit - lastbit) + 16;
00979         lastbit =(2+count)*8 ;
00980     }
00981
00982     ret = 0;
00983     for(i = curbit, j = 0; j < code_size; ++i, ++j)
00984         ret |=((buf[ i / 8 ] &(1 <<(i % 8))) != 0) << j;
00985
00986     curbit += code_size;
00987
00988     return ret;
00989 }
00990
00991 int gdImage::LWZReadByte(FILE *fd, int flag, int input_code_size)
00992 {
00993     static int      fresh = FALSE;
00994     int             code, incode;
00995     static int      code_size, set_code_size;
00996     static int      max_code, max_code_size;
00997     static int      firstcode, oldcode;
00998     static int      clear_code, end_code;
00999     static int      table[2][(1<< MAX_LWZ_BITS)];
01000     static int      stack[(1<<(MAX_LWZ_BITS))*2], *sp;
01001     register int    i;
01002
01003     if(flag) {
01004         set_code_size = input_code_size;
01005         code_size = set_code_size+1;
01006         clear_code = 1 << set_code_size ;
01007         end_code = clear_code + 1;
01008         max_code_size = 2*clear_code;
01009         max_code = clear_code+2;
01010
01011         GetCode(fd, 0, TRUE);
01012
01013         fresh = TRUE;
01014
01015         for(i = 0; i < clear_code; ++i) {
01016             table[0][i] = 0;
01017             table[1][i] = i;
01018         }
01019         for(; i <(1<<MAX_LWZ_BITS); ++i)
01020             table[0][i] = table[1][0] = 0;
01021
01022         sp = stack;
01023
01024         return 0;
01025     } else if(fresh) {
01026         fresh = FALSE;
01027         do {
01028             firstcode = oldcode =
01029                 GetCode(fd, code_size, FALSE);
01030         } while(firstcode == clear_code);
01031         return firstcode;
01032     }
01033
01034     if(sp > stack)
01035         return *--sp;
01036
01037     while((code = GetCode(fd, code_size, FALSE)) >= 0) {
01038         if(code == clear_code) {
01039             for(i = 0; i < clear_code; ++i) {
01040                 table[0][i] = 0;
01041                 table[1][i] = i;
01042             }
01043             for(; i <(1<<MAX_LWZ_BITS); ++i)
01044                 table[0][i] = table[1][i] = 0;
01045             code_size = set_code_size+1;
01046             max_code_size = 2*clear_code;
01047             max_code = clear_code+2;
01048             sp = stack;
01049             firstcode = oldcode =
01050                 GetCode(fd, code_size, FALSE);
01051             return firstcode;
01052         } else if(code == end_code) {
01053             int             count;
01054             unsigned char   buf[260];
01055
01056             if(ZeroDataBlock)
01057                 return -2;
01058
01059             while((count = GetDataBlock(fd, buf)) > 0)
01060                 ;
01061
01062             if(count != 0)
01063                 return -2;
01064         }
01065
01066         incode = code;
01067
01068         if(code >= max_code) {
01069             *sp++ = firstcode;
01070             code = oldcode;
01071         }
01072
01073         while(code >= clear_code) {
01074             *sp++ = table[1][code];
01075             if(code == table[0][code]) {
01076                 /* Oh well */
01077             }
01078             code = table[0][code];
01079         }
01080
01081         *sp++ = firstcode = table[1][code];
01082
01083         if((code = max_code) <(1<<MAX_LWZ_BITS)) {
01084             table[0][code] = oldcode;
01085             table[1][code] = firstcode;
01086             ++max_code;
01087             if((max_code >= max_code_size) &&
01088                 (max_code_size <(1<<MAX_LWZ_BITS))) {
01089                 max_code_size *= 2;
01090                 ++code_size;
01091             }
01092         }
01093
01094         oldcode = incode;
01095
01096         if(sp > stack)
01097             return *--sp;
01098     }
01099     return code;
01100 }
01101
01102 void gdImage::ReadImage(FILE *fd, int len, int height, unsigned char(*cmap)[256], int interlace, int ignore)
01103 {
01104     unsigned char   c;
01105     int             v;
01106     int             xpos = 0, ypos = 0, pass = 0;
01107     int i;
01108     /* Stash the color map into the image */
01109     for(i=0;(i<gdMaxColors); i++) {
01110         red[i] = cmap[CM_RED][i];
01111         green[i] = cmap[CM_GREEN][i];
01112         blue[i] = cmap[CM_BLUE][i];
01113         open[i] = 1;
01114     }
01115     /* Many(perhaps most) of these colors will remain marked open. */
01116     colorsTotal = gdMaxColors;
01117     /*
01118     **  Initialize the Compression routines
01119     */
01120     if(! ReadOK(fd,&c,1)) {
01121         return;
01122     }
01123     if(LWZReadByte(fd, TRUE, c) < 0) {
01124         return;
01125     }
01126
01127     /*
01128     **  If this is an "uninteresting picture" ignore it.
01129     */
01130     if(ignore) {
01131         while(LWZReadByte(fd, FALSE, c) >= 0)
01132             ;
01133         return;
01134     }
01135
01136     while((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {
01137         /* This how we recognize which colors are actually used. */
01138         if(open[v]) {
01139             open[v] = 0;
01140         }
01141         SetPixel(xpos, ypos, v);
01142         ++xpos;
01143         if(xpos == len) {
01144             xpos = 0;
01145             if(interlace) {
01146                 switch(pass) {
01147                 case 0:
01148                 case 1:
01149                     ypos += 8; break;
01150                 case 2:
01151                     ypos += 4; break;
01152                 case 3:
01153                     ypos += 2; break;
01154                 }
01155
01156                 if(ypos >= height) {
01157                     ++pass;
01158                     switch(pass) {
01159                     case 1:
01160                         ypos = 4; break;
01161                     case 2:
01162                         ypos = 2; break;
01163                     case 3:
01164                         ypos = 1; break;
01165                     default:
01166                         goto fini;
01167                     }
01168                 }
01169             } else {
01170                 ++ypos;
01171             }
01172         }
01173         if(ypos >= height)
01174             break;
01175     }
01176
01177 fini:
01178     if(LWZReadByte(fd,FALSE,c)>=0) {
01179         /* Ignore extra */
01180     }
01181 }
01182


hash.C File Reference

Parser: hash parser class. More...

Include dependency graph for hash.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MHash

Functions

DECLARE_CLASS_VAR (hash, new MHash, 0)
void | copy_all_overwrite_to (HashStringValue::key_type key, HashStringValue::value_type value, HashStringValue *dest)
void | _create_or_add (Request &r, MethodParams &params)
void | remove_key_from (HashStringValue::key_type key, HashStringValue::value_type, HashStringValue *dest)
void | _sub (Request &r, MethodParams &params)
void | copy_all_dontoverwrite_to (HashStringValue::key_type key, HashStringValue::value_type value, HashStringValue *dest)
void | _union (Request &r, MethodParams &params)
void | copy_intersection_to (HashStringValue::key_type key, HashStringValue::value_type value, Copy_intersection_to_info *info)
void | _intersection (Request &r, MethodParams &params)
bool | intersects (HashStringValue::key_type key, HashStringValue::value_type, HashStringValue *b)
void | _intersects (Request &r, MethodParams &params)
int | marshal_binds (HashStringValue &hash, SQL_Driver::Placeholder *&placeholders)
void | unmarshal_bind_updates (HashStringValue &hash, int placeholder_count, SQL_Driver::Placeholder *placeholders)
void | _sql (Request &r, MethodParams &params)
void | keys_collector (HashStringValue::key_type key, HashStringValue::value_type, Table *table)
void | _keys (Request &r, MethodParams &params)
void | _count (Request &r, MethodParams &)
void | _delete (Request &r, MethodParams &params)
void | one_foreach_cycle (HashStringValue::key_type akey, HashStringValue::value_type avalue, Foreach_info *info)
void | _foreach (Request &r, MethodParams &params)

Variables

const char *const | IDENT_HASH_C = "$Date: 2005/08/26 12:01:38 $"
String sql_bind_name
String sql_limit_name
String sql_offset_name
String sql_default_name
String sql_distinct_name

Detailed Description

Parser: hash parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file hash.C.

Function Documentation

DECLARE_CLASS_VAR | ( | hash | ,
 |  | new | MHash,
 |  | 0 |
 | ) |

void copy_all_overwrite_to | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | HashStringValue * | dest
 | ) | [static]

Definition at line 116 of file hash.C.

References Hash< const String::Body, Value * >::put(), and value.

Referenced by _create_or_add().

void _create_or_add | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 122 of file hash.C.

References Value::as(), MethodParams::as_no_junction(), copy_all_overwrite_to(), Array< Value * >::count(), Hash< const String::Body, Value * >::for_each(), VHash::get_default(), Value::get_hash(), GET_SELF, VHash::hash(), VHash::set_default(), and VHASH_TYPE.

Referenced by MHash::MHash().

void remove_key_from | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | ,
 |  | HashStringValue * | dest
 | ) | [static]

Definition at line 138 of file hash.C.

References Hash< const String::Body, Value * >::remove().

Referenced by _sub().

void _sub | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 144 of file hash.C.

References MethodParams::as_no_junction(), Hash< const String::Body, Value * >::clear(), Hash< const String::Body, Value * >::for_each(), Value::get_hash(), GET_SELF, and remove_key_from().

Referenced by MHash::MHash().

void copy_all_dontoverwrite_to | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | HashStringValue * | dest
 | ) | [static]

Definition at line 156 of file hash.C.

References Hash< const String::Body, Value * >::put_dont_replace(), and value.

Referenced by _union().

void _union | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 162 of file hash.C.

References MethodParams::as_no_junction(), copy_all_dontoverwrite_to(), Hash< const String::Body, Value * >::for_each(), Value::get_hash(), GET_SELF, result, and Request::write_no_lang().

Referenced by MHash::MHash().

void copy_intersection_to | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | Copy_intersection_to_info * | info
 | ) | [static]

Definition at line 180 of file hash.C.

References value.

Referenced by _intersection().

void _intersection | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 187 of file hash.C.

References MethodParams::as_no_junction(), copy_intersection_to(), Value::get_hash(), GET_SELF, result, and Request::write_no_lang().

Referenced by MHash::MHash().

bool intersects | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | ,
 |  | HashStringValue * | b
 | ) | [static]

Definition at line 200 of file hash.C.

References Hash< const String::Body, Value * >::get().

Referenced by _intersects().

void _intersects | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 207 of file hash.C.

References MethodParams::as_no_junction(), Value::get_hash(), GET_SELF, intersects(), result, and Request::write_no_lang().

Referenced by MHash::MHash().

int marshal_binds | ( | HashStringValue & | hash,
 |  | SQL_Driver::Placeholder *& | placeholders
 | ) |

Definition at line 916 of file table.C.

void unmarshal_bind_updates | ( | HashStringValue & | hash,
 |  | int | placeholder_count,
 |  | SQL_Driver::Placeholder * | placeholders
 | ) |

Definition at line 925 of file table.C.

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 227 of file hash.C.

References Value::as_bool(), Value::as_double(), MethodParams::as_junction(), MethodParams::as_no_junction(), Hash< const String::Body, Value * >::clear(), Request::connection(), Hash< const String::Body, Value * >::count(), Array< Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), Value::get_hash(), GET_SELF, Value::is_defined(), Value::is_string(), String::L_SQL, String::L_UNSPECIFIED, marshal_binds(), offset, Request::process_to_string(), Request::process_to_value(), SQL_Connection::query(), uint, ulong, and unmarshal_bind_updates().

Referenced by MHash::MHash().

void keys_collector | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | ,
 |  | Table * | table
 | ) | [static]

Definition at line 291 of file hash.C.

References Array< ArrayString * >::element_type, and String::L_TAINTED.

Referenced by _keys().

void _keys | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 299 of file hash.C.

References MethodParams::as_string(), Table::columns_type, Array< Value * >::count(), GET_SELF, keys_collector(), and Request::write_no_lang().

Referenced by MHash::MHash().

void _count | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 315 of file hash.C.

References GET_SELF, and Request::write_no_lang().

Referenced by MHash::MHash().

void _delete | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 319 of file hash.C.

References MethodParams::as_string(), and GET_SELF.

Referenced by MHash::MHash().

void one_foreach_cycle | ( | HashStringValue::key_type | akey,
 |  | HashStringValue::value_type | avalue,
 |  | Foreach_info * | info
 | ) | [static]

Definition at line 336 of file hash.C.

References StringOrValue::get_string(), String::L_TAINTED, String::length(), and Value::put_element().

Referenced by _foreach().

void _foreach | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 354 of file hash.C.

References MethodParams::as_junction(), MethodParams::as_string(), Array< Value * >::count(), Hash< const String::Body, Value * >::for_each(), Array< Value * >::get(), GET_SELF, VHash::hash(), and one_foreach_cycle().

Referenced by MHash::MHash().

Variable Documentation

const char* const IDENT_HASH_C = "$Date: 2005/08/26 12:01:38 $" [static]

Definition at line 8 of file hash.C.

String sql_bind_name

Definition at line 219 of file hash.C.

String sql_limit_name

Definition at line 220 of file hash.C.

String sql_offset_name

Definition at line 221 of file hash.C.

String sql_default_name

Definition at line 222 of file hash.C.

String sql_distinct_name

Definition at line 223 of file hash.C.


hash.C Source File

hash.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_HASH_C="$Date: 2005/08/26 12:01:38 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vhash.h"
00015 #include "pa_vvoid.h"
00016 #include "pa_sql_connection.h"
00017 #include "pa_vtable.h"
00018 #include "pa_vbool.h"
00019 #include "pa_vmethod_frame.h"
00020
00021 // class
00022
00023 class MHash: public Methoded {
00024 public: // VStateless_class
00025     Value* create_new_value(Pool&, HashStringValue&) { return new VHash(); }
00026
00027 public:
00028     MHash();
00029 public: // Methoded
00030     bool used_directly() { return true; }
00031 };
00032
00033 // global variable
00034
00035 DECLARE_CLASS_VAR(hash, new MHash, 0);
00036
00037 // methods
00038
00039 #ifndef DOXYGEN
00040 class Hash_sql_event_handlers: public SQL_Driver_query_event_handlers {
00041     const String& statement_string; const char* statement_cstr;
00042     bool distinct;
00043     HashStringValue& rows_hash;
00044     HashStringValue* row_hash;
00045     int column_index;
00046     ArrayString columns;
00047     bool only_one_column;
00048     static VBool only_one_column_value;
00049 public:
00050     Hash_sql_event_handlers(
00051         const String& astatement_string, const char* astatement_cstr,
00052         bool adistinct,
00053         HashStringValue& arows_hash):
00054         statement_string(astatement_string), statement_cstr(astatement_cstr),
00055         distinct(adistinct),
00056         rows_hash(arows_hash),
00057         row_hash(0),
00058         column_index(0),
00059         only_one_column(false) {
00060     }
00061     bool add_column(SQL_Error& error, const char* str, size_t length) {
00062         try {
00063             columns+=new String(str, length, true);
00064             return false;
00065         } catch(...) {
00066             error=SQL_Error("exception occured in Hash_sql_event_handlers::add_column");
00067             return true;
00068         }
00069     }
00070     bool before_rows(SQL_Error& error) {
00071         if(columns.count()<1) {
00072             error=SQL_Error("parser.runtime", "no columns");
00073             return true;
00074         }
00075         only_one_column=columns.count()==1;
00076
00077         return false;
00078     }
00079     bool add_row(SQL_Error& /*error*/) {
00080         column_index=0;
00081         return false;
00082     }
00083     bool add_row_cell(SQL_Error& error, const char *ptr, size_t length) {
00084         try {
00085             String& cell=*new String;
00086             if(length)
00087                 cell.append_know_length(ptr, length, String::L_TAINTED);
00088             bool duplicate=false;
00089             if(only_one_column) {
00090                 duplicate=rows_hash.put_dont_replace(cell, &only_one_column_value);  // put. existed?
00091             } else if(column_index==0) {
00092                 VHash* row_vhash=new VHash;
00093                 row_hash=&row_vhash->hash();
00094                 duplicate=rows_hash.put_dont_replace(cell, row_vhash); // put. existed?
00095             } else
00096                 row_hash->put(*columns[column_index], new VString(cell));
00097
00098             if(duplicate & !distinct) {
00099                 error=SQL_Error("parser.runtime", "duplicate key");
00100                 return true;
00101             }
00102
00103             column_index++;
00104             return false;
00105         } catch(...) {
00106             error=SQL_Error("exception occured in Hash_sql_event_handlers::add_row_cell");
00107             return true;
00108         }
00109     }
00110
00111 };
00112 VBool Hash_sql_event_handlers::only_one_column_value(true);
00113
00114 #endif
00115
00116 static void copy_all_overwrite_to(
00117                                   HashStringValue::key_type key,
00118                                   HashStringValue::value_type value,
00119                                   HashStringValue* dest) {
00120     dest->put(key, value);
00121 }
00122 static void _create_or_add(Request& r, MethodParams& params) {
00123     if(params.count()) {
00124         Value& vsrc=params.as_no_junction(0, "param must be hash");
00125         if(HashStringValue* src=vsrc.get_hash()) {
00126             VHash& self=GET_SELF(r, VHash);
00127             HashStringValue* self_hash=&(self.hash());
00128             if(src==self_hash) // same: doing nothing
00129                 return;
00130             src->for_each(copy_all_overwrite_to, self_hash);
00131
00132             if(VHash* vhash_src=static_cast<VHash*>(vsrc.as(VHASH_TYPE, false)))
00133                 self.set_default(vhash_src->get_default());
00134         }
00135     }
00136 }
00137
00138 static void remove_key_from(
00139                             HashStringValue::key_type key,
00140                             HashStringValue::value_type /*value*/,
00141                             HashStringValue* dest) {
00142     dest->remove(key);
00143 }
00144 static void _sub(Request& r, MethodParams& params) {
00145     Value& vsrc=params.as_no_junction(0, "param must be hash");
00146     if(HashStringValue* src=vsrc.get_hash()) {
00147         HashStringValue* self=&(GET_SELF(r, VHash).hash());
00148         if(src==self) { // same: clearing
00149             self->clear();
00150             return;
00151         }
00152         src->for_each(remove_key_from, self);
00153     }
00154 }
00155
00156 static void copy_all_dontoverwrite_to(
00157                                   HashStringValue::key_type key,
00158                                   HashStringValue::value_type value,
00159                                   HashStringValue* dest) {
00160     dest->put_dont_replace(key, value);
00161 }
00162 static void _union(Request& r, MethodParams& params) {
00163     // dest = copy of self
00164     Value& result=*new VHash(GET_SELF(r, VHash).hash());
00165     // dest += b
00166     Value& vsrc=params.as_no_junction(0, "param must be hash");
00167     if(HashStringValue* src=vsrc.get_hash())
00168         src->for_each(copy_all_dontoverwrite_to, result.get_hash());
00169
00170     // return result
00171     r.write_no_lang(result);
00172 }
00173
00174 #ifndef DOXYGEN
00175 struct Copy_intersection_to_info {
00176     HashStringValue* b;
00177     HashStringValue* dest;
00178 };
00179 #endif
00180 static void copy_intersection_to(
00181                                  HashStringValue::key_type key,
00182                                  HashStringValue::value_type value,
00183                                  Copy_intersection_to_info *info) {
00184     if(info->b->get(key))
00185         info->dest->put_dont_replace(key, value);
00186 }
00187 static void _intersection(Request& r, MethodParams& params) {
00188     Value& result=*new VHash;
00189     // dest += b
00190     Value& vb=params.as_no_junction(0, "param must be hash");
00191     if(HashStringValue* b=vb.get_hash()) {
00192         Copy_intersection_to_info info={b, result.get_hash()};
00193         GET_SELF(r, VHash).hash().for_each(copy_intersection_to, &info);
00194     }
00195
00196     // return result
00197     r.write_no_lang(result);
00198 }
00199
00200 static bool intersects(
00201                        HashStringValue::key_type key,
00202                        HashStringValue::value_type /*value*/,
00203                        HashStringValue* b) {
00204     return b->get(key)!=0;
00205 }
00206
00207 static void _intersects(Request& r, MethodParams& params) {
00208     bool result=false;
00209
00210     Value& vb=params.as_no_junction(0, "param must be hash");
00211     if(HashStringValue* b=vb.get_hash())
00212         result=GET_SELF(r, VHash).hash().first_that(intersects, b)!=0;
00213
00214     // return result
00215     r.write_no_lang(*new VBool(result));
00216 }
00217
00218
00219 extern String sql_bind_name;
00220 extern String sql_limit_name;
00221 extern String sql_offset_name;
00222 extern String sql_default_name;
00223 extern String sql_distinct_name;
00224 extern int marshal_binds(HashStringValue& hash, SQL_Driver::Placeholder*& placeholders);
00225 extern void unmarshal_bind_updates(HashStringValue& hash, int placeholder_count, SQL_Driver::Placeholder* placeholders);
00226
00227 static void _sql(Request& r, MethodParams& params) {
00228     Value& statement=params.as_junction(0, "statement must be code");
00229
00230     HashStringValue* bind=0;
00231     ulong limit=0;
00232     ulong offset=0;
00233     bool distinct=false;
00234     if(params.count()>1) {
00235         Value& voptions=params.as_no_junction(1, "options must be hash, not code");
00236         if(voptions.is_defined() && !voptions.is_string())
00237             if(HashStringValue* options=voptions.get_hash()) {
00238                 int valid_options=0;
00239                 if(Value* vbind=options->get(sql_bind_name)) {
00240                     valid_options++;
00241                     bind=vbind->get_hash();
00242                 }
00243                 if(Value* vlimit=options->get(sql_limit_name)) {
00244                     valid_options++;
00245                     limit=(ulong)r.process_to_value(*vlimit).as_double();
00246                 }
00247                 if(Value* voffset=options->get(sql_offset_name)) {
00248                     valid_options++;
00249                     offset=(ulong)r.process_to_value(*voffset).as_double();
00250                 }
00251                 if(Value* vdistinct=options->get(sql_distinct_name)) {
00252                     valid_options++;
00253                     distinct=r.process_to_value(*vdistinct).as_bool();
00254                 }
00255                 if(valid_options!=options->count())
00256                     throw Exception("parser.runtime",
00257                         0,
00258                         "called with invalid option");
00259             } else
00260                 throw Exception("parser.runtime",
00261                     0,
00262                     "options must be hash");
00263     }
00264
00265     SQL_Driver::Placeholder* placeholders=0;
00266     uint placeholders_count=0;
00267     if(bind)
00268         placeholders_count=marshal_binds(*bind, placeholders);
00269
00270     Temp_lang temp_lang(r, String::L_SQL);
00271     const String& statement_string=r.process_to_string(statement);
00272     const char* statement_cstr=
00273         statement_string.cstr(String::L_UNSPECIFIED, r.connection());
00274     HashStringValue& hash=GET_SELF(r, VHash).hash();
00275     hash.clear();
00276     Hash_sql_event_handlers handlers(
00277         statement_string, statement_cstr,
00278         distinct,
00279         hash);
00280     r.connection()->query(
00281         statement_cstr,
00282         placeholders_count, placeholders,
00283         offset, limit,
00284         handlers,
00285         statement_string);
00286
00287     if(bind)
00288         unmarshal_bind_updates(*bind, placeholders_count, placeholders);
00289 }
00290
00291 static void keys_collector(
00292                HashStringValue::key_type key,
00293                HashStringValue::value_type,
00294                Table *table) {
00295     Table::element_type row(new ArrayString);
00296     *row+=new String(key, String::L_TAINTED);
00297     *table+=row;
00298 }
00299 static void _keys(Request& r, MethodParams& params) {
00300     const String* keys_column_name;
00301     if(params.count()>0)
00302         keys_column_name=&params.as_string(0, "column name must be string");
00303     else
00304         keys_column_name=new String("key");
00305
00306     Table::columns_type columns(new ArrayString);
00307     *columns+=keys_column_name;
00308     Table* table=new Table(columns);
00309
00310     GET_SELF(r, VHash).hash().for_each(keys_collector, table);
00311
00312     r.write_no_lang(*new VTable(table));
00313 }
00314
00315 static void _count(Request& r, MethodParams&) {
00316     r.write_no_lang(*new VInt(GET_SELF(r, VHash).hash().count()));
00317 }
00318
00319 static void _delete(Request& r, MethodParams& params) {
00320
00321     GET_SELF(r, VHash).hash().remove(params.as_string(0, "key must be string"));
00322 }
00323
00324 #ifndef DOXYGEN
00325 struct Foreach_info {
00326     Request *r;
00327     const String* key_var_name;
00328     const String* value_var_name;
00329     Value* body_code;
00330     Value* delim_maybe_code;
00331
00332     VString* vkey;
00333     bool need_delim;
00334 };
00335 #endif
00336 static void one_foreach_cycle(
00337                   HashStringValue::key_type akey,
00338                   HashStringValue::value_type avalue,
00339                   Foreach_info *info) {
00340     info->vkey->set_string(*new String(akey, String::L_TAINTED));
00341     Value& ncontext=*info->r->get_method_frame()->caller();
00342     ncontext.put_element(ncontext, *info->key_var_name, info->vkey, false);
00343     ncontext.put_element(ncontext, *info->value_var_name, avalue, false);
00344
00345     StringOrValue sv_processed=info->r->process(*info->body_code);
00346     const String* s_processed=sv_processed.get_string();
00347     if(info->delim_maybe_code && s_processed && s_processed->length()) { // delimiter set and we have body
00348         if(info->need_delim) // need delim & iteration produced string?
00349             info->r->write_pass_lang(info->r->process(*info->delim_maybe_code));
00350         info->need_delim=true;
00351     }
00352     info->r->write_pass_lang(sv_processed);
00353 }
00354 static void _foreach(Request& r, MethodParams& params) {
00355     Foreach_info info={
00356         &r,
00357         &params.as_string(0, "key-var name must be string"),
00358         &params.as_string(1, "value-var name must be string"),
00359         &params.as_junction(2, "body must be code"),
00360         params.count()>3?params.get(3):0,
00361         /*vkey=*/new VString,
00362         false
00363     };
00364
00365     VHash& self=GET_SELF(r, VHash);
00366     HashStringValue& hash=self.hash();
00367     VHash_lock lock(self);
00368     hash.for_each(one_foreach_cycle, &info);
00369 }
00370
00371 // constructor
00372
00373 MHash::MHash(): Methoded("hash")
00374 {
00375     // ^hash::create[[copy_from]]
00376     add_native_method("create", Method::CT_DYNAMIC, _create_or_add, 0, 1);
00377     // ^hash.add[add_from]
00378     add_native_method("add", Method::CT_DYNAMIC, _create_or_add, 1, 1);
00379     // ^hash.sub[sub_from]
00380     add_native_method("sub", Method::CT_DYNAMIC, _sub, 1, 1);
00381     // ^a.union[b] = hash
00382     add_native_method("union", Method::CT_DYNAMIC, _union, 1, 1);
00383     // ^a.intersection[b] = hash
00384     add_native_method("intersection", Method::CT_DYNAMIC, _intersection, 1, 1);
00385     // ^a.intersects[b] = bool
00386     add_native_method("intersects", Method::CT_DYNAMIC, _intersects, 1, 1);
00387
00388     // ^a.delete[key]
00389     add_native_method("delete", Method::CT_DYNAMIC, _delete, 1, 1);
00390
00391     // ^hash:sql[query][options hash]
00392     add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2);
00393
00394     // ^hash._keys[[column name]]
00395     add_native_method("_keys", Method::CT_DYNAMIC, _keys, 0, 1);
00396
00397     // ^hash._count[]
00398     add_native_method("_count", Method::CT_DYNAMIC, _count, 0, 0);
00399
00400     // ^hash.foreach[key;value]{code}[delim]
00401     add_native_method("foreach", Method::CT_DYNAMIC, _foreach, 2+1, 2+1+1);
00402 }


hashfile.C File Reference

Parser: hashfile parser class. More...

Include dependency graph for hashfile.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MHashfile

Defines

#define | OPEN_DATA_NAME "HASHFILE-OPEN-DATA"

Typedefs

typedef Hash< const String::Body,
bool > 		HashStringBool

Functions

DECLARE_CLASS_VAR (hashfile, new MHashfile, 0)
void | _open (Request &r, MethodParams &params)
void | _hash (Request &r, MethodParams &)
void | _delete (Request &r, MethodParams &params)
void | _clear (Request &r, MethodParams &)
void | one_foreach_cycle (const String::Body key, const String &value, void *ainfo)
void | _foreach (Request &r, MethodParams &params)

Variables

const char *const | IDENT = "$Id: hashfile.C,v 1.36 2005/08/09 08:14:47 paf Exp $"

Detailed Description

Parser: hashfile parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file hashfile.C.

Define Documentation

#define OPEN_DATA_NAME "HASHFILE-OPEN-DATA"

Definition at line 36 of file hashfile.C.

Referenced by _open().

Typedef Documentation

typedef Hash<const String::Body, bool> HashStringBool

Definition at line 40 of file hashfile.C.

Function Documentation

DECLARE_CLASS_VAR | ( | hashfile | ,
 |  | new | MHashfile,
 |  | 0 |
 | ) |

void _open | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 42 of file hashfile.C.

References Request::absolute(), MethodParams::as_string(), Request::classes_conf, Hash< const String::Body, bool >::get(), Hash< const String::Body, void * >::get(), GET_SELF, HashStringBool, VHashfile::open(), OPEN_DATA_NAME, Hash< const String::Body, bool >::put(), and Hash< const String::Body, void * >::put().

Referenced by MHashfile::MHashfile().

void _hash | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 60 of file hashfile.C.

References VHashfile::get_hash(), GET_SELF, result, and Request::write_no_lang().

Referenced by MHashfile::MHashfile().

void _delete | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 68 of file hashfile.C.

References MethodParams::as_string(), Array< Value * >::count(), VHashfile::delete_files(), GET_SELF, and VHashfile::remove().

Referenced by MHashfile::MHashfile().

void _clear | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 82 of file hashfile.C.

References VHashfile::clear(), and GET_SELF.

Referenced by MHashfile::MHashfile().

void one_foreach_cycle | ( | const String::Body | key,
 |  | const String & | value,
 |  | void * | ainfo
 | ) | [static]

Definition at line 101 of file hashfile.C.

References StringOrValue::get_string(), String::L_TAINTED, String::length(), and value.

Referenced by _foreach().

void _foreach | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 117 of file hashfile.C.

References MethodParams::as_junction(), MethodParams::as_string(), Array< Value * >::count(), VHashfile::for_each(), Array< Value * >::get(), GET_SELF, and one_foreach_cycle().

Referenced by MHashfile::MHashfile().

Variable Documentation

const char* const IDENT = "$Id: hashfile.C,v 1.36 2005/08/09 08:14:47 paf Exp $" [static]

Definition at line 9 of file hashfile.C.


hashfile.C Source File

hashfile.C

Go to the documentation of this file.
00001
00009 static const char * const IDENT="$Id: hashfile.C,v 1.36 2005/08/09 08:14:47 paf Exp $";
00010
00011 #include "classes.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vmethod_frame.h"
00015 #include "pa_vhashfile.h"
00016 #include "pa_vhash.h"
00017
00018 // class
00019
00020 class MHashfile : public Methoded {
00021 public: // VStateless_class
00022     Value *create_new_value(Pool& apool, HashStringValue&) { return new VHashfile(apool); }
00023
00024 public:
00025     MHashfile();
00026 public: // Methoded
00027     bool used_directly() { return true; }
00028 };
00029
00030 // global variable
00031
00032 DECLARE_CLASS_VAR(hashfile, new MHashfile, 0);
00033
00034 // defines for statics
00035
00036 #define OPEN_DATA_NAME "HASHFILE-OPEN-DATA"
00037
00038 // methods
00039
00040 typedef Hash<const String::Body, bool> HashStringBool;
00041
00042 static void _open(Request& r, MethodParams& params) {
00043     HashStringBool* file_list=static_cast<HashStringBool*>(r.classes_conf.get(OPEN_DATA_NAME));
00044     if(!file_list) {
00045         file_list=new HashStringBool();
00046         r.classes_conf.put(OPEN_DATA_NAME, file_list);
00047     }
00048
00049     const String& file_spec=r.absolute(params.as_string(0, "filename must be string"));
00050     if(file_list->get(file_spec))
00051         throw Exception("parser.runtime",
00052             0,
00053             "this hashfile is already opened, use existing variable");
00054     file_list->put(file_spec, true);
00055
00056     VHashfile& self=GET_SELF(r, VHashfile);
00057     self.open(file_spec);
00058 }
00059
00060 static void _hash(Request& r, MethodParams&) {
00061     VHashfile& self=GET_SELF(r, VHashfile);
00062
00063     // write out result
00064     VHash& result=*new VHash(*self.get_hash());
00065     r.write_no_lang(result);
00066 }
00067
00068 static void _delete(Request& r, MethodParams& params) {
00069     VHashfile& self=GET_SELF(r, VHashfile);
00070
00071     if(!params.count()) {
00072         // ^hashfile.delete[] asked to delete hashfile itself
00073         self.delete_files();
00074         return;
00075     }
00076     // key
00077     const String &key=params.as_string(0, "key must be string");
00078     // remove
00079     self.remove(key);
00080 }
00081
00082 static void _clear(Request& r, MethodParams&) {
00083     VHashfile& self=GET_SELF(r, VHashfile);
00084     self.clear();
00085 }
00086
00087 #ifndef DOXYGEN
00088 struct Foreach_info {
00089     Request* r;
00090     const String* key_var_name;
00091     const String* value_var_name;
00092     Value* body_code;
00093     Value* delim_maybe_code;
00094
00095     Value* var_context;
00096     VString* vkey;
00097     VString* vvalue;
00098     bool need_delim;
00099 };
00100 #endif
00101 static void one_foreach_cycle(const String::Body key, const String& value, void* ainfo) {
00102     Foreach_info& info=*static_cast<Foreach_info*>(ainfo);
00103     info.vkey->set_string(*new String(key, String::L_TAINTED));
00104     info.vvalue->set_string(value);
00105     info.var_context->put_element(*info.var_context, *info.key_var_name, info.vkey, false);
00106     info.var_context->put_element(*info.var_context, *info.value_var_name, info.vvalue, false);
00107
00108     StringOrValue sv_processed=info.r->process(*info.body_code);
00109     const String* s_processed=sv_processed.get_string();
00110     if(info.delim_maybe_code && s_processed && s_processed->length()) { // delimiter set and we have body
00111         if(info.need_delim) // need delim & iteration produced string?
00112             info.r->write_pass_lang(info.r->process(*info.delim_maybe_code));
00113         info.need_delim=true;
00114     }
00115     info.r->write_pass_lang(sv_processed);
00116 }
00117 static void _foreach(Request& r, MethodParams& params) {
00118     VHashfile& self=GET_SELF(r, VHashfile);
00119
00120     Foreach_info info;
00121
00122     info.r=&r;
00123     info.key_var_name=&params.as_string(0, "key-var name must be string");
00124     info.value_var_name=&params.as_string(1, "value-var name must be string");
00125     info.body_code=&params.as_junction(2, "body must be code");
00126     info.delim_maybe_code=params.count()>3?params.get(3):0;
00127
00128     info.var_context=info.body_code->get_junction()->wcontext;
00129     info.vkey=new VString;
00130     info.vvalue=new VString;
00131
00132     info.need_delim=false;
00133
00134     self.for_each(one_foreach_cycle, &info);
00135 }
00136
00137 // constructor
00138
00139 MHashfile::MHashfile(): Methoded("hashfile") {
00140     // ^hashfile::open[db_home;filename]
00141     add_native_method("open", Method::CT_DYNAMIC, _open, 1, 1);
00142     // ^hash[]
00143     add_native_method("hash", Method::CT_DYNAMIC, _hash, 0, 0);
00144     // ^hashfile.delete[key]
00145     add_native_method("delete", Method::CT_DYNAMIC, _delete, 0, 1);
00146     // ^hashfile.clear[]
00147     add_native_method("clear", Method::CT_DYNAMIC, _clear, 0, 0);
00148     // ^hashfile.foreach[key;value]{code}[delim]
00149     add_native_method("foreach", Method::CT_DYNAMIC, _foreach, 2+1, 2+1+1);
00150 }


image.C File Reference

Parser: image parser class. More...

Include dependency graph for image.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MImage
class | EXIF_tag_value2name
value of exif tag -> it's value. More...

struct | PNG_Header
PNG file header. More...

struct | GIF_Header
GIF file header. More...

struct | JPG_Segment_head
JPEG record head. More...

struct | JPG_Size_segment_body
JPEG frame header. More...

struct | JPG_Exif_segment_begin
JPEG frame header. More...

struct | JPG_Exif_TIFF_header
JPEG Exif TIFF Header. More...

struct | JPG_Exif_IFD_begin
struct | JPG_Exif_IFD_entry

Defines

#define | EXIF_TAG(tag, name) put(tag, #name);
#define | JPG_IFD_TAG_EXIF_OFFSET 0x8769
#define | JPEG_EXIF_DATE_CHARS 20
#define | Y(y) (y+index*height)

Functions

DECLARE_CLASS_VAR (image, new MImage, 0)
ushort | x_endian_to_ushort (uchar b0, uchar b1)
uint | x_endian_to_uint (uchar b0, uchar b1, uchar b2, uchar b3)
ushort | endian_to_ushort (bool is_big, const uchar *b)
uint | endian_to_uint (bool is_big, const uchar *b)
void | measure_gif (const String &origin_string, Measure_reader &reader, ushort &width, ushort &height)
Value * | parse_IFD_entry_formatted_one_value (bool is_big, ushort format, size_t component_size, const uchar *value)
tm | cstr_to_time_t (char *cstr)
Value * | parse_IFD_entry_formatted_value (bool is_big, ushort format, size_t component_size, uint components_count, const uchar *value)
Value * | parse_IFD_entry_value (bool is_big, Measure_reader &reader, long tiff_base, JPG_Exif_IFD_entry &entry)
void | parse_IFD (HashStringValue &hash, bool is_big, Measure_reader &reader, long tiff_base)
void | parse_IFD_entry (HashStringValue &hash, bool is_big, Measure_reader &reader, long tiff_base, JPG_Exif_IFD_entry &entry)
Value * | parse_exif (Measure_reader &reader, const String &origin_string)
void | measure_jpeg (const String &origin_string, Measure_reader &reader, ushort &width, ushort &height, Value **exif)
void | measure_png (const String &origin_string, Measure_reader &reader, ushort &width, ushort &height)
void | measure (const String &file_name, Measure_reader &reader, ushort &width, ushort &height, Value **exif)
void | file_measure_action (struct stat &, int f, const String &, const char *fname, bool, void *context)
void | _measure (Request &r, MethodParams &params)
void | append_attrib_pair (HashStringValue::key_type key, HashStringValue::value_type value, Attrib_info *info)
void | _html (Request &r, MethodParams &params)
gdImage * | load (Request &r, const String &file_name)
void | _load (Request &r, MethodParams &params)
void | _create (Request &r, MethodParams &params)
void | _gif (Request &r, MethodParams &params)
void | _line (Request &r, MethodParams &params)
void | _fill (Request &r, MethodParams &params)
void | _rectangle (Request &r, MethodParams &params)
void | _bar (Request &r, MethodParams &params)
void | _replace (Request &r, MethodParams &params)
void | _polyline (Request &r, MethodParams &params)
void | _polygon (Request &r, MethodParams &params)
void | _polybar (Request &r, MethodParams &params)
void | _font (Request &r, MethodParams &params)
void | _text (Request &r, MethodParams &params)
void | _length (Request &r, MethodParams &params)
void | _arc (Request &r, MethodParams &params)
void | _sector (Request &r, MethodParams &params)
void | _circle (Request &r, MethodParams &params)
gdImage & | as_image (MethodParams &params, int index, const char *msg)
void | _copy (Request &r, MethodParams &params)
void | _pixel (Request &r, MethodParams &params)

Variables

const char *const | IDENT_IMAGE_C = "$Date: 2005/08/09 08:14:48 $"
EXIF_tag_value2name exif_tag_value2name
value of exif tag -> it's value. More...

Detailed Description

Parser: image parser class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file image.C.

Define Documentation

#define EXIF_TAG | ( | tag,
 |  | name | ) | put(tag, #name);

#define JPG_IFD_TAG_EXIF_OFFSET 0x8769

Definition at line 304 of file image.C.

Referenced by parse_IFD_entry().

#define JPEG_EXIF_DATE_CHARS 20

Definition at line 306 of file image.C.

Referenced by parse_IFD_entry_formatted_value().

#define Y ( y ) (y+index*height)

Definition at line 956 of file image.C.

Referenced by Font::index_display(), and Font::index_width().

Function Documentation

DECLARE_CLASS_VAR | ( | image | ,
 |  | new | MImage,
 |  | 0 |
 | ) |

ushort x_endian_to_ushort | ( | uchar | b0,
 |  | uchar | b1
 | ) | [inline]

Definition at line 310 of file image.C.

References uchar, and ushort.

Referenced by endian_to_ushort().

uint x_endian_to_uint | ( | uchar | b0,
 |  | uchar | b1,
 |  | uchar | b2,
 |  | uchar | b3
 | ) | [inline]

Definition at line 314 of file image.C.

References uchar, and uint.

Referenced by endian_to_uint().

ushort endian_to_ushort | ( | bool | is_big,
 |  | const uchar * | b
 | ) | [inline]

Definition at line 318 of file image.C.

References uchar, ushort, and x_endian_to_ushort().

Referenced by measure_gif(), measure_jpeg(), measure_png(), parse_IFD(), parse_IFD_entry(), parse_IFD_entry_formatted_one_value(), and parse_IFD_entry_value().

uint endian_to_uint | ( | bool | is_big,
 |  | const uchar * | b
 | ) | [inline]

Definition at line 323 of file image.C.

References uchar, uint, and x_endian_to_uint().

Referenced by parse_exif(), parse_IFD_entry(), parse_IFD_entry_formatted_one_value(), and parse_IFD_entry_value().

void measure_gif | ( | const String & | origin_string,
 |  | Measure_reader & | reader,
 |  | ushort & | width,
 |  | ushort & | height
 | ) | [static]

Definition at line 328 of file image.C.

References endian_to_ushort(), GIF_Header::height, GIF_Header::signature, ushort, and GIF_Header::width.

Referenced by measure().

Value* parse_IFD_entry_formatted_one_value | ( | bool | is_big,
 |  | ushort | format,
 |  | size_t | component_size,
 |  | const uchar * | value
 | ) | [static]

Definition at line 348 of file image.C.

References endian_to_uint(), endian_to_ushort(), uchar, uint, ushort, and value.

Referenced by parse_IFD_entry_formatted_value().

tm cstr_to_time_t ( char * cstr )

Definition at line 75 of file date.C.

References lsplit(), pa_atoi(), and to_tm_year().

Referenced by _create(), and parse_IFD_entry_formatted_value().

Value* parse_IFD_entry_formatted_value | ( | bool | is_big,
 |  | ushort | format,
 |  | size_t | component_size,
 |  | uint | components_count,
 |  | const uchar * | value
 | ) | [static]

Definition at line 397 of file image.C.

References cstr_to_time_t(), String::Body::Format(), VHash::hash(), JPEG_EXIF_DATE_CHARS, parse_IFD_entry_formatted_one_value(), Hash< const String::Body, Value * >::put(), result, uchar, uint, ushort, and value.

Referenced by parse_IFD_entry_value().

Value* parse_IFD_entry_value | ( | bool | is_big,
 |  | Measure_reader & | reader,
 |  | long | tiff_base,
 |  | JPG_Exif_IFD_entry & | entry
 | ) | [static]

Definition at line 435 of file image.C.

References JPG_Exif_IFD_entry::components_count, endian_to_uint(), endian_to_ushort(), entry, JPG_Exif_IFD_entry::format, parse_IFD_entry_formatted_value(), result, SEEK_SET, uchar, uint, ushort, value, and JPG_Exif_IFD_entry::value_or_offset_to_it.

Referenced by parse_IFD_entry().

void parse_IFD | ( | HashStringValue & | hash,
 |  | bool | is_big,
 |  | Measure_reader & | reader,
 |  | long | tiff_base
 | ) | [static]

Definition at line 519 of file image.C.

References JPG_Exif_IFD_begin::directory_entry_count, endian_to_ushort(), parse_IFD_entry(), and ushort.

Referenced by parse_exif(), and parse_IFD_entry().

void parse_IFD_entry | ( | HashStringValue & | hash,
 |  | bool | is_big,
 |  | Measure_reader & | reader,
 |  | long | tiff_base,
 |  | JPG_Exif_IFD_entry & | entry
 | ) | [static]

Definition at line 497 of file image.C.

References endian_to_uint(), endian_to_ushort(), entry, exif_tag_value2name, String::Body::Format(), Hash< int, const char * >::get(), JPG_IFD_TAG_EXIF_OFFSET, parse_IFD(), parse_IFD_entry_value(), Hash< const String::Body, Value * >::put(), SEEK_SET, JPG_Exif_IFD_entry::tag, ushort, value, and JPG_Exif_IFD_entry::value_or_offset_to_it.

Referenced by parse_IFD().

Value* parse_exif | ( | Measure_reader & | reader,
 |  | const String & | origin_string
 | ) | [static]

Definition at line 537 of file image.C.

References JPG_Exif_TIFF_header::byte_align_identifier, endian_to_uint(), JPG_Exif_TIFF_header::first_IFD_offset, VHash::hash(), parse_IFD(), SEEK_SET, JPG_Exif_segment_begin::signature, and uint.

Referenced by measure_jpeg().

void measure_jpeg | ( | const String & | origin_string,
 |  | Measure_reader & | reader,
 |  | ushort & | width,
 |  | ushort & | height,
 |  | Value ** | exif
 | ) | [static]

Definition at line 566 of file image.C.

References JPG_Segment_head::code, endian_to_ushort(), JPG_Size_segment_body::height, JPG_Segment_head::length, JPG_Segment_head::marker, parse_exif(), SEEK_SET, uchar, uint, ushort, and JPG_Size_segment_body::width.

Referenced by measure().

void measure_png | ( | const String & | origin_string,
 |  | Measure_reader & | reader,
 |  | ushort & | width,
 |  | ushort & | height
 | ) | [static]

Definition at line 634 of file image.C.

References endian_to_ushort(), PNG_Header::height, PNG_Header::signature, ushort, and PNG_Header::width.

Referenced by measure().

void measure | ( | const String & | file_name,
 |  | Measure_reader & | reader,
 |  | ushort & | width,
 |  | ushort & | height,
 |  | Value ** | exif
 | ) | [static]

Definition at line 656 of file image.C.

References String::cstr(), String::L_FILE_SPEC, measure_gif(), measure_jpeg(), measure_png(), and ushort.

Referenced by _measure(), and file_measure_action().

void file_measure_action | ( | struct stat & | ,
 |  | int | f,
 |  | const String & | ,
 |  | const char * | fname,
 |  | bool | ,
 |  | void * | context
 | ) | [static]

Definition at line 687 of file image.C.

References context, and measure().

Referenced by _measure().

void _measure | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 697 of file image.C.

References Request::absolute(), MethodParams::as_no_junction(), Value::as_string(), Value::as_vfile(), data, VFile::fields(), file_measure_action(), file_read_action_under_lock(), Hash< const String::Body, Value * >::get(), GET_SELF, Value::get_string(), measure(), ushort, VFile::value_ptr(), and VFile::value_size().

Referenced by MImage::MImage().

void append_attrib_pair | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | Attrib_info * | info
 | ) | [static]

Definition at line 732 of file image.C.

References value.

Referenced by _html().

void _html | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 745 of file image.C.

References append_attrib_pair(), Array< Value * >::count(), Hash< const String::Body, Value * >::for_each(), Value::get_hash(), GET_SELF, Value::is_string(), Request::process_to_value(), and Request::write_pass_lang().

Referenced by MImage::MImage().

gdImage* load | ( | Request & | r,
 |  | const String & | file_name
 | ) | [static]

Test:
wrap FILE to auto-object

Definition at line 776 of file image.C.

References Request::absolute(), gdImage::CreateFromGif(), String::cstr(), and String::L_FILE_SPEC.

Referenced by _font(), and _load().

void _load | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 796 of file image.C.

References MethodParams::as_string(), GET_SELF, load(), gdImage::SX(), and gdImage::SY().

Referenced by MImage::MImage().

void _create | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 803 of file image.C.

References MethodParams::as_int(), gdImage::Color(), Array< Value * >::count(), gdImage::Create(), gdImage::FilledRectangle(), and GET_SELF.

Referenced by MImage::MImage().

void _gif | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 815 of file image.C.

References MethodParams::as_string(), Array< Value * >::count(), String::cstr(), GET_SELF, gdImage::Gif(), String::L_FILE_SPEC, gdBuf::ptr, VFile::set(), gdBuf::size, and Request::write_no_lang().

Referenced by MImage::MImage().

void _line | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 834 of file image.C.

References MethodParams::as_int(), gdImage::Color(), GET_SELF, and gdImage::Line().

Referenced by MImage::MImage().

void _fill | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 845 of file image.C.

References MethodParams::as_int(), gdImage::Color(), gdImage::Fill(), and GET_SELF.

Referenced by MImage::MImage().

void _rectangle | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 854 of file image.C.

References MethodParams::as_int(), gdImage::Color(), GET_SELF, and gdImage::Rectangle().

Referenced by MImage::MImage().

void _bar | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 865 of file image.C.

References MethodParams::as_int(), gdImage::Color(), gdImage::FilledRectangle(), and GET_SELF.

Referenced by MImage::MImage().

void _replace | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 888 of file image.C.

References MethodParams::as_int(), MethodParams::as_no_junction(), gdImage::Color(), Array< ArrayString * >::count(), gdImage::FilledPolygonReplaceColor(), Array< ArrayString * >::for_each(), GET_SELF, and Value::get_table().

Referenced by MImage::MImage().

void _polyline | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 905 of file image.C.

References MethodParams::as_int(), MethodParams::as_no_junction(), gdImage::Color(), Array< ArrayString * >::count(), Array< ArrayString * >::for_each(), GET_SELF, Value::get_table(), and gdImage::Polygon().

Referenced by MImage::MImage().

void _polygon | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 922 of file image.C.

References MethodParams::as_int(), MethodParams::as_no_junction(), gdImage::Color(), Array< ArrayString * >::count(), Array< ArrayString * >::for_each(), GET_SELF, Value::get_table(), and gdImage::Polygon().

Referenced by MImage::MImage().

void _polybar | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 938 of file image.C.

References MethodParams::as_int(), MethodParams::as_no_junction(), gdImage::Color(), Array< ArrayString * >::count(), gdImage::FilledPolygon(), Array< ArrayString * >::for_each(), GET_SELF, and Value::get_table().

Referenced by MImage::MImage().

void _font | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1021 of file image.C.

References MethodParams::as_int(), MethodParams::as_string(), Array< Value * >::count(), GET_SELF, String::length(), load(), gdImage::SX(), and gdImage::SY().

Referenced by MImage::MImage().

void _text | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1050 of file image.C.

References MethodParams::as_int(), MethodParams::as_string(), VImage::font(), GET_SELF, VImage::image(), and Font::string_display().

Referenced by MImage::MImage().

void _length | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1059 of file image.C.

References MethodParams::as_string(), VImage::font(), GET_SELF, Font::string_width(), and Request::write_no_lang().

Referenced by MImage::MImage().

void _arc | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1066 of file image.C.

References gdImage::Arc(), MethodParams::as_int(), gdImage::Color(), and GET_SELF.

Referenced by MImage::MImage().

void _sector | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1079 of file image.C.

References MethodParams::as_int(), gdImage::Color(), GET_SELF, and gdImage::Sector().

Referenced by MImage::MImage().

void _circle | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1092 of file image.C.

References gdImage::Arc(), MethodParams::as_int(), gdImage::Color(), GET_SELF, and size.

Referenced by MImage::MImage().

gdImage& as_image | ( | MethodParams & | params,
 |  | int | index,
 |  | const char * | msg
 | ) |

Definition at line 1106 of file image.C.

References Value::as(), MethodParams::as_no_junction(), value, and VIMAGE_TYPE.

Referenced by _copy().

void _copy | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1117 of file image.C.

References as_image(), MethodParams::as_int(), gdImage::Copy(), gdImage::CopyResampled(), Array< Value * >::count(), and GET_SELF.

Referenced by MImage::MImage().

void _pixel | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1140 of file image.C.

References MethodParams::as_int(), gdImage::Color(), Array< Value * >::count(), gdImage::DecodeColor(), GET_SELF, gdImage::GetPixel(), gdImage::SetPixel(), and Request::write_no_lang().

Referenced by MImage::MImage().

Variable Documentation

const char* const IDENT_IMAGE_C = "$Date: 2005/08/09 08:14:48 $" [static]

Definition at line 8 of file image.C.

EXIF_tag_value2name exif_tag_value2name

value of exif tag -> it's value.

Referenced by parse_IFD_entry().


image.C Source File

image.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_IMAGE_C="$Date: 2005/08/09 08:14:48 $";
00009
00010 /*
00011     jpegsize: gets the width and height (in pixels) of a jpeg file
00012     Andrew Tong, werdna@ugcs.caltech.edu           February 14, 1995
00013     modified slightly by alex@ed.ac.uk
00014     and further still by rjray@uswest.com
00015     optimization and general re-write from tmetro@vl.com
00016     from perl by paf@design.ru
00017 */
00018
00019 #include "pa_config_includes.h"
00020
00021 #include "pa_vmethod_frame.h"
00022
00023 #include "gif.h"
00024
00025 #include "pa_common.h"
00026 #include "pa_request.h"
00027 #include "pa_vfile.h"
00028 #include "pa_vimage.h"
00029 #include "pa_vdate.h"
00030 #include "pa_table.h"
00031
00032 // class
00033
00034 class MImage: public Methoded {
00035 public: // VStateless_class
00036     Value* create_new_value(Pool&, HashStringValue&) { return new VImage(); }
00037
00038 public:
00039     MImage();
00040
00041 public: // Methoded
00042     bool used_directly() { return true; }
00043
00044 };
00045
00046 // globals
00047
00048 DECLARE_CLASS_VAR(image, new MImage, 0);
00049
00050 // helpers
00051
00053 class EXIF_tag_value2name: public Hash<int, const char*> {
00054 public:
00055     EXIF_tag_value2name() {
00056     // image JPEG Exif
00057         #define EXIF_TAG(tag, name) \
00058             put(tag, #name);
00059         // Tags used by IFD0 (main image)
00060         EXIF_TAG(0x010e,    ImageDescription);
00061         EXIF_TAG(0x010f,    Make);
00062         EXIF_TAG(0x0110,    Model);
00063         EXIF_TAG(0x0112,    Orientation);
00064         EXIF_TAG(0x011a,    XResolution);
00065         EXIF_TAG(0x011b,    YResolution);
00066         EXIF_TAG(0x0128,    ResolutionUnit);
00067         EXIF_TAG(0x0131,    Software);
00068         EXIF_TAG(0x0132,    DateTime);
00069         EXIF_TAG(0x013e,    WhitePoint);
00070         EXIF_TAG(0x013f,    PrimaryChromaticities);
00071         EXIF_TAG(0x0211,    YCbCrCoefficients);
00072         EXIF_TAG(0x0213,    YCbCrPositioning);
00073         EXIF_TAG(0x0214,    ReferenceBlackWhite);
00074         EXIF_TAG(0x8298,    Copyright);
00075         EXIF_TAG(0x8769,    ExifOffset);
00076         // Tags used by Exif SubIFD
00077         EXIF_TAG(0x829a,    ExposureTime);
00078         EXIF_TAG(0x829d,    FNumber);
00079         EXIF_TAG(0x8822,    ExposureProgram);
00080         EXIF_TAG(0x8827,    ISOSpeedRatings);
00081         EXIF_TAG(0x9000,    ExifVersion);
00082         EXIF_TAG(0x9003,    DateTimeOriginal);
00083         EXIF_TAG(0x9004,    DateTimeDigitized);
00084         EXIF_TAG(0x9101,    ComponentsConfiguration);
00085         EXIF_TAG(0x9102,    CompressedBitsPerPixel);
00086         EXIF_TAG(0x9201,    ShutterSpeedValue);
00087         EXIF_TAG(0x9202,    ApertureValue);
00088         EXIF_TAG(0x9203,    BrightnessValue);
00089         EXIF_TAG(0x9204,    ExposureBiasValue);
00090         EXIF_TAG(0x9205,    MaxApertureValue);
00091         EXIF_TAG(0x9206,    SubjectDistance);
00092         EXIF_TAG(0x9207,    MeteringMode);
00093         EXIF_TAG(0x9208,    LightSource);
00094         EXIF_TAG(0x9209,    Flash);
00095         EXIF_TAG(0x920a,    FocalLength);
00096         EXIF_TAG(0x927c,    MakerNote);
00097         EXIF_TAG(0x9286,    UserComment);
00098         EXIF_TAG(0x9290,    SubsecTime);
00099         EXIF_TAG(0x9291,    SubsecTimeOriginal);
00100         EXIF_TAG(0x9292,    SubsecTimeDigitized);
00101         EXIF_TAG(0xa000,    FlashPixVersion);
00102         EXIF_TAG(0xa001,    ColorSpace);
00103         EXIF_TAG(0xa002,    ExifImageWidth);
00104         EXIF_TAG(0xa003,    ExifImageHeight);
00105         EXIF_TAG(0xa004,    RelatedSoundFile);
00106         EXIF_TAG(0xa005,    ExifInteroperabilityOffset);
00107         EXIF_TAG(0xa20e,    FocalPlaneXResolution);
00108         EXIF_TAG(0xa20f,    FocalPlaneYResolution);
00109         EXIF_TAG(0xa210,    FocalPlaneResolutionUnit);
00110         EXIF_TAG(0xa215,    ExposureIndex);
00111         EXIF_TAG(0xa217,    SensingMethod);
00112         EXIF_TAG(0xa300,    FileSource);
00113         EXIF_TAG(0xa301,    SceneType);
00114         EXIF_TAG(0xa302,    CFAPattern);
00115         // Misc Tags
00116         EXIF_TAG(0x00fe,    NewSubfileType);
00117         EXIF_TAG(0x00ff,    SubfileType);
00118         EXIF_TAG(0x012d,    TransferFunction);
00119         EXIF_TAG(0x013b,    Artist);
00120         EXIF_TAG(0x013d,    Predictor);
00121         EXIF_TAG(0x0142,    TileWidth);
00122         EXIF_TAG(0x0143,    TileLength);
00123         EXIF_TAG(0x0144,    TileOffsets);
00124         EXIF_TAG(0x0145,    TileByteCounts);
00125         EXIF_TAG(0x014a,    SubIFDs);
00126         EXIF_TAG(0x015b,    JPEGTables);
00127         EXIF_TAG(0x828d,    CFARepeatPatternDim);
00128         EXIF_TAG(0x828e,    CFAPattern);
00129         EXIF_TAG(0x828f,    BatteryLevel);
00130         EXIF_TAG(0x83bb,    IPTC/NAA);
00131         EXIF_TAG(0x8773,    InterColorProfile);
00132         EXIF_TAG(0x8824,    SpectralSensitivity);
00133         EXIF_TAG(0x8825,    GPSInfo);
00134         EXIF_TAG(0x8828,    OECF);
00135         EXIF_TAG(0x8829,    Interlace);
00136         EXIF_TAG(0x882a,    TimeZoneOffset);
00137         EXIF_TAG(0x882b,    SelfTimerMode);
00138         EXIF_TAG(0x920b,    FlashEnergy);
00139         EXIF_TAG(0x920c,    SpatialFrequencyResponse);
00140         EXIF_TAG(0x920d,    Noise);
00141         EXIF_TAG(0x9211,    ImageNumber);
00142         EXIF_TAG(0x9212,    SecurityClassification);
00143         EXIF_TAG(0x9213,    ImageHistory);
00144         EXIF_TAG(0x9214,    SubjectLocation);
00145         EXIF_TAG(0x9215,    ExposureIndex);
00146         EXIF_TAG(0x9216,    TIFF/EPStandardID);
00147         EXIF_TAG(0xa20b,    FlashEnergy);
00148         EXIF_TAG(0xa20c,    SpatialFrequencyResponse);
00149         EXIF_TAG(0xa214,    SubjectLocation);
00150         #undef EXIF_TAG
00151     }
00152 } exif_tag_value2name;
00153
00154
00155 #ifndef DOXYGEN
00156 class Measure_reader {
00157 public:
00158     virtual size_t read(const char* &buf, size_t limit)=0;
00159     virtual void seek(long value, int whence)=0;
00160     virtual long tell()=0;
00161 };
00162
00163 class Measure_file_reader: public Measure_reader {
00164     const String& file_name; const char* fname;
00165     int f;
00166
00167 public:
00168     Measure_file_reader(int af, const String& afile_name, const char* afname):
00169         file_name(afile_name), fname(afname), f(af) {
00170     }
00171
00172     override size_t read(const char* &abuf, size_t limit) {
00173         if(limit==0)
00174             return 0;
00175
00176         char* lbuf=new(PointerFreeGC) char[limit];
00177         size_t read_size=(size_t)::read(f, lbuf, limit);  abuf=lbuf;
00178         if(ssize_t(read_size)<0 || read_size>limit)
00179             throw Exception(0,
00180                 &file_name,
00181                 "measure failed: actually read %u bytes count not in [0..%u] valid range",
00182             read_size, limit);
00183
00184         return read_size;
00185     }
00186
00187     override void seek(long value, int whence) {
00188         if(lseek(f, value, whence)<0)
00189             throw Exception("image.format",
00190                 &file_name,
00191                 "seek(value=%ld, whence=%d) failed: %s (%d), actual filename '%s'",
00192                     value, whence, strerror(errno), errno, fname);
00193     }
00194
00195     override long tell() { return lseek(f, 0, SEEK_CUR); }
00196
00197 };
00198
00199 class Measure_buf_reader: public Measure_reader {
00200
00201     const char* buf; size_t size;
00202     const String& file_name;
00203
00204     size_t offset;
00205
00206 public:
00207     Measure_buf_reader(const char* abuf, size_t asize, const String& afile_name):
00208         buf(abuf), size(asize), file_name(afile_name), offset(0) {
00209     }
00210
00211     override size_t read(const char* &abuf, size_t limit) {
00212         size_t to_read=min(limit, size-offset);
00213         abuf=buf+offset;
00214         offset+=to_read;
00215         return to_read;
00216     }
00217
00218     override void seek(long value, int whence) {
00219         size_t new_offset;
00220         switch(whence) {
00221         case SEEK_CUR: new_offset=offset+value; break;
00222         case SEEK_SET: new_offset=(size_t)value; break;
00223         default:
00224             throw Exception(0,
00225                 0,
00226                 "whence #%d not supported", 0, whence);
00227             break; // never
00228         }
00229
00230         if((ssize_t)new_offset<0 || new_offset>size)
00231             throw Exception("image.format",
00232                 &file_name,
00233                 "seek(value=%l, whence=%d) failed: out of buffer, new_offset>size (%l>%l) or new_offset<0",
00234                     value, whence, new_offset, size);
00235         offset=new_offset;
00236     }
00237
00238     override long tell() { return offset; }
00239
00240 };
00241
00242 #endif
00243
00245 struct PNG_Header {
00246     char dummy[12];
00247     char signature[4]; //< must be "IHDR"
00248     uchar high_width[2]; //< image width high bytes [we ignore for now]
00249     uchar width[2]; //< image width low bytes
00250     uchar high_height[2]; //< image height high bytes [we ignore for now]
00251     uchar height[4]; //< image height
00252 };
00253
00255 struct GIF_Header {
00256     char       signature[3];         // 'GIF'
00257     char       version[3];
00258     uchar       width[2];
00259     uchar       height[2];
00260     char       dif;
00261     char       fonColor;
00262     char       nulls;
00263 };
00264
00266 struct JPG_Segment_head {
00267     uchar marker;
00268     uchar code;
00269     uchar length[2];
00270 };
00272 struct JPG_Size_segment_body {
00273     char data;                    //< data precision of bits/sample
00274     uchar height[2];               //< image height
00275     uchar width[2];                //< image width
00276     char numComponents;           //< number of color components
00277 };
00278
00280 struct JPG_Exif_segment_begin {
00281     char signature[6]; // Exif\0\0
00282 };
00283
00285 struct JPG_Exif_TIFF_header {
00286     uchar byte_align_identifier[2];
00287     char dummy[2]; // always 000A [or 0A00]
00288     uchar first_IFD_offset[4]; // Usually the first IFD starts immediately next to TIFF header, so this offset has value '0x00000008'.
00289 };
00290
00291 // JPEG Exif IFD start
00292 struct JPG_Exif_IFD_begin {
00293     uchar directory_entry_count[2]; // the number of directory entry contains in this IFD
00294 };
00295
00296 // TTTT ffff NNNNNNNN DDDDDDDD
00297 struct JPG_Exif_IFD_entry {
00298     uchar tag[2]; // Tag number, this shows a kind of data
00299     uchar format[2]; // data format
00300     uchar components_count[4]; // number of components
00301     uchar value_or_offset_to_it[4]; // data value or offset to data value
00302 };
00303
00304 #define JPG_IFD_TAG_EXIF_OFFSET 0x8769
00305
00306 #define JPEG_EXIF_DATE_CHARS 20
00307
00308 //
00309
00310 inline ushort x_endian_to_ushort(uchar b0, uchar b1) {
00311     return (ushort)((b1<<8) + b0);
00312 }
00313
00314 inline uint x_endian_to_uint(uchar b0, uchar b1, uchar b2, uchar b3) {
00315     return (uint)(((((b3<<8) + b2)<<8)+b1)<<8)+b0;
00316 }
00317
00318 inline ushort endian_to_ushort(bool is_big, const uchar *b/* [2] */) {
00319     return is_big?x_endian_to_ushort(b[1], b[0]):
00320         x_endian_to_ushort(b[0], b[1]);
00321 }
00322
00323 inline uint endian_to_uint(bool is_big, const uchar *b /* [4] */) {
00324     return is_big?x_endian_to_uint(b[3], b[2], b[1], b[0]):
00325         x_endian_to_uint(b[0], b[1], b[2], b[3]);
00326 }
00327
00328 static void measure_gif(const String& origin_string,
00329              Measure_reader& reader, ushort& width, ushort& height) {
00330
00331     const char* buf;
00332     const size_t head_size=sizeof(GIF_Header);
00333     if(reader.read(buf, head_size)<head_size)
00334         throw Exception("image.format",
00335             &origin_string,
00336             "not GIF file - too small");
00337     GIF_Header *head=(GIF_Header *)buf;
00338
00339     if(strncmp(head->signature, "GIF", 3)!=0)
00340         throw Exception("image.format",
00341             &origin_string,
00342             "not GIF file - wrong signature");
00343
00344     width=endian_to_ushort(false, head->width);
00345     height=endian_to_ushort(false, head->height);
00346 }
00347
00348 static Value* parse_IFD_entry_formatted_one_value(
00349                                                   bool is_big,
00350                                                   ushort format,
00351                                                   size_t component_size,
00352                                                   const uchar *value) {
00353     switch(format) {
00354     case 1: // unsigned byte
00355         return new VInt((uchar)value[0]);
00356     case 3: // unsigned short
00357         return new VInt(endian_to_ushort(is_big, value));
00358     case 4: // unsigned long
00359          // 'double' because parser's Int is signed
00360         return new VDouble(endian_to_uint(is_big, value));
00361     case 5: // unsigned rational
00362         {
00363             uint numerator=endian_to_uint(is_big, value); value+=component_size/2;
00364             uint denominator=endian_to_uint(is_big, value);
00365             if(!denominator)
00366                 return 0;
00367             return new VDouble(((double)numerator)/denominator);
00368         }
00369     case 6: // signed byte
00370         return new VInt((signed char)value[0]);
00371     case 8: // signed short
00372         return new VInt((signed short)endian_to_ushort(is_big, value));
00373     case 9: // signed long
00374         return new VInt((signed int)endian_to_uint(is_big, value));
00375     case 10: // signed rational
00376         {
00377             signed int numerator=(signed int)endian_to_uint(is_big, value); value+=component_size/2;
00378             uint denominator=endian_to_uint(is_big, value);
00379             if(!denominator)
00380                 return 0;
00381             return new VDouble(numerator/denominator);
00382         }
00383         /*
00384     case 11: // single float
00385         todo
00386     case 12: // double float
00387         todo
00388         */
00389     };
00390
00391     return 0;
00392 }
00393
00394 // date.C
00395 tm cstr_to_time_t(char *cstr);
00396
00397 static Value* parse_IFD_entry_formatted_value(bool is_big, ushort format,
00398                           size_t component_size, uint components_count,
00399                           const uchar *value) {
00400     if(format==2) { // ascii string, exception: the only type with varying size
00401         const char* cstr=(const char* )value;
00402         size_t length=components_count;
00403         // Data format is "YYYY:MM:DD HH:MM:SS"+0x00, total 20bytes
00404         if(length==JPEG_EXIF_DATE_CHARS
00405             && isdigit((unsigned char)cstr[0])
00406             && cstr[length-1]==0) {
00407             char cstr_writable[JPEG_EXIF_DATE_CHARS];
00408             strcpy(cstr_writable, cstr);
00409
00410             try {
00411                 return new VDate(cstr_to_time_t(cstr_writable));
00412             }
00413             catch(...) { /*ignore bad date times*/ }
00414         }
00415
00416         if(const char* premature_zero_pos=(const char* )memchr(cstr, 0, length))
00417             length=premature_zero_pos-cstr;
00418         return new VString(*new String(cstr, length, true/*tainted*/));
00419     }
00420
00421     if(components_count==1)
00422         return parse_IFD_entry_formatted_one_value(is_big, format, component_size, value);
00423
00424     VHash* result=new VHash;
00425     HashStringValue& hash=result->hash();
00426     for(uint i=0; i<components_count; i++, value+=component_size) {
00427         hash.put(
00428             String::Body::Format(i),
00429             parse_IFD_entry_formatted_one_value(is_big, format, component_size, value));
00430     }
00431
00432     return result;
00433 }
00434
00435 static Value* parse_IFD_entry_value(
00436                                     bool is_big, Measure_reader& reader, long tiff_base,
00437                                     JPG_Exif_IFD_entry& entry) {
00438     size_t format2component_size[]={
00439         0, // undefined
00440         1, // unsigned byte
00441         1, // ascii string
00442         2, // unsigned short
00443         4, // unsigned long
00444         8, // unsigned rational
00445         1, // signed byte
00446         0, // undefined
00447         2, // signed short
00448         4, // signed long
00449         8, // signed rational
00450         /*
00451         4, // single float
00452         8, // double float
00453         */
00454     };
00455
00456     ushort format=endian_to_ushort(is_big, entry.format);
00457     if(format>=sizeof(format2component_size)/sizeof(format2component_size[0]))
00458         return 0; // format out of range, ignoring
00459
00460     size_t component_size=format2component_size[format];
00461     if(component_size==0)
00462         return 0; // undefined format
00463
00464     // You can get the total data byte length by multiplies
00465     // a 'bytes/components' value (see above chart) by number of components stored 'NNNNNNNN' area
00466     uint components_count=endian_to_uint(is_big, entry.components_count);
00467     size_t value_size=component_size*components_count;
00468     // If its size is over 4bytes, 'DDDDDDDD' contains the offset to data stored address
00469     Value* result;
00470
00471     if(value_size<=4)
00472         result=parse_IFD_entry_formatted_value(
00473             is_big, format,
00474             component_size, components_count,
00475             entry.value_or_offset_to_it);
00476     else {
00477         long remembered=reader.tell();
00478         {
00479             reader.seek(tiff_base+endian_to_uint(is_big, entry.value_or_offset_to_it), SEEK_SET);
00480             const char* value;
00481             if(reader.read(value, value_size)<sizeof(value_size))
00482                 return 0;
00483             result=parse_IFD_entry_formatted_value(
00484                 is_big, format,
00485                 component_size, components_count,
00486                 (const uchar*)value);
00487         }
00488         reader.seek(remembered, SEEK_SET);
00489     }
00490
00491     return result;
00492 }
00493
00494 static void parse_IFD(HashStringValue& hash,
00495               bool is_big, Measure_reader& reader, long tiff_base);
00496
00497 static void parse_IFD_entry(HashStringValue& hash,
00498                 bool is_big, Measure_reader& reader, long tiff_base,
00499                 JPG_Exif_IFD_entry& entry) {
00500     ushort tag=endian_to_ushort(is_big, entry.tag);
00501     if(tag==JPG_IFD_TAG_EXIF_OFFSET) {
00502         long remembered=reader.tell();
00503         {
00504             reader.seek(tiff_base+endian_to_uint(is_big, entry.value_or_offset_to_it), SEEK_SET);
00505             parse_IFD(hash, is_big, reader, tiff_base);
00506         }
00507         reader.seek(remembered, SEEK_SET);
00508         return;
00509     }
00510
00511     if(Value* value=parse_IFD_entry_value(is_big, reader, tiff_base, entry)) {
00512         if(const char* name=exif_tag_value2name.get(tag))
00513             hash.put(String::Body(name), value);
00514         else
00515             hash.put(String::Body::Format(tag), value);
00516     }
00517 }
00518
00519 static void parse_IFD(
00520               HashStringValue& hash,
00521               bool is_big, Measure_reader& reader, long tiff_base) {
00522     const char* buf;
00523     if(reader.read(buf, sizeof(JPG_Exif_IFD_begin))<sizeof(JPG_Exif_IFD_begin))
00524         return;
00525     JPG_Exif_IFD_begin *start=(JPG_Exif_IFD_begin *)buf;
00526
00527     ushort directory_entry_count=endian_to_ushort(is_big, start->directory_entry_count);
00528     for(int i=0; i<directory_entry_count; i++) {
00529         if(reader.read(buf, sizeof(JPG_Exif_IFD_entry))<sizeof(JPG_Exif_IFD_entry))
00530             return;
00531
00532         parse_IFD_entry(hash, is_big, reader, tiff_base, *(JPG_Exif_IFD_entry *)buf);
00533     }
00534     // then goes: LLLLLLLL Offset to next IFD [not going there]
00535 }
00536
00537 static Value* parse_exif(Measure_reader& reader, const String& origin_string) {
00538     const char* buf;
00539     if(reader.read(buf, sizeof(JPG_Exif_segment_begin))<sizeof(JPG_Exif_segment_begin))
00540         throw Exception("image.format",
00541             &origin_string,
00542             "not JPEG file - can not fully read Exif segment start");
00543
00544     JPG_Exif_segment_begin *start=(JPG_Exif_segment_begin *)buf;
00545     if(memcmp(start->signature, "Exif\0\0", 4+2)!=0) //signature invalid?
00546         return 0; // ignore invalid block
00547
00548     uint tiff_base=reader.tell();
00549     if(reader.read(buf, sizeof(JPG_Exif_TIFF_header))<sizeof(JPG_Exif_TIFF_header))
00550         return 0;
00551
00552     JPG_Exif_TIFF_header *head=(JPG_Exif_TIFF_header *)buf;
00553     bool is_big=head->byte_align_identifier[0]=='M'; // [M]otorola vs [I]ntel
00554
00555     uint first_IFD_offset=endian_to_uint(is_big, head->first_IFD_offset);
00556     reader.seek(tiff_base+first_IFD_offset, SEEK_SET);
00557
00558     VHash* vhash=new VHash;
00559
00560     // IFD
00561     parse_IFD(vhash->hash(), is_big, reader, tiff_base);
00562
00563     return vhash;
00564 }
00565
00566 static void measure_jpeg(const String& origin_string,
00567              Measure_reader& reader, ushort& width, ushort& height, Value** exif) {
00568     // JFIF format markers
00569     const uchar MARKER=0xFF;
00570     const uchar CODE_SIZE_A=0xC0;
00571     const uchar CODE_SIZE_B=0xC1;
00572     const uchar CODE_SIZE_C=0xC2;
00573     const uchar CODE_SIZE_D=0xC3;
00574     const uchar CODE_EXIF=0xE1;
00575
00576     const char* buf;
00577     const size_t prefix_size=2;
00578     if(reader.read(buf, prefix_size)<prefix_size)
00579         throw Exception("image.format",
00580             &origin_string,
00581             "not JPEG file - too small");
00582     uchar *signature=(uchar *)buf;
00583
00584     if(!(signature[0]==0xFF && signature[1]==0xD8))
00585         throw Exception("image.format",
00586             &origin_string,
00587             "not JPEG file - wrong signature");
00588
00589     while(true) {
00590         uint segment_base=reader.tell()+2/*marker,code*/;
00591         if(reader.read(buf, sizeof(JPG_Segment_head))<sizeof(JPG_Segment_head))
00592             break;
00593         JPG_Segment_head *head=(JPG_Segment_head *)buf;
00594
00595         // Verify that it's a valid segment.
00596         if(head->marker!=MARKER)
00597             throw Exception("image.format",
00598                 &origin_string,
00599                 "not JPEG file - marker not found");
00600
00601         switch(head->code) {
00602         // http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
00603         case CODE_EXIF:
00604             if(exif && !*exif) // seen .jpg with some xml under EXIF tag, after real exif block :)
00605                 *exif=parse_exif(reader, origin_string);
00606             break;
00607
00608         case CODE_SIZE_A:
00609         case CODE_SIZE_B:
00610         case CODE_SIZE_C:
00611         case CODE_SIZE_D:
00612             {
00613                 // Segments that contain size info
00614                 if(reader.read(buf, sizeof(JPG_Size_segment_body))<sizeof(JPG_Size_segment_body))
00615                     throw Exception("image.format",
00616                         &origin_string,
00617                         "not JPEG file - can not fully read Size segment");
00618                 JPG_Size_segment_body *body=(JPG_Size_segment_body *)buf;
00619
00620                 width=endian_to_ushort(true, body->width);
00621                 height=endian_to_ushort(true, body->height);
00622             }
00623             return;
00624         };
00625
00626         reader.seek(segment_base+endian_to_ushort(true, head->length), SEEK_SET);
00627     }
00628
00629     throw Exception("image.format",
00630         &origin_string,
00631         "broken JPEG file - size frame not found");
00632 }
00633
00634 static void measure_png(const String& origin_string,
00635              Measure_reader& reader, ushort& width, ushort& height) {
00636
00637     const char* buf;
00638     const size_t head_size=sizeof(PNG_Header);
00639     if(reader.read(buf, head_size)<head_size)
00640         throw Exception("image.format",
00641             &origin_string,
00642             "not PNG file - too small");
00643     PNG_Header *head=(PNG_Header *)buf;
00644
00645     if(strncmp(head->signature, "IHDR", 4)!=0)
00646         throw Exception("image.format",
00647             &origin_string,
00648             "not PNG file - wrong signature");
00649
00650     width=endian_to_ushort(true, head->width);
00651     height=endian_to_ushort(true, head->height);
00652 }
00653
00654 // measure center
00655
00656 static void measure(const String& file_name,
00657              Measure_reader& reader, ushort& width, ushort& height, Value** exif) {
00658     const char* file_name_cstr=file_name.cstr(String::L_FILE_SPEC);
00659     if(const char* cext=strrchr(file_name_cstr, '.')) {
00660         cext++;
00661         if(strcasecmp(cext, "GIF")==0)
00662             measure_gif(file_name, reader, width, height);
00663         else if(strcasecmp(cext, "JPG")==0 || strcasecmp(cext, "JPEG")==0)
00664             measure_jpeg(file_name, reader, width, height, exif);
00665         else if(strcasecmp(cext, "PNG")==0)
00666             measure_png(file_name, reader, width, height);
00667         else
00668             throw Exception("image.format",
00669                 &file_name,
00670                 "unhandled image file name extension '%s'", cext);
00671     } else
00672         throw Exception("image.format",
00673             &file_name,
00674             "can not determine image type - no file name extension");
00675 }
00676
00677 // methods
00678
00679 #ifndef DOXYGEN
00680 struct File_measure_action_info {
00681     ushort* width;
00682     ushort* height;
00683     Value** exif;
00684     const String* file_name;
00685 };
00686 #endif
00687 static void file_measure_action(
00688                                 struct stat& /*finfo*/, int f,
00689                                 const String& /*file_spec*/, const char* fname, bool /*as_text*/,
00690                                 void *context) {
00691     File_measure_action_info& info=*static_cast<File_measure_action_info *>(context);
00692
00693     Measure_file_reader reader(f, *info.file_name, fname);
00694     measure(*info.file_name, reader, *info.width, *info.height, info.exif);
00695 }
00696
00697 static void _measure(Request& r, MethodParams& params) {
00698     Value& data=params.as_no_junction(0, "data must not be code");
00699
00700     ushort width=0;
00701     ushort height=0;
00702     Value* exif=0;
00703     const String* file_name;
00704     if((file_name=data.get_string())) {
00705         File_measure_action_info info={
00706             &width, &height,
00707             &exif,
00708             file_name
00709         };
00710         file_read_action_under_lock(r.absolute(*file_name),
00711             "measure", file_measure_action, &info);
00712     } else {
00713         VFile* vfile=data.as_vfile();
00714         file_name=&vfile->fields().get(name_name)->as_string();
00715         Measure_buf_reader reader(
00716             vfile->value_ptr(),
00717             vfile->value_size(),
00718             *file_name
00719         );
00720         measure(*file_name, reader, width, height, &exif);
00721     }
00722
00723     GET_SELF(r, VImage).set(file_name, width, height, 0, exif);
00724 }
00725
00726 #ifndef DOXYGEN
00727 struct Attrib_info {
00728     String* tag;
00729     HashStringValue* skip;
00730 };
00731 #endif
00732 static void append_attrib_pair(
00733                    HashStringValue::key_type key,
00734                    HashStringValue::value_type value,
00735                    Attrib_info* info) {
00736     // skip user-specified and internal(starting with "line-") attributes
00737     if(info->skip && info->skip->get(key) || key.pos("line-")==0)
00738         return;
00739
00740     // src="a.gif" width=123 ismap[=-1]
00741     *info->tag << " " << key;
00742     if(value->is_string() || value->as_int()>=0)
00743         *info->tag << "=\"" << value->as_string() << "\"";
00744 }
00745 static void _html(Request& r, MethodParams& params) {
00746
00747     String tag;
00748     tag << "<img";
00749
00750     const HashStringValue& fields=GET_SELF(r, VImage).fields();
00751     HashStringValue* attribs=0;
00752
00753     if(params.count()) {
00754         // for backward compatibility: someday was ^html{}
00755         Value& vattribs=r.process_to_value(params[0],
00756             false/*don't intercept string*/);
00757         if(!vattribs.is_string()) // allow empty
00758             if((attribs=vattribs.get_hash())) {
00759                 Attrib_info info={&tag, 0};
00760                 attribs->for_each(append_attrib_pair, &info);
00761             } else
00762                 throw Exception("parser.runtime",
00763                     0,
00764                     "attributes must be hash");
00765     }
00766
00767     {
00768         Attrib_info info={&tag, attribs};
00769         fields.for_each(append_attrib_pair, &info);
00770     }
00771     tag << " />";
00772     r.write_pass_lang(tag);
00773 }
00774
00776 static gdImage* load(Request& r,
00777                      const String& file_name){
00778     const char* file_name_cstr=r.absolute(file_name).cstr(String::L_FILE_SPEC);
00779     if(FILE *f=fopen(file_name_cstr, "rb")) {
00780         gdImage* image=new gdImage;
00781         bool ok=image->CreateFromGif(f);
00782         fclose(f);
00783         if(!ok)
00784             throw Exception("image.format",
00785                 &file_name,
00786                 "is not in GIF format");
00787         return image;
00788     } else {
00789         throw Exception("file.missing",
00790             0,
00791             "can not open '%s'", file_name_cstr);
00792     }
00793 }
00794
00795
00796 static void _load(Request& r, MethodParams& params) {
00797     const String& file_name=params.as_string(0, "file name must not be code");
00798
00799     gdImage* image=load(r, file_name);
00800     GET_SELF(r, VImage).set(&file_name, image->SX(), image->SY(), image);
00801 }
00802
00803 static void _create(Request& r, MethodParams& params) {
00804     int width=params.as_int(0, "width must be int", r);
00805     int height=params.as_int(1, "height must be int", r);
00806     int bgcolor_value=0xffFFff;
00807     if(params.count()>2)
00808         bgcolor_value=params.as_int(2, "color must be int", r);
00809     gdImage* image=new gdImage;
00810     image->Create(width, height);
00811     image->FilledRectangle(0, 0, width-1, height-1, image->Color(bgcolor_value));
00812     GET_SELF(r, VImage).set(0, width, height, image);
00813 }
00814
00815 static void _gif(Request& r, MethodParams& params) {
00816     gdImage& image=GET_SELF(r, VImage).image();
00817
00818     const String *file_name=0;
00819     if(params.count()>0)
00820         file_name=&params.as_string(0, "file name must be string");
00821
00822     gdBuf buf=image.Gif();
00823
00824     VFile& vfile=*new VFile;
00825     Value* content_type=new VString(*new String("image/gif"));
00826     vfile.set(false/*not tainted*/,
00827         (const char*)buf.ptr, buf.size,
00828         file_name? file_name->cstr(String::L_FILE_SPEC): 0,
00829         content_type);
00830
00831     r.write_no_lang(vfile);
00832 }
00833
00834 static void _line(Request& r, MethodParams& params) {
00835     gdImage& image=GET_SELF(r, VImage).image();
00836
00837     image.Line(
00838         params.as_int(0, "x0 must be int", r),
00839         params.as_int(1, "y0 must be int", r),
00840         params.as_int(2, "x1 must be int", r),
00841         params.as_int(3, "y1 must be int", r),
00842         image.Color(params.as_int(4, "color must be int", r)));
00843 }
00844
00845 static void _fill(Request& r, MethodParams& params) {
00846     gdImage& image=GET_SELF(r, VImage).image();
00847
00848     image.Fill(
00849         params.as_int(0, "x must be int", r),
00850         params.as_int(1, "y must be int", r),
00851         image.Color(params.as_int(2, "color must be int", r)));
00852 }
00853
00854 static void _rectangle(Request& r, MethodParams& params) {
00855     gdImage& image=GET_SELF(r, VImage).image();
00856
00857     image.Rectangle(
00858         params.as_int(0, "x0 must be int", r),
00859         params.as_int(1, "y0 must be int", r),
00860         params.as_int(2, "x1 must be int", r),
00861         params.as_int(3, "y1 must be int", r),
00862         image.Color(params.as_int(4, "color must be int", r)));
00863 }
00864
00865 static void _bar(Request& r, MethodParams& params) {
00866     gdImage& image=GET_SELF(r, VImage).image();
00867
00868     image.FilledRectangle(
00869         params.as_int(0, "x0 must be int", r),
00870         params.as_int(1, "y0 must be int", r),
00871         params.as_int(2, "x1 must be int", r),
00872         params.as_int(3, "y1 must be int", r),
00873         image.Color(params.as_int(4, "color must be int", r)));
00874 }
00875
00876 #ifndef DOXYGEN
00877 static void add_point(Table::element_type row,
00878                       gdImage::Point **p) {
00879     if(row->count()!=2)
00880         throw Exception(0,
00881             0,
00882             "coordinates table must contain two columns: x and y values");
00883     (**p).x=row->get(0)->as_int();
00884     (**p).y=row->get(1)->as_int();
00885     (*p)++;
00886 }
00887 #endif
00888 static void _replace(Request& r, MethodParams& params) {
00889     gdImage& image=GET_SELF(r, VImage).image();
00890
00891     Table* table=params.as_no_junction(2, "coordinates must not be code").get_table();
00892     if(!table)
00893         throw Exception(0,
00894             0,
00895             "coordinates must be table");
00896
00897     gdImage::Point *all_p=new(PointerFreeGC) gdImage::Point[table->count()];
00898     gdImage::Point *add_p=all_p;
00899     table->for_each(add_point, &add_p);
00900     image.FilledPolygonReplaceColor(all_p, table->count(),
00901         image.Color(params.as_int(0, "src color must be int", r)),
00902         image.Color(params.as_int(1, "dest color must be int", r)));
00903 }
00904
00905 static void _polyline(Request& r, MethodParams& params) {
00906     gdImage& image=GET_SELF(r, VImage).image();
00907
00908     Table* table=params.as_no_junction(1, "coordinates must not be code").get_table();
00909     if(!table)
00910         throw Exception(0,
00911             0,
00912             "coordinates must be table");
00913
00914     gdImage::Point* all_p=new(PointerFreeGC) gdImage::Point[table->count()];
00915     gdImage::Point *add_p=all_p;
00916     table->for_each(add_point, &add_p);
00917     image.Polygon(all_p, table->count(),
00918         image.Color(params.as_int(0, "color must be int", r)),
00919         false/*not closed*/);
00920 }
00921
00922 static void _polygon(Request& r, MethodParams& params) {
00923     gdImage& image=GET_SELF(r, VImage).image();
00924
00925     Table* table=params.as_no_junction(1, "coordinates must not be code").get_table();
00926     if(!table)
00927         throw Exception(0,
00928             0,
00929             "coordinates must be table");
00930
00931     gdImage::Point* all_p=new(PointerFreeGC) gdImage::Point[table->count()];
00932     gdImage::Point *add_p=all_p;
00933     table->for_each(add_point, &add_p);
00934     image.Polygon(all_p, table->count(),
00935         image.Color(params.as_int(0, "color must be int", r)));
00936 }
00937
00938 static void _polybar(Request& r, MethodParams& params) {
00939     gdImage& image=GET_SELF(r, VImage).image();
00940
00941     Table* table=params.as_no_junction(1, "coordinates must not be code").get_table();
00942     if(!table)
00943         throw Exception("parser.runtime",
00944             0,
00945             "coordinates must be table");
00946
00947     gdImage::Point* all_p=new(PointerFreeGC) gdImage::Point[table->count()];
00948     gdImage::Point *add_p=all_p;
00949     table->for_each(add_point, &add_p);
00950     image.FilledPolygon(all_p, table->count(),
00951         image.Color(params.as_int(0, "color must be int", r)));
00952 }
00953
00954 // font
00955
00956 #define Y(y)(y+index*height)
00957
00958 // Font class
00959
00960 const int Font::letter_spacing=1;
00961
00962 Font::Font(//,
00963     const String& aalphabet,
00964     gdImage* aifont, int aheight, int amonospace, int aspacebarspace):
00965     height(aheight), monospace(amonospace),  spacebarspace(aspacebarspace),
00966     ifont(aifont),
00967     alphabet(aalphabet) {
00968 }
00969
00970 /* ******************************** char ********************************** */
00971
00972 size_t Font::index_of(char ch) {
00973     if(ch==' ') return STRING_NOT_FOUND;
00974     return alphabet.pos(ch);
00975 }
00976
00977 int Font::index_width(size_t index) {
00978     if(index==STRING_NOT_FOUND)
00979         return spacebarspace;
00980     int tr=ifont->GetTransparent();
00981     for(int x=ifont->SX()-1; x>=0; x--) {
00982         for(int y=0; y<height; y++)
00983             if(ifont->GetPixel(x, Y(y))!=tr)
00984                 return x+1;
00985     }
00986     return 0;
00987 }
00988
00989 void Font::index_display(gdImage& image, int x, int y, size_t index){
00990     if(index!=STRING_NOT_FOUND)
00991         ifont->Copy(image, x, y, 0, Y(0), index_width(index), height);
00992 }
00993
00994 /* ******************************** string ********************************** */
00995
00996 int Font::step_width(int index) {
00997     return letter_spacing + (monospace ? monospace : index_width(index));
00998 }
00999
01000 // counts trailing letter_spacing, consider this OK. useful for contiuations
01001 int Font::string_width(const String& s){
01002     const char* cstr=s.cstr();
01003     int result=0;
01004     for(const char* current=cstr; *current; current++)
01005         result+=step_width(index_of(*current));
01006     return result;
01007 }
01008
01009 void Font::string_display(gdImage& image, int x, int y, const String& s){
01010     const char* cstr=s.cstr();
01011     for(const char* current=cstr; *current; current++) {
01012         size_t index=index_of(*current);
01013         index_display(image, x, y, index);
01014         x+=step_width(index);
01015     }
01016 }
01017
01018 //
01019
01020
01021 static void _font(Request& r, MethodParams& params) {
01022     const String& alphabet=params.as_string(0, "alphabet must not be code");
01023     gdImage* image=load(r, params.as_string(1, "file_name must not be code"));
01024     int spacebar_width=params.as_int(2, "spacebar_width must be int", r);
01025     int monospace_width;
01026     if(params.count()>3) {
01027         monospace_width=params.as_int(3, "monospace_width must be int", r);
01028         if(!monospace_width)
01029             monospace_width=image->SX();
01030     } else
01031         monospace_width=0;
01032
01033     if(!alphabet.length())
01034         throw Exception("parser.runtime",
01035             0,
01036             "alphabet must not be empty");
01037
01038     if(int remainder=image->SY() % alphabet.length())
01039         throw Exception("parser.runtime",
01040             0,
01041             "font-file height(%d) not divisable by alphabet size(%d), remainder=%d",
01042                 image->SY(), alphabet.length(), remainder);
01043
01044     GET_SELF(r, VImage).set_font(new Font(
01045         alphabet,
01046         image,
01047         image->SY() / alphabet.length(), monospace_width, spacebar_width));
01048 }
01049
01050 static void _text(Request& r, MethodParams& params) {
01051     int x=params.as_int(0, "x must be int", r);
01052     int y=params.as_int(1, "y must be int", r);
01053     const String& s=params.as_string(2, "text must not be code");
01054
01055     VImage& vimage=GET_SELF(r, VImage);
01056     vimage.font().string_display(vimage.image(), x, y, s);
01057 }
01058
01059 static void _length(Request& r, MethodParams& params) {
01060     const String& s=params.as_string(0, "text must not be code");
01061
01062     VImage& vimage=GET_SELF(r, VImage);
01063     r.write_no_lang(*new VInt(vimage.font().string_width(s)));
01064 }
01065
01066 static void _arc(Request& r, MethodParams& params) {
01067     gdImage& image=GET_SELF(r, VImage).image();
01068
01069     image.Arc(
01070         params.as_int(0, "center_x must be int", r),
01071         params.as_int(1, "center_y must be int", r),
01072         params.as_int(2, "width must be int", r),
01073         params.as_int(3, "height must be int", r),
01074         params.as_int(4, "start degrees must be int", r),
01075         params.as_int(5, "end degrees must be int", r),
01076         image.Color(params.as_int(6, "cx must be int", r)));
01077 }
01078
01079 static void _sector(Request& r, MethodParams& params) {
01080     gdImage& image=GET_SELF(r, VImage).image();
01081
01082     image.Sector(
01083         params.as_int(0, "center_x must be int", r),
01084         params.as_int(1, "center_y must be int", r),
01085         params.as_int(2, "width must be int", r),
01086         params.as_int(3, "height must be int", r),
01087         params.as_int(4, "start degrees must be int", r),
01088         params.as_int(5, "end degrees must be int", r),
01089         image.Color(params.as_int(6, "color must be int", r)));
01090 }
01091
01092 static void _circle(Request& r, MethodParams& params) {
01093     gdImage& image=GET_SELF(r, VImage).image();
01094
01095     int size=params.as_int(2, "radius must be int", r)*2;
01096     image.Arc(
01097         params.as_int(0, "center_x must be int", r),
01098         params.as_int(1, "center_y must be int", r),
01099         size, //w
01100         size, //h
01101         0, //s
01102         360, //e
01103         image.Color(params.as_int(3, "color must be int", r)));
01104 }
01105
01106 gdImage& as_image(MethodParams& params, int index, const char* msg) {
01107     Value& value=params.as_no_junction(index, msg);
01108
01109     if(Value* vimage=value.as(VIMAGE_TYPE, false)) {
01110         return static_cast<VImage *>(vimage)->image();
01111     } else
01112         throw Exception("parser.runtime",
01113             0,
01114             msg);
01115 }
01116
01117 static void _copy(Request& r, MethodParams& params) {
01118     gdImage& dest=GET_SELF(r, VImage).image();
01119
01120     gdImage& src=as_image(params, 0, "src must be image");
01121
01122     int sx=params.as_int(1, "src_x must be int", r);
01123     int sy=params.as_int(2, "src_y must be int", r);
01124     int sw=params.as_int(3, "src_w must be int", r);
01125     int sh=params.as_int(4, "src_h must be int", r);
01126     int dx=params.as_int(5, "dest_x must be int", r);
01127     int dy=params.as_int(6, "dest_y must be int", r);
01128     if(params.count()>1+2+2+2) {
01129         int dw=params.as_int(1+2+2+2, "dest_w must be int", r);
01130         int dh=(int)(params.count()>1+2+2+2+1?
01131             params.as_int(1+2+2+2+1, "dest_h must be int", r):sh*(((double)dw)/((double)sw)));
01132         int tolerance=params.count()>1+2+2+2+2?
01133             params.as_int(1+2+2+2+2, "tolerance must be int", r):150;
01134
01135         src.CopyResampled(dest, dx, dy, sx, sy, dw, dh, sw, sh, tolerance);
01136     } else
01137         src.Copy(dest, dx, dy, sx, sy, sw, sh);
01138 }
01139
01140 static void _pixel(Request& r, MethodParams& params) {
01141     gdImage& image=GET_SELF(r, VImage).image();
01142
01143     int x=params.as_int(0, "x must be int", r);
01144     int y=params.as_int(1, "y must be int", r);
01145
01146     if(params.count()>2) {
01147         image.SetPixel(x, y,
01148             image.Color(params.as_int(2, "color must be int", r)));
01149     } else
01150         r.write_no_lang(*new VInt(image.DecodeColor(image.GetPixel(x, y))));
01151 }
01152
01153
01154 // constructor
01155
01156 MImage::MImage(): Methoded("image") {
01157     // ^image:measure[DATA]
01158     add_native_method("measure", Method::CT_DYNAMIC, _measure, 1, 1);
01159
01160     // ^image.html[]
01161     // ^image.html[hash]
01162     add_native_method("html", Method::CT_DYNAMIC, _html, 0, 1);
01163
01164     // ^image.load[background.gif]
01165     add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
01166
01167     // ^image.create[width;height] bgcolor=white
01168     // ^image.create[width;height;bgcolor]
01169     add_native_method("create", Method::CT_DYNAMIC, _create, 2, 3);
01170
01171     // ^image.gif[]
01172     add_native_method("gif", Method::CT_DYNAMIC, _gif, 0, 1);
01173
01174     // ^image.line(x0;y0;x1;y1;color)
01175     add_native_method("line", Method::CT_DYNAMIC, _line, 5, 5);
01176
01177     // ^image.fill(x;y;color)
01178     add_native_method("fill", Method::CT_DYNAMIC, _fill, 3, 3);
01179
01180     // ^image.rectangle(x0;y0;x1;y1;color)
01181     add_native_method("rectangle", Method::CT_DYNAMIC, _rectangle, 5, 5);
01182
01183     // ^image.bar(x0;y0;x1;y1;color)
01184     add_native_method("bar", Method::CT_DYNAMIC, _bar, 5, 5);
01185
01186     // ^image.replace(color-source;color-dest)[table x:y]
01187     add_native_method("replace", Method::CT_DYNAMIC, _replace, 3, 3);
01188
01189     // ^image.polyline(color)[table x:y]
01190     add_native_method("polyline", Method::CT_DYNAMIC, _polyline, 2, 2);
01191
01192     // ^image.polygon(color)[table x:y]
01193     add_native_method("polygon", Method::CT_DYNAMIC, _polygon, 2, 2);
01194
01195     // ^image.polybar(color)[table x:y]
01196     add_native_method("polybar", Method::CT_DYNAMIC, _polybar, 2, 2);
01197
01198     // ^image.font[alPHAbet;font-file-name.gif](spacebar_width)
01199     // ^image.font[alPHAbet;font-file-name.gif](spacebar_width;width)
01200     add_native_method("font", Method::CT_DYNAMIC, _font, 3, 4);
01201
01202     // ^image.text(x;y)[text]
01203     add_native_method("text", Method::CT_DYNAMIC, _text, 3, 3);
01204
01205     // ^image.ngth[text]
01206     add_native_method("length", Method::CT_DYNAMIC, _length, 1, 1);
01207
01208     // ^image.arc(center x;center y;width;height;start in degrees;end in degrees;color)
01209     add_native_method("arc", Method::CT_DYNAMIC, _arc, 7, 7);
01210
01211     // ^image.sector(center x;center y;width;height;start in degrees;end in degrees;color)
01212     add_native_method("sector", Method::CT_DYNAMIC, _sector, 7, 7);
01213
01214     // ^image.circle(center x;center y;r;color)
01215     add_native_method("circle", Method::CT_DYNAMIC, _circle, 4, 4);
01216
01217     // ^image.copy[source](src x;src y;src w;src h;dst x;dst y[;dest w[;dest h[;tolerance]]])
01218     add_native_method("copy", Method::CT_DYNAMIC, _copy, 1+2+2+2, (1+2+2+2)+2+1);
01219
01220     // ^image.pixel(x;y)[(color)]
01221     add_native_method("pixel", Method::CT_DYNAMIC, _pixel, 2, 3);
01222 }


index.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


int.C File Reference

Parser: int parser class. More...

Include dependency graph for int.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MInt

Typedefs

typedef void(* | vint_op_func_ptr )(VInt &vint, double param)

Functions

void | _string_format (Request &r, MethodParams &)
DECLARE_CLASS_VAR (int, new MInt, 0)
void | _int (Request &r, MethodParams &params)
void | _double (Request &r, MethodParams &params)
void | __inc (VInt &vint, double param)
void | __dec (VInt &vint, double param)
void | __mul (VInt &vint, double param)
void | __div (VInt &vint, double param)
void | __mod (VInt &vint, double param)
void | vint_op (Request &r, MethodParams &params, vint_op_func_ptr func)
void | _inc (Request &r, MethodParams &params)
void | _dec (Request &r, MethodParams &params)
void | _mul (Request &r, MethodParams &params)
void | _div (Request &r, MethodParams &params)
void | _mod (Request &r, MethodParams &params)
const String * | sql_result_string (Request &r, MethodParams &params, HashStringValue *&options, Value *&default_code)
void | _sql (Request &r, MethodParams &params)

Variables

const char *const | IDENT_INT_C = "$Date: 2005/08/26 11:12:45 $"

Detailed Description

Parser: int parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file int.C.

Typedef Documentation

typedef void(* vint_op_func_ptr)(VInt& vint, double param)

Definition at line 54 of file int.C.

Referenced by vint_op().

Function Documentation

void _string_format | ( | Request & | r,
 |  | MethodParams & |
 | ) |

Definition at line 91 of file string.C.

References Value::as_double(), String::cstrm(), format(), Request::get_self(), Request::process_to_string(), and Request::write_no_lang().

DECLARE_CLASS_VAR | ( | int | ,
 |  | new | MInt,
 |  | 0 |
 | ) |

void _int | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 36 of file int.C.

References MethodParams::as_int(), Array< Value * >::count(), VInt::get_int(), GET_SELF, and Request::write_no_lang().

Referenced by MInt::MInt().

void _double | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 45 of file int.C.

References VInt::as_double(), MethodParams::as_double(), Array< Value * >::count(), GET_SELF, and Request::write_no_lang().

Referenced by MInt::MInt().

void __inc | ( | VInt & | vint,
 |  | double | param
 | ) | [static]

Definition at line 56 of file int.C.

References VInt::inc().

Referenced by _inc().

void __dec | ( | VInt & | vint,
 |  | double | param
 | ) | [static]

Definition at line 57 of file int.C.

References VInt::inc().

Referenced by _dec().

void __mul | ( | VInt & | vint,
 |  | double | param
 | ) | [static]

Definition at line 58 of file int.C.

References VInt::mul().

Referenced by _mul().

void __div | ( | VInt & | vint,
 |  | double | param
 | ) | [static]

Definition at line 59 of file int.C.

References VInt::div().

Referenced by _div().

void __mod | ( | VInt & | vint,
 |  | double | param
 | ) | [static]

Definition at line 60 of file int.C.

References VInt::mod().

Referenced by _mod().

void vint_op | ( | Request & | r,
 |  | MethodParams & | params,
 |  | vint_op_func_ptr | func
 | ) | [static]

Definition at line 62 of file int.C.

References MethodParams::as_double(), Array< Value * >::count(), func, GET_SELF, and vint_op_func_ptr.

Referenced by _dec(), _div(), _inc(), _mod(), and _mul().

void _inc | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 69 of file int.C.

References __inc(), and vint_op().

Referenced by MInt::MInt().

void _dec | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 70 of file int.C.

References __dec(), and vint_op().

Referenced by MInt::MInt().

void _mul | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 71 of file int.C.

References __mul(), and vint_op().

Referenced by MInt::MInt().

void _div | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 72 of file int.C.

References __div(), and vint_op().

Referenced by MInt::MInt().

void _mod | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 73 of file int.C.

References __mod(), and vint_op().

Referenced by MInt::MInt().

const String* sql_result_string | ( | Request & | r,
 |  | MethodParams & | params,
 |  | HashStringValue *& | options,
 |  | Value *& | default_code
 | ) |

Definition at line 422 of file string.C.

References Value::as_double(), MethodParams::as_junction(), MethodParams::as_no_junction(), Request::connection(), Array< Value * >::count(), Hash< const String::Body, Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::is_defined(), Value::is_string(), String::L_SQL, String::L_UNSPECIFIED, marshal_binds(), offset, Request::process_to_string(), Request::process_to_value(), SQL_Connection::query(), uint, ulong, and unmarshal_bind_updates().

Referenced by _sql().

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 79 of file int.C.

References Value::as_int(), String::as_int(), Request::process_to_value(), sql_result_string(), val, and Request::write_no_lang().

Referenced by MInt::MInt().

Variable Documentation

const char* const IDENT_INT_C = "$Date: 2005/08/26 11:12:45 $" [static]

Definition at line 8 of file int.C.


int.C Source File

int.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_INT_C="$Date: 2005/08/26 11:12:45 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vdouble.h"
00015 #include "pa_vint.h"
00016
00017 // externs
00018
00019 void _string_format(Request& r, MethodParams&);
00020
00021 // class
00022
00023 class MInt: public Methoded {
00024 public:
00025     MInt();
00026 public: // Methoded
00027     bool used_directly() { return true; }
00028 };
00029
00030 // global variable
00031
00032 DECLARE_CLASS_VAR(int, new MInt, 0);
00033
00034 // methods
00035
00036 static void _int(Request& r, MethodParams& params) {
00037     // just checking (default) syntax validity, never really using it  here, just for string.int compatibility
00038     if(params.count()>0)
00039         params.as_int(0, "default must be int", r);
00040
00041     VInt& vint=GET_SELF(r, VInt);
00042     r.write_no_lang(*new VInt(vint.get_int()));
00043 }
00044
00045 static void _double(Request& r, MethodParams& params) {
00046     // just checking (default) syntax validity, never really using it  here, just for string.doube compatibility
00047     if(params.count()>0)
00048         params.as_double(0, "default must be double", r);
00049
00050     VInt& vint=GET_SELF(r, VInt);
00051     r.write_no_lang(*new VDouble(vint.as_double()));
00052 }
00053
00054 typedef void (*vint_op_func_ptr)(VInt& vint, double param);
00055
00056 static void __inc(VInt& vint, double param) { vint.inc((int)param); }
00057 static void __dec(VInt& vint, double param) { vint.inc((int)-param); }
00058 static void __mul(VInt& vint, double param) { vint.mul(param); }
00059 static void __div(VInt& vint, double param) { vint.div(param); }
00060 static void __mod(VInt& vint, double param) { vint.mod((int)param); }
00061
00062 static void vint_op(Request& r, MethodParams& params,
00063                      vint_op_func_ptr func) {
00064     VInt& vint=GET_SELF(r, VInt);
00065     double param=params.count()?params.as_double(0, "param must be numerical", r):1;
00066     (*func)(vint, param);
00067 }
00068
00069 static void _inc(Request& r, MethodParams& params) { vint_op(r, params, &__inc); }
00070 static void _dec(Request& r, MethodParams& params) { vint_op(r, params, &__dec); }
00071 static void _mul(Request& r, MethodParams& params) { vint_op(r, params, &__mul); }
00072 static void _div(Request& r, MethodParams& params) { vint_op(r, params, &__div); }
00073 static void _mod(Request& r, MethodParams& params) { vint_op(r, params, &__mod); }
00074
00075 // from string.C
00076 extern
00077 const String* sql_result_string(Request& r, MethodParams& params,
00078                 HashStringValue*& options, Value*& default_code);
00079 static void _sql(Request& r, MethodParams& params) {
00080     int val;
00081     HashStringValue* options;
00082     Value* default_code=0;
00083     if(const String* string=sql_result_string(r, params, options, default_code))
00084         val=string->as_int();
00085     else
00086         if(default_code)
00087             val=r.process_to_value(*default_code).as_int();
00088         else {
00089             throw Exception("parser.runtime",
00090                 0,
00091                 "produced no result, but no default option specified");
00092         }
00093     r.write_no_lang(*new VInt(val));
00094 }
00095
00096 // constructor
00097
00098 MInt::MInt(): Methoded("int") {
00099     // ^int.int[]
00100     add_native_method("int", Method::CT_DYNAMIC, _int, 0, 1);
00101
00102     // ^int.double[]
00103     add_native_method("double", Method::CT_DYNAMIC, _double, 0, 1);
00104
00105     // ^int.inc[]
00106     // ^int.inc[offset]
00107     add_native_method("inc", Method::CT_DYNAMIC, _inc, 0, 1);
00108     // ^int.dec[]
00109     // ^int.dec[offset]
00110     add_native_method("dec", Method::CT_DYNAMIC, _dec, 0, 1);
00111     // ^int.mul[k]
00112     add_native_method("mul", Method::CT_DYNAMIC, _mul, 1, 1);
00113     // ^int.div[d]
00114     add_native_method("div", Method::CT_DYNAMIC, _div, 1, 1);
00115     // ^int.mod[offset]
00116     add_native_method("mod", Method::CT_DYNAMIC, _mod, 1, 1);
00117
00118
00119     // ^int.format{format}
00120     add_native_method("format", Method::CT_DYNAMIC, _string_format, 1, 1);
00121
00122     // ^sql[query]
00123     // ^sql[query][$.limit(1) $.offset(2) $.default(0)]
00124     add_native_method("sql", Method::CT_STATIC, _sql, 1, 2);
00125 }


internal.h File Reference

Include dependency graph for internal.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | real_pcre
struct | real_pcre_extra
struct | compile_data
struct | match_data

Defines

#define | PCRE_MAX_POS (10*0x400*0x400)
#define | offsetof(p_type, field) ((size_t)&(((p_type *)0)->field))
#define | PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
#define | PCRE_FIRSTSET 0x40000000
#define | PCRE_REQCHSET 0x20000000
#define | PCRE_STARTLINE 0x10000000
#define | PCRE_INGROUP 0x08000000
#define | PCRE_ICHANGED 0x04000000
#define | PCRE_STUDY_MAPPED 0x01
#define | PUBLIC_OPTIONS
#define | PUBLIC_EXEC_OPTIONS (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY)
#define | PUBLIC_STUDY_OPTIONS 0
#define | MAGIC_NUMBER 0x50435245UL
#define | FALSE 0
#define | TRUE 1
#define | EXTRACT_MAX 99
#define | ERR1 "\\ at end of pattern"
#define | ERR2 "\\c at end of pattern"
#define | ERR3 "unrecognized character follows \\"
#define | ERR4 "numbers out of order in {} quantifier"
#define | ERR5 "number too big in {} quantifier"
#define | ERR6 "missing terminating ] for character class"
#define | ERR7 "invalid escape sequence in character class"
#define | ERR8 "range out of order in character class"
#define | ERR9 "nothing to repeat"
#define | ERR10 "operand of unlimited repeat could match the empty string"
#define | ERR11 "internal error: unexpected repeat"
#define | ERR12 "unrecognized character after (?"
#define | ERR13 "too many capturing parenthesized sub-patterns"
#define | ERR14 "missing )"
#define | ERR15 "back reference to non-existent subpattern"
#define | ERR16 "erroffset passed as NULL"
#define | ERR17 "unknown option bit(s) set"
#define | ERR18 "missing ) after comment"
#define | ERR19 "too many sets of parentheses"
#define | ERR20 "regular expression too large"
#define | ERR21 "failed to get memory"
#define | ERR22 "unmatched parentheses"
#define | ERR23 "internal error: code overflow"
#define | ERR24 "unrecognized character after (?<"
#define | ERR25 "lookbehind assertion is not fixed length"
#define | ERR26 "malformed number after (?("
#define | ERR27 "conditional group contains more than two branches"
#define | ERR28 "assertion expected after (?("
#define | ctype_space 0x01
#define | ctype_letter 0x02
#define | ctype_digit 0x04
#define | ctype_xdigit 0x08
#define | ctype_word 0x10
#define | ctype_meta 0x80
#define | cbit_digit 0
#define | cbit_word 32
#define | cbit_space 64
#define | cbit_length 96
#define | lcc_offset 0
#define | fcc_offset 256
#define | cbits_offset 512
#define | ctypes_offset (cbits_offset + cbit_length)
#define | tables_length (ctypes_offset + 256)

Typedefs

typedef int | BOOL
typedef unsigned char | uschar
typedef real_pcre | real_pcre
typedef real_pcre_extra | real_pcre_extra
typedef compile_data | compile_data
typedef match_data | match_data

Enumerations

enum {
ESC_A = 1, ESC_B, ESC_b, ESC_D,
ESC_d, ESC_S, ESC_s, ESC_W,
ESC_w, ESC_Z, ESC_z, ESC_REF
}
enum {
OP_END, OP_SOD, OP_NOT_WORD_BOUNDARY, OP_WORD_BOUNDARY,
OP_NOT_DIGIT, OP_DIGIT, OP_NOT_WHITESPACE, OP_WHITESPACE,
OP_NOT_WORDCHAR, OP_WORDCHAR, OP_EODN, OP_EOD,
OP_OPT, OP_CIRC, OP_DOLL, OP_ANY,
OP_CHARS, OP_NOT, OP_STAR, OP_MINSTAR,
OP_PLUS, OP_MINPLUS, OP_QUERY, OP_MINQUERY,
OP_UPTO, OP_MINUPTO, OP_EXACT, OP_NOTSTAR,
OP_NOTMINSTAR, OP_NOTPLUS, OP_NOTMINPLUS, OP_NOTQUERY,
OP_NOTMINQUERY, OP_NOTUPTO, OP_NOTMINUPTO, OP_NOTEXACT,
OP_TYPESTAR, OP_TYPEMINSTAR, OP_TYPEPLUS, OP_TYPEMINPLUS,
OP_TYPEQUERY, OP_TYPEMINQUERY, OP_TYPEUPTO, OP_TYPEMINUPTO,
OP_TYPEEXACT, OP_CRSTAR, OP_CRMINSTAR, OP_CRPLUS,
OP_CRMINPLUS, OP_CRQUERY, OP_CRMINQUERY, OP_CRRANGE,
OP_CRMINRANGE, OP_CLASS, OP_REF, OP_ALT,
OP_KET, OP_KETRMAX, OP_KETRMIN, OP_ASSERT,
OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_REVERSE,
OP_ONCE, OP_COND, OP_CREF, OP_BRAZERO,
OP_BRAMINZERO, OP_BRA
}

Define Documentation

#define PCRE_MAX_POS (10*0x400*0x400)

Definition at line 54 of file internal.h.

Referenced by compile_regex(), and match().

#define offsetof | ( | p_type,
 |  | field | ) | ((size_t)&(((p_type *)0)->field))

Definition at line 66 of file internal.h.

Referenced by pcre_compile().

#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)

Definition at line 71 of file internal.h.

Referenced by compile_branch(), compile_regex(), match(), and pcre_compile().

#define PCRE_FIRSTSET 0x40000000

Definition at line 79 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), pcre_info(), and pcre_study().

#define PCRE_REQCHSET 0x20000000

Definition at line 80 of file internal.h.

Referenced by pcre_compile(), and pcre_exec().

#define PCRE_STARTLINE 0x10000000

Definition at line 81 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), pcre_info(), and pcre_study().

#define PCRE_INGROUP 0x08000000

Definition at line 82 of file internal.h.

Referenced by compile_branch().

#define PCRE_ICHANGED 0x04000000

Definition at line 83 of file internal.h.

Referenced by pcre_compile(), and pcre_exec().

#define PCRE_STUDY_MAPPED 0x01

Definition at line 87 of file internal.h.

Referenced by pcre_exec(), and pcre_study().

#define PUBLIC_OPTIONS

Value:

(PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
   PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY)

Definition at line 92 of file internal.h.

Referenced by pcre_compile(), and pcre_info().

#define PUBLIC_EXEC_OPTIONS (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY)

Definition at line 96 of file internal.h.

Referenced by pcre_exec().

#define PUBLIC_STUDY_OPTIONS 0

Definition at line 99 of file internal.h.

Referenced by pcre_study().

#define MAGIC_NUMBER 0x50435245UL

Definition at line 103 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), pcre_info(), and pcre_study().

#define FALSE 0

Definition at line 110 of file internal.h.

#define TRUE 1

Definition at line 113 of file internal.h.

#define EXTRACT_MAX 99

Definition at line 228 of file internal.h.

Referenced by compile_branch().

#define ERR1 "\\ at end of pattern"

Definition at line 235 of file internal.h.

Referenced by check_escape().

#define ERR2 "\\c at end of pattern"

Definition at line 236 of file internal.h.

Referenced by check_escape().

#define ERR3 "unrecognized character follows \\"

Definition at line 237 of file internal.h.

Referenced by check_escape().

#define ERR4 "numbers out of order in {} quantifier"

Definition at line 238 of file internal.h.

Referenced by read_repeat_counts().

#define ERR5 "number too big in {} quantifier"

Definition at line 239 of file internal.h.

Referenced by read_repeat_counts().

#define ERR6 "missing terminating ] for character class"

Definition at line 240 of file internal.h.

Referenced by compile_branch().

#define ERR7 "invalid escape sequence in character class"

Definition at line 241 of file internal.h.

Referenced by compile_branch().

#define ERR8 "range out of order in character class"

Definition at line 242 of file internal.h.

Referenced by compile_branch().

#define ERR9 "nothing to repeat"

Definition at line 243 of file internal.h.

Referenced by compile_branch().

#define ERR10 "operand of unlimited repeat could match the empty string"

Definition at line 244 of file internal.h.

#define ERR11 "internal error: unexpected repeat"

Definition at line 245 of file internal.h.

Referenced by compile_branch().

#define ERR12 "unrecognized character after (?"

Definition at line 246 of file internal.h.

Referenced by compile_branch(), and pcre_compile().

#define ERR13 "too many capturing parenthesized sub-patterns"

Definition at line 247 of file internal.h.

Referenced by compile_branch().

#define ERR14 "missing )"

Definition at line 248 of file internal.h.

Referenced by compile_branch().

#define ERR15 "back reference to non-existent subpattern"

Definition at line 249 of file internal.h.

Referenced by pcre_compile().

#define ERR16 "erroffset passed as NULL"

Definition at line 250 of file internal.h.

Referenced by pcre_compile().

#define ERR17 "unknown option bit(s) set"

Definition at line 251 of file internal.h.

Referenced by pcre_compile().

#define ERR18 "missing ) after comment"

Definition at line 252 of file internal.h.

Referenced by pcre_compile().

#define ERR19 "too many sets of parentheses"

Definition at line 253 of file internal.h.

Referenced by pcre_compile().

#define ERR20 "regular expression too large"

Definition at line 254 of file internal.h.

Referenced by pcre_compile().

#define ERR21 "failed to get memory"

Definition at line 255 of file internal.h.

Referenced by pcre_compile().

#define ERR22 "unmatched parentheses"

Definition at line 256 of file internal.h.

Referenced by pcre_compile().

#define ERR23 "internal error: code overflow"

Definition at line 257 of file internal.h.

Referenced by pcre_compile().

#define ERR24 "unrecognized character after (?<"

Definition at line 258 of file internal.h.

Referenced by compile_branch(), and pcre_compile().

#define ERR25 "lookbehind assertion is not fixed length"

Definition at line 259 of file internal.h.

Referenced by compile_regex().

#define ERR26 "malformed number after (?("

Definition at line 260 of file internal.h.

Referenced by pcre_compile().

#define ERR27 "conditional group contains more than two branches"

Definition at line 261 of file internal.h.

Referenced by compile_branch().

#define ERR28 "assertion expected after (?("

Definition at line 262 of file internal.h.

Referenced by pcre_compile().

#define ctype_space 0x01

Definition at line 329 of file internal.h.

Referenced by compile_branch(), main(), match(), pcre_compile(), and pcre_maketables().

#define ctype_letter 0x02

Definition at line 330 of file internal.h.

Referenced by main(), pcre_maketables(), and set_bit().

#define ctype_digit 0x04

Definition at line 331 of file internal.h.

Referenced by check_escape(), compile_branch(), is_counted_repeat(), main(), match(), pcre_compile(), pcre_maketables(), and read_repeat_counts().

#define ctype_xdigit 0x08

Definition at line 332 of file internal.h.

Referenced by check_escape(), main(), and pcre_maketables().

#define ctype_word 0x10

Definition at line 333 of file internal.h.

Referenced by main(), match(), and pcre_maketables().

#define ctype_meta 0x80

Definition at line 334 of file internal.h.

Referenced by compile_branch(), main(), pcre_compile(), and pcre_maketables().

#define cbit_digit 0

Definition at line 339 of file internal.h.

Referenced by compile_branch(), pcre_maketables(), and set_start_bits().

#define cbit_word 32

Definition at line 340 of file internal.h.

Referenced by compile_branch(), pcre_maketables(), and set_start_bits().

#define cbit_space 64

Definition at line 341 of file internal.h.

Referenced by compile_branch(), pcre_maketables(), and set_start_bits().

#define cbit_length 96

Definition at line 342 of file internal.h.

Referenced by main(), and pcre_maketables().

#define lcc_offset 0

Definition at line 347 of file internal.h.

Referenced by String::change_case(), main(), pcre_compile(), pcre_exec(), and pcre_study().

#define fcc_offset 256

Definition at line 348 of file internal.h.

Referenced by String::change_case(), pcre_compile(), pcre_exec(), and pcre_study().

#define cbits_offset 512

Definition at line 349 of file internal.h.

Referenced by pcre_compile(), and pcre_study().

#define ctypes_offset (cbits_offset + cbit_length)

Definition at line 350 of file internal.h.

Referenced by main(), pcre_compile(), pcre_exec(), and pcre_study().

#define tables_length (ctypes_offset + 256)

Definition at line 351 of file internal.h.

Referenced by pcre_maketables().

Typedef Documentation

typedef int BOOL

Definition at line 107 of file internal.h.

Referenced by check_escape(), compile_branch(), compile_regex(), CreateHiddenConsoleProcess(), DllMain(), first_significant_code(), GetExtensionVersion(), match(), pcre_exec(), set_bit(), set_start_bits(), and TerminateExtension().

typedef unsigned char uschar

Definition at line 271 of file internal.h.

Referenced by check_escape(), compile_branch(), compile_regex(), find_firstchar(), find_fixedlength(), first_significant_code(), is_anchored(), is_counted_repeat(), is_startline(), match(), match_ref(), pcre_compile(), pcre_exec(), pcre_study(), read_repeat_counts(), set_bit(), and set_start_bits().

typedef struct real_pcre real_pcre

typedef struct real_pcre_extra real_pcre_extra

typedef struct compile_data compile_data

typedef struct match_data match_data

Enumeration Type Documentation

anonymous enum

Enumeration values:
ESC_A
ESC_B
ESC_b
ESC_D
ESC_d
ESC_S
ESC_s
ESC_W
ESC_w
ESC_Z
ESC_z
ESC_REF

Definition at line 125 of file internal.h.

anonymous enum

Enumeration values:
OP_END
OP_SOD
OP_NOT_WORD_BOUNDARY
OP_WORD_BOUNDARY
OP_NOT_DIGIT
OP_DIGIT
OP_NOT_WHITESPACE
OP_WHITESPACE
OP_NOT_WORDCHAR
OP_WORDCHAR
OP_EODN
OP_EOD
OP_OPT
OP_CIRC
OP_DOLL
OP_ANY
OP_CHARS
OP_NOT
OP_STAR
OP_MINSTAR
OP_PLUS
OP_MINPLUS
OP_QUERY
OP_MINQUERY
OP_UPTO
OP_MINUPTO
OP_EXACT
OP_NOTSTAR
OP_NOTMINSTAR
OP_NOTPLUS
OP_NOTMINPLUS
OP_NOTQUERY
OP_NOTMINQUERY
OP_NOTUPTO
OP_NOTMINUPTO
OP_NOTEXACT
OP_TYPESTAR
OP_TYPEMINSTAR
OP_TYPEPLUS
OP_TYPEMINPLUS
OP_TYPEQUERY
OP_TYPEMINQUERY
OP_TYPEUPTO
OP_TYPEMINUPTO
OP_TYPEEXACT
OP_CRSTAR
OP_CRMINSTAR
OP_CRPLUS
OP_CRMINPLUS
OP_CRQUERY
OP_CRMINQUERY
OP_CRRANGE
OP_CRMINRANGE
OP_CLASS
OP_REF
OP_ALT
OP_KET
OP_KETRMAX
OP_KETRMIN
OP_ASSERT
OP_ASSERT_NOT
OP_ASSERTBACK
OP_ASSERTBACK_NOT
OP_REVERSE
OP_ONCE
OP_COND
OP_CREF
OP_BRAZERO
OP_BRAMINZERO
OP_BRA

Definition at line 132 of file internal.h.


internal.h Source File

internal.h

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005
00006 /* This is a library of functions to support regular expressions whose syntax
00007 and semantics are as close as possible to those of the Perl 5 language. See
00008 the file Tech.Notes for some information on the internals.
00009
00010 Written by: Philip Hazel <ph10@cam.ac.uk>
00011
00012            Copyright (c) 1997-1999 University of Cambridge
00013
00014 -----------------------------------------------------------------------------
00015 Permission is granted to anyone to use this software for any purpose on any
00016 computer system, and to redistribute it freely, subject to the following
00017 restrictions:
00018
00019 1. This software is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022
00023 2. The origin of this software must not be misrepresented, either by
00024    explicit claim or by omission.
00025
00026 3. Altered versions must be plainly marked as such, and must not be
00027    misrepresented as being the original software.
00028
00029 4. If PCRE is embedded in any software that is released under the GNU
00030    General Purpose Licence (GPL), then the terms of that licence shall
00031    supersede any condition above with which it is incompatible.
00032 -----------------------------------------------------------------------------
00033 */
00034
00035 /* This header contains definitions that are shared between the different
00036 modules, but which are not relevant to the outside. */
00037
00038 /* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
00039 define a macro for memmove() if USE_BCOPY is defined. */
00040
00041 #ifdef USE_BCOPY
00042 #undef  memmove        /* some systems may have a macro */
00043 #define memmove(a, b, c) bcopy(b, a, c)
00044 #endif
00045
00046 /* Standard C headers plus the external interface definition */
00047
00048 #include <ctype.h>
00049 /* #include <limits.h>
00050 PAF@design.ru removed this, for it were used only for stupid MAX_INT for
00051 mimimum searches, changed that to some out-of-reasonable-text-length value
00052 of 10M
00053 */
00054 #define PCRE_MAX_POS (10*0x400*0x400)
00055
00056 #include <stddef.h>
00057 #include <stdio.h>
00058 #include <stdlib.h>
00059 #include <string.h>
00060 #include "pcre.h"
00061
00062 /* In case there is no definition of offsetof() provided - though any proper
00063 Standard C system should have one. */
00064
00065 #ifndef offsetof
00066 #define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
00067 #endif
00068
00069 /* These are the public options that can change during matching. */
00070
00071 #define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
00072
00073 /* Private options flags start at the most significant end of the four bytes,
00074 but skip the top bit so we can use ints for convenience without getting tangled
00075 with negative values. The public options defined in pcre.h start at the least
00076 significant end. Make sure they don't overlap, though now that we have expanded
00077 to four bytes there is plenty of space. */
00078
00079 #define PCRE_FIRSTSET      0x40000000  /* first_char is set */
00080 #define PCRE_REQCHSET      0x20000000  /* req_char is set */
00081 #define PCRE_STARTLINE     0x10000000  /* start after \n for multiline */
00082 #define PCRE_INGROUP       0x08000000  /* compiling inside a group */
00083 #define PCRE_ICHANGED      0x04000000  /* i option changes within regex */
00084
00085 /* Options for the "extra" block produced by pcre_study(). */
00086
00087 #define PCRE_STUDY_MAPPED   0x01     /* a map of starting chars exists */
00088
00089 /* Masks for identifying the public options which are permitted at compile
00090 time, run time or study time, respectively. */
00091
00092 #define PUBLIC_OPTIONS \
00093   (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
00094    PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY)
00095
00096 #define PUBLIC_EXEC_OPTIONS \
00097   (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY)
00098
00099 #define PUBLIC_STUDY_OPTIONS 0   /* None defined */
00100
00101 /* Magic number to provide a small check against being handed junk. */
00102
00103 #define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */
00104
00105 /* Miscellaneous definitions */
00106
00107 typedef int BOOL;
00108
00109 #ifndef FALSE
00110 #define FALSE   0
00111 #endif
00112 #ifndef TRUE
00113 #define TRUE    1
00114 #endif
00115
00116 /* These are escaped items that aren't just an encoding of a particular data
00117 value such as \n. They must have non-zero values, as check_escape() returns
00118 their negation. Also, they must appear in the same order as in the opcode
00119 definitions below, up to ESC_z. The final one must be ESC_REF as subsequent
00120 values are used for \1, \2, \3, etc. There is a test in the code for an escape
00121 greater than ESC_b and less than ESC_X to detect the types that may be
00122 repeated. If any new escapes are put in-between that don't consume a character,
00123 that code will have to change. */
00124
00125 enum { ESC_A = 1, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w,
00126        ESC_Z, ESC_z, ESC_REF };
00127
00128 /* Opcode table: OP_BRA must be last, as all values >= it are used for brackets
00129 that extract substrings. Starting from 1 (i.e. after OP_END), the values up to
00130 OP_EOD must correspond in order to the list of escapes immediately above. */
00131
00132 enum {
00133   OP_END,            /* End of pattern */
00134
00135   /* Values corresponding to backslashed metacharacters */
00136
00137   OP_SOD,            /* Start of data: \A */
00138   OP_NOT_WORD_BOUNDARY,  /* \B */
00139   OP_WORD_BOUNDARY,      /* \b */
00140   OP_NOT_DIGIT,          /* \D */
00141   OP_DIGIT,              /* \d */
00142   OP_NOT_WHITESPACE,     /* \S */
00143   OP_WHITESPACE,         /* \s */
00144   OP_NOT_WORDCHAR,       /* \W */
00145   OP_WORDCHAR,           /* \w */
00146   OP_EODN,           /* End of data or \n at end of data: \Z. */
00147   OP_EOD,            /* End of data: \z */
00148
00149   OP_OPT,            /* Set runtime options */
00150   OP_CIRC,           /* Start of line - varies with multiline switch */
00151   OP_DOLL,           /* End of line - varies with multiline switch */
00152   OP_ANY,            /* Match any character */
00153   OP_CHARS,          /* Match string of characters */
00154   OP_NOT,            /* Match anything but the following char */
00155
00156   OP_STAR,           /* The maximizing and minimizing versions of */
00157   OP_MINSTAR,        /* all these opcodes must come in pairs, with */
00158   OP_PLUS,           /* the minimizing one second. */
00159   OP_MINPLUS,        /* This first set applies to single characters */
00160   OP_QUERY,
00161   OP_MINQUERY,
00162   OP_UPTO,           /* From 0 to n matches */
00163   OP_MINUPTO,
00164   OP_EXACT,          /* Exactly n matches */
00165
00166   OP_NOTSTAR,        /* The maximizing and minimizing versions of */
00167   OP_NOTMINSTAR,     /* all these opcodes must come in pairs, with */
00168   OP_NOTPLUS,        /* the minimizing one second. */
00169   OP_NOTMINPLUS,     /* This first set applies to "not" single characters */
00170   OP_NOTQUERY,
00171   OP_NOTMINQUERY,
00172   OP_NOTUPTO,        /* From 0 to n matches */
00173   OP_NOTMINUPTO,
00174   OP_NOTEXACT,       /* Exactly n matches */
00175
00176   OP_TYPESTAR,       /* The maximizing and minimizing versions of */
00177   OP_TYPEMINSTAR,    /* all these opcodes must come in pairs, with */
00178   OP_TYPEPLUS,       /* the minimizing one second. These codes must */
00179   OP_TYPEMINPLUS,    /* be in exactly the same order as those above. */
00180   OP_TYPEQUERY,      /* This set applies to character types such as \d */
00181   OP_TYPEMINQUERY,
00182   OP_TYPEUPTO,       /* From 0 to n matches */
00183   OP_TYPEMINUPTO,
00184   OP_TYPEEXACT,      /* Exactly n matches */
00185
00186   OP_CRSTAR,         /* The maximizing and minimizing versions of */
00187   OP_CRMINSTAR,      /* all these opcodes must come in pairs, with */
00188   OP_CRPLUS,         /* the minimizing one second. These codes must */
00189   OP_CRMINPLUS,      /* be in exactly the same order as those above. */
00190   OP_CRQUERY,        /* These are for character classes and back refs */
00191   OP_CRMINQUERY,
00192   OP_CRRANGE,        /* These are different to the three seta above. */
00193   OP_CRMINRANGE,
00194
00195   OP_CLASS,          /* Match a character class */
00196   OP_REF,            /* Match a back reference */
00197
00198   OP_ALT,            /* Start of alternation */
00199   OP_KET,            /* End of group that doesn't have an unbounded repeat */
00200   OP_KETRMAX,        /* These two must remain together and in this */
00201   OP_KETRMIN,        /* order. They are for groups the repeat for ever. */
00202
00203   /* The assertions must come before ONCE and COND */
00204
00205   OP_ASSERT,         /* Positive lookahead */
00206   OP_ASSERT_NOT,     /* Negative lookahead */
00207   OP_ASSERTBACK,     /* Positive lookbehind */
00208   OP_ASSERTBACK_NOT, /* Negative lookbehind */
00209   OP_REVERSE,        /* Move pointer back - used in lookbehind assertions */
00210
00211   /* ONCE and COND must come after the assertions, with ONCE first, as there's
00212   a test for >= ONCE for a subpattern that isn't an assertion. */
00213
00214   OP_ONCE,           /* Once matched, don't back up into the subpattern */
00215   OP_COND,           /* Conditional group */
00216   OP_CREF,           /* Used to hold an extraction string number */
00217
00218   OP_BRAZERO,        /* These two must remain together and in this */
00219   OP_BRAMINZERO,     /* order. */
00220
00221   OP_BRA             /* This and greater values are used for brackets that
00222                         extract substrings. */
00223 };
00224
00225 /* The highest extraction number. This is limited by the number of opcodes
00226 left after OP_BRA, i.e. 255 - OP_BRA. We actually set it somewhat lower. */
00227
00228 #define EXTRACT_MAX  99
00229
00230 /* The texts of compile-time error messages are defined as macros here so that
00231 they can be accessed by the POSIX wrapper and converted into error codes.  Yes,
00232 I could have used error codes in the first place, but didn't feel like changing
00233 just to accommodate the POSIX wrapper. */
00234
00235 #define ERR1  "\\ at end of pattern"
00236 #define ERR2  "\\c at end of pattern"
00237 #define ERR3  "unrecognized character follows \\"
00238 #define ERR4  "numbers out of order in {} quantifier"
00239 #define ERR5  "number too big in {} quantifier"
00240 #define ERR6  "missing terminating ] for character class"
00241 #define ERR7  "invalid escape sequence in character class"
00242 #define ERR8  "range out of order in character class"
00243 #define ERR9  "nothing to repeat"
00244 #define ERR10 "operand of unlimited repeat could match the empty string"
00245 #define ERR11 "internal error: unexpected repeat"
00246 #define ERR12 "unrecognized character after (?"
00247 #define ERR13 "too many capturing parenthesized sub-patterns"
00248 #define ERR14 "missing )"
00249 #define ERR15 "back reference to non-existent subpattern"
00250 #define ERR16 "erroffset passed as NULL"
00251 #define ERR17 "unknown option bit(s) set"
00252 #define ERR18 "missing ) after comment"
00253 #define ERR19 "too many sets of parentheses"
00254 #define ERR20 "regular expression too large"
00255 #define ERR21 "failed to get memory"
00256 #define ERR22 "unmatched parentheses"
00257 #define ERR23 "internal error: code overflow"
00258 #define ERR24 "unrecognized character after (?<"
00259 #define ERR25 "lookbehind assertion is not fixed length"
00260 #define ERR26 "malformed number after (?("
00261 #define ERR27 "conditional group contains more than two branches"
00262 #define ERR28 "assertion expected after (?("
00263
00264 /* All character handling must be done as unsigned characters. Otherwise there
00265 are problems with top-bit-set characters and functions such as isspace().
00266 However, we leave the interface to the outside world as char *, because that
00267 should make things easier for callers. We define a short type for unsigned char
00268 to save lots of typing. I tried "uchar", but it causes problems on Digital
00269 Unix, where it is defined in sys/types, so use "uschar" instead. */
00270
00271 typedef unsigned char uschar;
00272
00273 /* The real format of the start of the pcre block; the actual code vector
00274 runs on as long as necessary after the end. */
00275
00276 typedef struct real_pcre {
00277   unsigned long int magic_number;
00278   const unsigned char *tables;
00279   unsigned long int options;
00280   uschar top_bracket;
00281   uschar top_backref;
00282   uschar first_char;
00283   uschar req_char;
00284   uschar code[1];
00285 } real_pcre;
00286
00287 /* The real format of the extra block returned by pcre_study(). */
00288
00289 typedef struct real_pcre_extra {
00290   uschar options;
00291   uschar start_bits[32];
00292 } real_pcre_extra;
00293
00294
00295 /* Structure for passing "static" information around between the functions
00296 doing the compiling, so that they are thread-safe. */
00297
00298 typedef struct compile_data {
00299   const uschar *lcc;            /* Points to lower casing table */
00300   const uschar *fcc;            /* Points to case-flipping table */
00301   const uschar *cbits;          /* Points to character type table */
00302   const uschar *ctypes;         /* Points to table of type maps */
00303 } compile_data;
00304
00305 /* Structure for passing "static" information around between the functions
00306 doing the matching, so that they are thread-safe. */
00307
00308 typedef struct match_data {
00309   int    errorcode;             /* As it says */
00310   int   *offset_vector;         /* Offset vector */
00311   int    offset_end;            /* One past the end */
00312   int    offset_max;            /* The maximum usable for return data */
00313   const uschar *lcc;            /* Points to lower casing table */
00314   const uschar *ctypes;         /* Points to table of type maps */
00315   BOOL   offset_overflow;       /* Set if too many extractions */
00316   BOOL   notbol;                /* NOTBOL flag */
00317   BOOL   noteol;                /* NOTEOL flag */
00318   BOOL   endonly;               /* Dollar not before final \n */
00319   BOOL   notempty;              /* Empty string match not wanted */
00320   const uschar *start_subject;  /* Start of the subject string */
00321   const uschar *end_subject;    /* End of the subject string */
00322   const uschar *start_match;    /* Start of this match attempt */
00323   const uschar *end_match_ptr;  /* Subject position at end match */
00324   int     end_offset_top;       /* Highwater mark at end of match */
00325 } match_data;
00326
00327 /* Bit definitions for entries in the pcre_ctypes table. */
00328
00329 #define ctype_space   0x01
00330 #define ctype_letter  0x02
00331 #define ctype_digit   0x04
00332 #define ctype_xdigit  0x08
00333 #define ctype_word    0x10   /* alphameric or '_' */
00334 #define ctype_meta    0x80   /* regexp meta char or zero (end pattern) */
00335
00336 /* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
00337 of bits for a class map. */
00338
00339 #define cbit_digit    0      /* for \d */
00340 #define cbit_word    32      /* for \w */
00341 #define cbit_space   64      /* for \s */
00342 #define cbit_length  96      /* Length of the cbits table */
00343
00344 /* Offsets of the various tables from the base tables pointer, and
00345 total length. */
00346
00347 #define lcc_offset      0
00348 #define fcc_offset    256
00349 #define cbits_offset  512
00350 #define ctypes_offset (cbits_offset + cbit_length)
00351 #define tables_length (ctypes_offset + 256)
00352
00353 /* End of internal.h */


ltdl.c File Reference

Include dependency graph for ltdl.c:

Include dependency graph

Go to the source code of this file.

Compounds

struct | lt_dlloader
struct | lt_dlhandle_struct
struct | lt_dlsymlists_t

Defines

#define | assert(arg) ((void) 0)
#define | LT_GLOBAL_DATA
#define | LT_READTEXT_MODE "rt"
#define | LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
#define | LTDL_ARCHIVE_EXT ".la"
#define | LT_FILENAME_MAX 1024
#define | LT_SYMBOL_LENGTH 128
#define | LT_SYMBOL_OVERHEAD 5
#define | LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
#define | LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
#define | LT_DLFREE(p) LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
#define | LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
#define | LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
#define | LT_DLMEM_REASSIGN(p, q)
#define | strdup rpl_strdup
#define | realloc rpl_realloc
#define | argz_append rpl_argz_append
#define | argz_create_sep rpl_argz_create_sep
#define | argz_insert rpl_argz_insert
#define | argz_next rpl_argz_next
#define | argz_stringify rpl_argz_stringify
#define | LT_ERROR(name, diagnostic) (diagnostic),
#define | LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
#define | LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
#define | LT_DLRESIDENT_FLAG (0x01 << 0)
#define | LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
#define | LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
#define | LT_DLMUTEX_LOCK()
#define | LT_DLMUTEX_UNLOCK()
#define | LT_DLMUTEX_SETERROR(errormsg)
#define | LT_DLMUTEX_GETERROR(errormsg)
#define | STR_DLNAME "dlname="
#define | STR_OLD_LIBRARY "old_library="
#define | STR_LIBDIR "libdir="
#define | STR_DL_DEPLIBS "dependency_libs="
#define | STR_LIBRARY_NAMES "library_names="

Typedefs

typedef lt_dlsymlists_t | lt_dlsymlists_t
typedef int foreach_callback_func | LT_PARAMS ((char *filename, lt_ptr data1, lt_ptr data2))

Functions

char *lt_estrdup | LT_PARAMS ((const char *str))
lt_ptr lt_emalloc | LT_PARAMS ((size_t size))
lt_ptr lt_erealloc | LT_PARAMS ((lt_ptr addr, size_t size))
lt_ptr rpl_realloc | LT_PARAMS ((lt_ptr ptr, size_t size))
LT_GLOBAL_DATA void lt_dlfree | LT_PARAMS ((lt_ptr ptr))=(void(*) LT_PARAMS((lt_ptr))) free
char * | strdup (str) const char *str
error_t | argz_append (pargz, pargz_len, buf, buf_len) char **pargz
error_t | argz_create_sep (str, delim, pargz, pargz_len) const char *str
error_t | argz_insert (pargz, pargz_len, before, entry) char **pargz
char * | argz_next (argz, argz_len, entry) char *argz
void | argz_stringify (argz, argz_len, sep) char *argz
int | lt_dlmutex_register (lock, unlock, seterror, geterror) lt_dlmutex_lock *lock
int | lt_dladderror (diagnostic) const char *diagnostic
lt_module | sys_wll_open (loader_data, filename) lt_user_data loader_data
int | presym_init (loader_data) lt_user_data loader_data
int foreach_dirinpath | LT_PARAMS ((const char *search_path, const char *base_name, foreach_callback_func *func, lt_ptr data1, lt_ptr data2))
int find_file_callback | LT_PARAMS ((char *filename, lt_ptr data, lt_ptr ignored))
int foreachfile_callback | LT_PARAMS ((char *filename, lt_ptr data1, lt_ptr data2))
int canonicalize_path | LT_PARAMS ((const char *path, char **pcanonical))
int argzize_path | LT_PARAMS ((const char *path, char **pargz, size_t *pargz_len))
FILE *find_file | LT_PARAMS ((const char *search_path, const char *base_name, char **pdir))
lt_dlhandle *find_handle | LT_PARAMS ((const char *search_path, const char *base_name, lt_dlhandle *handle))
int find_module | LT_PARAMS ((lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, const char *old_name, int installed))
int free_vars | LT_PARAMS ((char *dlname, char *oldname, char *libdir, char *deplibs))
int load_deplibs | LT_PARAMS ((lt_dlhandle handle, char *deplibs))
int trim | LT_PARAMS ((char **dest, const char *str))
int try_dlopen | LT_PARAMS ((lt_dlhandle *handle, const char *filename))
int unload_deplibs | LT_PARAMS ((lt_dlhandle handle))
int lt_argz_insert | LT_PARAMS ((char **pargz, size_t *pargz_len, char *before, const char *entry))
int lt_argz_insertinorder | LT_PARAMS ((char **pargz, size_t *pargz_len, const char *entry))
int lt_argz_insertdir | LT_PARAMS ((char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp))
int lt_dlpath_insertdir | LT_PARAMS ((char **ppath, char *before, const char *dir))
int list_files_by_dir | LT_PARAMS ((const char *dirnam, char **pargz, size_t *pargz_len))
int file_not_found | LT_PARAMS ((void))
int | lt_dlinit ()
int | lt_dlpreload (preloaded) const lt_dlsymlist *preloaded
int func | LT_PARAMS ((const char *filename, lt_ptr data))

Variables

LT_GLOBAL_DATA lt_ptr lt_dlrealloc
size_t 		rpl_realloc
size_t | size
size_t * | pargz_len
const char * | buf
size_t | buf_len
int | delim
char ** | pargz
char * | before
const char * | entry
size_t | argz_len
int | sep
const char * | lt_dlerror_strings []
const char | objdir [] = LTDL_OBJDIR
const char | archive_ext [] = LTDL_ARCHIVE_EXT
const char | shlib_ext [] = LTDL_SHLIB_EXT
lt_dlmutex_lock * | lt_dlmutex_lock_func = NULL
lt_dlmutex_unlock * | lt_dlmutex_unlock_func = NULL
lt_dlmutex_seterror * | lt_dlmutex_seterror_func = NULL
lt_dlmutex_geterror * | lt_dlmutex_geterror_func = NULL
const char * | lt_dllast_error = NULL
lt_dlmutex_unlock * | unlock
lt_dlmutex_seterror * | seterror
lt_dlmutex_geterror * | geterror
int | errorcount = LT_ERROR_MAX
const char * | filename
lt_module module
const char * | symbol
const lt_dlsymlist * | default_preloaded_symbols = NULL
lt_dlsymlists_t * | preloaded_symbols = NULL
char * | user_search_path = NULL
lt_dlloader * | loaders = NULL
lt_dlhandle | handles = NULL
int | initialized = 0
const char * | prefix
const char * | dirname
const char * | dlname
const char * | dir
const char * | libdir
const char * | old_name
int | installed
char ** | pcanonical
const char * | base_name
foreach_callback_func * | func
lt_ptr | data1
lt_ptr | data2
char ** | pdir
lt_ptr | data
lt_ptr | ignored
lt_dlhandle * handle
char * | deplibs
const char * | str
char * | oldname
const char * | dirnam
dirent * dp
const char * | search_dir
const struct lt_user_dlloader * | dlloader
const char * | loader_name

Define Documentation

#define assert ( arg ) ((void) 0)

Definition at line 92 of file ltdl.c.

Referenced by String::Languages::append(), String::Body::Body(), String::change_case(), change_string_literal_value(), file_read_action(), Array< Operation >::get(), Array< Operation >::get_ref(), VXnode::get_vxdoc(), getopt(), locked_process_and_cache_put_action(), maybe_change_string_literal_to_double_literal(), pa_base64_decode(), pa_base64_encode(), Array< Operation >::put(), Junction::reattach(), Table::set_current(), and Stack< StackItem >::top_value().

#define LT_GLOBAL_DATA

Definition at line 110 of file ltdl.c.

#define LT_READTEXT_MODE "rt"

Definition at line 116 of file ltdl.c.

#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"

Definition at line 129 of file ltdl.c.

#define LTDL_ARCHIVE_EXT ".la"

Definition at line 133 of file ltdl.c.

#define LT_FILENAME_MAX 1024

Definition at line 137 of file ltdl.c.

#define LT_SYMBOL_LENGTH 128

Definition at line 142 of file ltdl.c.

#define LT_SYMBOL_OVERHEAD 5

Definition at line 146 of file ltdl.c.

#define LT_DLMALLOC | ( | tp,
 |  | n | ) | ((tp *) lt_dlmalloc ((n) * sizeof(tp)))

Definition at line 185 of file ltdl.c.

#define LT_DLREALLOC | ( | tp,
 |  | p,
 |  | n | ) | ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))

Definition at line 186 of file ltdl.c.

#define LT_DLFREE ( p ) LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END

Definition at line 187 of file ltdl.c.

#define LT_EMALLOC | ( | tp,
 |  | n | ) | ((tp *) lt_emalloc ((n) * sizeof(tp)))

Definition at line 190 of file ltdl.c.

#define LT_EREALLOC | ( | tp,
 |  | p,
 |  | n | ) | ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))

Definition at line 191 of file ltdl.c.

#define LT_DLMEM_REASSIGN | ( | p,
 |  | q | )

Value:

LT_STMT_START { \
    if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; }   \
                        } LT_STMT_END

Definition at line 195 of file ltdl.c.

#define strdup rpl_strdup

Definition at line 204 of file ltdl.c.

Referenced by text_value_to_string().

#define realloc rpl_realloc

#define argz_append rpl_argz_append

#define argz_create_sep rpl_argz_create_sep

#define argz_insert rpl_argz_insert

#define argz_next rpl_argz_next

#define argz_stringify rpl_argz_stringify

#define LT_ERROR | ( | name,
 |  | diagnostic | ) | (diagnostic),

#define LT_DLGET_FLAG | ( | handle,
 |  | flag | ) | (((handle)->flags & (flag)) == (flag))

Definition at line 712 of file ltdl.c.

#define LT_DLSET_FLAG | ( | handle,
 |  | flag | ) | ((handle)->flags |= (flag))

Definition at line 713 of file ltdl.c.

#define LT_DLRESIDENT_FLAG (0x01 << 0)

Definition at line 715 of file ltdl.c.

#define LT_DLIS_RESIDENT ( handle ) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)

Definition at line 718 of file ltdl.c.

#define LT_DLSTRERROR ( name ) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]

Definition at line 721 of file ltdl.c.

Referenced by lt_dlinit().

#define LT_DLMUTEX_LOCK ( )

Value:

LT_STMT_START { \
    if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)();    \
                        } LT_STMT_END

Definition at line 743 of file ltdl.c.

Referenced by lt_dlinit().

#define LT_DLMUTEX_UNLOCK ( )

Value:

LT_STMT_START { \
    if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
                        } LT_STMT_END

Definition at line 746 of file ltdl.c.

Referenced by lt_dlinit().

#define LT_DLMUTEX_SETERROR ( errormsg )

Value:

LT_STMT_START { \
    if (lt_dlmutex_seterror_func)               \
        (*lt_dlmutex_seterror_func) (errormsg);     \
    else    lt_dllast_error = (errormsg);   } LT_STMT_END

Definition at line 749 of file ltdl.c.

Referenced by lt_dlinit().

#define LT_DLMUTEX_GETERROR ( errormsg )

Value:

LT_STMT_START { \
    if (lt_dlmutex_seterror_func)               \
        (errormsg) = (*lt_dlmutex_geterror_func) ();    \
    else    (errormsg) = lt_dllast_error;   } LT_STMT_END

Definition at line 753 of file ltdl.c.

#define STR_DLNAME "dlname="

#define STR_OLD_LIBRARY "old_library="

#define STR_LIBDIR "libdir="

#define STR_DL_DEPLIBS "dependency_libs="

#define STR_LIBRARY_NAMES "library_names="

Typedef Documentation

typedef struct lt_dlsymlists_t lt_dlsymlists_t

int lt_dlloader_remove LT_PARAMS

Definition at line 1650 of file ltdl.c.

Function Documentation

char* lt_estrdup LT_PARAMS ( (const char *str) ) [static]

lt_ptr lt_emalloc LT_PARAMS ( (size_t size) ) [static]

lt_ptr lt_erealloc LT_PARAMS ( (lt_ptr addr, size_t size) ) [static]

lt_ptr rpl_realloc LT_PARAMS ( (lt_ptr ptr, size_t size) ) [static]

LT_GLOBAL_DATA void lt_dlfree LT_PARAMS ( (lt_ptr ptr) )

char* strdup ( str ) const [static]

error_t argz_append | ( | pargz | ,
 |  | pargz_len | ,
 |  | buf | ,
 |  | buf_len |
 | ) | [static]

error_t argz_create_sep | ( | str | ,
 |  | delim | ,
 |  | pargz | ,
 |  | pargz_len |
 | ) | const [static]

error_t argz_insert | ( | pargz | ,
 |  | pargz_len | ,
 |  | before | ,
 |  | entry |
 | ) | [static]

char* argz_next | ( | argz | ,
 |  | argz_len | ,
 |  | entry |
 | ) | [static]

void argz_stringify | ( | argz | ,
 |  | argz_len | ,
 |  | sep |
 | ) | [static]

int lt_dlmutex_register | ( | lock | ,
 |  | unlock | ,
 |  | seterror | ,
 |  | geterror |
 | ) |

int lt_dladderror ( diagnostic ) const

lt_module sys_wll_open | ( | loader_data | ,
 |  | filename |
 | ) | [static]

int presym_init ( loader_data ) [static]

Referenced by lt_dlinit().

int foreach_dirinpath LT_PARAMS ( (const char *search_path, const char *base_name, foreach_callback_func *func, lt_ptr data1, lt_ptr data2) ) [static]

int find_file_callback LT_PARAMS ( (char *filename, lt_ptr data, lt_ptr ignored) ) [static]

int foreachfile_callback LT_PARAMS ( (char *filename, lt_ptr data1, lt_ptr data2) ) [static]

int canonicalize_path LT_PARAMS ( (const char *path, char **pcanonical) ) [static]

int argzize_path LT_PARAMS ( (const char *path, char **pargz, size_t *pargz_len) ) [static]

FILE* find_file LT_PARAMS ( (const char *search_path, const char *base_name, char **pdir) ) [static]

lt_dlhandle* find_handle LT_PARAMS ( (const char *search_path, const char *base_name, lt_dlhandle *handle) ) [static]

int find_module LT_PARAMS ( (lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, const char *old_name, int installed) ) [static]

int free_vars LT_PARAMS ( (char *dlname, char *oldname, char *libdir, char *deplibs) ) [static]

int load_deplibs LT_PARAMS ( (lt_dlhandle handle, char *deplibs) ) [static]

int trim LT_PARAMS ( (char **dest, const char *str) ) [static]

int try_dlopen LT_PARAMS ( (lt_dlhandle *handle, const char *filename) ) [static]

int unload_deplibs LT_PARAMS ( (lt_dlhandle handle) ) [static]

int lt_argz_insert LT_PARAMS ( (char **pargz, size_t *pargz_len, char *before, const char *entry) ) [static]

int lt_argz_insertinorder LT_PARAMS ( (char **pargz, size_t *pargz_len, const char *entry) ) [static]

int lt_argz_insertdir LT_PARAMS ( (char **pargz, size_t *pargz_len, const char *dirnam, struct dirent *dp) ) [static]

int lt_dlpath_insertdir LT_PARAMS ( (char **ppath, char *before, const char *dir) ) [static]

int list_files_by_dir LT_PARAMS ( (const char *dirnam, char **pargz, size_t *pargz_len) ) [static]

int file_not_found LT_PARAMS ( (void) ) [static]

int lt_dlinit ( )

Definition at line 1720 of file ltdl.c.

References lt_user_dlloader::dlloader_data, initialized, LT_DLMUTEX_LOCK, LT_DLMUTEX_SETERROR, LT_DLMUTEX_UNLOCK, LT_DLSTRERROR, presym_init(), and user_search_path.

Referenced by SQL_Driver_manager::get_connection().

int lt_dlpreload ( preloaded ) const

int func LT_PARAMS ( (const char *filename, lt_ptr data) )

Variable Documentation

LT_GLOBAL_DATA lt_ptr lt_dlrealloc size_t rpl_realloc

Definition at line 167 of file ltdl.c.

size_t size

Definition at line 885 of file ltdl.c.

Referenced by _circle(), _menu(), _select(), _sql_string(), _stat(), buildCommand(), CORD_range_contains_chr_greater_then_proc(), die_or_abort(), ec_append(), entry_readable(), file_write(), format(), Random_provider::generate(), generic_hash_code(), VRequest::get_element(), hex_string(), lastposafter(), log(), SAPI::log(), SQL_Driver_services_impl::malloc(), PA_Allocated::malloc(), SQL_Driver_services_impl::malloc_atomic(), PA_Allocated::malloc_atomic(), String::Body::ncmp(), need_quote_http_header(), SQL_Driver::operator new(), PA_Allocated::operator new(), operator new(), operator new[](), output_pieces(), pa_fail_alloc(), pa_gc_malloc(), pa_gc_malloc_atomic(), pa_gc_realloc(), pa_malloc(), pa_malloc_atomic(), pa_realloc(), pa_strdup(), pcre_compile(), pcre_copy_substring(), pcre_get_substring_list(), random(), read_pipe(), SQL_Driver_services_impl::realloc(), PA_Allocated::realloc(), SAPI::send_body(), stdout_write(), Request::use_file(), and gdGifEncoder::Write().

size_t * pargz_len

Definition at line 3152 of file ltdl.c.

size_t buf_len

Definition at line 434 of file ltdl.c.

int delim

Definition at line 474 of file ltdl.c.

Referenced by getrow(), lsplit(), rsplit(), and String::split().

char ** pargz

Definition at line 3151 of file ltdl.c.

char * before

Definition at line 3445 of file ltdl.c.

Referenced by Request::core().

const char * entry

Definition at line 3062 of file ltdl.c.

Referenced by parse_IFD_entry(), and parse_IFD_entry_value().

size_t argz_len

Definition at line 639 of file ltdl.c.

int sep

Definition at line 640 of file ltdl.c.

const char* lt_dlerror_strings[] [static]

Initial value:

  {
#define LT_ERROR(name, diagnostic)
    lt_dlerror_table

    0
  }

Definition at line 677 of file ltdl.c.

const char objdir[] = LTDL_OBJDIR [static]

Definition at line 723 of file ltdl.c.

const char archive_ext[] = LTDL_ARCHIVE_EXT [static]

Definition at line 724 of file ltdl.c.

const char shlib_ext[] = LTDL_SHLIB_EXT [static]

Definition at line 726 of file ltdl.c.

lt_dlmutex_lock* lt_dlmutex_lock_func = NULL [static]

Definition at line 760 of file ltdl.c.

lt_dlmutex_unlock* lt_dlmutex_unlock_func = NULL [static]

Definition at line 761 of file ltdl.c.

lt_dlmutex_seterror* lt_dlmutex_seterror_func = NULL [static]

Definition at line 762 of file ltdl.c.

lt_dlmutex_geterror* lt_dlmutex_geterror_func = NULL [static]

Definition at line 763 of file ltdl.c.

const char* lt_dllast_error = NULL [static]

Definition at line 764 of file ltdl.c.

lt_dlmutex_unlock* unlock

Definition at line 774 of file ltdl.c.

lt_dlmutex_seterror* seterror

Definition at line 775 of file ltdl.c.

lt_dlmutex_geterror* geterror

Definition at line 776 of file ltdl.c.

int errorcount = LT_ERROR_MAX [static]

Definition at line 814 of file ltdl.c.

const char * filename

Definition at line 2540 of file ltdl.c.

Referenced by SQL_Driver_manager::get_connection(), and output_pieces().

lt_module module

Definition at line 1617 of file ltdl.c.

const char * symbol

Definition at line 3340 of file ltdl.c.

const lt_dlsymlist* default_preloaded_symbols = NULL [static]

Definition at line 1464 of file ltdl.c.

lt_dlsymlists_t* preloaded_symbols = NULL [static]

Definition at line 1465 of file ltdl.c.

char* user_search_path = NULL [static]

Definition at line 1713 of file ltdl.c.

Referenced by lt_dlinit().

lt_dlloader* loaders = NULL [static]

Definition at line 1714 of file ltdl.c.

lt_dlhandle handles = NULL [static]

Definition at line 1715 of file ltdl.c.

int initialized = 0 [static]

Definition at line 1716 of file ltdl.c.

Referenced by lt_dlinit().

const char* prefix

Definition at line 1961 of file ltdl.c.

const char* dirname

Definition at line 1962 of file ltdl.c.

Referenced by _find(), and prep().

const char * dlname

Definition at line 2013 of file ltdl.c.

const char * dir

Definition at line 3446 of file ltdl.c.

Referenced by CreateHiddenConsoleProcess(), gdImage::FilledPolygon(), and gdImage::FilledPolygonReplaceColor().

char * libdir

Definition at line 2526 of file ltdl.c.

const char* old_name

Definition at line 2014 of file ltdl.c.

int installed

Definition at line 2015 of file ltdl.c.

char** pcanonical

Definition at line 2058 of file ltdl.c.

const char * base_name

Definition at line 2295 of file ltdl.c.

Referenced by delete_file().

foreach_callback_func* func

Definition at line 2156 of file ltdl.c.

Referenced by CORD_dump_inner(), math1(), math2(), Table::table_first_that(), Table::table_for_each(), vdouble_op(), and vint_op().

lt_ptr data1

Definition at line 3189 of file ltdl.c.

lt_ptr data2

Definition at line 3190 of file ltdl.c.

char** pdir

Definition at line 2260 of file ltdl.c.

lt_ptr data

Definition at line 3702 of file ltdl.c.

Referenced by _case(), _create(), _load(), _measure(), _switch(), atoi(), cleanup(), database_cleanup(), file_write(), VForm::getAttributeValue(), getHeader(), match(), VForm::ParseFormInput(), VForm::ParseMimeInput(), VForm::refill_fields_and_tables(), Pool::register_cleanup(), searchAttribute(), SMTP::SendBuffer(), SMTP::SendLine(), and skip_empty_and_comment_lines().

lt_ptr ignored

Definition at line 2273 of file ltdl.c.

lt_dlhandle handle

Definition at line 3756 of file ltdl.c.

Referenced by SQL_Driver_manager::get_connection(), and Mutex::Mutex().

char * deplibs

Definition at line 2527 of file ltdl.c.

const char* str

Definition at line 2494 of file ltdl.c.

Referenced by String::append_help_length(), String::Body::append_know_length(), String::append_know_length(), String::append_strdup(), String::Body::append_strdup_know_length(), String::Body::Body(), check(), CORD_vsprintf(), Dictionary::first_that_begins(), fix_line_breaks(), String::Body::operator<<(), pa_ap_log_error(), pa_ap_log_rerror(), pa_atod(), pa_atoi(), pa_exec(), SQL_Connection::quote(), sdbm_hash(), and VForm::strpart().

char* oldname

Definition at line 2525 of file ltdl.c.

const char* dirnam

Definition at line 3086 of file ltdl.c.

struct dirent* dp

Definition at line 3087 of file ltdl.c.

const char* search_dir

Definition at line 3534 of file ltdl.c.

const struct lt_user_dlloader* dlloader

Definition at line 3790 of file ltdl.c.

const char* loader_name

Definition at line 3791 of file ltdl.c.


ltdl.c Source File

ltdl.c

Go to the documentation of this file.
00001 /* ltdl.c -- system independent dlopen wrapper
00002    Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
00003    Originally by Thomas Tanner <tanner@ffii.org>
00004    This file is part of GNU Libtool.
00005
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2 of the License, or (at your option) any later version.
00010
00011 As a special exception to the GNU Lesser General Public License,
00012 if you distribute this file as part of a program or library that
00013 is built using GNU libtool, you may include it under the same
00014 distribution terms that you use for the rest of that program.
00015
00016 This library is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 Lesser General Public License for more details.
00020
00021 You should have received a copy of the GNU Lesser General Public
00022 License along with this library; if not, write to the Free Software
00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00024 02111-1307  USA
00025
00026 */
00027
00028 #include "config.h"
00029
00030 #if HAVE_UNISTD_H
00031 #  include <unistd.h>
00032 #endif
00033
00034 #if HAVE_STDIO_H
00035 #  include <stdio.h>
00036 #endif
00037
00038 #if HAVE_STDLIB_H
00039 #  include <stdlib.h>
00040 #endif
00041
00042 #if HAVE_STRING_H
00043 #  include <string.h>
00044 #else
00045 #  if HAVE_STRINGS_H
00046 #    include <strings.h>
00047 #  endif
00048 #endif
00049
00050 #if HAVE_CTYPE_H
00051 #  include <ctype.h>
00052 #endif
00053
00054 #if HAVE_MALLOC_H
00055 #  include <malloc.h>
00056 #endif
00057
00058 #if HAVE_MEMORY_H
00059 #  include <memory.h>
00060 #endif
00061
00062 #if HAVE_ERRNO_H
00063 #  include <errno.h>
00064 #endif
00065
00066 #ifdef HAVE_CONFIG_H
00067 #if HAVE_DIRENT_H
00068 #  include <dirent.h>
00069 #  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
00070 #else
00071 #  define dirent direct
00072 #  define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
00073 #  if HAVE_SYS_NDIR_H
00074 #    include <sys/ndir.h>
00075 #  endif
00076 #  if HAVE_SYS_DIR_H
00077 #    include <sys/dir.h>
00078 #  endif
00079 #  if HAVE_NDIR_H
00080 #    include <ndir.h>
00081 #  endif
00082 #endif
00083 #endif
00084
00085 #if HAVE_ARGZ_H
00086 #  include <argz.h>
00087 #endif
00088
00089 #if HAVE_ASSERT_H
00090 #  include <assert.h>
00091 #else
00092 #  define assert(arg)   ((void) 0)
00093 #endif
00094
00095 #include "ltdl.h"
00096
00097 #if WITH_DMALLOC
00098 #  include <dmalloc.h>
00099 #endif
00100
00101
00102
00103
00104 /* --- WINDOWS SUPPORT --- */
00105
00106
00107 #ifdef DLL_EXPORT
00108 #  define LT_GLOBAL_DATA    __declspec(dllexport)
00109 #else
00110 #  define LT_GLOBAL_DATA
00111 #endif
00112
00113 /* fopen() mode flags for reading a text file */
00114 #undef  LT_READTEXT_MODE
00115 #ifdef __WINDOWS__
00116 #  define LT_READTEXT_MODE "rt"
00117 #else
00118 #  define LT_READTEXT_MODE "r"
00119 #endif
00120
00121
00122
00123
00124 /* --- MANIFEST CONSTANTS --- */
00125
00126
00127 /* Standard libltdl search path environment variable name  */
00128 #undef  LTDL_SEARCHPATH_VAR
00129 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
00130
00131 /* Standard libtool archive file extension.  */
00132 #undef  LTDL_ARCHIVE_EXT
00133 #define LTDL_ARCHIVE_EXT    ".la"
00134
00135 /* max. filename length */
00136 #ifndef LT_FILENAME_MAX
00137 #  define LT_FILENAME_MAX   1024
00138 #endif
00139
00140 /* This is the maximum symbol size that won't require malloc/free */
00141 #undef  LT_SYMBOL_LENGTH
00142 #define LT_SYMBOL_LENGTH    128
00143
00144 /* This accounts for the _LTX_ separator */
00145 #undef  LT_SYMBOL_OVERHEAD
00146 #define LT_SYMBOL_OVERHEAD  5
00147
00148
00149
00150
00151 /* --- MEMORY HANDLING --- */
00152
00153
00154 /* These are the functions used internally.  In addition to making
00155    use of the associated function pointers above, they also perform
00156    error handling.  */
00157 static char   *lt_estrdup   LT_PARAMS((const char *str));
00158 static lt_ptr lt_emalloc    LT_PARAMS((size_t size));
00159 static lt_ptr lt_erealloc   LT_PARAMS((lt_ptr addr, size_t size));
00160
00161 static lt_ptr rpl_realloc   LT_PARAMS((lt_ptr ptr, size_t size));
00162
00163 /* These are the pointers that can be changed by the caller:  */
00164 LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc)    LT_PARAMS((size_t size))
00165             = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
00166 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)   LT_PARAMS((lt_ptr ptr, size_t size))
00167             = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
00168 LT_GLOBAL_DATA void   (*lt_dlfree)  LT_PARAMS((lt_ptr ptr))
00169             = (void (*) LT_PARAMS((lt_ptr))) free;
00170
00171 /* The following macros reduce the amount of typing needed to cast
00172    assigned memory.  */
00173 #if WITH_DMALLOC
00174
00175 #define LT_DLMALLOC(tp, n)  ((tp *) xmalloc ((n) * sizeof(tp)))
00176 #define LT_DLREALLOC(tp, p, n)  ((tp *) xrealloc ((p), (n) * sizeof(tp)))
00177 #define LT_DLFREE(p)                        \
00178     LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
00179
00180 #define LT_EMALLOC(tp, n)   ((tp *) xmalloc ((n) * sizeof(tp)))
00181 #define LT_EREALLOC(tp, p, n)   ((tp *) xrealloc ((p), (n) * sizeof(tp)))
00182
00183 #else
00184
00185 #define LT_DLMALLOC(tp, n)  ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
00186 #define LT_DLREALLOC(tp, p, n)  ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
00187 #define LT_DLFREE(p)                        \
00188     LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
00189
00190 #define LT_EMALLOC(tp, n)   ((tp *) lt_emalloc ((n) * sizeof(tp)))
00191 #define LT_EREALLOC(tp, p, n)   ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
00192
00193 #endif
00194
00195 #define LT_DLMEM_REASSIGN(p, q)         LT_STMT_START { \
00196     if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; }   \
00197                         } LT_STMT_END
00198
00199
00200 /* --- REPLACEMENT FUNCTIONS --- */
00201
00202
00203 #undef strdup
00204 #define strdup rpl_strdup
00205
00206 static char *strdup LT_PARAMS((const char *str));
00207
00208 static char *
00209 strdup(str)
00210      const char *str;
00211 {
00212   char *tmp = NULL;
00213
00214   if (str)
00215     {
00216       tmp = LT_DLMALLOC (char, 1+ strlen (str));
00217       if (tmp)
00218     {
00219       strcpy(tmp, str);
00220     }
00221     }
00222
00223   return tmp;
00224 }
00225
00226
00227 #if ! HAVE_STRCMP
00228
00229 #undef strcmp
00230 #define strcmp rpl_strcmp
00231
00232 static int strcmp LT_PARAMS((const char *str1, const char *str2));
00233
00234 static int
00235 strcmp (str1, str2)
00236      const char *str1;
00237      const char *str2;
00238 {
00239   if (str1 == str2)
00240     return 0;
00241   if (str1 == NULL)
00242     return -1;
00243   if (str2 == NULL)
00244     return 1;
00245
00246   for (;*str1 && *str2; ++str1, ++str2)
00247     {
00248       if (*str1 != *str2)
00249     break;
00250     }
00251
00252   return (int)(*str1 - *str2);
00253 }
00254 #endif
00255
00256
00257 #if ! HAVE_STRCHR
00258
00259 #  if HAVE_INDEX
00260 #    define strchr index
00261 #  else
00262 #    define strchr rpl_strchr
00263
00264 static const char *strchr LT_PARAMS((const char *str, int ch));
00265
00266 static const char*
00267 strchr(str, ch)
00268      const char *str;
00269      int ch;
00270 {
00271   const char *p;
00272
00273   for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
00274     /*NOWORK*/;
00275
00276   return (*p == (char)ch) ? p : 0;
00277 }
00278
00279 #  endif
00280 #endif /* !HAVE_STRCHR */
00281
00282
00283 #if ! HAVE_STRRCHR
00284
00285 #  if HAVE_RINDEX
00286 #    define strrchr rindex
00287 #  else
00288 #    define strrchr rpl_strrchr
00289
00290 static const char *strrchr LT_PARAMS((const char *str, int ch));
00291
00292 static const char*
00293 strrchr(str, ch)
00294      const char *str;
00295      int ch;
00296 {
00297   const char *p, *q = NULL;
00298
00299   for (p = str; *p != LT_EOS_CHAR; ++p)
00300     {
00301       if (*p == (char) ch)
00302     {
00303       q = p;
00304     }
00305     }
00306
00307   return q;
00308 }
00309
00310 # endif
00311 #endif
00312
00313 /* NOTE:  Neither bcopy nor the memcpy implementation below can
00314           reliably handle copying in overlapping areas of memory.  Use
00315           memmove (for which there is a fallback implmentation below)
00316       if you need that behaviour.  */
00317 #if ! HAVE_MEMCPY
00318
00319 #  if HAVE_BCOPY
00320 #    define memcpy(dest, src, size) bcopy (src, dest, size)
00321 #  else
00322 #    define memcpy rpl_memcpy
00323
00324 static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
00325
00326 static lt_ptr
00327 memcpy (dest, src, size)
00328      lt_ptr dest;
00329      const lt_ptr src;
00330      size_t size;
00331 {
00332   size_t i = 0;
00333
00334   for (i = 0; i < size; ++i)
00335     {
00336       dest[i] = src[i];
00337     }
00338
00339   return dest;
00340 }
00341
00342 #  endif /* !HAVE_BCOPY */
00343 #endif   /* !HAVE_MEMCPY */
00344
00345 #if ! HAVE_MEMMOVE
00346 #  define memmove rpl_memmove
00347
00348 static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
00349
00350 static lt_ptr
00351 memmove (dest, src, size)
00352      lt_ptr dest;
00353      const lt_ptr src;
00354      size_t size;
00355 {
00356   size_t i;
00357
00358   if (dest < src)
00359     for (i = 0; i < size; ++i)
00360       {
00361     dest[i] = src[i];
00362       }
00363   else if (dest > src)
00364     for (i = size -1; i >= 0; --i)
00365       {
00366     dest[i] = src[i];
00367       }
00368
00369   return dest;
00370 }
00371
00372 #endif /* !HAVE_MEMMOVE */
00373
00374
00375 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
00376     ``realloc is not entirely portable''
00377    In any case we want to use the allocator supplied by the user without
00378    burdening them with an lt_dlrealloc function pointer to maintain.
00379    Instead implement our own version (with known boundary conditions)
00380    using lt_dlmalloc and lt_dlfree. */
00381
00382 #undef realloc
00383 #define realloc rpl_realloc
00384
00385 static lt_ptr
00386 realloc (ptr, size)
00387      lt_ptr ptr;
00388      size_t size;
00389 {
00390   if (size == 0)
00391     {
00392       /* For zero or less bytes, free the original memory */
00393       if (ptr != NULL)
00394     {
00395       lt_dlfree (ptr);
00396     }
00397
00398       return (lt_ptr) 0;
00399     }
00400   else if (ptr == NULL)
00401     {
00402       /* Allow reallocation of a NULL pointer.  */
00403       return lt_dlmalloc (size);
00404     }
00405   else
00406     {
00407       /* Allocate a new block, copy and free the old block.  */
00408       lt_ptr mem = lt_dlmalloc (size);
00409
00410       if (mem)
00411     {
00412       memcpy (mem, ptr, size);
00413       lt_dlfree (ptr);
00414     }
00415
00416       /* Note that the contents of PTR are not damaged if there is
00417      insufficient memory to realloc.  */
00418       return mem;
00419     }
00420 }
00421
00422
00423 #if ! HAVE_ARGZ_APPEND
00424 #  define argz_append rpl_argz_append
00425
00426 static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
00427                     const char *buf, size_t buf_len));
00428
00429 static error_t
00430 argz_append (pargz, pargz_len, buf, buf_len)
00431      char **pargz;
00432      size_t *pargz_len;
00433      const char *buf;
00434      size_t buf_len;
00435 {
00436   size_t argz_len;
00437   char  *argz;
00438
00439   assert (pargz);
00440   assert (pargz_len);
00441   assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
00442
00443   /* If nothing needs to be appended, no more work is required.  */
00444   if (buf_len == 0)
00445     return 0;
00446
00447   /* Ensure there is enough room to append BUF_LEN.  */
00448   argz_len = *pargz_len + buf_len;
00449   argz = LT_DLREALLOC (char, *pargz, argz_len);
00450   if (!argz)
00451     return ENOMEM;
00452
00453   /* Copy characters from BUF after terminating '\0' in ARGZ.  */
00454   memcpy (argz + *pargz_len, buf, buf_len);
00455
00456   /* Assign new values.  */
00457   *pargz = argz;
00458   *pargz_len = argz_len;
00459
00460   return 0;
00461 }
00462 #endif /* !HAVE_ARGZ_APPEND */
00463
00464
00465 #if ! HAVE_ARGZ_CREATE_SEP
00466 #  define argz_create_sep rpl_argz_create_sep
00467
00468 static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
00469                         char **pargz, size_t *pargz_len));
00470
00471 static error_t
00472 argz_create_sep (str, delim, pargz, pargz_len)
00473      const char *str;
00474      int delim;
00475      char **pargz;
00476      size_t *pargz_len;
00477 {
00478   size_t argz_len;
00479   char *argz = NULL;
00480
00481   assert (str);
00482   assert (pargz);
00483   assert (pargz_len);
00484
00485   /* Make a copy of STR, but replacing each occurence of
00486      DELIM with '\0'.  */
00487   argz_len = 1+ LT_STRLEN (str);
00488   if (argz_len)
00489     {
00490       const char *p;
00491       char *q;
00492
00493       argz = LT_DLMALLOC (char, argz_len);
00494       if (!argz)
00495     return ENOMEM;
00496
00497       for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
00498     {
00499       if (*p == delim)
00500         {
00501           /* Ignore leading delimiters, and fold consecutive
00502          delimiters in STR into a single '\0' in ARGZ.  */
00503           if ((q > argz) && (q[-1] != LT_EOS_CHAR))
00504         *q++ = LT_EOS_CHAR;
00505           else
00506         --argz_len;
00507         }
00508       else
00509         *q++ = *p;
00510     }
00511       /* Copy terminating LT_EOS_CHAR.  */
00512       *q = *p;
00513     }
00514
00515   /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */
00516   if (!argz_len)
00517     LT_DLFREE (argz);
00518
00519   /* Assign new values.  */
00520   *pargz = argz;
00521   *pargz_len = argz_len;
00522
00523   return 0;
00524 }
00525 #endif /* !HAVE_ARGZ_CREATE_SEP */
00526
00527
00528 #if ! HAVE_ARGZ_INSERT
00529 #  define argz_insert rpl_argz_insert
00530
00531 static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
00532                     char *before, const char *entry));
00533
00534 static error_t
00535 argz_insert (pargz, pargz_len, before, entry)
00536      char **pargz;
00537      size_t *pargz_len;
00538      char *before;
00539      const char *entry;
00540 {
00541   assert (pargz);
00542   assert (pargz_len);
00543   assert (entry && *entry);
00544
00545   /* No BEFORE address indicates ENTRY should be inserted after the
00546      current last element.  */
00547   if (!before)
00548     return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
00549
00550   /* This probably indicates a programmer error, but to preserve
00551      semantics, scan back to the start of an entry if BEFORE points
00552      into the middle of it.  */
00553   while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))
00554     --before;
00555
00556   {
00557     size_t entry_len    = 1+ LT_STRLEN (entry);
00558     size_t argz_len = *pargz_len + entry_len;
00559     size_t offset   = before - *pargz;
00560     char   *argz    = LT_DLREALLOC (char, *pargz, argz_len);
00561
00562     if (!argz)
00563       return ENOMEM;
00564
00565     /* Make BEFORE point to the equivalent offset in ARGZ that it
00566        used to have in *PARGZ incase realloc() moved the block.  */
00567     before = argz + offset;
00568
00569     /* Move the ARGZ entries starting at BEFORE up into the new
00570        space at the end -- making room to copy ENTRY into the
00571        resulting gap.  */
00572     memmove (before + entry_len, before, *pargz_len - offset);
00573     memcpy  (before, entry, entry_len);
00574
00575     /* Assign new values.  */
00576     *pargz = argz;
00577     *pargz_len = argz_len;
00578   }
00579
00580   return 0;
00581 }
00582 #endif /* !HAVE_ARGZ_INSERT */
00583
00584
00585 #if ! HAVE_ARGZ_NEXT
00586 #  define argz_next rpl_argz_next
00587
00588 static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
00589                     const char *entry));
00590
00591 static char *
00592 argz_next (argz, argz_len, entry)
00593      char *argz;
00594      size_t argz_len;
00595      const char *entry;
00596 {
00597   assert ((argz && argz_len) || (!argz && !argz_len));
00598
00599   if (entry)
00600     {
00601       /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
00602      within the ARGZ vector.  */
00603       assert ((!argz && !argz_len)
00604           || ((argz <= entry) && (entry < (argz + argz_len))));
00605
00606       /* Move to the char immediately after the terminating
00607      '\0' of ENTRY.  */
00608       entry = 1+ strchr (entry, LT_EOS_CHAR);
00609
00610       /* Return either the new ENTRY, or else NULL if ARGZ is
00611      exhausted.  */
00612       return (entry >= argz + argz_len) ? 0 : (char *) entry;
00613     }
00614   else
00615     {
00616       /* This should probably be flagged as a programmer error,
00617      since starting an argz_next loop with the iterator set
00618      to ARGZ is safer.  To preserve semantics, handle the NULL
00619      case by returning the start of ARGZ (if any).  */
00620       if (argz_len > 0)
00621     return argz;
00622       else
00623     return 0;
00624     }
00625 }
00626 #endif /* !HAVE_ARGZ_NEXT */
00627
00628
00629
00630 #if ! HAVE_ARGZ_STRINGIFY
00631 #  define argz_stringify rpl_argz_stringify
00632
00633 static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
00634                        int sep));
00635
00636 static void
00637 argz_stringify (argz, argz_len, sep)
00638      char *argz;
00639      size_t argz_len;
00640      int sep;
00641 {
00642   assert ((argz && argz_len) || (!argz && !argz_len));
00643
00644   if (sep)
00645     {
00646       --argz_len;       /* don't stringify the terminating EOS */
00647       while (--argz_len > 0)
00648     {
00649       if (argz[argz_len] == LT_EOS_CHAR)
00650         argz[argz_len] = sep;
00651     }
00652     }
00653 }
00654 #endif /* !HAVE_ARGZ_STRINGIFY */
00655
00656
00657
00658
00659 /* --- TYPE DEFINITIONS -- */
00660
00661
00662 /* This type is used for the array of caller data sets in each handler. */
00663 typedef struct {
00664   lt_dlcaller_id    key;
00665   lt_ptr        data;
00666 } lt_caller_data;
00667
00668
00669
00670
00671 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
00672
00673
00674 /* Extract the diagnostic strings from the error table macro in the same
00675    order as the enumerated indices in ltdl.h. */
00676
00677 static const char *lt_dlerror_strings[] =
00678   {
00679 #define LT_ERROR(name, diagnostic)  (diagnostic),
00680     lt_dlerror_table
00681 #undef LT_ERROR
00682
00683     0
00684   };
00685
00686 /* This structure is used for the list of registered loaders. */
00687 struct lt_dlloader {
00688   struct lt_dlloader   *next;
00689   const char           *loader_name;    /* identifying name for each loader */
00690   const char           *sym_prefix; /* prefix for symbols */
00691   lt_module_open       *module_open;
00692   lt_module_close      *module_close;
00693   lt_find_sym          *find_sym;
00694   lt_dlloader_exit     *dlloader_exit;
00695   lt_user_data      dlloader_data;
00696 };
00697
00698 struct lt_dlhandle_struct {
00699   struct lt_dlhandle_struct   *next;
00700   lt_dlloader          *loader;     /* dlopening interface */
00701   lt_dlinfo     info;
00702   int           depcount;   /* number of dependencies */
00703   lt_dlhandle          *deplibs;    /* dependencies */
00704   lt_module     module;     /* system module handle */
00705   lt_ptr        system;     /* system specific data */
00706   lt_caller_data       *caller_data;    /* per caller associated data */
00707   int           flags;      /* various boolean stats */
00708 };
00709
00710 /* Various boolean flags can be stored in the flags field of an
00711    lt_dlhandle_struct... */
00712 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
00713 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
00714
00715 #define LT_DLRESIDENT_FLAG      (0x01 << 0)
00716 /* ...add more flags here... */
00717
00718 #define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
00719
00720
00721 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
00722
00723 static  const char  objdir[]        = LTDL_OBJDIR;
00724 static  const char  archive_ext[]       = LTDL_ARCHIVE_EXT;
00725 #ifdef  LTDL_SHLIB_EXT
00726 static  const char  shlib_ext[]     = LTDL_SHLIB_EXT;
00727 #endif
00728 #ifdef  LTDL_SYSSEARCHPATH
00729 static  const char  sys_search_path[]   = LTDL_SYSSEARCHPATH;
00730 #endif
00731
00732
00733
00734
00735 /* --- MUTEX LOCKING --- */
00736
00737
00738 /* Macros to make it easier to run the lock functions only if they have
00739    been registered.  The reason for the complicated lock macro is to
00740    ensure that the stored error message from the last error is not
00741    accidentally erased if the current function doesn't generate an
00742    error of its own.  */
00743 #define LT_DLMUTEX_LOCK()           LT_STMT_START { \
00744     if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)();    \
00745                         } LT_STMT_END
00746 #define LT_DLMUTEX_UNLOCK()         LT_STMT_START { \
00747     if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
00748                         } LT_STMT_END
00749 #define LT_DLMUTEX_SETERROR(errormsg)       LT_STMT_START { \
00750     if (lt_dlmutex_seterror_func)               \
00751         (*lt_dlmutex_seterror_func) (errormsg);     \
00752     else    lt_dllast_error = (errormsg);   } LT_STMT_END
00753 #define LT_DLMUTEX_GETERROR(errormsg)       LT_STMT_START { \
00754     if (lt_dlmutex_seterror_func)               \
00755         (errormsg) = (*lt_dlmutex_geterror_func) ();    \
00756     else    (errormsg) = lt_dllast_error;   } LT_STMT_END
00757
00758 /* The mutex functions stored here are global, and are necessarily the
00759    same for all threads that wish to share access to libltdl.  */
00760 static  lt_dlmutex_lock     *lt_dlmutex_lock_func     = NULL;
00761 static  lt_dlmutex_unlock   *lt_dlmutex_unlock_func   = NULL;
00762 static  lt_dlmutex_seterror *lt_dlmutex_seterror_func = NULL;
00763 static  lt_dlmutex_geterror *lt_dlmutex_geterror_func = NULL;
00764 static  const char      *lt_dllast_error          = NULL;
00765
00766
00767 /* Either set or reset the mutex functions.  Either all the arguments must
00768    be valid functions, or else all can be NULL to turn off locking entirely.
00769    The registered functions should be manipulating a static global lock
00770    from the lock() and unlock() callbacks, which needs to be reentrant.  */
00771 int
00772 lt_dlmutex_register (lock, unlock, seterror, geterror)
00773      lt_dlmutex_lock *lock;
00774      lt_dlmutex_unlock *unlock;
00775      lt_dlmutex_seterror *seterror;
00776      lt_dlmutex_geterror *geterror;
00777 {
00778   lt_dlmutex_unlock *old_unlock = unlock;
00779   int            errors = 0;
00780
00781   /* Lock using the old lock() callback, if any.  */
00782   LT_DLMUTEX_LOCK ();
00783
00784   if ((lock && unlock && seterror && geterror)
00785       || !(lock || unlock || seterror || geterror))
00786     {
00787       lt_dlmutex_lock_func     = lock;
00788       lt_dlmutex_unlock_func   = unlock;
00789       lt_dlmutex_geterror_func = geterror;
00790     }
00791   else
00792     {
00793       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
00794       ++errors;
00795     }
00796
00797   /* Use the old unlock() callback we saved earlier, if any.  Otherwise
00798      record any errors using internal storage.  */
00799   if (old_unlock)
00800     (*old_unlock) ();
00801
00802   /* Return the number of errors encountered during the execution of
00803      this function.  */
00804   return errors;
00805 }
00806
00807
00808
00809
00810 /* --- ERROR HANDLING --- */
00811
00812
00813 static  const char    **user_error_strings  = NULL;
00814 static  int     errorcount      = LT_ERROR_MAX;
00815
00816 int
00817 lt_dladderror (diagnostic)
00818      const char *diagnostic;
00819 {
00820   int       errindex = 0;
00821   int       result   = -1;
00822   const char  **temp     = NULL;
00823
00824   assert (diagnostic);
00825
00826   LT_DLMUTEX_LOCK ();
00827
00828   errindex = errorcount - LT_ERROR_MAX;
00829   temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
00830   if (temp)
00831     {
00832       user_error_strings        = temp;
00833       user_error_strings[errindex]  = diagnostic;
00834       result                = errorcount++;
00835     }
00836
00837   LT_DLMUTEX_UNLOCK ();
00838
00839   return result;
00840 }
00841
00842 int
00843 lt_dlseterror (errindex)
00844      int errindex;
00845 {
00846   int       errors   = 0;
00847
00848   LT_DLMUTEX_LOCK ();
00849
00850   if (errindex >= errorcount || errindex < 0)
00851     {
00852       /* Ack!  Error setting the error message! */
00853       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
00854       ++errors;
00855     }
00856   else if (errindex < LT_ERROR_MAX)
00857     {
00858       /* No error setting the error message! */
00859       LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
00860     }
00861   else
00862     {
00863       /* No error setting the error message! */
00864       LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
00865     }
00866
00867   LT_DLMUTEX_UNLOCK ();
00868
00869   return errors;
00870 }
00871
00872 static lt_ptr
00873 lt_emalloc (size)
00874      size_t size;
00875 {
00876   lt_ptr mem = lt_dlmalloc (size);
00877   if (size && !mem)
00878     LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
00879   return mem;
00880 }
00881
00882 static lt_ptr
00883 lt_erealloc (addr, size)
00884      lt_ptr addr;
00885      size_t size;
00886 {
00887   lt_ptr mem = realloc (addr, size);
00888   if (size && !mem)
00889     LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
00890   return mem;
00891 }
00892
00893 static char *
00894 lt_estrdup (str)
00895      const char *str;
00896 {
00897   char *copy = strdup (str);
00898   if (LT_STRLEN (str) && !copy)
00899     LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
00900   return copy;
00901 }
00902
00903
00904
00905
00906 /* --- DLOPEN() INTERFACE LOADER --- */
00907
00908
00909 /* The Cygwin dlopen implementation prints a spurious error message to
00910    stderr if its call to LoadLibrary() fails for any reason.  We can
00911    mitigate this by not using the Cygwin implementation, and falling
00912    back to our own LoadLibrary() wrapper. */
00913 #if HAVE_LIBDL && !defined(__CYGWIN__)
00914
00915 /* dynamic linking with dlopen/dlsym */
00916
00917 #if HAVE_DLFCN_H
00918 #  include <dlfcn.h>
00919 #endif
00920
00921 #if HAVE_SYS_DL_H
00922 #  include <sys/dl.h>
00923 #endif
00924
00925 #ifdef RTLD_GLOBAL
00926 #  define LT_GLOBAL     RTLD_GLOBAL
00927 #else
00928 #  ifdef DL_GLOBAL
00929 #    define LT_GLOBAL       DL_GLOBAL
00930 #  endif
00931 #endif /* !RTLD_GLOBAL */
00932 #ifndef LT_GLOBAL
00933 #  define LT_GLOBAL     0
00934 #endif /* !LT_GLOBAL */
00935
00936 /* We may have to define LT_LAZY_OR_NOW in the command line if we
00937    find out it does not work in some platform. */
00938 #ifndef LT_LAZY_OR_NOW
00939 #  ifdef RTLD_LAZY
00940 #    define LT_LAZY_OR_NOW  RTLD_LAZY
00941 #  else
00942 #    ifdef DL_LAZY
00943 #      define LT_LAZY_OR_NOW    DL_LAZY
00944 #    endif
00945 #  endif /* !RTLD_LAZY */
00946 #endif
00947 #ifndef LT_LAZY_OR_NOW
00948 #  ifdef RTLD_NOW
00949 #    define LT_LAZY_OR_NOW  RTLD_NOW
00950 #  else
00951 #    ifdef DL_NOW
00952 #      define LT_LAZY_OR_NOW    DL_NOW
00953 #    endif
00954 #  endif /* !RTLD_NOW */
00955 #endif
00956 #ifndef LT_LAZY_OR_NOW
00957 #  define LT_LAZY_OR_NOW    0
00958 #endif /* !LT_LAZY_OR_NOW */
00959
00960 #if HAVE_DLERROR
00961 #  define DLERROR(arg)  dlerror ()
00962 #else
00963 #  define DLERROR(arg)  LT_DLSTRERROR (arg)
00964 #endif
00965
00966 static lt_module
00967 sys_dl_open (loader_data, filename)
00968      lt_user_data loader_data;
00969      const char *filename;
00970 {
00971   lt_module   module   = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
00972
00973   if (!module)
00974     {
00975       LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
00976     }
00977
00978   return module;
00979 }
00980
00981 static int
00982 sys_dl_close (loader_data, module)
00983      lt_user_data loader_data;
00984      lt_module module;
00985 {
00986   int errors = 0;
00987
00988   if (dlclose (module) != 0)
00989     {
00990       LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
00991       ++errors;
00992     }
00993
00994   return errors;
00995 }
00996
00997 static lt_ptr
00998 sys_dl_sym (loader_data, module, symbol)
00999      lt_user_data loader_data;
01000      lt_module module;
01001      const char *symbol;
01002 {
01003   lt_ptr address = dlsym (module, symbol);
01004
01005   if (!address)
01006     {
01007       LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
01008     }
01009
01010   return address;
01011 }
01012
01013 static struct lt_user_dlloader sys_dl =
01014   {
01015 #  ifdef NEED_USCORE
01016     "_",
01017 #  else
01018     0,
01019 #  endif
01020     sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
01021
01022
01023 #endif /* HAVE_LIBDL */
01024
01025
01026
01027 /* --- SHL_LOAD() INTERFACE LOADER --- */
01028
01029 #if HAVE_SHL_LOAD
01030
01031 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
01032
01033 #ifdef HAVE_DL_H
01034 #  include <dl.h>
01035 #endif
01036
01037 /* some flags are missing on some systems, so we provide
01038  * harmless defaults.
01039  *
01040  * Mandatory:
01041  * BIND_IMMEDIATE  - Resolve symbol references when the library is loaded.
01042  * BIND_DEFERRED   - Delay code symbol resolution until actual reference.
01043  *
01044  * Optionally:
01045  * BIND_FIRST      - Place the library at the head of the symbol search
01046  *           order.
01047  * BIND_NONFATAL   - The default BIND_IMMEDIATE behavior is to treat all
01048  *           unsatisfied symbols as fatal.  This flag allows
01049  *           binding of unsatisfied code symbols to be deferred
01050  *           until use.
01051  *           [Perl: For certain libraries, like DCE, deferred
01052  *           binding often causes run time problems. Adding
01053  *           BIND_NONFATAL to BIND_IMMEDIATE still allows
01054  *           unresolved references in situations like this.]
01055  * BIND_NOSTART    - Do not call the initializer for the shared library
01056  *           when the library is loaded, nor on a future call to
01057  *           shl_unload().
01058  * BIND_VERBOSE    - Print verbose messages concerning possible
01059  *           unsatisfied symbols.
01060  *
01061  * hp9000s700/hp9000s800:
01062  * BIND_RESTRICTED - Restrict symbols visible by the library to those
01063  *           present at library load time.
01064  * DYNAMIC_PATH    - Allow the loader to dynamically search for the
01065  *           library specified by the path argument.
01066  */
01067
01068 #ifndef DYNAMIC_PATH
01069 #  define DYNAMIC_PATH      0
01070 #endif
01071 #ifndef BIND_RESTRICTED
01072 #  define BIND_RESTRICTED   0
01073 #endif
01074
01075 #define LT_BIND_FLAGS   (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
01076
01077 static lt_module
01078 sys_shl_open (loader_data, filename)
01079      lt_user_data loader_data;
01080      const char *filename;
01081 {
01082   static shl_t self = (shl_t) 0;
01083   lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
01084
01085   /* Since searching for a symbol against a NULL module handle will also
01086      look in everything else that was already loaded and exported with
01087      the -E compiler flag, we always cache a handle saved before any
01088      modules are loaded.  */
01089   if (!self)
01090     {
01091       lt_ptr address;
01092       shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
01093     }
01094
01095   if (!filename)
01096     {
01097       module = self;
01098     }
01099   else
01100     {
01101       module = shl_load (filename, LT_BIND_FLAGS, 0L);
01102
01103       if (!module)
01104     {
01105       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
01106     }
01107     }
01108
01109   return module;
01110 }
01111
01112 static int
01113 sys_shl_close (loader_data, module)
01114      lt_user_data loader_data;
01115      lt_module module;
01116 {
01117   int errors = 0;
01118
01119   if (module && (shl_unload ((shl_t) (module)) != 0))
01120     {
01121       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
01122       ++errors;
01123     }
01124
01125   return errors;
01126 }
01127
01128 static lt_ptr
01129 sys_shl_sym (loader_data, module, symbol)
01130      lt_user_data loader_data;
01131      lt_module module;
01132      const char *symbol;
01133 {
01134   lt_ptr address = NULL;
01135
01136   /* sys_shl_open should never return a NULL module handle */
01137   if (module == (lt_module) 0)
01138   {
01139     LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
01140   }
01141   else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
01142     {
01143       if (!address)
01144     {
01145       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
01146     }
01147     }
01148
01149   return address;
01150 }
01151
01152 static struct lt_user_dlloader sys_shl = {
01153   0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
01154 };
01155
01156 #endif /* HAVE_SHL_LOAD */
01157
01158
01159
01160
01161 /* --- LOADLIBRARY() INTERFACE LOADER --- */
01162
01163 #ifdef __WINDOWS__
01164
01165 /* dynamic linking for Win32 */
01166
01167 #include <windows.h>
01168
01169 /* Forward declaration; required to implement handle search below. */
01170 static lt_dlhandle handles;
01171
01172 static lt_module
01173 sys_wll_open (loader_data, filename)
01174      lt_user_data loader_data;
01175      const char *filename;
01176 {
01177   lt_dlhandle   cur;
01178   lt_module module     = NULL;
01179   const char   *errormsg   = NULL;
01180   char         *searchname = NULL;
01181   char         *ext;
01182   char      self_name_buf[MAX_PATH];
01183
01184   if (!filename)
01185     {
01186       /* Get the name of main module */
01187       *self_name_buf = '\0';
01188       GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
01189       filename = ext = self_name_buf;
01190     }
01191   else
01192     {
01193       ext = strrchr (filename, '.');
01194     }
01195
01196   if (ext)
01197     {
01198       /* FILENAME already has an extension. */
01199       searchname = lt_estrdup (filename);
01200     }
01201   else
01202     {
01203       /* Append a `.' to stop Windows from adding an
01204      implicit `.dll' extension. */
01205       searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
01206       if (searchname)
01207     sprintf (searchname, "%s.", filename);
01208     }
01209   if (!searchname)
01210     return 0;
01211
01212 #if __CYGWIN__
01213   {
01214     char wpath[MAX_PATH];
01215     cygwin_conv_to_full_win32_path(searchname, wpath);
01216     module = LoadLibrary(wpath);
01217   }
01218 #else
01219   module = LoadLibrary (searchname);
01220 #endif
01221   LT_DLFREE (searchname);
01222
01223   /* libltdl expects this function to fail if it is unable
01224      to physically load the library.  Sadly, LoadLibrary
01225      will search the loaded libraries for a match and return
01226      one of them if the path search load fails.
01227
01228      We check whether LoadLibrary is returning a handle to
01229      an already loaded module, and simulate failure if we
01230      find one. */
01231   LT_DLMUTEX_LOCK ();
01232   cur = handles;
01233   while (cur)
01234     {
01235       if (!cur->module)
01236     {
01237       cur = NULL;
01238       break;
01239     }
01240
01241       if (cur->module == module)
01242     {
01243       break;
01244     }
01245
01246       cur = cur->next;
01247   }
01248   LT_DLMUTEX_UNLOCK ();
01249
01250   if (cur || !module)
01251     {
01252       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
01253       module = NULL;
01254     }
01255
01256   return module;
01257 }
01258
01259 static int
01260 sys_wll_close (loader_data, module)
01261      lt_user_data loader_data;
01262      lt_module module;
01263 {
01264   int         errors   = 0;
01265
01266   if (FreeLibrary(module) == 0)
01267     {
01268       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
01269       ++errors;
01270     }
01271
01272   return errors;
01273 }
01274
01275 static lt_ptr
01276 sys_wll_sym (loader_data, module, symbol)
01277      lt_user_data loader_data;
01278      lt_module module;
01279      const char *symbol;
01280 {
01281   lt_ptr      address  = GetProcAddress (module, symbol);
01282
01283   if (!address)
01284     {
01285       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
01286     }
01287
01288   return address;
01289 }
01290
01291 static struct lt_user_dlloader sys_wll = {
01292   0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
01293 };
01294
01295 #endif /* __WINDOWS__ */
01296
01297
01298
01299
01300 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
01301
01302
01303 #ifdef __BEOS__
01304
01305 /* dynamic linking for BeOS */
01306
01307 #include <kernel/image.h>
01308
01309 static lt_module
01310 sys_bedl_open (loader_data, filename)
01311      lt_user_data loader_data;
01312      const char *filename;
01313 {
01314   image_id image = 0;
01315
01316   if (filename)
01317     {
01318       image = load_add_on (filename);
01319     }
01320   else
01321     {
01322       image_info info;
01323       int32 cookie = 0;
01324       if (get_next_image_info (0, &cookie, &info) == B_OK)
01325     image = load_add_on (info.name);
01326     }
01327
01328   if (image <= 0)
01329     {
01330       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
01331       image = 0;
01332     }
01333
01334   return (lt_module) image;
01335 }
01336
01337 static int
01338 sys_bedl_close (loader_data, module)
01339      lt_user_data loader_data;
01340      lt_module module;
01341 {
01342   int errors = 0;
01343
01344   if (unload_add_on ((image_id) module) != B_OK)
01345     {
01346       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
01347       ++errors;
01348     }
01349
01350   return errors;
01351 }
01352
01353 static lt_ptr
01354 sys_bedl_sym (loader_data, module, symbol)
01355      lt_user_data loader_data;
01356      lt_module module;
01357      const char *symbol;
01358 {
01359   lt_ptr address = NULL;
01360   image_id image = (image_id) module;
01361
01362   if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
01363     {
01364       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
01365       address = NULL;
01366     }
01367
01368   return address;
01369 }
01370
01371 static struct lt_user_dlloader sys_bedl = {
01372   0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
01373 };
01374
01375 #endif /* __BEOS__ */
01376
01377
01378
01379
01380 /* --- DLD_LINK() INTERFACE LOADER --- */
01381
01382
01383 #if HAVE_DLD
01384
01385 /* dynamic linking with dld */
01386
01387 #if HAVE_DLD_H
01388 #include <dld.h>
01389 #endif
01390
01391 static lt_module
01392 sys_dld_open (loader_data, filename)
01393      lt_user_data loader_data;
01394      const char *filename;
01395 {
01396   lt_module module = strdup (filename);
01397
01398   if (dld_link (filename) != 0)
01399     {
01400       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
01401       LT_DLFREE (module);
01402       module = NULL;
01403     }
01404
01405   return module;
01406 }
01407
01408 static int
01409 sys_dld_close (loader_data, module)
01410      lt_user_data loader_data;
01411      lt_module module;
01412 {
01413   int errors = 0;
01414
01415   if (dld_unlink_by_file ((char*)(module), 1) != 0)
01416     {
01417       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
01418       ++errors;
01419     }
01420   else
01421     {
01422       LT_DLFREE (module);
01423     }
01424
01425   return errors;
01426 }
01427
01428 static lt_ptr
01429 sys_dld_sym (loader_data, module, symbol)
01430      lt_user_data loader_data;
01431      lt_module module;
01432      const char *symbol;
01433 {
01434   lt_ptr address = dld_get_func (symbol);
01435
01436   if (!address)
01437     {
01438       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
01439     }
01440
01441   return address;
01442 }
01443
01444 static struct lt_user_dlloader sys_dld = {
01445   0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
01446 };
01447
01448 #endif /* HAVE_DLD */
01449
01450
01451
01452
01453 /* --- DLPREOPEN() INTERFACE LOADER --- */
01454
01455
01456 /* emulate dynamic linking using preloaded_symbols */
01457
01458 typedef struct lt_dlsymlists_t
01459 {
01460   struct lt_dlsymlists_t       *next;
01461   const lt_dlsymlist           *syms;
01462 } lt_dlsymlists_t;
01463
01464 static  const lt_dlsymlist     *default_preloaded_symbols   = NULL;
01465 static  lt_dlsymlists_t        *preloaded_symbols       = NULL;
01466
01467 static int
01468 presym_init (loader_data)
01469      lt_user_data loader_data;
01470 {
01471   int errors = 0;
01472
01473   LT_DLMUTEX_LOCK ();
01474
01475   preloaded_symbols = NULL;
01476   if (default_preloaded_symbols)
01477     {
01478       errors = lt_dlpreload (default_preloaded_symbols);
01479     }
01480
01481   LT_DLMUTEX_UNLOCK ();
01482
01483   return errors;
01484 }
01485
01486 static int
01487 presym_free_symlists ()
01488 {
01489   lt_dlsymlists_t *lists;
01490
01491   LT_DLMUTEX_LOCK ();
01492
01493   lists = preloaded_symbols;
01494   while (lists)
01495     {
01496       lt_dlsymlists_t   *tmp = lists;
01497
01498       lists = lists->next;
01499       LT_DLFREE (tmp);
01500     }
01501   preloaded_symbols = NULL;
01502
01503   LT_DLMUTEX_UNLOCK ();
01504
01505   return 0;
01506 }
01507
01508 static int
01509 presym_exit (loader_data)
01510      lt_user_data loader_data;
01511 {
01512   presym_free_symlists ();
01513   return 0;
01514 }
01515
01516 static int
01517 presym_add_symlist (preloaded)
01518      const lt_dlsymlist *preloaded;
01519 {
01520   lt_dlsymlists_t *tmp;
01521   lt_dlsymlists_t *lists;
01522   int          errors   = 0;
01523
01524   LT_DLMUTEX_LOCK ();
01525
01526   lists = preloaded_symbols;
01527   while (lists)
01528     {
01529       if (lists->syms == preloaded)
01530     {
01531       goto done;
01532     }
01533       lists = lists->next;
01534     }
01535
01536   tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
01537   if (tmp)
01538     {
01539       memset (tmp, 0, sizeof(lt_dlsymlists_t));
01540       tmp->syms = preloaded;
01541       tmp->next = preloaded_symbols;
01542       preloaded_symbols = tmp;
01543     }
01544   else
01545     {
01546       ++errors;
01547     }
01548
01549  done:
01550   LT_DLMUTEX_UNLOCK ();
01551   return errors;
01552 }
01553
01554 static lt_module
01555 presym_open (loader_data, filename)
01556      lt_user_data loader_data;
01557      const char *filename;
01558 {
01559   lt_dlsymlists_t *lists;
01560   lt_module    module = (lt_module) 0;
01561
01562   LT_DLMUTEX_LOCK ();
01563   lists = preloaded_symbols;
01564
01565   if (!lists)
01566     {
01567       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
01568       goto done;
01569     }
01570
01571   /* Can't use NULL as the reflective symbol header, as NULL is
01572      used to mark the end of the entire symbol list.  Self-dlpreopened
01573      symbols follow this magic number, chosen to be an unlikely
01574      clash with a real module name.  */
01575   if (!filename)
01576     {
01577       filename = "@PROGRAM@";
01578     }
01579
01580   while (lists)
01581     {
01582       const lt_dlsymlist *syms = lists->syms;
01583
01584       while (syms->name)
01585     {
01586       if (!syms->address && strcmp(syms->name, filename) == 0)
01587         {
01588           module = (lt_module) syms;
01589           goto done;
01590         }
01591       ++syms;
01592     }
01593
01594       lists = lists->next;
01595     }
01596
01597   LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
01598
01599  done:
01600   LT_DLMUTEX_UNLOCK ();
01601   return module;
01602 }
01603
01604 static int
01605 presym_close (loader_data, module)
01606      lt_user_data loader_data;
01607      lt_module module;
01608 {
01609   /* Just to silence gcc -Wall */
01610   module = NULL;
01611   return 0;
01612 }
01613
01614 static lt_ptr
01615 presym_sym (loader_data, module, symbol)
01616      lt_user_data loader_data;
01617      lt_module module;
01618      const char *symbol;
01619 {
01620   lt_dlsymlist *syms = (lt_dlsymlist*) module;
01621
01622   ++syms;
01623   while (syms->address)
01624     {
01625       if (strcmp(syms->name, symbol) == 0)
01626     {
01627       return syms->address;
01628     }
01629
01630     ++syms;
01631   }
01632
01633   LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
01634
01635   return 0;
01636 }
01637
01638 static struct lt_user_dlloader presym = {
01639   0, presym_open, presym_close, presym_sym, presym_exit, 0
01640 };
01641
01642
01643
01644
01645
01646 /* --- DYNAMIC MODULE LOADING --- */
01647
01648
01649 /* The type of a function used at each iteration of  foreach_dirinpath().  */
01650 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
01651                          lt_ptr data2));
01652
01653 static  int foreach_dirinpath     LT_PARAMS((const char *search_path,
01654                          const char *base_name,
01655                          foreach_callback_func *func,
01656                          lt_ptr data1, lt_ptr data2));
01657
01658 static  int find_file_callback    LT_PARAMS((char *filename, lt_ptr data,
01659                          lt_ptr ignored));
01660 static  int find_handle_callback  LT_PARAMS((char *filename, lt_ptr data,
01661                          lt_ptr ignored));
01662 static  int foreachfile_callback  LT_PARAMS((char *filename, lt_ptr data1,
01663                          lt_ptr data2));
01664
01665
01666 static  int     canonicalize_path     LT_PARAMS((const char *path,
01667                          char **pcanonical));
01668 static  int argzize_path          LT_PARAMS((const char *path,
01669                          char **pargz,
01670                          size_t *pargz_len));
01671 static  FILE   *find_file         LT_PARAMS((const char *search_path,
01672                          const char *base_name,
01673                          char **pdir));
01674 static  lt_dlhandle *find_handle      LT_PARAMS((const char *search_path,
01675                          const char *base_name,
01676                          lt_dlhandle *handle));
01677 static  int find_module       LT_PARAMS((lt_dlhandle *handle,
01678                          const char *dir,
01679                          const char *libdir,
01680                          const char *dlname,
01681                          const char *old_name,
01682                          int installed));
01683 static  int free_vars         LT_PARAMS((char *dlname, char *oldname,
01684                          char *libdir, char *deplibs));
01685 static  int load_deplibs          LT_PARAMS((lt_dlhandle handle,
01686                          char *deplibs));
01687 static  int trim              LT_PARAMS((char **dest,
01688                          const char *str));
01689 static  int try_dlopen        LT_PARAMS((lt_dlhandle *handle,
01690                          const char *filename));
01691 static  int tryall_dlopen         LT_PARAMS((lt_dlhandle *handle,
01692                          const char *filename));
01693 static  int unload_deplibs        LT_PARAMS((lt_dlhandle handle));
01694 static  int lt_argz_insert        LT_PARAMS((char **pargz,
01695                          size_t *pargz_len,
01696                          char *before,
01697                          const char *entry));
01698 static  int lt_argz_insertinorder LT_PARAMS((char **pargz,
01699                          size_t *pargz_len,
01700                          const char *entry));
01701 static  int lt_argz_insertdir     LT_PARAMS((char **pargz,
01702                          size_t *pargz_len,
01703                          const char *dirnam,
01704                          struct dirent *dp));
01705 static  int lt_dlpath_insertdir   LT_PARAMS((char **ppath,
01706                          char *before,
01707                          const char *dir));
01708 static  int list_files_by_dir     LT_PARAMS((const char *dirnam,
01709                          char **pargz,
01710                          size_t *pargz_len));
01711 static  int file_not_found        LT_PARAMS((void));
01712
01713 static  char           *user_search_path= NULL;
01714 static  lt_dlloader    *loaders     = NULL;
01715 static  lt_dlhandle handles     = NULL;
01716 static  int     initialized     = 0;
01717
01718 /* Initialize libltdl. */
01719 int
01720 lt_dlinit ()
01721 {
01722   int         errors   = 0;
01723
01724   LT_DLMUTEX_LOCK ();
01725
01726   /* Initialize only at first call. */
01727   if (++initialized == 1)
01728     {
01729       handles = NULL;
01730       user_search_path = NULL; /* empty search path */
01731
01732 #if HAVE_LIBDL && !defined(__CYGWIN__)
01733       errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
01734 #endif
01735 #if HAVE_SHL_LOAD
01736       errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
01737 #endif
01738 #ifdef __WINDOWS__
01739       errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
01740 #endif
01741 #ifdef __BEOS__
01742       errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
01743 #endif
01744 #if HAVE_DLD
01745       errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
01746 #endif
01747       errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
01748
01749       if (presym_init (presym.dlloader_data))
01750     {
01751       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
01752       ++errors;
01753     }
01754       else if (errors != 0)
01755     {
01756       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
01757       ++errors;
01758     }
01759     }
01760
01761   LT_DLMUTEX_UNLOCK ();
01762
01763   return errors;
01764 }
01765
01766 int
01767 lt_dlpreload (preloaded)
01768      const lt_dlsymlist *preloaded;
01769 {
01770   int errors = 0;
01771
01772   if (preloaded)
01773     {
01774       errors = presym_add_symlist (preloaded);
01775     }
01776   else
01777     {
01778       presym_free_symlists();
01779
01780       LT_DLMUTEX_LOCK ();
01781       if (default_preloaded_symbols)
01782     {
01783       errors = lt_dlpreload (default_preloaded_symbols);
01784     }
01785       LT_DLMUTEX_UNLOCK ();
01786     }
01787
01788   return errors;
01789 }
01790
01791 int
01792 lt_dlpreload_default (preloaded)
01793      const lt_dlsymlist *preloaded;
01794 {
01795   LT_DLMUTEX_LOCK ();
01796   default_preloaded_symbols = preloaded;
01797   LT_DLMUTEX_UNLOCK ();
01798   return 0;
01799 }
01800
01801 int
01802 lt_dlexit ()
01803 {
01804   /* shut down libltdl */
01805   lt_dlloader *loader;
01806   int          errors   = 0;
01807
01808   LT_DLMUTEX_LOCK ();
01809   loader = loaders;
01810
01811   if (!initialized)
01812     {
01813       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
01814       ++errors;
01815       goto done;
01816     }
01817
01818   /* shut down only at last call. */
01819   if (--initialized == 0)
01820     {
01821       int   level;
01822
01823       while (handles && LT_DLIS_RESIDENT (handles))
01824     {
01825       handles = handles->next;
01826     }
01827
01828       /* close all modules */
01829       for (level = 1; handles; ++level)
01830     {
01831       lt_dlhandle cur = handles;
01832       int saw_nonresident = 0;
01833
01834       while (cur)
01835         {
01836           lt_dlhandle tmp = cur;
01837           cur = cur->next;
01838           if (!LT_DLIS_RESIDENT (tmp))
01839         saw_nonresident = 1;
01840           if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
01841         {
01842           if (lt_dlclose (tmp))
01843             {
01844               ++errors;
01845             }
01846         }
01847         }
01848       /* done if only resident modules are left */
01849       if (!saw_nonresident)
01850         break;
01851     }
01852
01853       /* close all loaders */
01854       while (loader)
01855     {
01856       lt_dlloader *next = loader->next;
01857       lt_user_data data = loader->dlloader_data;
01858       if (loader->dlloader_exit && loader->dlloader_exit (data))
01859         {
01860           ++errors;
01861         }
01862
01863       LT_DLMEM_REASSIGN (loader, next);
01864     }
01865       loaders = NULL;
01866     }
01867
01868  done:
01869   LT_DLMUTEX_UNLOCK ();
01870   return errors;
01871 }
01872
01873 static int
01874 tryall_dlopen (handle, filename)
01875      lt_dlhandle *handle;
01876      const char *filename;
01877 {
01878   lt_dlhandle    cur;
01879   lt_dlloader   *loader;
01880   const char    *saved_error;
01881   int        errors     = 0;
01882
01883   LT_DLMUTEX_GETERROR (saved_error);
01884   LT_DLMUTEX_LOCK ();
01885
01886   cur    = handles;
01887   loader = loaders;
01888
01889   /* check whether the module was already opened */
01890   while (cur)
01891     {
01892       /* try to dlopen the program itself? */
01893       if (!cur->info.filename && !filename)
01894     {
01895       break;
01896     }
01897
01898       if (cur->info.filename && filename
01899       && strcmp (cur->info.filename, filename) == 0)
01900     {
01901       break;
01902     }
01903
01904       cur = cur->next;
01905     }
01906
01907   if (cur)
01908     {
01909       ++cur->info.ref_count;
01910       *handle = cur;
01911       goto done;
01912     }
01913
01914   cur = *handle;
01915   if (filename)
01916     {
01917       cur->info.filename = lt_estrdup (filename);
01918       if (!cur->info.filename)
01919     {
01920       ++errors;
01921       goto done;
01922     }
01923     }
01924   else
01925     {
01926       cur->info.filename = NULL;
01927     }
01928
01929   while (loader)
01930     {
01931       lt_user_data data = loader->dlloader_data;
01932
01933       cur->module = loader->module_open (data, filename);
01934
01935       if (cur->module != NULL)
01936     {
01937       break;
01938     }
01939       loader = loader->next;
01940     }
01941
01942   if (!loader)
01943     {
01944       LT_DLFREE (cur->info.filename);
01945       ++errors;
01946       goto done;
01947     }
01948
01949   cur->loader   = loader;
01950   LT_DLMUTEX_SETERROR (saved_error);
01951
01952  done:
01953   LT_DLMUTEX_UNLOCK ();
01954
01955   return errors;
01956 }
01957
01958 static int
01959 tryall_dlopen_module (handle, prefix, dirname, dlname)
01960      lt_dlhandle *handle;
01961      const char *prefix;
01962      const char *dirname;
01963      const char *dlname;
01964 {
01965   int      error    = 0;
01966   char     *filename    = NULL;
01967   size_t   filename_len = 0;
01968   size_t   dirname_len  = LT_STRLEN (dirname);
01969
01970   assert (handle);
01971   assert (dirname);
01972   assert (dlname);
01973 #ifdef LT_DIRSEP_CHAR
01974   /* Only canonicalized names (i.e. with DIRSEP chars already converted)
01975      should make it into this function:  */
01976   assert (strchr (dirname, LT_DIRSEP_CHAR) == NULL);
01977 #endif
01978
01979   if (dirname[dirname_len -1] == '/')
01980     --dirname_len;
01981   filename_len = dirname_len + 1 + LT_STRLEN (dlname);
01982
01983   /* Allocate memory, and combine DIRNAME and MODULENAME into it.
01984      The PREFIX (if any) is handled below.  */
01985   filename  = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
01986   if (!filename)
01987     return 1;
01988
01989   sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
01990
01991   /* Now that we have combined DIRNAME and MODULENAME, if there is
01992      also a PREFIX to contend with, simply recurse with the arguments
01993      shuffled.  Otherwise, attempt to open FILENAME as a module.  */
01994   if (prefix)
01995     {
01996       error += tryall_dlopen_module (handle,
01997                      (const char *) 0, prefix, filename);
01998     }
01999   else if (tryall_dlopen (handle, filename) != 0)
02000     {
02001       ++error;
02002     }
02003
02004   LT_DLFREE (filename);
02005   return error;
02006 }
02007
02008 static int
02009 find_module (handle, dir, libdir, dlname, old_name, installed)
02010      lt_dlhandle *handle;
02011      const char *dir;
02012      const char *libdir;
02013      const char *dlname;
02014      const char *old_name;
02015      int installed;
02016 {
02017   /* Try to open the old library first; if it was dlpreopened,
02018      we want the preopened version of it, even if a dlopenable
02019      module is available.  */
02020   if (old_name && tryall_dlopen (handle, old_name) == 0)
02021     {
02022       return 0;
02023     }
02024
02025   /* Try to open the dynamic library.  */
02026   if (dlname)
02027     {
02028       /* try to open the installed module */
02029       if (installed && libdir)
02030     {
02031       if (tryall_dlopen_module (handle,
02032                     (const char *) 0, libdir, dlname) == 0)
02033         return 0;
02034     }
02035
02036       /* try to open the not-installed module */
02037       if (!installed)
02038     {
02039       if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
02040         return 0;
02041     }
02042
02043       /* maybe it was moved to another directory */
02044       {
02045       if (tryall_dlopen_module (handle,
02046                     (const char *) 0, dir, dlname) == 0)
02047         return 0;
02048       }
02049     }
02050
02051   return 1;
02052 }
02053
02054
02055 static int
02056 canonicalize_path (path, pcanonical)
02057      const char *path;
02058      char **pcanonical;
02059 {
02060   char *canonical = NULL;
02061
02062   assert (path && *path);
02063   assert (pcanonical);
02064
02065   canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
02066   if (!canonical)
02067     return 1;
02068
02069   {
02070     size_t dest = 0;
02071     size_t src;
02072     for (src = 0; path[src] != LT_EOS_CHAR; ++src)
02073       {
02074     /* Path separators are not copied to the beginning or end of
02075        the destination, or if another separator would follow
02076        immediately.  */
02077     if (path[src] == LT_PATHSEP_CHAR)
02078       {
02079         if ((dest == 0)
02080         || (path[1+ src] == LT_PATHSEP_CHAR)
02081         || (path[1+ src] == LT_EOS_CHAR))
02082           continue;
02083       }
02084
02085     /* Anything other than a directory separator is copied verbatim.  */
02086     if ((path[src] != '/')
02087 #ifdef LT_DIRSEP_CHAR
02088         && (path[src] != LT_DIRSEP_CHAR)
02089 #endif
02090         )
02091       {
02092         canonical[dest++] = path[src];
02093       }
02094     /* Directory separators are converted and copied only if they are
02095        not at the end of a path -- i.e. before a path separator or
02096        NULL terminator.  */
02097     else if ((path[1+ src] != LT_PATHSEP_CHAR)
02098          && (path[1+ src] != LT_EOS_CHAR)
02099 #ifdef LT_DIRSEP_CHAR
02100          && (path[1+ src] != LT_DIRSEP_CHAR)
02101 #endif
02102          && (path[1+ src] != '/'))
02103       {
02104         canonical[dest++] = '/';
02105       }
02106       }
02107
02108     /* Add an end-of-string marker at the end.  */
02109     canonical[dest] = LT_EOS_CHAR;
02110   }
02111
02112   /* Assign new value.  */
02113   *pcanonical = canonical;
02114
02115   return 0;
02116 }
02117
02118 static int
02119 argzize_path (path, pargz, pargz_len)
02120      const char *path;
02121      char **pargz;
02122      size_t *pargz_len;
02123 {
02124   error_t error;
02125
02126   assert (path);
02127   assert (pargz);
02128   assert (pargz_len);
02129
02130   if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
02131     {
02132       switch (error)
02133     {
02134     case ENOMEM:
02135       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
02136       break;
02137     default:
02138       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
02139       break;
02140     }
02141
02142       return 1;
02143     }
02144
02145   return 0;
02146 }
02147
02148 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
02149    of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
02150    non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
02151    it is appended to each SEARCH_PATH element before FUNC is called.  */
02152 static int
02153 foreach_dirinpath (search_path, base_name, func, data1, data2)
02154      const char *search_path;
02155      const char *base_name;
02156      foreach_callback_func *func;
02157      lt_ptr data1;
02158      lt_ptr data2;
02159 {
02160   int    result     = 0;
02161   int    filenamesize   = 0;
02162   size_t lenbase    = LT_STRLEN (base_name);
02163   size_t argz_len   = 0;
02164   char *argz        = NULL;
02165   char *filename    = NULL;
02166   char *canonical   = NULL;
02167
02168   LT_DLMUTEX_LOCK ();
02169
02170   if (!search_path || !*search_path)
02171     {
02172       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
02173       goto cleanup;
02174     }
02175
02176   if (canonicalize_path (search_path, &canonical) != 0)
02177     goto cleanup;
02178
02179   if (argzize_path (canonical, &argz, &argz_len) != 0)
02180     goto cleanup;
02181
02182   {
02183     char *dir_name = NULL;
02184     while ((dir_name = argz_next (argz, argz_len, dir_name)))
02185       {
02186     size_t lendir = LT_STRLEN (dir_name);
02187
02188     if (lendir +1 +lenbase >= filenamesize)
02189     {
02190       LT_DLFREE (filename);
02191       filenamesize  = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
02192       filename  = LT_EMALLOC (char, filenamesize);
02193       if (!filename)
02194         goto cleanup;
02195     }
02196
02197     assert (filenamesize > lendir);
02198     strcpy (filename, dir_name);
02199
02200     if (base_name && *base_name)
02201       {
02202         if (filename[lendir -1] != '/')
02203           filename[lendir++] = '/';
02204         strcpy (filename +lendir, base_name);
02205       }
02206
02207     if ((result = (*func) (filename, data1, data2)))
02208       {
02209         break;
02210       }
02211       }
02212   }
02213
02214  cleanup:
02215   LT_DLFREE (argz);
02216   LT_DLFREE (canonical);
02217   LT_DLFREE (filename);
02218
02219   LT_DLMUTEX_UNLOCK ();
02220
02221   return result;
02222 }
02223
02224 /* If FILEPATH can be opened, store the name of the directory component
02225    in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
02226    DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
02227 static int
02228 find_file_callback (filename, data1, data2)
02229      char *filename;
02230      lt_ptr data1;
02231      lt_ptr data2;
02232 {
02233   char       **pdir = (char **) data1;
02234   FILE       **pfile    = (FILE **) data2;
02235   int        is_done    = 0;
02236
02237   assert (filename && *filename);
02238   assert (pdir);
02239   assert (pfile);
02240
02241   if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
02242     {
02243       char *dirend = strrchr (filename, '/');
02244
02245       if (dirend > filename)
02246     *dirend   = LT_EOS_CHAR;
02247
02248       LT_DLFREE (*pdir);
02249       *pdir   = lt_estrdup (filename);
02250       is_done = (*pdir == NULL) ? -1 : 1;
02251     }
02252
02253   return is_done;
02254 }
02255
02256 static FILE *
02257 find_file (search_path, base_name, pdir)
02258      const char *search_path;
02259      const char *base_name;
02260      char **pdir;
02261 {
02262   FILE *file = NULL;
02263
02264   foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
02265
02266   return file;
02267 }
02268
02269 static int
02270 find_handle_callback (filename, data, ignored)
02271      char *filename;
02272      lt_ptr data;
02273      lt_ptr ignored;
02274 {
02275   lt_dlhandle  *handle      = (lt_dlhandle *) data;
02276   int       notfound    = access (filename, R_OK);
02277
02278   /* Bail out if file cannot be read...  */
02279   if (notfound)
02280     return 0;
02281
02282   /* Try to dlopen the file, but do not continue searching in any
02283      case.  */
02284   if (tryall_dlopen (handle, filename) != 0)
02285     *handle = NULL;
02286
02287   return 1;
02288 }
02289
02290 /* If HANDLE was found return it, otherwise return 0.  If HANDLE was
02291    found but could not be opened, *HANDLE will be set to 0.  */
02292 static lt_dlhandle *
02293 find_handle (search_path, base_name, handle)
02294      const char *search_path;
02295      const char *base_name;
02296      lt_dlhandle *handle;
02297 {
02298   if (!search_path)
02299     return 0;
02300
02301   if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
02302               handle, 0))
02303     return 0;
02304
02305   return handle;
02306 }
02307
02308 static int
02309 load_deplibs (handle, deplibs)
02310      lt_dlhandle handle;
02311      char *deplibs;
02312 {
02313 #if LTDL_DLOPEN_DEPLIBS
02314   char  *p, *save_search_path = NULL;
02315   int   depcount = 0;
02316   int   i;
02317   char  **names = NULL;
02318 #endif
02319   int   errors = 0;
02320
02321   handle->depcount = 0;
02322
02323 #if LTDL_DLOPEN_DEPLIBS
02324   if (!deplibs)
02325     {
02326       return errors;
02327     }
02328   ++errors;
02329
02330   LT_DLMUTEX_LOCK ();
02331   if (user_search_path)
02332     {
02333       save_search_path = lt_estrdup (user_search_path);
02334       if (!save_search_path)
02335     goto cleanup;
02336     }
02337
02338   /* extract search paths and count deplibs */
02339   p = deplibs;
02340   while (*p)
02341     {
02342       if (!isspace ((unsigned char) *p))
02343     {
02344       char *end = p+1;
02345       while (*end && !isspace((unsigned char) *end))
02346         {
02347           ++end;
02348         }
02349
02350       if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
02351         {
02352           char save = *end;
02353           *end = '\0'; /* set a temporary string terminator */
02354           if (lt_dladdsearchdir(p+2))
02355         {
02356           goto cleanup;
02357         }
02358           *end = save;
02359         }
02360       else
02361         {
02362           ++depcount;
02363         }
02364
02365       p = end;
02366     }
02367       else
02368     {
02369       ++p;
02370     }
02371     }
02372
02373   /* restore the old search path */
02374   LT_DLFREE (user_search_path);
02375   user_search_path = save_search_path;
02376
02377   LT_DLMUTEX_UNLOCK ();
02378
02379   if (!depcount)
02380     {
02381       errors = 0;
02382       goto cleanup;
02383     }
02384
02385   names = LT_EMALLOC (char *, depcount * sizeof (char*));
02386   if (!names)
02387     goto cleanup;
02388
02389   /* now only extract the actual deplibs */
02390   depcount = 0;
02391   p = deplibs;
02392   while (*p)
02393     {
02394       if (isspace ((unsigned char) *p))
02395     {
02396       ++p;
02397     }
02398       else
02399     {
02400       char *end = p+1;
02401       while (*end && !isspace ((unsigned char) *end))
02402         {
02403           ++end;
02404         }
02405
02406       if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
02407         {
02408           char *name;
02409           char save = *end;
02410           *end = '\0'; /* set a temporary string terminator */
02411           if (strncmp(p, "-l", 2) == 0)
02412         {
02413           size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
02414           name = LT_EMALLOC (char, 1+ name_len);
02415           if (name)
02416             sprintf (name, "lib%s", p+2);
02417         }
02418           else
02419         name = lt_estrdup(p);
02420
02421           if (!name)
02422         goto cleanup_names;
02423
02424           names[depcount++] = name;
02425           *end = save;
02426         }
02427       p = end;
02428     }
02429     }
02430
02431   /* load the deplibs (in reverse order)
02432      At this stage, don't worry if the deplibs do not load correctly,
02433      they may already be statically linked into the loading application
02434      for instance.  There will be a more enlightening error message
02435      later on if the loaded module cannot resolve all of its symbols.  */
02436   if (depcount)
02437     {
02438       int   j = 0;
02439
02440       handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
02441       if (!handle->deplibs)
02442     goto cleanup;
02443
02444       for (i = 0; i < depcount; ++i)
02445     {
02446       handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
02447       if (handle->deplibs[j])
02448         {
02449           ++j;
02450         }
02451     }
02452
02453       handle->depcount  = j;    /* Number of successfully loaded deplibs */
02454       errors        = 0;
02455     }
02456
02457  cleanup_names:
02458   for (i = 0; i < depcount; ++i)
02459     {
02460       LT_DLFREE (names[i]);
02461     }
02462
02463  cleanup:
02464   LT_DLFREE (names);
02465 #endif
02466
02467   return errors;
02468 }
02469
02470 static int
02471 unload_deplibs (handle)
02472      lt_dlhandle handle;
02473 {
02474   int i;
02475   int errors = 0;
02476
02477   if (handle->depcount)
02478     {
02479       for (i = 0; i < handle->depcount; ++i)
02480     {
02481       if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
02482         {
02483           errors += lt_dlclose (handle->deplibs[i]);
02484         }
02485     }
02486     }
02487
02488   return errors;
02489 }
02490
02491 static int
02492 trim (dest, str)
02493      char **dest;
02494      const char *str;
02495 {
02496   /* remove the leading and trailing "'" from str
02497      and store the result in dest */
02498   const char *end   = strrchr (str, '\'');
02499   size_t len        = LT_STRLEN (str);
02500   char *tmp;
02501
02502   LT_DLFREE (*dest);
02503
02504   if (len > 3 && str[0] == '\'')
02505     {
02506       tmp = LT_EMALLOC (char, end - str);
02507       if (!tmp)
02508     return 1;
02509
02510       strncpy(tmp, &str[1], (end - str) - 1);
02511       tmp[len-3] = LT_EOS_CHAR;
02512       *dest = tmp;
02513     }
02514   else
02515     {
02516       *dest = NULL;
02517     }
02518
02519   return 0;
02520 }
02521
02522 static int
02523 free_vars (dlname, oldname, libdir, deplibs)
02524      char *dlname;
02525      char *oldname;
02526      char *libdir;
02527      char *deplibs;
02528 {
02529   LT_DLFREE (dlname);
02530   LT_DLFREE (oldname);
02531   LT_DLFREE (libdir);
02532   LT_DLFREE (deplibs);
02533
02534   return 0;
02535 }
02536
02537 static int
02538 try_dlopen (phandle, filename)
02539      lt_dlhandle *phandle;
02540      const char *filename;
02541 {
02542   const char *  ext     = NULL;
02543   const char *  saved_error = NULL;
02544   char *    canonical   = NULL;
02545   char *    base_name   = NULL;
02546   char *    dir     = NULL;
02547   char *    name        = NULL;
02548   int       errors      = 0;
02549   lt_dlhandle   newhandle;
02550
02551   assert (phandle);
02552   assert (*phandle == NULL);
02553
02554   LT_DLMUTEX_GETERROR (saved_error);
02555
02556   /* dlopen self? */
02557   if (!filename)
02558     {
02559       *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
02560       if (*phandle == NULL)
02561     return 1;
02562
02563       memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
02564       newhandle = *phandle;
02565
02566       /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
02567       LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
02568
02569       if (tryall_dlopen (&newhandle, 0) != 0)
02570     {
02571       LT_DLFREE (*phandle);
02572       return 1;
02573     }
02574
02575       goto register_handle;
02576     }
02577
02578   assert (filename && *filename);
02579
02580   /* Doing this immediately allows internal functions to safely
02581      assume only canonicalized paths are passed.  */
02582   if (canonicalize_path (filename, &canonical) != 0)
02583     {
02584       ++errors;
02585       goto cleanup;
02586     }
02587
02588   /* If the canonical module name is a path (relative or absolute)
02589      then split it into a directory part and a name part.  */
02590   base_name = strrchr (canonical, '/');
02591   if (base_name)
02592     {
02593       size_t dirlen = (1+ base_name) - canonical;
02594
02595       dir = LT_EMALLOC (char, 1+ dirlen);
02596       if (!dir)
02597     {
02598       ++errors;
02599       goto cleanup;
02600     }
02601
02602       strncpy (dir, canonical, dirlen);
02603       dir[dirlen] = LT_EOS_CHAR;
02604
02605       ++base_name;
02606     }
02607   else
02608     LT_DLMEM_REASSIGN (base_name, canonical);
02609
02610   assert (base_name && *base_name);
02611
02612   /* Check whether we are opening a libtool module (.la extension).  */
02613   ext = strrchr (base_name, '.');
02614   if (ext && strcmp (ext, archive_ext) == 0)
02615     {
02616       /* this seems to be a libtool module */
02617       FILE *    file     = NULL;
02618       char *    dlname   = NULL;
02619       char *    old_name = NULL;
02620       char *    libdir   = NULL;
02621       char *    deplibs  = NULL;
02622       char *    line     = NULL;
02623       size_t    line_len;
02624
02625       /* if we can't find the installed flag, it is probably an
02626      installed libtool archive, produced with an old version
02627      of libtool */
02628       int   installed = 1;
02629
02630       /* extract the module name from the file name */
02631       name = LT_EMALLOC (char, ext - base_name + 1);
02632       if (!name)
02633     {
02634       ++errors;
02635       goto cleanup;
02636     }
02637
02638       /* canonicalize the module name */
02639       {
02640         size_t i;
02641         for (i = 0; i < ext - base_name; ++i)
02642       {
02643         if (isalnum ((unsigned char)(base_name[i])))
02644           {
02645             name[i] = base_name[i];
02646           }
02647         else
02648           {
02649             name[i] = '_';
02650           }
02651       }
02652         name[ext - base_name] = LT_EOS_CHAR;
02653       }
02654
02655       /* Now try to open the .la file.  If there is no directory name
02656          component, try to find it first in user_search_path and then other
02657          prescribed paths.  Otherwise (or in any case if the module was not
02658          yet found) try opening just the module name as passed.  */
02659       if (!dir)
02660     {
02661       const char *search_path;
02662
02663       LT_DLMUTEX_LOCK ();
02664       search_path = user_search_path;
02665       if (search_path)
02666         file = find_file (user_search_path, base_name, &dir);
02667       LT_DLMUTEX_UNLOCK ();
02668
02669       if (!file)
02670         {
02671           search_path = getenv (LTDL_SEARCHPATH_VAR);
02672           if (search_path)
02673         file = find_file (search_path, base_name, &dir);
02674         }
02675
02676 #ifdef LTDL_SHLIBPATH_VAR
02677       if (!file)
02678         {
02679           search_path = getenv (LTDL_SHLIBPATH_VAR);
02680           if (search_path)
02681         file = find_file (search_path, base_name, &dir);
02682         }
02683 #endif
02684 #ifdef LTDL_SYSSEARCHPATH
02685       if (!file && sys_search_path)
02686         {
02687           file = find_file (sys_search_path, base_name, &dir);
02688         }
02689 #endif
02690     }
02691       if (!file)
02692     {
02693       file = fopen (filename, LT_READTEXT_MODE);
02694     }
02695
02696       /* If we didn't find the file by now, it really isn't there.  Set
02697      the status flag, and bail out.  */
02698       if (!file)
02699     {
02700       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
02701       ++errors;
02702       goto cleanup;
02703     }
02704
02705       line_len = LT_FILENAME_MAX;
02706       line = LT_EMALLOC (char, line_len);
02707       if (!line)
02708     {
02709       fclose (file);
02710       ++errors;
02711       goto cleanup;
02712     }
02713
02714       /* read the .la file */
02715       while (!feof (file))
02716     {
02717       if (!fgets (line, (int) line_len, file))
02718         {
02719           break;
02720         }
02721
02722       /* Handle the case where we occasionally need to read a line
02723          that is longer than the initial buffer size.  */
02724       while (line[LT_STRLEN(line) -1] != '\n')
02725         {
02726           line = LT_DLREALLOC (char, line, line_len *2);
02727           if (!fgets (&line[line_len -1], (int) line_len +1, file))
02728         {
02729           break;
02730         }
02731           line_len *= 2;
02732         }
02733
02734       if (line[0] == '\n' || line[0] == '#')
02735         {
02736           continue;
02737         }
02738
02739 #undef  STR_DLNAME
02740 #define STR_DLNAME  "dlname="
02741       if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
02742         {
02743           errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
02744         }
02745
02746 #undef  STR_OLD_LIBRARY
02747 #define STR_OLD_LIBRARY "old_library="
02748       else if (strncmp (line, STR_OLD_LIBRARY,
02749                 sizeof (STR_OLD_LIBRARY) - 1) == 0)
02750         {
02751           errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
02752         }
02753 #undef  STR_LIBDIR
02754 #define STR_LIBDIR  "libdir="
02755       else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
02756         {
02757           errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
02758         }
02759
02760 #undef  STR_DL_DEPLIBS
02761 #define STR_DL_DEPLIBS  "dependency_libs="
02762       else if (strncmp (line, STR_DL_DEPLIBS,
02763                 sizeof (STR_DL_DEPLIBS) - 1) == 0)
02764         {
02765           errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
02766         }
02767       else if (strcmp (line, "installed=yes\n") == 0)
02768         {
02769           installed = 1;
02770         }
02771       else if (strcmp (line, "installed=no\n") == 0)
02772         {
02773           installed = 0;
02774         }
02775
02776 #undef  STR_LIBRARY_NAMES
02777 #define STR_LIBRARY_NAMES "library_names="
02778       else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
02779                     sizeof (STR_LIBRARY_NAMES) - 1) == 0)
02780         {
02781           char *last_libname;
02782           errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
02783           if (!errors
02784           && dlname
02785           && (last_libname = strrchr (dlname, ' ')) != NULL)
02786         {
02787           last_libname = lt_estrdup (last_libname + 1);
02788           if (!last_libname)
02789             {
02790               ++errors;
02791               goto cleanup;
02792             }
02793           LT_DLMEM_REASSIGN (dlname, last_libname);
02794         }
02795         }
02796
02797       if (errors)
02798         break;
02799     }
02800
02801       fclose (file);
02802       LT_DLFREE (line);
02803
02804       /* allocate the handle */
02805       *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
02806       if (*phandle == NULL)
02807     ++errors;
02808
02809       if (errors)
02810     {
02811       free_vars (dlname, old_name, libdir, deplibs);
02812       LT_DLFREE (*phandle);
02813       goto cleanup;
02814     }
02815
02816       assert (*phandle);
02817
02818       memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
02819       if (load_deplibs (*phandle, deplibs) == 0)
02820     {
02821       newhandle = *phandle;
02822       /* find_module may replace newhandle */
02823       if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
02824         {
02825           unload_deplibs (*phandle);
02826           ++errors;
02827         }
02828     }
02829       else
02830     {
02831       ++errors;
02832     }
02833
02834       free_vars (dlname, old_name, libdir, deplibs);
02835       if (errors)
02836     {
02837       LT_DLFREE (*phandle);
02838       goto cleanup;
02839     }
02840
02841       if (*phandle != newhandle)
02842     {
02843       unload_deplibs (*phandle);
02844     }
02845     }
02846   else
02847     {
02848       /* not a libtool module */
02849       *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
02850       if (*phandle == NULL)
02851     {
02852       ++errors;
02853       goto cleanup;
02854     }
02855
02856       memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
02857       newhandle = *phandle;
02858
02859       /* If the module has no directory name component, try to find it
02860      first in user_search_path and then other prescribed paths.
02861      Otherwise (or in any case if the module was not yet found) try
02862      opening just the module name as passed.  */
02863       if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
02864            && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
02865                     &newhandle)
02866 #ifdef LTDL_SHLIBPATH_VAR
02867            && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
02868                     &newhandle)
02869 #endif
02870 #ifdef LTDL_SYSSEARCHPATH
02871            && !find_handle (sys_search_path, base_name, &newhandle)
02872 #endif
02873            )))
02874     {
02875           if (tryall_dlopen (&newhandle, filename) != 0)
02876             {
02877               newhandle = NULL;
02878             }
02879     }
02880
02881       if (!newhandle)
02882     {
02883       LT_DLFREE (*phandle);
02884       ++errors;
02885       goto cleanup;
02886     }
02887     }
02888
02889  register_handle:
02890   LT_DLMEM_REASSIGN (*phandle, newhandle);
02891
02892   if ((*phandle)->info.ref_count == 0)
02893     {
02894       (*phandle)->info.ref_count    = 1;
02895       LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
02896
02897       LT_DLMUTEX_LOCK ();
02898       (*phandle)->next      = handles;
02899       handles           = *phandle;
02900       LT_DLMUTEX_UNLOCK ();
02901     }
02902
02903   LT_DLMUTEX_SETERROR (saved_error);
02904
02905  cleanup:
02906   LT_DLFREE (dir);
02907   LT_DLFREE (name);
02908   LT_DLFREE (canonical);
02909
02910   return errors;
02911 }
02912
02913 lt_dlhandle
02914 lt_dlopen (filename)
02915      const char *filename;
02916 {
02917   lt_dlhandle handle = NULL;
02918
02919   /* Just incase we missed a code path in try_dlopen() that reports
02920      an error, but forgets to reset handle... */
02921   if (try_dlopen (&handle, filename) != 0)
02922     return 0;
02923
02924   return handle;
02925 }
02926
02927 /* If the last error messge store was `FILE_NOT_FOUND', then return
02928    non-zero.  */
02929 static int
02930 file_not_found ()
02931 {
02932   const char *error = NULL;
02933
02934   LT_DLMUTEX_GETERROR (error);
02935   if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
02936     return 1;
02937
02938   return 0;
02939 }
02940
02941 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
02942    open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
02943    and if a file is still not found try again with SHLIB_EXT appended
02944    instead.  */
02945 lt_dlhandle
02946 lt_dlopenext (filename)
02947      const char *filename;
02948 {
02949   lt_dlhandle   handle      = NULL;
02950   char *    tmp     = NULL;
02951   char *    ext     = NULL;
02952   size_t    len;
02953   int       errors      = 0;
02954
02955   if (!filename)
02956     {
02957       return lt_dlopen (filename);
02958     }
02959
02960   assert (filename);
02961
02962   len = LT_STRLEN (filename);
02963   ext = strrchr (filename, '.');
02964
02965   /* If FILENAME already bears a suitable extension, there is no need
02966      to try appending additional extensions.  */
02967   if (ext && ((strcmp (ext, archive_ext) == 0)
02968 #ifdef LTDL_SHLIB_EXT
02969           || (strcmp (ext, shlib_ext) == 0)
02970 #endif
02971       ))
02972     {
02973       return lt_dlopen (filename);
02974     }
02975
02976   /* First try appending ARCHIVE_EXT.  */
02977   tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
02978   if (!tmp)
02979     return 0;
02980
02981   strcpy (tmp, filename);
02982   strcat (tmp, archive_ext);
02983   errors = try_dlopen (&handle, tmp);
02984
02985   /* If we found FILENAME, stop searching -- whether we were able to
02986      load the file as a module or not.  If the file exists but loading
02987      failed, it is better to return an error message here than to
02988      report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
02989      in the module search path.  */
02990   if (handle || ((errors > 0) && file_not_found ()))
02991     {
02992       LT_DLFREE (tmp);
02993       return handle;
02994     }
02995
02996 #ifdef LTDL_SHLIB_EXT
02997   /* Try appending SHLIB_EXT.   */
02998   if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
02999     {
03000       LT_DLFREE (tmp);
03001       tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
03002       if (!tmp)
03003     return 0;
03004
03005       strcpy (tmp, filename);
03006     }
03007   else
03008     {
03009       tmp[len] = LT_EOS_CHAR;
03010     }
03011
03012   strcat(tmp, shlib_ext);
03013   errors = try_dlopen (&handle, tmp);
03014
03015   /* As before, if the file was found but loading failed, return now
03016      with the current error message.  */
03017   if (handle || ((errors > 0) && file_not_found ()))
03018     {
03019       LT_DLFREE (tmp);
03020       return handle;
03021     }
03022 #endif
03023
03024   /* Still here?  Then we really did fail to locate any of the file
03025      names we tried.  */
03026   LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
03027   LT_DLFREE (tmp);
03028   return 0;
03029 }
03030
03031
03032 static int
03033 lt_argz_insert (pargz, pargz_len, before, entry)
03034      char **pargz;
03035      size_t *pargz_len;
03036      char *before;
03037      const char *entry;
03038 {
03039   error_t error;
03040
03041   if ((error = argz_insert (pargz, pargz_len, before, entry)))
03042     {
03043       switch (error)
03044     {
03045     case ENOMEM:
03046       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
03047       break;
03048     default:
03049       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
03050       break;
03051     }
03052       return 1;
03053     }
03054
03055   return 0;
03056 }
03057
03058 static int
03059 lt_argz_insertinorder (pargz, pargz_len, entry)
03060      char **pargz;
03061      size_t *pargz_len;
03062      const char *entry;
03063 {
03064   char *before = NULL;
03065
03066   assert (pargz);
03067   assert (pargz_len);
03068   assert (entry && *entry);
03069
03070   if (*pargz)
03071     while ((before = argz_next (*pargz, *pargz_len, before)))
03072       {
03073     int cmp = strcmp (entry, before);
03074
03075     if (cmp < 0)  break;
03076     if (cmp == 0) return 0; /* No duplicates! */
03077       }
03078
03079   return lt_argz_insert (pargz, pargz_len, before, entry);
03080 }
03081
03082 static int
03083 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
03084      char **pargz;
03085      size_t *pargz_len;
03086      const char *dirnam;
03087      struct dirent *dp;
03088 {
03089   char   *buf       = NULL;
03090   size_t buf_len    = 0;
03091   char   *end       = NULL;
03092   size_t end_offset = 0;
03093   size_t dir_len    = 0;
03094   int    errors     = 0;
03095
03096   assert (pargz);
03097   assert (pargz_len);
03098   assert (dp);
03099
03100   dir_len = LT_STRLEN (dirnam);
03101   end     = dp->d_name + LT_D_NAMLEN(dp);
03102
03103   /* Ignore version numbers.  */
03104   {
03105     char *p;
03106     for (p = end; p -1 > dp->d_name; --p)
03107       if (strchr (".0123456789", p[-1]) == 0)
03108     break;
03109
03110     if (*p == '.')
03111       end = p;
03112   }
03113
03114   /* Ignore filename extension.  */
03115   {
03116     char *p;
03117     for (p = end -1; p > dp->d_name; --p)
03118       if (*p == '.')
03119     {
03120       end = p;
03121       break;
03122     }
03123   }
03124
03125   /* Prepend the directory name.  */
03126   end_offset    = end - dp->d_name;
03127   buf_len   = dir_len + 1+ end_offset;
03128   buf       = LT_EMALLOC (char, 1+ buf_len);
03129   if (!buf)
03130     return ++errors;
03131
03132   assert (buf);
03133
03134   strcpy  (buf, dirnam);
03135   strcat  (buf, "/");
03136   strncat (buf, dp->d_name, end_offset);
03137   buf[buf_len] = LT_EOS_CHAR;
03138
03139   /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
03140   if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
03141     ++errors;
03142
03143   LT_DLFREE (buf);
03144
03145   return errors;
03146 }
03147
03148 static int
03149 list_files_by_dir (dirnam, pargz, pargz_len)
03150      const char *dirnam;
03151      char **pargz;
03152      size_t *pargz_len;
03153 {
03154   DIR   *dirp     = NULL;
03155   int    errors   = 0;
03156
03157   assert (dirnam && *dirnam);
03158   assert (pargz);
03159   assert (pargz_len);
03160   assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
03161
03162   dirp = opendir (dirnam);
03163   if (dirp)
03164     {
03165       struct dirent *dp = NULL;
03166
03167       while ((dp = readdir (dirp)))
03168     if (dp->d_name[0] != '.')
03169       if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
03170         {
03171           ++errors;
03172           break;
03173         }
03174
03175       closedir (dirp);
03176     }
03177   else
03178     ++errors;
03179
03180   return errors;
03181 }
03182
03183
03184 /* If there are any files in DIRNAME, call the function passed in
03185    DATA1 (with the name of each file and DATA2 as arguments).  */
03186 static int
03187 foreachfile_callback (dirname, data1, data2)
03188      char *dirname;
03189      lt_ptr data1;
03190      lt_ptr data2;
03191 {
03192   int (*func) LT_PARAMS((const char *filename, lt_ptr data))
03193     = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
03194
03195   int     is_done  = 0;
03196   char   *argz     = NULL;
03197   size_t  argz_len = 0;
03198
03199   if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
03200     goto cleanup;
03201   if (!argz)
03202     goto cleanup;
03203
03204   {
03205     char *filename = NULL;
03206     while ((filename = argz_next (argz, argz_len, filename)))
03207       if ((is_done = (*func) (filename, data2)))
03208     break;
03209   }
03210
03211  cleanup:
03212   LT_DLFREE (argz);
03213
03214   return is_done;
03215 }
03216
03217
03218 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
03219    with DATA.  The filenames passed to FUNC would be suitable for
03220    passing to lt_dlopenext.  The extensions are stripped so that
03221    individual modules do not generate several entries (e.g. libfoo.la,
03222    libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
03223    then the same directories that lt_dlopen would search are examined.  */
03224 int
03225 lt_dlforeachfile (search_path, func, data)
03226      const char *search_path;
03227      int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
03228      lt_ptr data;
03229 {
03230   int is_done = 0;
03231
03232   if (search_path)
03233     {
03234       /* If a specific path was passed, search only the directories
03235      listed in it.  */
03236       is_done = foreach_dirinpath (search_path, 0,
03237                    foreachfile_callback, func, data);
03238     }
03239   else
03240     {
03241       /* Otherwise search the default paths.  */
03242       is_done = foreach_dirinpath (user_search_path, 0,
03243                    foreachfile_callback, func, data);
03244       if (!is_done)
03245     {
03246       is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
03247                        foreachfile_callback, func, data);
03248     }
03249
03250 #ifdef LTDL_SHLIBPATH_VAR
03251       if (!is_done)
03252     {
03253       is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
03254                        foreachfile_callback, func, data);
03255     }
03256 #endif
03257 #ifdef LTDL_SYSSEARCHPATH
03258       if (!is_done)
03259     {
03260       is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
03261                        foreachfile_callback, func, data);
03262     }
03263 #endif
03264     }
03265
03266   return is_done;
03267 }
03268
03269 int
03270 lt_dlclose (handle)
03271      lt_dlhandle handle;
03272 {
03273   lt_dlhandle cur, last;
03274   int errors = 0;
03275
03276   LT_DLMUTEX_LOCK ();
03277
03278   /* check whether the handle is valid */
03279   last = cur = handles;
03280   while (cur && handle != cur)
03281     {
03282       last = cur;
03283       cur = cur->next;
03284     }
03285
03286   if (!cur)
03287     {
03288       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
03289       ++errors;
03290       goto done;
03291     }
03292
03293   handle->info.ref_count--;
03294
03295   /* Note that even with resident modules, we must track the ref_count
03296      correctly incase the user decides to reset the residency flag
03297      later (even though the API makes no provision for that at the
03298      moment).  */
03299   if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
03300     {
03301       lt_user_data data = handle->loader->dlloader_data;
03302
03303       if (handle != handles)
03304     {
03305       last->next = handle->next;
03306     }
03307       else
03308     {
03309       handles = handle->next;
03310     }
03311
03312       errors += handle->loader->module_close (data, handle->module);
03313       errors += unload_deplibs(handle);
03314
03315       /* It is up to the callers to free the data itself.  */
03316       LT_DLFREE (handle->caller_data);
03317
03318       LT_DLFREE (handle->info.filename);
03319       LT_DLFREE (handle->info.name);
03320       LT_DLFREE (handle);
03321
03322       goto done;
03323     }
03324
03325   if (LT_DLIS_RESIDENT (handle))
03326     {
03327       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
03328       ++errors;
03329     }
03330
03331  done:
03332   LT_DLMUTEX_UNLOCK ();
03333
03334   return errors;
03335 }
03336
03337 lt_ptr
03338 lt_dlsym (handle, symbol)
03339      lt_dlhandle handle;
03340      const char *symbol;
03341 {
03342   size_t lensym;
03343   char  lsym[LT_SYMBOL_LENGTH];
03344   char  *sym;
03345   lt_ptr address;
03346   lt_user_data data;
03347
03348   if (!handle)
03349     {
03350       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
03351       return 0;
03352     }
03353
03354   if (!symbol)
03355     {
03356       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
03357       return 0;
03358     }
03359
03360   lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
03361                     + LT_STRLEN (handle->info.name);
03362
03363   if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
03364     {
03365       sym = lsym;
03366     }
03367   else
03368     {
03369       sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
03370       if (!sym)
03371     {
03372       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
03373       return 0;
03374     }
03375     }
03376
03377   data = handle->loader->dlloader_data;
03378   if (handle->info.name)
03379     {
03380       const char *saved_error;
03381
03382       LT_DLMUTEX_GETERROR (saved_error);
03383
03384       /* this is a libtool module */
03385       if (handle->loader->sym_prefix)
03386     {
03387       strcpy(sym, handle->loader->sym_prefix);
03388       strcat(sym, handle->info.name);
03389     }
03390       else
03391     {
03392       strcpy(sym, handle->info.name);
03393     }
03394
03395       strcat(sym, "_LTX_");
03396       strcat(sym, symbol);
03397
03398       /* try "modulename_LTX_symbol" */
03399       address = handle->loader->find_sym (data, handle->module, sym);
03400       if (address)
03401     {
03402       if (sym != lsym)
03403         {
03404           LT_DLFREE (sym);
03405         }
03406       return address;
03407     }
03408       LT_DLMUTEX_SETERROR (saved_error);
03409     }
03410
03411   /* otherwise try "symbol" */
03412   if (handle->loader->sym_prefix)
03413     {
03414       strcpy(sym, handle->loader->sym_prefix);
03415       strcat(sym, symbol);
03416     }
03417   else
03418     {
03419       strcpy(sym, symbol);
03420     }
03421
03422   address = handle->loader->find_sym (data, handle->module, sym);
03423   if (sym != lsym)
03424     {
03425       LT_DLFREE (sym);
03426     }
03427
03428   return address;
03429 }
03430
03431 const char *
03432 lt_dlerror ()
03433 {
03434   const char *error;
03435
03436   LT_DLMUTEX_GETERROR (error);
03437   LT_DLMUTEX_SETERROR (0);
03438
03439   return error ? error : LT_DLSTRERROR (UNKNOWN);
03440 }
03441
03442 static int
03443 lt_dlpath_insertdir (ppath, before, dir)
03444      char **ppath;
03445      char *before;
03446      const char *dir;
03447 {
03448   int    errors     = 0;
03449   char  *canonical  = NULL;
03450   char  *argz       = NULL;
03451   size_t argz_len   = 0;
03452
03453   assert (ppath);
03454   assert (dir && *dir);
03455
03456   if (canonicalize_path (dir, &canonical) != 0)
03457     {
03458       ++errors;
03459       goto cleanup;
03460     }
03461
03462   assert (canonical && *canonical);
03463
03464   /* If *PPATH is empty, set it to DIR.  */
03465   if (*ppath == NULL)
03466     {
03467       assert (!before);     /* BEFORE cannot be set without PPATH.  */
03468       assert (dir);     /* Without DIR, don't call this function!  */
03469
03470       *ppath = lt_estrdup (dir);
03471       if (*ppath == NULL)
03472     ++errors;
03473
03474       return errors;
03475     }
03476
03477   assert (ppath && *ppath);
03478
03479   if (argzize_path (*ppath, &argz, &argz_len) != 0)
03480     {
03481       ++errors;
03482       goto cleanup;
03483     }
03484
03485   /* Convert BEFORE into an equivalent offset into ARGZ.  This only works
03486      if *PPATH is already canonicalized, and hence does not change length
03487      with respect to ARGZ.  We canonicalize each entry as it is added to
03488      the search path, and don't call this function with (uncanonicalized)
03489      user paths, so this is a fair assumption.  */
03490   if (before)
03491     {
03492       assert (*ppath <= before);
03493       assert (before - *ppath <= strlen (*ppath));
03494
03495       before = before - *ppath + argz;
03496     }
03497
03498   if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
03499     {
03500       ++errors;
03501       goto cleanup;
03502     }
03503
03504   argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
03505   LT_DLMEM_REASSIGN (*ppath,  argz);
03506
03507  cleanup:
03508   LT_DLFREE (canonical);
03509   LT_DLFREE (argz);
03510
03511   return errors;
03512 }
03513
03514 int
03515 lt_dladdsearchdir (search_dir)
03516      const char *search_dir;
03517 {
03518   int errors = 0;
03519
03520   if (search_dir && *search_dir)
03521     {
03522       LT_DLMUTEX_LOCK ();
03523       if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
03524     ++errors;
03525       LT_DLMUTEX_UNLOCK ();
03526     }
03527
03528   return errors;
03529 }
03530
03531 int
03532 lt_dlinsertsearchdir (before, search_dir)
03533      const char *before;
03534      const char *search_dir;
03535 {
03536   int errors = 0;
03537
03538   if (before)
03539     {
03540       LT_DLMUTEX_LOCK ();
03541       if ((before < user_search_path)
03542       || (before >= user_search_path + LT_STRLEN (user_search_path)))
03543     {
03544       LT_DLMUTEX_UNLOCK ();
03545       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
03546       return 1;
03547     }
03548       LT_DLMUTEX_UNLOCK ();
03549     }
03550
03551   if (search_dir && *search_dir)
03552     {
03553       LT_DLMUTEX_LOCK ();
03554       if (lt_dlpath_insertdir (&user_search_path,
03555                    (char *) before, search_dir) != 0)
03556     {
03557       ++errors;
03558     }
03559       LT_DLMUTEX_UNLOCK ();
03560     }
03561
03562   return errors;
03563 }
03564
03565 int
03566 lt_dlsetsearchpath (search_path)
03567      const char *search_path;
03568 {
03569   int   errors      = 0;
03570
03571   LT_DLMUTEX_LOCK ();
03572   LT_DLFREE (user_search_path);
03573   LT_DLMUTEX_UNLOCK ();
03574
03575   if (!search_path || !LT_STRLEN (search_path))
03576     {
03577       return errors;
03578     }
03579
03580   LT_DLMUTEX_LOCK ();
03581   if (canonicalize_path (search_path, &user_search_path) != 0)
03582     ++errors;
03583   LT_DLMUTEX_UNLOCK ();
03584
03585   return errors;
03586 }
03587
03588 const char *
03589 lt_dlgetsearchpath ()
03590 {
03591   const char *saved_path;
03592
03593   LT_DLMUTEX_LOCK ();
03594   saved_path = user_search_path;
03595   LT_DLMUTEX_UNLOCK ();
03596
03597   return saved_path;
03598 }
03599
03600 int
03601 lt_dlmakeresident (handle)
03602      lt_dlhandle handle;
03603 {
03604   int errors = 0;
03605
03606   if (!handle)
03607     {
03608       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
03609       ++errors;
03610     }
03611   else
03612     {
03613       LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
03614     }
03615
03616   return errors;
03617 }
03618
03619 int
03620 lt_dlisresident (handle)
03621      lt_dlhandle handle;
03622 {
03623   if (!handle)
03624     {
03625       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
03626       return -1;
03627     }
03628
03629   return LT_DLIS_RESIDENT (handle);
03630 }
03631
03632
03633
03634
03635 /* --- MODULE INFORMATION --- */
03636
03637 const lt_dlinfo *
03638 lt_dlgetinfo (handle)
03639      lt_dlhandle handle;
03640 {
03641   if (!handle)
03642     {
03643       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
03644       return 0;
03645     }
03646
03647   return &(handle->info);
03648 }
03649
03650 lt_dlhandle
03651 lt_dlhandle_next (place)
03652      lt_dlhandle place;
03653 {
03654   return place ? place->next : handles;
03655 }
03656
03657 int
03658 lt_dlforeach (func, data)
03659      int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
03660      lt_ptr data;
03661 {
03662   int errors = 0;
03663   lt_dlhandle cur;
03664
03665   LT_DLMUTEX_LOCK ();
03666
03667   cur = handles;
03668   while (cur)
03669     {
03670       lt_dlhandle tmp = cur;
03671
03672       cur = cur->next;
03673       if ((*func) (tmp, data))
03674     {
03675       ++errors;
03676       break;
03677     }
03678     }
03679
03680   LT_DLMUTEX_UNLOCK ();
03681
03682   return errors;
03683 }
03684
03685 lt_dlcaller_id
03686 lt_dlcaller_register ()
03687 {
03688   static lt_dlcaller_id last_caller_id = 0;
03689   int result;
03690
03691   LT_DLMUTEX_LOCK ();
03692   result = ++last_caller_id;
03693   LT_DLMUTEX_UNLOCK ();
03694
03695   return result;
03696 }
03697
03698 lt_ptr
03699 lt_dlcaller_set_data (key, handle, data)
03700      lt_dlcaller_id key;
03701      lt_dlhandle handle;
03702      lt_ptr data;
03703 {
03704   int n_elements = 0;
03705   lt_ptr stale = NULL;
03706   int i;
03707
03708   /* This needs to be locked so that the caller data can be updated
03709      simultaneously by different threads.  */
03710   LT_DLMUTEX_LOCK ();
03711
03712   if (handle->caller_data)
03713     while (handle->caller_data[n_elements].key)
03714       ++n_elements;
03715
03716   for (i = 0; i < n_elements; ++i)
03717     {
03718       if (handle->caller_data[i].key == key)
03719     {
03720       stale = handle->caller_data[i].data;
03721       break;
03722     }
03723     }
03724
03725   /* Ensure that there is enough room in this handle's caller_data
03726      array to accept a new element (and an empty end marker).  */
03727   if (i == n_elements)
03728     {
03729       lt_caller_data *temp
03730     = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
03731
03732       if (!temp)
03733     {
03734       stale = NULL;
03735       goto done;
03736     }
03737
03738       handle->caller_data = temp;
03739
03740       /* We only need this if we needed to allocate a new caller_data.  */
03741       handle->caller_data[i].key  = key;
03742       handle->caller_data[1+ i].key = 0;
03743     }
03744
03745   handle->caller_data[i].data = data;
03746
03747  done:
03748   LT_DLMUTEX_UNLOCK ();
03749
03750   return stale;
03751 }
03752
03753 lt_ptr
03754 lt_dlcaller_get_data  (key, handle)
03755      lt_dlcaller_id key;
03756      lt_dlhandle handle;
03757 {
03758   lt_ptr result = (lt_ptr) 0;
03759
03760   /* This needs to be locked so that the caller data isn't updated by
03761      another thread part way through this function.  */
03762   LT_DLMUTEX_LOCK ();
03763
03764   /* Locate the index of the element with a matching KEY.  */
03765   {
03766     int i;
03767     for (i = 0; handle->caller_data[i].key; ++i)
03768       {
03769     if (handle->caller_data[i].key == key)
03770       {
03771         result = handle->caller_data[i].data;
03772         break;
03773       }
03774       }
03775   }
03776
03777   LT_DLMUTEX_UNLOCK ();
03778
03779   return result;
03780 }
03781
03782
03783
03784 /* --- USER MODULE LOADER API --- */
03785
03786
03787 int
03788 lt_dlloader_add (place, dlloader, loader_name)
03789      lt_dlloader *place;
03790      const struct lt_user_dlloader *dlloader;
03791      const char *loader_name;
03792 {
03793   int errors = 0;
03794   lt_dlloader *node = NULL, *ptr = NULL;
03795
03796   if ((dlloader == NULL)    /* diagnose null parameters */
03797       || (dlloader->module_open == NULL)
03798       || (dlloader->module_close == NULL)
03799       || (dlloader->find_sym == NULL))
03800     {
03801       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
03802       return 1;
03803     }
03804
03805   /* Create a new dlloader node with copies of the user callbacks.  */
03806   node = LT_EMALLOC (lt_dlloader, 1);
03807   if (!node)
03808     return 1;
03809
03810   node->next        = NULL;
03811   node->loader_name = loader_name;
03812   node->sym_prefix  = dlloader->sym_prefix;
03813   node->dlloader_exit   = dlloader->dlloader_exit;
03814   node->module_open = dlloader->module_open;
03815   node->module_close    = dlloader->module_close;
03816   node->find_sym    = dlloader->find_sym;
03817   node->dlloader_data   = dlloader->dlloader_data;
03818
03819   LT_DLMUTEX_LOCK ();
03820   if (!loaders)
03821     {
03822       /* If there are no loaders, NODE becomes the list! */
03823       loaders = node;
03824     }
03825   else if (!place)
03826     {
03827       /* If PLACE is not set, add NODE to the end of the
03828      LOADERS list. */
03829       for (ptr = loaders; ptr->next; ptr = ptr->next)
03830     {
03831       /*NOWORK*/;
03832     }
03833
03834       ptr->next = node;
03835     }
03836   else if (loaders == place)
03837     {
03838       /* If PLACE is the first loader, NODE goes first. */
03839       node->next = place;
03840       loaders = node;
03841     }
03842   else
03843     {
03844       /* Find the node immediately preceding PLACE. */
03845       for (ptr = loaders; ptr->next != place; ptr = ptr->next)
03846     {
03847       /*NOWORK*/;
03848     }
03849
03850       if (ptr->next != place)
03851     {
03852       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
03853       ++errors;
03854     }
03855       else
03856     {
03857       /* Insert NODE between PTR and PLACE. */
03858       node->next = place;
03859       ptr->next  = node;
03860     }
03861     }
03862
03863   LT_DLMUTEX_UNLOCK ();
03864
03865   return errors;
03866 }
03867
03868 int
03869 lt_dlloader_remove (loader_name)
03870      const char *loader_name;
03871 {
03872   lt_dlloader *place = lt_dlloader_find (loader_name);
03873   lt_dlhandle handle;
03874   int errors = 0;
03875
03876   if (!place)
03877     {
03878       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
03879       return 1;
03880     }
03881
03882   LT_DLMUTEX_LOCK ();
03883
03884   /* Fail if there are any open modules which use this loader. */
03885   for  (handle = handles; handle; handle = handle->next)
03886     {
03887       if (handle->loader == place)
03888     {
03889       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
03890       ++errors;
03891       goto done;
03892     }
03893     }
03894
03895   if (place == loaders)
03896     {
03897       /* PLACE is the first loader in the list. */
03898       loaders = loaders->next;
03899     }
03900   else
03901     {
03902       /* Find the loader before the one being removed. */
03903       lt_dlloader *prev;
03904       for (prev = loaders; prev->next; prev = prev->next)
03905     {
03906       if (!strcmp (prev->next->loader_name, loader_name))
03907         {
03908           break;
03909         }
03910     }
03911
03912       place = prev->next;
03913       prev->next = prev->next->next;
03914     }
03915
03916   if (place->dlloader_exit)
03917     {
03918       errors = place->dlloader_exit (place->dlloader_data);
03919     }
03920
03921   LT_DLFREE (place);
03922
03923  done:
03924   LT_DLMUTEX_UNLOCK ();
03925
03926   return errors;
03927 }
03928
03929 lt_dlloader *
03930 lt_dlloader_next (place)
03931      lt_dlloader *place;
03932 {
03933   lt_dlloader *next;
03934
03935   LT_DLMUTEX_LOCK ();
03936   next = place ? place->next : loaders;
03937   LT_DLMUTEX_UNLOCK ();
03938
03939   return next;
03940 }
03941
03942 const char *
03943 lt_dlloader_name (place)
03944      lt_dlloader *place;
03945 {
03946   const char *name = NULL;
03947
03948   if (place)
03949     {
03950       LT_DLMUTEX_LOCK ();
03951       name = place ? place->loader_name : 0;
03952       LT_DLMUTEX_UNLOCK ();
03953     }
03954   else
03955     {
03956       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
03957     }
03958
03959   return name;
03960 }
03961
03962 lt_user_data *
03963 lt_dlloader_data (place)
03964      lt_dlloader *place;
03965 {
03966   lt_user_data *data = NULL;
03967
03968   if (place)
03969     {
03970       LT_DLMUTEX_LOCK ();
03971       data = place ? &(place->dlloader_data) : 0;
03972       LT_DLMUTEX_UNLOCK ();
03973     }
03974   else
03975     {
03976       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
03977     }
03978
03979   return data;
03980 }
03981
03982 lt_dlloader *
03983 lt_dlloader_find (loader_name)
03984      const char *loader_name;
03985 {
03986   lt_dlloader *place = NULL;
03987
03988   LT_DLMUTEX_LOCK ();
03989   for (place = loaders; place; place = place->next)
03990     {
03991       if (strcmp (place->loader_name, loader_name) == 0)
03992     {
03993       break;
03994     }
03995     }
03996   LT_DLMUTEX_UNLOCK ();
03997
03998   return place;
03999 }


ltdl.h File Reference

Include dependency graph for ltdl.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | lt_dlsymlist
struct | lt_dlinfo
struct | lt_user_dlloader

Defines

#define | LTDL_H 1
#define | LT_EOS_CHAR '\0'
#define | LT_BEGIN_C_DECLS
#define | LT_END_C_DECLS
#define | LT_PARAMS(protos) protos
#define | lt_ptr void*
#define | LT_STMT_START do
#define | LT_STMT_END while (0)
#define | LT_CONC(s, t) s/**/t
#define | LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0)
#define | __WINDOWS__ WIN32
#define | LT_DIRSEP_CHAR '\\'
#define | LT_PATHSEP_CHAR ';'
#define | LT_SCOPE extern
#define | LTDL_SET_PRELOADED_SYMBOLS()
#define | lt_dlerror_table
#define | LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name),

Typedefs

typedef lt_dlhandle_struct * | lt_dlhandle
typedef void lt_dlmutex_lock | LT_PARAMS ((void))
typedef unsigned | lt_dlcaller_id
typedef lt_dlloader | lt_dlloader
typedef lt_ptr | lt_user_data
typedef lt_ptr | lt_module

Enumerations

enum | { name, LT_ERROR_MAX }

Functions

int lt_dlinit | LT_PARAMS ((void))
int lt_dladdsearchdir | LT_PARAMS ((const char *search_dir))
int lt_dlinsertsearchdir | LT_PARAMS ((const char *before, const char *search_dir))
int lt_dlsetsearchpath | LT_PARAMS ((const char *search_path))
int lt_dlforeachfile | LT_PARAMS ((const char *search_path, int(*func)(const char *filename, lt_ptr data), lt_ptr data))
lt_dlhandle lt_dlopen | LT_PARAMS ((const char *filename))
lt_ptr lt_dlsym | LT_PARAMS ((lt_dlhandle handle, const char *name))
int lt_dlclose | LT_PARAMS ((lt_dlhandle handle))
int lt_dlmutex_register | LT_PARAMS ((lt_dlmutex_lock *lock, lt_dlmutex_unlock *unlock, lt_dlmutex_seterror *seterror, lt_dlmutex_geterror *geterror))
LT_SCOPE lt_ptr lt_dlmalloc | LT_PARAMS ((size_t size))
LT_SCOPE lt_ptr lt_dlrealloc | LT_PARAMS ((lt_ptr ptr, size_t size))
LT_SCOPE void lt_dlfree | LT_PARAMS ((lt_ptr ptr))
int lt_dlpreload | LT_PARAMS ((const lt_dlsymlist *preloaded))
lt_dlhandle lt_dlhandle_next | LT_PARAMS ((lt_dlhandle place))
int lt_dlforeach | LT_PARAMS ((int(*func)(lt_dlhandle handle, lt_ptr data), lt_ptr data))
lt_ptr lt_dlcaller_set_data | LT_PARAMS ((lt_dlcaller_id key, lt_dlhandle handle, lt_ptr data))
lt_ptr lt_dlcaller_get_data | LT_PARAMS ((lt_dlcaller_id key, lt_dlhandle handle))
lt_dlloader *lt_dlloader_next | LT_PARAMS ((lt_dlloader *place))
lt_dlloader *lt_dlloader_find | LT_PARAMS ((const char *loader_name))
int lt_dlloader_add | LT_PARAMS ((lt_dlloader *place, const struct lt_user_dlloader *dlloader, const char *loader_name))
int lt_dladderror | LT_PARAMS ((const char *diagnostic))
int lt_dlseterror | LT_PARAMS ((int errorcode))

Define Documentation

#define LTDL_H 1

Definition at line 29 of file ltdl.h.

#define LT_EOS_CHAR '\0'

Definition at line 38 of file ltdl.h.

#define LT_BEGIN_C_DECLS

Definition at line 47 of file ltdl.h.

#define LT_END_C_DECLS

Definition at line 48 of file ltdl.h.

#define LT_PARAMS ( protos ) protos

Definition at line 58 of file ltdl.h.

#define lt_ptr void*

Definition at line 59 of file ltdl.h.

#define LT_STMT_START do

Definition at line 75 of file ltdl.h.

#define LT_STMT_END while (0)

Definition at line 76 of file ltdl.h.

#define LT_CONC | ( | s,
 |  | t | ) | s/**/t

Definition at line 85 of file ltdl.h.

#define LT_STRLEN ( s ) (((s) && (s)[0]) ? strlen (s) : 0)

Definition at line 89 of file ltdl.h.

#define __WINDOWS__ WIN32

Definition at line 108 of file ltdl.h.

#define LT_DIRSEP_CHAR '\\'

Definition at line 118 of file ltdl.h.

#define LT_PATHSEP_CHAR ';'

Definition at line 119 of file ltdl.h.

#define LT_SCOPE extern

Definition at line 138 of file ltdl.h.

#define LTDL_SET_PRELOADED_SYMBOLS ( )

Value:

LT_STMT_START{  \
    extern const lt_dlsymlist lt_preloaded_symbols[];       \
    lt_dlpreload_default(lt_preloaded_symbols);         \
                        }LT_STMT_END

Definition at line 225 of file ltdl.h.

#define lt_dlerror_table

Value:

LT_ERROR(UNKNOWN,           "unknown error")            \
    LT_ERROR(DLOPEN_NOT_SUPPORTED,  "dlopen support not available") \
    LT_ERROR(INVALID_LOADER,        "invalid loader")           \
    LT_ERROR(INIT_LOADER,       "loader initialization failed") \
    LT_ERROR(REMOVE_LOADER,     "loader removal failed")        \
    LT_ERROR(FILE_NOT_FOUND,        "file not found")           \
    LT_ERROR(DEPLIB_NOT_FOUND,      "dependency library not found") \
    LT_ERROR(NO_SYMBOLS,        "no symbols defined")       \
    LT_ERROR(CANNOT_OPEN,       "can't open the module")        \
    LT_ERROR(CANNOT_CLOSE,      "can't close the module")       \
    LT_ERROR(SYMBOL_NOT_FOUND,      "symbol not found")         \
    LT_ERROR(NO_MEMORY,         "not enough memory")        \
    LT_ERROR(INVALID_HANDLE,        "invalid module handle")        \
    LT_ERROR(BUFFER_OVERFLOW,       "internal buffer overflow")     \
    LT_ERROR(INVALID_ERRORCODE,     "invalid errorcode")        \
    LT_ERROR(SHUTDOWN,          "library already shutdown")     \
    LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module")  \
    LT_ERROR(INVALID_MUTEX_ARGS,    "invalid mutex handler registration") \
    LT_ERROR(INVALID_POSITION,      "invalid search path insert position")

Definition at line 308 of file ltdl.h.

#define LT_ERROR | ( | name,
 |  | diagnostic | ) | LT_CONC(LT_ERROR_, name),

Typedef Documentation

typedef struct lt_dlhandle_struct* lt_dlhandle

Definition at line 148 of file ltdl.h.

typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data))

Definition at line 183 of file ltdl.h.

typedef unsigned lt_dlcaller_id

Definition at line 251 of file ltdl.h.

typedef struct lt_dlloader lt_dlloader

Definition at line 265 of file ltdl.h.

typedef lt_ptr lt_user_data

Definition at line 266 of file ltdl.h.

typedef lt_ptr lt_module

Definition at line 267 of file ltdl.h.

Enumeration Type Documentation

anonymous enum

Enumeration values:
name
LT_ERROR_MAX

Definition at line 330 of file ltdl.h.

Function Documentation

int lt_dlinit LT_PARAMS ( (void) )

int lt_dladdsearchdir LT_PARAMS ( (const char *search_dir) )

int lt_dlinsertsearchdir LT_PARAMS ( (const char *before, const char *search_dir) )

int lt_dlsetsearchpath LT_PARAMS ( (const char *search_path) )

int lt_dlforeachfile LT_PARAMS ( (const char *search_path, int(*func )(const char *filename, lt_ptr data), lt_ptr data) )

lt_dlhandle lt_dlopen LT_PARAMS ( (const char *filename) )

lt_ptr lt_dlsym LT_PARAMS ( (lt_dlhandle handle, const char *name) )

int lt_dlclose LT_PARAMS ( (lt_dlhandle handle) )

int lt_dlmutex_register LT_PARAMS ( (lt_dlmutex_lock *lock, lt_dlmutex_unlock *unlock, lt_dlmutex_seterror *seterror, lt_dlmutex_geterror *geterror) )

LT_SCOPE lt_ptr lt_dlmalloc LT_PARAMS ( (size_t size) )

LT_SCOPE lt_ptr lt_dlrealloc LT_PARAMS ( (lt_ptr ptr, size_t size) )

LT_SCOPE void lt_dlfree LT_PARAMS ( (lt_ptr ptr) )

int lt_dlpreload LT_PARAMS ( (const lt_dlsymlist *preloaded) )

lt_dlhandle lt_dlhandle_next LT_PARAMS ( (lt_dlhandle place) )

int lt_dlforeach LT_PARAMS ( (int(*func )(lt_dlhandle handle, lt_ptr data), lt_ptr data) )

lt_ptr lt_dlcaller_set_data LT_PARAMS ( (lt_dlcaller_id key, lt_dlhandle handle, lt_ptr data) )

lt_ptr lt_dlcaller_get_data LT_PARAMS ( (lt_dlcaller_id key, lt_dlhandle handle) )

lt_dlloader* lt_dlloader_next LT_PARAMS ( (lt_dlloader *place) )

lt_dlloader* lt_dlloader_find LT_PARAMS ( (const char *loader_name) )

int lt_dlloader_add LT_PARAMS ( (lt_dlloader *place, const struct lt_user_dlloader *dlloader, const char *loader_name) )

int lt_dladderror LT_PARAMS ( (const char *diagnostic) )

int lt_dlseterror LT_PARAMS ( (int errorcode) )


ltdl.h Source File

ltdl.h

Go to the documentation of this file.
00001 /* ltdl.h -- generic dlopen functions
00002    Copyright (C) 1998-2000 Free Software Foundation, Inc.
00003    Originally by Thomas Tanner <tanner@ffii.org>
00004    This file is part of GNU Libtool.
00005
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2 of the License, or (at your option) any later version.
00010
00011 As a special exception to the GNU Lesser General Public License,
00012 if you distribute this file as part of a program or library that
00013 is built using GNU libtool, you may include it under the same
00014 distribution terms that you use for the rest of that program.
00015
00016 This library is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 Lesser General Public License for more details.
00020
00021 You should have received a copy of the GNU Lesser General Public
00022 License along with this library; if not, write to the Free
00023 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00024 02111-1307  USA
00025 */
00026
00027 /* Only include this header file once. */
00028 #ifndef LTDL_H
00029 #define LTDL_H 1
00030
00031 #include <sys/types.h>      /* for size_t declaration */
00032
00033
00034 /* --- MACROS FOR PORTABILITY --- */
00035
00036
00037 /* Saves on those hard to debug '\0' typos....  */
00038 #define LT_EOS_CHAR '\0'
00039
00040 /* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations,
00041    so that C++ compilers don't mangle their names.  Use LTDL_END_C_DECLS at
00042    the end of C declarations. */
00043 #ifdef __cplusplus
00044 # define LT_BEGIN_C_DECLS   extern "C" {
00045 # define LT_END_C_DECLS     }
00046 #else
00047 # define LT_BEGIN_C_DECLS   /* empty */
00048 # define LT_END_C_DECLS     /* empty */
00049 #endif
00050
00051 LT_BEGIN_C_DECLS
00052
00053
00054 /* LT_PARAMS is a macro used to wrap function prototypes, so that compilers
00055    that don't understand ANSI C prototypes still work, and ANSI C
00056    compilers can issue warnings about type mismatches.  */
00057 #if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
00058 # define LT_PARAMS(protos)  protos
00059 # define lt_ptr     void*
00060 #else
00061 # define LT_PARAMS(protos)  ()
00062 # define lt_ptr     char*
00063 #endif
00064
00065 /* LT_STMT_START/END are used to create macros which expand to a
00066    a single compound statement in a portable way.  */
00067 #if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
00068 #  define LT_STMT_START        (void)(
00069 #  define LT_STMT_END          )
00070 #else
00071 #  if (defined (sun) || defined (__sun__))
00072 #    define LT_STMT_START      if (1)
00073 #    define LT_STMT_END        else (void)0
00074 #  else
00075 #    define LT_STMT_START      do
00076 #    define LT_STMT_END        while (0)
00077 #  endif
00078 #endif
00079
00080 /* LT_CONC creates a new concatenated symbol for the compiler
00081    in a portable way.  */
00082 #if defined(__STDC__) || defined(__cplusplus)
00083 #  define LT_CONC(s,t)  s##t
00084 #else
00085 #  define LT_CONC(s,t)  st
00086 #endif
00087
00088 /* LT_STRLEN can be used safely on NULL pointers.  */
00089 #define LT_STRLEN(s)    (((s) && (s)[0]) ? strlen (s) : 0)
00090
00091
00092
00093 /* --- WINDOWS SUPPORT --- */
00094
00095
00096 /* Canonicalise Windows and Cygwin recognition macros.  */
00097 #ifdef __CYGWIN32__
00098 #  ifndef __CYGWIN__
00099 #    define __CYGWIN__ __CYGWIN32__
00100 #  endif
00101 #endif
00102 #if defined(_WIN32) || defined(WIN32)
00103 #  ifndef __WINDOWS__
00104 #    ifdef _WIN32
00105 #      define __WINDOWS__ _WIN32
00106 #    else
00107 #      ifdef WIN32
00108 #        define __WINDOWS__ WIN32
00109 #      endif
00110 #    endif
00111 #  endif
00112 #endif
00113
00114 #ifdef __WINDOWS__
00115 #  ifndef __CYGWIN__
00116 /* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
00117    separator when it is set. */
00118 #    define LT_DIRSEP_CHAR  '\\'
00119 #    define LT_PATHSEP_CHAR ';'
00120 #  endif
00121 #endif
00122 #ifndef LT_PATHSEP_CHAR
00123 #  define LT_PATHSEP_CHAR   ':'
00124 #endif
00125
00126 /* DLL building support on win32 hosts;  mostly to workaround their
00127    ridiculous implementation of data symbol exporting. */
00128 #ifndef LT_SCOPE
00129 #  ifdef __WINDOWS__
00130 #    ifdef DLL_EXPORT       /* defined by libtool (if required) */
00131 #      define LT_SCOPE  __declspec(dllexport)
00132 #    endif
00133 #    ifdef LIBLTDL_DLL_IMPORT   /* define if linking with this dll */
00134 #      define LT_SCOPE  extern __declspec(dllimport)
00135 #    endif
00136 #  endif
00137 #  ifndef LT_SCOPE      /* static linking or !__WINDOWS__ */
00138 #    define LT_SCOPE    extern
00139 #  endif
00140 #endif
00141
00142
00143
00144
00145 /* --- DYNAMIC MODULE LOADING API --- */
00146
00147
00148 typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module.  */
00149
00150 /* Initialisation and finalisation functions for libltdl. */
00151 extern  int     lt_dlinit       LT_PARAMS((void));
00152 extern  int     lt_dlexit       LT_PARAMS((void));
00153
00154 /* Module search path manipulation.  */
00155 extern  int     lt_dladdsearchdir    LT_PARAMS((const char *search_dir));
00156 extern  int     lt_dlinsertsearchdir LT_PARAMS((const char *before,
00157                             const char *search_dir));
00158 extern  int         lt_dlsetsearchpath   LT_PARAMS((const char *search_path));
00159 extern  const char *lt_dlgetsearchpath   LT_PARAMS((void));
00160 extern  int     lt_dlforeachfile     LT_PARAMS((
00161             const char *search_path,
00162             int (*func) (const char *filename, lt_ptr data),
00163             lt_ptr data));
00164
00165 /* Portable libltdl versions of the system dlopen() API. */
00166 extern  lt_dlhandle lt_dlopen       LT_PARAMS((const char *filename));
00167 extern  lt_dlhandle lt_dlopenext    LT_PARAMS((const char *filename));
00168 extern  lt_ptr      lt_dlsym        LT_PARAMS((lt_dlhandle handle,
00169                              const char *name));
00170 extern  const char *lt_dlerror      LT_PARAMS((void));
00171 extern  int     lt_dlclose      LT_PARAMS((lt_dlhandle handle));
00172
00173 /* Module residency management. */
00174 extern  int     lt_dlmakeresident   LT_PARAMS((lt_dlhandle handle));
00175 extern  int     lt_dlisresident LT_PARAMS((lt_dlhandle handle));
00176
00177
00178
00179
00180 /* --- MUTEX LOCKING --- */
00181
00182
00183 typedef void    lt_dlmutex_lock     LT_PARAMS((void));
00184 typedef void    lt_dlmutex_unlock   LT_PARAMS((void));
00185 typedef void    lt_dlmutex_seterror LT_PARAMS((const char *errmsg));
00186 typedef const char *lt_dlmutex_geterror LT_PARAMS((void));
00187
00188 extern  int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock,
00189                         lt_dlmutex_unlock *unlock,
00190                         lt_dlmutex_seterror *seterror,
00191                         lt_dlmutex_geterror *geterror));
00192
00193
00194
00195
00196 /* --- MEMORY HANDLING --- */
00197
00198
00199 /* By default, the realloc function pointer is set to our internal
00200    realloc implementation which iself uses lt_dlmalloc and lt_dlfree.
00201    libltdl relies on a featureful realloc, but if you are sure yours
00202    has the right semantics then you can assign it directly.  Generally,
00203    it is safe to assign just a malloc() and a free() function.  */
00204 LT_SCOPE  lt_ptr   (*lt_dlmalloc)   LT_PARAMS((size_t size));
00205 LT_SCOPE  lt_ptr   (*lt_dlrealloc)  LT_PARAMS((lt_ptr ptr, size_t size));
00206 LT_SCOPE  void     (*lt_dlfree)     LT_PARAMS((lt_ptr ptr));
00207
00208
00209
00210
00211 /* --- PRELOADED MODULE SUPPORT --- */
00212
00213
00214 /* A preopened symbol. Arrays of this type comprise the exported
00215    symbols for a dlpreopened module. */
00216 typedef struct {
00217   const char *name;
00218   lt_ptr      address;
00219 } lt_dlsymlist;
00220
00221 extern  int lt_dlpreload    LT_PARAMS((const lt_dlsymlist *preloaded));
00222 extern  int lt_dlpreload_default
00223                 LT_PARAMS((const lt_dlsymlist *preloaded));
00224
00225 #define LTDL_SET_PRELOADED_SYMBOLS()        LT_STMT_START{  \
00226     extern const lt_dlsymlist lt_preloaded_symbols[];       \
00227     lt_dlpreload_default(lt_preloaded_symbols);         \
00228                         }LT_STMT_END
00229
00230
00231
00232
00233 /* --- MODULE INFORMATION --- */
00234
00235
00236 /* Read only information pertaining to a loaded module. */
00237 typedef struct {
00238   char  *filename;      /* file name */
00239   char  *name;          /* module name */
00240   int   ref_count;      /* number of times lt_dlopened minus
00241                    number of times lt_dlclosed. */
00242 } lt_dlinfo;
00243
00244 extern  const lt_dlinfo *lt_dlgetinfo       LT_PARAMS((lt_dlhandle handle));
00245 extern  lt_dlhandle lt_dlhandle_next    LT_PARAMS((lt_dlhandle place));
00246 extern  int     lt_dlforeach        LT_PARAMS((
00247                 int (*func) (lt_dlhandle handle, lt_ptr data),
00248                 lt_ptr data));
00249
00250 /* Associating user data with loaded modules. */
00251 typedef unsigned lt_dlcaller_id;
00252
00253 extern  lt_dlcaller_id  lt_dlcaller_register  LT_PARAMS((void));
00254 extern  lt_ptr      lt_dlcaller_set_data  LT_PARAMS((lt_dlcaller_id key,
00255                         lt_dlhandle handle,
00256                         lt_ptr data));
00257 extern  lt_ptr      lt_dlcaller_get_data  LT_PARAMS((lt_dlcaller_id key,
00258                         lt_dlhandle handle));
00259
00260
00261
00262 /* --- USER MODULE LOADER API --- */
00263
00264
00265 typedef struct lt_dlloader  lt_dlloader;
00266 typedef lt_ptr          lt_user_data;
00267 typedef lt_ptr          lt_module;
00268
00269 /* Function pointer types for creating user defined module loaders. */
00270 typedef lt_module   lt_module_open  LT_PARAMS((lt_user_data loader_data,
00271                         const char *filename));
00272 typedef int     lt_module_close LT_PARAMS((lt_user_data loader_data,
00273                         lt_module handle));
00274 typedef lt_ptr      lt_find_sym     LT_PARAMS((lt_user_data loader_data,
00275                         lt_module handle,
00276                         const char *symbol));
00277 typedef int     lt_dlloader_exit    LT_PARAMS((lt_user_data loader_data));
00278
00279 struct lt_user_dlloader {
00280   const char           *sym_prefix;
00281   lt_module_open       *module_open;
00282   lt_module_close      *module_close;
00283   lt_find_sym          *find_sym;
00284   lt_dlloader_exit     *dlloader_exit;
00285   lt_user_data      dlloader_data;
00286 };
00287
00288 extern  lt_dlloader    *lt_dlloader_next    LT_PARAMS((lt_dlloader *place));
00289 extern  lt_dlloader    *lt_dlloader_find    LT_PARAMS((
00290                         const char *loader_name));
00291 extern  const char     *lt_dlloader_name    LT_PARAMS((lt_dlloader *place));
00292 extern  lt_user_data   *lt_dlloader_data    LT_PARAMS((lt_dlloader *place));
00293 extern  int     lt_dlloader_add     LT_PARAMS((lt_dlloader *place,
00294                 const struct lt_user_dlloader *dlloader,
00295                 const char *loader_name));
00296 extern  int     lt_dlloader_remove  LT_PARAMS((
00297                         const char *loader_name));
00298
00299
00300
00301 /* --- ERROR MESSAGE HANDLING --- */
00302
00303
00304 /* Defining error strings alongside their symbolic names in a macro in
00305    this way allows us to expand the macro in different contexts with
00306    confidence that the enumeration of symbolic names will map correctly
00307    onto the table of error strings.  */
00308 #define lt_dlerror_table                        \
00309     LT_ERROR(UNKNOWN,           "unknown error")            \
00310     LT_ERROR(DLOPEN_NOT_SUPPORTED,  "dlopen support not available") \
00311     LT_ERROR(INVALID_LOADER,        "invalid loader")           \
00312     LT_ERROR(INIT_LOADER,       "loader initialization failed") \
00313     LT_ERROR(REMOVE_LOADER,     "loader removal failed")        \
00314     LT_ERROR(FILE_NOT_FOUND,        "file not found")           \
00315     LT_ERROR(DEPLIB_NOT_FOUND,      "dependency library not found") \
00316     LT_ERROR(NO_SYMBOLS,        "no symbols defined")       \
00317     LT_ERROR(CANNOT_OPEN,       "can't open the module")        \
00318     LT_ERROR(CANNOT_CLOSE,      "can't close the module")       \
00319     LT_ERROR(SYMBOL_NOT_FOUND,      "symbol not found")         \
00320     LT_ERROR(NO_MEMORY,         "not enough memory")        \
00321     LT_ERROR(INVALID_HANDLE,        "invalid module handle")        \
00322     LT_ERROR(BUFFER_OVERFLOW,       "internal buffer overflow")     \
00323     LT_ERROR(INVALID_ERRORCODE,     "invalid errorcode")        \
00324     LT_ERROR(SHUTDOWN,          "library already shutdown")     \
00325     LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module")  \
00326     LT_ERROR(INVALID_MUTEX_ARGS,    "invalid mutex handler registration") \
00327     LT_ERROR(INVALID_POSITION,      "invalid search path insert position")
00328
00329 /* Enumerate the symbolic error names. */
00330 enum {
00331 #define LT_ERROR(name, diagnostic)  LT_CONC(LT_ERROR_, name),
00332     lt_dlerror_table
00333 #undef LT_ERROR
00334
00335     LT_ERROR_MAX
00336 };
00337
00338 /* These functions are only useful from inside custom module loaders. */
00339 extern  int lt_dladderror   LT_PARAMS((const char *diagnostic));
00340 extern  int lt_dlseterror   LT_PARAMS((int errorcode));
00341
00342
00343
00344
00345 /* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */
00346
00347
00348 #ifdef LT_NON_POSIX_NAMESPACE
00349 #  define lt_ptr_t      lt_ptr
00350 #  define lt_module_t       lt_module
00351 #  define lt_module_open_t  lt_module_open
00352 #  define lt_module_close_t lt_module_close
00353 #  define lt_find_sym_t     lt_find_sym
00354 #  define lt_dlloader_exit_t    lt_dlloader_exit
00355 #  define lt_dlloader_t     lt_dlloader
00356 #  define lt_dlloader_data_t    lt_user_data
00357 #endif
00358
00359 LT_END_C_DECLS
00360
00361 #endif /* !LTDL_H */


mail.C File Reference

Parser: mail parser class. More...

Include dependency graph for mail.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MMail

Defines

#define | MAIL_CLASS_NAME "mail"
#define | SENDMAIL_NAME "sendmail"
#define | MAIL_NAME "MAIL"

Functions

DECLARE_CLASS_VAR (mail, 0, new MMail)
const String | mail_name (MAIL_NAME)
const String | mail_sendmail_name (SENDMAIL_NAME)
void | sendmail (Value *, Value *smtp_server_port, const String &message, const String *from, const String *to, const String *options)
void | _send (Request &r, MethodParams &params)

Variables

const char *const | IDENT_MAIL_C = "$Date: 2005/08/09 08:14:48 $"
const int | ATTACHMENT_WEIGHT = 100

Detailed Description

Parser: mail parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file mail.C.

Define Documentation

#define MAIL_CLASS_NAME "mail"

Definition at line 30 of file mail.C.

Referenced by MMail::configure_user(), and MMail::MMail().

#define SENDMAIL_NAME "sendmail"

Definition at line 31 of file mail.C.

Referenced by sendmail().

#define MAIL_NAME "MAIL"

Definition at line 54 of file mail.C.

Referenced by MMail::configure_user(), and sendmail().

Function Documentation

DECLARE_CLASS_VAR | ( | mail | ,
 |  | 0 | ,
 |  | new | MMail
 | ) |

const String mail_name ( MAIL_NAME ) [static]

const String mail_sendmail_name ( SENDMAIL_NAME ) [static]

void sendmail | ( | Value * | ,
 |  | Value * | smtp_server_port,
 |  | const String & | message,
 |  | const String * | from,
 |  | const String * | to,
 |  | const String * | options
 | ) | [static]

Definition at line 63 of file mail.C.

References Value::as_string(), String::cstr(), String::cstrm(), PA_exec_result::err, file_executable(), String::L_AS_IS, String::L_UNSPECIFIED, String::length(), MAIL_NAME, MAIN_CLASS_NAME, String::mid(), pa_exec(), String::pos(), rsplit(), SMTP::Send(), SENDMAIL_NAME, String::split(), PA_exec_result::status, and STRING_NOT_FOUND.

Referenced by _send().

void _send | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 195 of file mail.C.

References MethodParams::as_no_junction(), Value::as_string(), Request::classes_conf, Hash< const String::Body, void * >::get(), Hash< const String::Body, Value * >::get(), Value::get_hash(), GET_SELF, mail_base_class, MAIL_OPTIONS_NAME, VStateless_class::name(), sendmail(), and Request::write_pass_lang().

Referenced by MMail::MMail().

Variable Documentation

const char* const IDENT_MAIL_C = "$Date: 2005/08/09 08:14:48 $" [static]

Definition at line 8 of file mail.C.

const int ATTACHMENT_WEIGHT = 100

Definition at line 35 of file mail.C.


mail.C Source File

mail.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_MAIL_C="$Date: 2005/08/09 08:14:48 $";
00009
00010 #include "pa_config_includes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_common.h"
00014 #include "pa_request.h"
00015 #include "pa_vfile.h"
00016 #include "pa_exec.h"
00017 #include "pa_charsets.h"
00018 #include "pa_charset.h"
00019 #include "pa_uue.h"
00020 #include "pa_vmail.h"
00021
00022 #include "smtp.h"
00023
00024 // debug switches
00025
00026 //#define DEBUG_JUST_SEE_MESSAGE
00027
00028 // defines
00029
00030 #define MAIL_CLASS_NAME "mail"
00031 #define SENDMAIL_NAME "sendmail"
00032
00033 // consts
00034
00035 const int ATTACHMENT_WEIGHT=100;
00036
00037 // class
00038
00039 class MMail: public Methoded {
00040 public: // Methoded
00041     bool used_directly() { return false; }
00042     void configure_user(Request& r);
00043
00044 public:
00045     MMail();
00046 };
00047
00048 // global variable
00049
00050 DECLARE_CLASS_VAR(mail, 0/*fictive*/, new MMail);
00051
00052 // defines for statics
00053
00054 #define MAIL_NAME "MAIL"
00055
00056 // statics
00057
00058 static const String mail_name(MAIL_NAME);
00059 static const String mail_sendmail_name(SENDMAIL_NAME);
00060
00061 // helpers
00062
00063 static void sendmail(
00064             Value*
00065 #ifndef WIN32
00066             vmail_conf
00067 #endif
00068             , Value* smtp_server_port,
00069              const String& message,
00070              const String* from, const String* to,
00071              const String*
00072 #ifndef _MSC_VER
00073              options
00074 #endif
00075              ) {
00076     const char* message_cstr=message.cstr(String::L_UNSPECIFIED);
00077
00078     const char* exception_type="email.format";
00079     if(!from) // we use in sendmail -f {from} && SMTP MAIL from: {from}
00080         throw Exception(exception_type,
00081             0,
00082             "parameter does not specify 'from' header field");
00083     if(smtp_server_port) {
00084         if(!to) // we use only in SMTP RCPT to: {to}
00085             throw Exception(exception_type,
00086                 0,
00087                 "parameter does not specify 'to' header field");
00088
00089         SMTP smtp;
00090         char* server=smtp_server_port->as_string().cstrm();
00091         const char* port=rsplit(server, ':');
00092         if(!port)
00093             port="25";
00094
00095         smtp.Send(server, port, message_cstr, from->cstrm(), to->cstrm());
00096         return;
00097     }
00098
00099 #if WIN32
00100     // win32 without SMTP server configured
00101     throw Exception("parser.runtime",
00102         0,
00103         "$"MAIN_CLASS_NAME":"MAIL_NAME".SMTP not defined");
00104 #else
00105     // unix
00106     // $MAIN:MAIL.sendmail["/usr/sbin/sendmail -t -i -f postmaster"] default
00107     // $MAIN:MAIL.sendmail["/usr/lib/sendmail -t -i  -f postmaster"] default
00108
00109     String* sendmail_command=new String;
00110     if(vmail_conf) {
00111 #ifdef PA_FORCED_SENDMAIL
00112         throw Exception("parser.runtime",
00113             0,
00114             "Parser was configured with --with-sendmail="PA_FORCED_SENDMAIL
00115             " key, to change sendmail you should reconfigure and recompie it");
00116 #else
00117         if(Value* sendmail_value=vmail_conf->get_hash()->get(mail_sendmail_name))
00118             *sendmail_command<<sendmail_value->as_string();
00119         else
00120             throw Exception("parser.runtime",
00121                 0,
00122                 "$"MAIN_CLASS_NAME":"MAIL_NAME"."SENDMAIL_NAME" not defined");
00123 #endif
00124     } else {
00125 #ifdef PA_FORCED_SENDMAIL
00126         *sendmail_command<<PA_FORCED_SENDMAIL;
00127 #else
00128         String* test=new String("/usr/sbin/sendmail");
00129         if(!file_executable(*test))
00130             test=new String("/usr/lib/sendmail");
00131         *sendmail_command<<*test;
00132         *sendmail_command<<" -t -i -f postmaster";
00133 #endif
00134     }
00135     if(options)
00136         *sendmail_command<<" "<<*options;
00137
00138     // we know sendmail_command here, should replace "postmaster" with "$from" from message
00139     size_t at_postmaster=sendmail_command->pos("postmaster");
00140     if(at_postmaster!=STRING_NOT_FOUND) {
00141         String& reconstructed=sendmail_command->mid(0, at_postmaster);
00142         reconstructed << *from;
00143         reconstructed << sendmail_command->mid(at_postmaster+10/*postmaster*/, sendmail_command->length());
00144         sendmail_command=&reconstructed;
00145     }
00146
00147     // execute it
00148     ArrayString argv;
00149     const String* file_spec;
00150     size_t after_file_spec=sendmail_command->pos(' ');
00151     if(after_file_spec==STRING_NOT_FOUND || after_file_spec==0)
00152         file_spec=sendmail_command;
00153     else {
00154         size_t pos_after=after_file_spec;
00155         file_spec=&sendmail_command->mid(0, pos_after++);
00156         sendmail_command->split(argv, pos_after, " ", String::L_AS_IS);
00157     }
00158
00159     if(!file_executable(*file_spec))
00160         throw Exception("email.send",
00161             file_spec,
00162             "is not executable."
00163 #ifdef PA_FORCED_SENDMAIL
00164             " Use configure key \"--with-sendmail=appropriate sendmail command\""
00165 #else
00166             " Set $"MAIN_CLASS_NAME":"MAIL_NAME"."SENDMAIL_NAME" to appropriate sendmail command"
00167 #endif
00168         );
00169
00170
00171     String in(message_cstr);
00172     PA_exec_result exec=pa_exec(
00173         // forced_allow
00174 #ifdef PA_FORCED_SENDMAIL
00175         true
00176 #else
00177         false
00178 #endif
00179         , *file_spec,
00180         0 /* pass env */,
00181         argv,
00182         in);
00183     if(exec.status || exec.err.length())
00184         throw Exception("email.send",
00185             0,
00186             "'%s' reported problem: %s (%d)",
00187                 file_spec->cstr(),
00188                 exec.err.length()?exec.err.cstr():"UNKNOWN",
00189                 exec.status);
00190 #endif
00191 }
00192
00193 // methods
00194
00195 static void _send(Request& r, MethodParams& params) {
00196     Value& vhash=params.as_no_junction(0, "message must not be code");
00197     HashStringValue* hash=vhash.get_hash();
00198     if(!hash)
00199         throw Exception("parser.runtime",
00200             0,
00201             "message must be hash");
00202
00203     const String* soptions=0;
00204     if(Value* voptions=hash->get(MAIL_OPTIONS_NAME))
00205         soptions=&voptions->as_string();
00206
00207     Value* vmail_conf=static_cast<Value*>(r.classes_conf.get(mail_base_class->name()));
00208     Value* smtp_server_port=0;
00209     if(vmail_conf) {
00210         // $MAIN:MAIL.SMTP[mail.yourdomain.ru[:port]]
00211         smtp_server_port=vmail_conf->get_hash()->get(String::Body("SMTP"));
00212     }
00213
00214
00215     const String* from=0;
00216     String* to=0;
00217     const String& message=
00218         GET_SELF(r, VMail).message_hash_to_string(r, hash, 0, from,
00219             smtp_server_port?true:false /*send by SMTP=strip to?*/, to);
00220
00221 #ifdef DEBUG_JUST_SEE_MESSAGE
00222     r.write_pass_lang(message);
00223 #else
00224     sendmail(vmail_conf, smtp_server_port,
00225         message, from, to, soptions);
00226 #endif
00227 }
00228
00229 // constructor & configurator
00230
00231 MMail::MMail(): Methoded(MAIL_CLASS_NAME) {
00232     // ^mail:send{hash}
00233     add_native_method("send", Method::CT_STATIC, _send, 1, 1);
00234 }
00235
00236 void MMail::configure_user(Request& r) {
00237
00238     // $MAIN:MAIL[$SMTP[mail.design.ru]]
00239     if(Value* mail_element=r.main_class.get_element(mail_name, r.main_class, false))
00240         if(mail_element->get_hash())
00241             r.classes_conf.put(name(), mail_element);
00242         else
00243             if( !mail_element->is_string() )
00244                 throw Exception("parser.runtime",
00245                     0,
00246                     "$" MAIL_CLASS_NAME ":" MAIL_NAME " is not hash");
00247 }


maketables.c File Reference

Include dependency graph for maketables.c:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

unsigned const char * pcre_maketables (void)

Function Documentation

unsigned const char* pcre_maketables ( void )

Definition at line 62 of file maketables.c.

References cbit_digit, cbit_length, cbit_space, cbit_word, ctype_digit, ctype_letter, ctype_meta, ctype_space, ctype_word, ctype_xdigit, p, and tables_length.

Referenced by main().


maketables.c Source File

maketables.c

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005 /*
00006 PCRE is a library of functions to support regular expressions whose syntax
00007 and semantics are as close as possible to those of the Perl 5 language.
00008
00009 Written by: Philip Hazel <ph10@cam.ac.uk>
00010
00011            Copyright (c) 1997-1999 University of Cambridge
00012
00013 -----------------------------------------------------------------------------
00014 Permission is granted to anyone to use this software for any purpose on any
00015 computer system, and to redistribute it freely, subject to the following
00016 restrictions:
00017
00018 1. This software is distributed in the hope that it will be useful,
00019    but WITHOUT ANY WARRANTY; without even the implied warranty of
00020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00021
00022 2. The origin of this software must not be misrepresented, either by
00023    explicit claim or by omission.
00024
00025 3. Altered versions must be plainly marked as such, and must not be
00026    misrepresented as being the original software.
00027
00028 4. If PCRE is embedded in any software that is released under the GNU
00029    General Purpose Licence (GPL), then the terms of that licence shall
00030    supersede any condition above with which it is incompatible.
00031 -----------------------------------------------------------------------------
00032
00033 See the file Tech.Notes for some information on the internals.
00034 */
00035
00036
00037 /* This file is compiled on its own as part of the PCRE library. However,
00038 it is also included in the compilation of dftables.c, in which case the macro
00039 DFTABLES is defined. */
00040
00041 #ifndef DFTABLES
00042 #include "internal.h"
00043 #endif
00044
00045
00046
00047 /*************************************************
00048 *           Create PCRE character tables         *
00049 *************************************************/
00050
00051 /* This function builds a set of character tables for use by PCRE and returns
00052 a pointer to them. They are build using the ctype functions, and consequently
00053 their contents will depend upon the current locale setting. When compiled as
00054 part of the library, the store is obtained via pcre_malloc(), but when compiled
00055 inside dftables, use malloc().
00056
00057 Arguments:   none
00058 Returns:     pointer to the contiguous block of data
00059 */
00060
00061 unsigned const char *
00062 pcre_maketables(void)
00063 {
00064 unsigned char *yield, *p;
00065 int i;
00066
00067 #ifndef DFTABLES
00068 yield = (unsigned char*)(pcre_malloc)(tables_length);
00069 #else
00070 yield = (unsigned char*)malloc(tables_length);
00071 #endif
00072
00073 if (yield == NULL) return NULL;
00074 p = yield;
00075
00076 /* First comes the lower casing table */
00077
00078 for (i = 0; i < 256; i++) *p++ = (unsigned char)tolower(i);
00079
00080 /* Next the case-flipping table */
00081
00082 for (i = 0; i < 256; i++) *p++ = (unsigned char)(islower(i)? toupper(i) : tolower(i));
00083
00084 /* Then the character class tables */
00085
00086 memset(p, 0, cbit_length);
00087 for (i = 0; i < 256; i++)
00088   {
00089   if (isdigit(i)) p[cbit_digit  + i/8] |= 1 << (i&7);
00090   if (isalnum(i) || i == '_')
00091                   p[cbit_word   + i/8] |= 1 << (i&7);
00092   if (isspace(i)) p[cbit_space  + i/8] |= 1 << (i&7);
00093   }
00094 p += cbit_length;
00095
00096 /* Finally, the character type table */
00097
00098 for (i = 0; i < 256; i++)
00099   {
00100   int x = 0;
00101   if (isspace(i)) x += ctype_space;
00102   if (isalpha(i)) x += ctype_letter;
00103   if (isdigit(i)) x += ctype_digit;
00104   if (isxdigit(i)) x += ctype_xdigit;
00105   if (isalnum(i) || i == '_') x += ctype_word;
00106   if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta;
00107   *p++ = (unsigned char)x;
00108   }
00109
00110 return yield;
00111 }
00112
00113 /* End of maketables.c */


math.C File Reference

Parser: math parser class. More...

Include dependency graph for math.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MMath
class | Random_provider
struct | uuid
to hell with extra bytes on 64bit platforms. More...

Defines

#define | _WIN32_WINNT 0x400
#define | MAX_SALT 8
#define | MAX_UINT 0xFFFFFFFFu
#define | MATH1(name)
#define | MATH1P(name_parser, name_c)
#define | MATH2(name)
#define | ADDX(name, X) add_native_method(#name, Method::CT_STATIC, _##name, X, X)
#define | ADD0(name) ADDX(name, 0)
#define | ADD1(name) ADDX(name, 1)
#define | ADD2(name) ADDX(name, 2)

Typedefs

typedef double(* | math1_func_ptr )(double)
typedef double(* | math2_func_ptr )(double, double)

Functions

char * | crypt (const char *, const char *)
DECLARE_CLASS_VAR (math, 0, new MMath)
void | random (void *buffer, size_t size)
int | _random (uint top)
void | _random (Request &r, MethodParams &params)
double | frac (double param)
double | degrees (double param)
double | radians (double param)
void | math1 (Request &r, MethodParams &params, math1_func_ptr func)
MATH1 (round)
MATH1 (floor)
MATH1P (ceiling, ceil)
MATH1 (trunc)
MATH1P (abs, fabs)
MATH1 (sign)
MATH1 (exp)
MATH1 (log)
MATH1 (asin)
MATH1 (cos)
MATH1 (degrees)
void | math2 (Request &r, MethodParams &params, math2_func_ptr func)
MATH2 (pow)
bool | is_salt_body_char (int c)
size_t | calc_prefix_size (const char *salt)
void | _crypt (Request &r, MethodParams &params)
const char * | hex_string (unsigned char *bytes, size_t size, bool upcase)
void | _md5 (Request &r, MethodParams &params)
void | _uuid (Request &r, MethodParams &)
void | _uid64 (Request &r, MethodParams &)

Variables

const char *const | IDENT_MATH_C = "$Date: 2005/08/26 11:12:45 $"
Random_provider random_provider

Detailed Description

Parser: math parser class.

Copyright(c) 2001-2005 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru>(http://paf.design.ru)

portions from gen_uuid.c, Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.

Definition in file math.C.

Define Documentation

#define _WIN32_WINNT 0x400

Definition at line 22 of file math.C.

#define MAX_SALT 8

Definition at line 37 of file math.C.

Referenced by _crypt().

#define MAX_UINT 0xFFFFFFFFu

Definition at line 158 of file math.C.

Referenced by _random().

#define MATH1 ( name )

Value:

static void _##name(Request& r, MethodParams& params) {\
        math1(r, params, &name);\
    }

Definition at line 188 of file math.C.

#define MATH1P | ( | name_parser,
 |  | name_c | )

Value:

static void _##name_parser(Request& r, MethodParams& params) {\
        math1(r, params, &name_c);\
    }

Definition at line 192 of file math.C.

#define MATH2 ( name )

Value:

static void _##name(Request& r, MethodParams& params) {\
        math2(r, params, &name);\
    }

Definition at line 215 of file math.C.

#define ADDX | ( | name,
 |  | X | ) | add_native_method(#name, Method::CT_STATIC, _##name, X, X)

#define ADD0 ( name ) ADDX(name, 0)

#define ADD1 ( name ) ADDX(name, 1)

#define ADD2 ( name ) ADDX(name, 2)

Typedef Documentation

typedef double(* math1_func_ptr)(double)

Definition at line 177 of file math.C.

Referenced by math1().

typedef double(* math2_func_ptr)(double, double)

Definition at line 207 of file math.C.

Referenced by math2().

Function Documentation

char* crypt | ( | const char * | ,
 |  | const char * |
 | ) |

Referenced by _crypt(), and MMath::MMath().

DECLARE_CLASS_VAR | ( | math | ,
 |  | 0 | ,
 |  | new | MMath
 | ) |

void random | ( | void * | buffer,
 |  | size_t | size
 | ) | [static]

Definition at line 147 of file math.C.

References Random_provider::generate(), random_provider, and size.

Referenced by _random(), _uid64(), _uuid(), and MMath::MMath().

int _random ( uint top ) [inline, static]

Definition at line 160 of file math.C.

References MAX_UINT, random(), and uint.

void _random | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 166 of file math.C.

References MethodParams::as_double(), MAX_UINT, uint, and Request::write_no_lang().

Referenced by _crypt().

double frac ( double param ) [static]

Definition at line 178 of file math.C.

Referenced by MMath::MMath().

double degrees ( double param ) [static]

Definition at line 179 of file math.C.

References PI.

Referenced by MMath::MMath().

double radians ( double param ) [static]

Definition at line 180 of file math.C.

References PI.

Referenced by MMath::MMath().

void math1 | ( | Request & | r,
 |  | MethodParams & | params,
 |  | math1_func_ptr | func
 | ) | [static]

Definition at line 182 of file math.C.

References MethodParams::as_double(), func, math1_func_ptr, result, and Request::write_no_lang().

MATH1 ( round )

MATH1 ( floor )

MATH1P | ( | ceiling | ,
 |  | ceil |
 | ) |

MATH1 ( trunc )

MATH1P | ( | abs | ,
 |  | fabs |
 | ) |

MATH1 ( sign )

MATH1 ( exp )

MATH1 ( log )

MATH1 ( asin )

MATH1 ( cos )

MATH1 ( degrees )

void math2 | ( | Request & | r,
 |  | MethodParams & | params,
 |  | math2_func_ptr | func
 | ) | [static]

Definition at line 208 of file math.C.

References MethodParams::as_double(), func, math2_func_ptr, result, and Request::write_no_lang().

MATH2 ( pow )

bool is_salt_body_char ( int c ) [inline]

Definition at line 221 of file math.C.

Referenced by calc_prefix_size().

size_t calc_prefix_size ( const char * salt ) [static]

Definition at line 224 of file math.C.

References is_salt_body_char(), and salt.

Referenced by _crypt().

void _crypt | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 236 of file math.C.

References _random(), MethodParams::as_string(), calc_prefix_size(), crypt(), String::cstr(), MAX_SALT, MAX_STRING, pa_MD5Encode(), PA_MD5PW_ID, PA_MD5PW_IDLEN, pa_strdup(), and Request::write_pass_lang().

const char* hex_string | ( | unsigned char * | bytes,
 |  | size_t | size,
 |  | bool | upcase
 | ) | [static]

Definition at line 284 of file math.C.

References size.

Referenced by _md5(), and _uid64().

void _md5 | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 301 of file math.C.

References MethodParams::as_string(), context, String::cstr(), hex_string(), PA_MD5_CTX, pa_MD5Final(), pa_MD5Init(), pa_MD5Update(), and Request::write_pass_lang().

void _uuid | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 322 of file math.C.

References uuid::clock_seq, uuid::node, random(), snprintf, uuid::time_hi_and_version, uuid::time_low, uuid::time_mid, and Request::write_pass_lang().

void _uid64 | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 357 of file math.C.

References hex_string(), random(), and Request::write_pass_lang().

Variable Documentation

const char* const IDENT_MATH_C = "$Date: 2005/08/26 11:12:45 $" [static]

Definition at line 11 of file math.C.

class Random_provider random_provider

Referenced by random().


math.C Source File

math.C

Go to the documentation of this file.
00001
00011 static const char * const IDENT_MATH_C="$Date: 2005/08/26 11:12:45 $";
00012
00013 #include "pa_vmethod_frame.h"
00014 #include "pa_common.h"
00015 #include "pa_vint.h"
00016 #include "pa_vmath.h"
00017 #include "pa_request.h"
00018 #include "pa_md5.h"
00019 #include "pa_threads.h"
00020
00021 #ifdef WIN32
00022 #   define _WIN32_WINNT 0x400
00023 #   include <windows.h>
00024 #   include <wincrypt.h>
00025 #endif
00026
00027 #ifdef HAVE_CRYPT
00028 #   ifdef HAVE_CRYPT_H
00029 #       include <crypt.h>
00030 #   endif
00031 #else
00032     extern char *crypt(const char* , const char* );
00033 #endif
00034
00035 // defines
00036
00037 #define MAX_SALT 8
00038
00039 // class
00040
00041 class MMath: public Methoded {
00042 public:
00043     MMath();
00044
00045 public: // Methoded
00046     bool used_directly() { return false; }
00047 };
00048
00049 // global variables
00050
00051 DECLARE_CLASS_VAR(math, 0 /*fictive*/, new MMath);
00052
00053 #ifdef WIN32
00054 class Random_provider {
00055     HCRYPTPROV fhProv;
00056
00057     void acquire() {
00058         SYNCHRONIZED;
00059
00060         if(fhProv)
00061             return;
00062
00063         if(!CryptAcquireContext(&fhProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
00064             throw Exception(0,
00065                 0,
00066                 "CryptAcquireContext failed");
00067     }
00068     void release() {
00069         if(fhProv)
00070             CryptReleaseContext(fhProv, 0);
00071     }
00072
00073 public:
00074     Random_provider(): fhProv(0) {}
00075     ~Random_provider() { release(); }
00076     void generate(void *buffer, size_t size) {
00077         acquire();
00078
00079         if(!CryptGenRandom(fhProv, size, (BYTE*)buffer))
00080             throw Exception(0,
00081                 0,
00082                 "CryptGenRandom failed");
00083     }
00084 }
00085     random_provider;
00086
00087 #else
00088
00090 static int get_random_fd(void)
00091 {
00092         struct timeval  tv;
00093         static int      fd = -2;
00094         int             i;
00095
00096         if (fd == -2) {
00097                 gettimeofday(&tv, 0);
00098                 fd = open("/dev/urandom", O_RDONLY);
00099                 if (fd == -1)
00100                         fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
00101                 srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
00102         }
00103         /* Crank the random number generator a few times */
00104         gettimeofday(&tv, 0);
00105         for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
00106                 rand();
00107         return fd;
00108 }
00109
00110
00111 /*
00112  * Generate a series of random bytes.  Use /dev/urandom if possible,
00113  * and if not, use srandom/random.
00114  */
00115 static void get_random_bytes(void *buf, int nbytes)
00116 {
00117         int i, fd = get_random_fd();
00118         int lose_counter = 0;
00119         char *cp = (char *) buf;
00120
00121         if (fd >= 0) {
00122                 while (nbytes > 0) {
00123                         i = read(fd, cp, nbytes);
00124                         if (i <= 0) {
00125                                 if (lose_counter++ > 16)
00126                                         break;
00127                                 continue;
00128                         }
00129                         nbytes -= i;
00130                         cp += i;
00131                         lose_counter = 0;
00132                 }
00133         }
00134
00135         /* XXX put something better here if no /dev/random! */
00136         for (i = 0; i < nbytes; i++)
00137                 *cp++ = rand() & 0xFF;
00138         return;
00139 }
00140
00141
00142 #endif
00143
00144
00145 // helpers
00146
00147 static void random(void *buffer, size_t size) {
00148 #ifdef WIN32
00149     random_provider.generate(buffer, size);
00150 #else
00151     get_random_bytes(buffer, size);
00152 #endif
00153 }
00154
00155
00156 // methods
00157
00158 #define MAX_UINT 0xFFFFFFFFu
00159
00160 static inline int _random(uint top) {
00161     uint raw;
00162     random(&raw, sizeof(raw));
00163     return int(double(raw) / MAX_UINT * top );
00164 }
00165
00166 static void _random(Request& r, MethodParams& params) {
00167     double top=params.as_double(0, "range must be expression", r);
00168     if(top<=0 || top>MAX_UINT)
00169         throw Exception("parser.runtime",
00170             0,
00171             "top(%g) must be [1..%u]", top, MAX_UINT);
00172
00173     r.write_no_lang(*new VInt(_random(uint(top))));
00174 }
00175
00176
00177 typedef double(*math1_func_ptr)(double);
00178 static double frac(double param) { return param-trunc(param); }
00179 static double degrees(double param) { return param /PI *180; }
00180 static double radians(double param) { return param /180 *PI; }
00181
00182 static void math1(Request& r, MethodParams& params, math1_func_ptr func) {
00183     double param=params.as_double(0, "parameter must be expression", r);
00184     double result=func(param);
00185     r.write_no_lang(*new VDouble(result));
00186 }
00187
00188 #define MATH1(name) \
00189     static void _##name(Request& r, MethodParams& params) {\
00190         math1(r, params, &name);\
00191     }
00192 #define MATH1P(name_parser, name_c) \
00193     static void _##name_parser(Request& r, MethodParams& params) {\
00194         math1(r, params, &name_c);\
00195     }
00196 MATH1(round);   MATH1(floor);   MATH1P(ceiling, ceil);
00197 MATH1(trunc);   MATH1(frac);
00198 MATH1P(abs, fabs);  MATH1(sign);
00199 MATH1(exp); MATH1(log);
00200 MATH1(sin); MATH1(asin);
00201 MATH1(cos); MATH1(acos);
00202 MATH1(tan); MATH1(atan);
00203 MATH1(degrees); MATH1(radians);
00204 MATH1(sqrt);
00205
00206
00207 typedef double (*math2_func_ptr)(double, double);
00208 static void math2(Request& r, MethodParams& params, math2_func_ptr func) {
00209     double a=params.as_double(0, "parameter must be expression", r);
00210     double b=params.as_double(1, "parameter must be expression", r);
00211     double result=func(a, b);
00212     r.write_no_lang(*new VDouble(result));
00213 }
00214
00215 #define MATH2(name) \
00216     static void _##name(Request& r, MethodParams& params) {\
00217         math2(r, params, &name);\
00218     }
00219 MATH2(pow);
00220
00221 inline bool is_salt_body_char(int c) {
00222     return isalnum(c) || c == '.' || c=='/';
00223 }
00224 static size_t calc_prefix_size(const char* salt) {
00225     if(strlen(salt)) {
00226         if(!is_salt_body_char((unsigned char)salt[0])) { // $...  {...
00227             const char* cur=salt+1; // skip
00228             while(is_salt_body_char((unsigned char)*cur++)) // ...$  ...}
00229                 ;
00230             return cur-salt;
00231         } else
00232             return 0;
00233     } else
00234         return 0;
00235 }
00236 static void _crypt(Request& r, MethodParams& params) {
00237     const char* password=params.as_string(0, "password must be string").cstr();
00238     const char* maybe_bodyless_salt=params.as_string(1, "salt must be string").cstr();
00239
00240     size_t prefix_size=calc_prefix_size(maybe_bodyless_salt);
00241     const char* normal_salt;
00242     char normalize_buf[MAX_STRING];
00243     if(prefix_size==strlen(maybe_bodyless_salt)) { // bodyless?
00244         strncpy(normalize_buf, maybe_bodyless_salt, MAX_STRING-MAX_SALT-1);
00245         char *cur=normalize_buf+strlen(normalize_buf);
00246         // sould add up MAX_SALT random chars
00247         static unsigned char itoa64[] =         /* 0 ... 63 => ASCII - 64 */
00248         "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00249         for(int i=0; i<MAX_SALT; i++)
00250             *cur++=itoa64[_random(64)];
00251         *cur=0;
00252         normal_salt=normalize_buf;
00253     } else
00254         normal_salt=maybe_bodyless_salt;
00255
00256     /* FreeBSD style MD5 string
00257      */
00258     if(strncmp(normal_salt, PA_MD5PW_ID, PA_MD5PW_IDLEN) == 0) {
00259         const size_t sample_size=120;
00260         char *sample_buf=new(PointerFreeGC) char[sample_size];
00261         pa_MD5Encode((const unsigned char *)password,
00262                 (const unsigned char *)normal_salt, sample_buf, sample_size);
00263         String sample(sample_buf);
00264         r.write_pass_lang(sample);
00265     } else {
00266 #ifdef HAVE_CRYPT
00267         const char* static_sample_buf=crypt(password, normal_salt);
00268         if(!static_sample_buf  // nothing generated
00269             || !static_sample_buf[0] // generated nothing
00270             || strncmp(static_sample_buf, normal_salt, prefix_size)!=0) // salt prefix not preserved
00271             throw Exception("parser.runtime",
00272                 0,
00273                 "crypt on this platform does not support '%.*s' salt prefix", prefix_size, normal_salt);
00274
00275         r.write_pass_lang(String(pa_strdup(static_sample_buf)));
00276 #else
00277         throw Exception("parser.runtime",
00278             0,
00279             "salt must start with '" PA_MD5PW_ID "'");
00280 #endif
00281     }
00282 }
00283
00284 static const char* hex_string(unsigned char* bytes, size_t size, bool upcase) {
00285     char *bytes_hex=new(PointerFreeGC) char [size*2/*byte->hh*/+1/*for zero-teminator*/];
00286     unsigned char *src=bytes;
00287     unsigned char *end=bytes+size;
00288     char *dest=bytes_hex;
00289
00290     static const char *hex=upcase?"0123456789ABCDEF":"0123456789abcdef";
00291
00292     for(; src<end; src++) {
00293                 *dest++=hex[*src/0x10];
00294                 *dest++=hex[*src%0x10];
00295     }
00296     *dest=0;
00297
00298     return bytes_hex;
00299 }
00300
00301 static void _md5(Request& r, MethodParams& params) {
00302     const char *string=params.as_string(0, "parameter must be string").cstr();
00303
00304
00305     PA_MD5_CTX context;
00306     unsigned char digest[16];
00307     pa_MD5Init(&context);
00308     pa_MD5Update(&context, (const unsigned char*)string, strlen(string));
00309     pa_MD5Final(digest, &context);
00310
00311     r.write_pass_lang(*new String(hex_string(digest, sizeof(digest), false)));
00312 }
00313
00315 struct uuid {
00316         unsigned int   time_low;
00317         unsigned short   time_mid;
00318         unsigned short   time_hi_and_version;
00319         unsigned short   clock_seq;
00320         unsigned char    node[6];
00321 };
00322 static void _uuid(Request& r, MethodParams& /*params*/) {
00323
00324     // random
00325     struct uuid uuid;
00326     random(&uuid, sizeof(uuid));
00327
00328     // http://www.opengroup.org/onlinepubs/9629399/apdxa.htm#tagtcjh_35
00329     // ~
00330     // version = DCE Security version, with embedded POSIX UIDs.
00331     // variant = DCE
00332     //
00333     // DCE=Distributed Computing Environment
00334     // http://www.opengroup.org/dce/
00335     //
00336     // they say this influences comparison&such,
00337     // but could not figure out how, hence structure layout specified strictly
00338     // anyhow, uuidgen on Win32 yield those values
00339     //
00340     // xxxxxxxx-xxxx-4xxx-{8,9,A,B}xxx-xxxxxxxxxxxx
00341     uuid.clock_seq = (uuid.clock_seq & 0x3FFF) | 0x8000;
00342         uuid.time_hi_and_version = (uuid.time_hi_and_version & 0x0FFF) | 0x4000;
00343
00344     // format
00345     const int uuid_cstr_bufsize=36+1/*for zero-teminator*/+1/*for faulty snprintfs*/;
00346     char *uuid_cstr=new(PointerFreeGC) char[uuid_cstr_bufsize];
00347         snprintf(uuid_cstr, uuid_cstr_bufsize,
00348                 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
00349                 uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
00350                 uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
00351                 uuid.node[0], uuid.node[1], uuid.node[2],
00352                 uuid.node[3], uuid.node[4], uuid.node[5]);
00353
00354     r.write_pass_lang(*new String(uuid_cstr));
00355 }
00356
00357 static void _uid64(Request& r, MethodParams& /*params*/) {
00358
00359     unsigned char id[64/8];
00360     random(&id, sizeof(id));
00361
00362     r.write_pass_lang(*new String(hex_string(id, sizeof(id), true)));
00363 }
00364
00365 // constructor
00366
00367 MMath::MMath(): Methoded("math") {
00368     // ^FUNC(expr)
00369 #define ADDX(name, X) \
00370     add_native_method(#name, Method::CT_STATIC, _##name, X, X)
00371 #define ADD0(name) ADDX(name, 0)
00372 #define ADD1(name) ADDX(name, 1)
00373 #define ADD2(name) ADDX(name, 2)
00374
00375     ADD1(round);    ADD1(floor);    ADD1(ceiling);
00376     ADD1(trunc);    ADD1(frac);
00377     ADD1(abs);  ADD1(sign);
00378     ADD1(exp);  ADD1(log);
00379     ADD1(sin);  ADD1(asin);
00380     ADD1(cos);  ADD1(acos);
00381     ADD1(tan);  ADD1(atan);
00382     ADD1(degrees);  ADD1(radians);
00383     ADD1(sqrt);
00384     ADD1(random);
00385
00386     // ^pow(x;y)
00387     ADD2(pow);
00388
00389     // ^crypt[password;salt]
00390     ADD2(crypt);
00391
00392     // ^md5[string]
00393     ADD1(md5);
00394
00395     // ^uuid[]
00396     ADD0(uuid);
00397
00398     // ^uid64[]
00399     ADD0(uid64);
00400 }


memory.C File Reference

Parser: memory parser class. More...

Include dependency graph for memory.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MMemory

Functions

DECLARE_CLASS_VAR (memory, 0, new MMemory)
void | _compact (Request &r, MethodParams &)

Variables

const char *const | IDENT_MATH_C = "$Date: 2005/08/09 08:14:48 $"

Detailed Description

Parser: memory parser class.

Copyright(c) 2001-2005 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru>(http://paf.design.ru)

Definition in file memory.C.

Function Documentation

DECLARE_CLASS_VAR | ( | memory | ,
 |  | 0 | ,
 |  | new | MMemory
 | ) |

void _compact | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 32 of file memory.C.

References GC_dont_gc, and Request::wipe_unused_execution_stack().

Referenced by MMemory::MMemory().

Variable Documentation

const char* const IDENT_MATH_C = "$Date: 2005/08/09 08:14:48 $" [static]

Definition at line 8 of file memory.C.


memory.C Source File

memory.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_MATH_C="$Date: 2005/08/09 08:14:48 $";
00009
00010 #include "pa_common.h"
00011 #include "pa_vmemory.h"
00012 #include "pa_request.h"
00013
00014 class MMemory: public Methoded {
00015 public:
00016     MMemory();
00017
00018 public: // Methoded
00019     bool used_directly() { return false; }
00020 };
00021
00022 // global variables
00023
00024 DECLARE_CLASS_VAR(memory, 0 /*fictive*/, new MMemory);
00025
00026 #undef GC_DEBUG
00027 #ifdef GC_DEBUG
00028 extern "C" GC_API void GC_print_backtrace(void *);
00029 void *debug_print_backtrace=0;
00030 #endif
00031
00032 static void _compact(Request& r, MethodParams&) {
00033     r.wipe_unused_execution_stack();
00034 #ifndef PA_DEBUG_DISABLE_GC
00035     {
00036         int saved=GC_dont_gc;
00037         GC_dont_gc=0;
00038         GC_gcollect();
00039         GC_dont_gc=saved;
00040     }
00041 #ifdef GC_DEBUG
00042     if(debug_print_backtrace)
00043         GC_print_backtrace(debug_print_backtrace);
00044 #endif
00045 #endif
00046     }
00047
00048 // constructor
00049
00050 MMemory::MMemory(): Methoded("memory") {
00051     // ^compact[]
00052     add_native_method("compact", Method::CT_STATIC, _compact, 0, 0);
00053 }


memory.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


methoded.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


mod_parser3.c File Reference

Parser: apache 1.3 module, part, compiled by Apache. More...

Include dependency graph for mod_parser3.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | PA_APLOG_EMERG 0
#define | PA_APLOG_ALERT 1
#define | PA_APLOG_CRIT 2
#define | PA_APLOG_ERR 3
#define | PA_APLOG_WARNING 4
#define | PA_APLOG_NOTICE 5
#define | PA_APLOG_INFO 6
#define | PA_APLOG_DEBUG 7
#define | PA_APLOG_LEVELMASK 7
#define | PA_APLOG_NOERRNO (PA_APLOG_LEVELMASK + 1)
#define | PA_APLOG_MARK __FILE__,__LINE__

Functions

Parser_module_config * | our_dconfig (request_rec *r)
const char * | cmd_parser_config (cmd_parms *cmd, void *mconfig, char *file_spec)
const char * | cmd_parser_status_allowed (cmd_parms *cmd, void *mconfig, char *file_spec)
int | parser_handler (request_rec *ar)
void | parser_module_init (server_rec *s, pool *p)
void | parser_module_done (server_rec *s, pool *p)
void * | parser_create_dir_config (pool *p, char *dirspec)
void * | parser_merge_dir_config (pool *p, void *parent_conf, void *newloc_conf)
void * | parser_create_server_config (pool *p, server_rec *s)
void * | parser_merge_server_config (pool *p, void *server1_conf, void *server2_conf)
int | parser_translate_handler (request_rec *r)
int | parser_check_user_id (request_rec *r)
int | parser_auth_checker (request_rec *r)
int | parser_access_checker (request_rec *r)
void | pa_ap_log_rerror (const char *file, int line, int level, const pa_request_rec *s, const char *fmt,...)
void | pa_ap_log_error (const char *file, int line, int level, const pa_server_rec *s, const char *fmt,...)
const char * | pa_ap_table_get (const pa_table *t, const char *name)
void | pa_ap_table_addn (pa_table *t, const char *name, const char *val)
int | pa_ap_table_size (const pa_table *t)
void | pa_ap_table_do (int(*comp)(void *, const char *, const char *), void *rec, const pa_table *t,...)
char * | pa_ap_pstrdup (pa_pool *p, const char *s)
int | pa_ap_setup_client_block (pa_request_rec *r, int read_policy)
int | pa_ap_should_client_block (pa_request_rec *r)
long | pa_ap_get_client_block (pa_request_rec *r, char *buffer, int bufsiz)
void | pa_ap_send_http_header (pa_request_rec *r)
int | pa_ap_rwrite (const void *buf, int nbyte, pa_request_rec *r)
void | pa_ap_hard_timeout (char *s, pa_request_rec *r)
void | pa_ap_reset_timeout (pa_request_rec *r)
void | pa_ap_kill_timeout (pa_request_rec *r)
void | pa_ap_add_cgi_vars (pa_request_rec *r)
void | pa_ap_add_common_vars (pa_request_rec *r)
void | pa_MD5Init (PA_MD5_CTX *context)
void | pa_MD5Update (PA_MD5_CTX *context, const unsigned char *input, unsigned int inputLen)
void | pa_MD5Final (unsigned char digest[MD5_DIGESTSIZE], PA_MD5_CTX *context)
void | pa_MD5Encode (const unsigned char *password, const unsigned char *salt, char *result, size_t nbytes)
void | pa_to64 (char *s, unsigned long v, int n)
void(*)(int) | pa_signal (int sig, void(*disp)(int))

Variables

const char *const | IDENT_MOD_PARSER3_C = "$Date: 2005/08/09 08:14:53 $"
module MODULE_VAR_EXPORT | parser3_module
const command_rec | parser_cmds []
const handler_rec | parser_handlers []

Detailed Description

Parser: apache 1.3 module, part, compiled by Apache.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file mod_parser3.c.

Define Documentation

#define PA_APLOG_EMERG 0

Definition at line 466 of file mod_parser3.c.

#define PA_APLOG_ALERT 1

Definition at line 467 of file mod_parser3.c.

#define PA_APLOG_CRIT 2

Definition at line 468 of file mod_parser3.c.

#define PA_APLOG_ERR 3

Definition at line 469 of file mod_parser3.c.

#define PA_APLOG_WARNING 4

Definition at line 470 of file mod_parser3.c.

#define PA_APLOG_NOTICE 5

Definition at line 471 of file mod_parser3.c.

#define PA_APLOG_INFO 6

Definition at line 472 of file mod_parser3.c.

#define PA_APLOG_DEBUG 7

Definition at line 473 of file mod_parser3.c.

#define PA_APLOG_LEVELMASK 7

Definition at line 475 of file mod_parser3.c.

#define PA_APLOG_NOERRNO (PA_APLOG_LEVELMASK + 1)

Definition at line 477 of file mod_parser3.c.

#define PA_APLOG_MARK __FILE__,__LINE__

Definition at line 479 of file mod_parser3.c.

Function Documentation

Parser_module_config* our_dconfig ( request_rec * r ) [static]

Definition at line 35 of file mod_parser3.c.

References parser3_module.

Referenced by parser_access_checker(), parser_auth_checker(), parser_check_user_id(), parser_handler(), and parser_translate_handler().

const char* cmd_parser_config | ( | cmd_parms * | cmd,
 |  | void * | mconfig,
 |  | char * | file_spec
 | ) | [static]

Definition at line 40 of file mod_parser3.c.

References Parser_module_config_tag::parser_config_filespec.

const char* cmd_parser_status_allowed | ( | cmd_parms * | cmd,
 |  | void * | mconfig,
 |  | char * | file_spec
 | ) | [static]

Definition at line 48 of file mod_parser3.c.

References Parser_module_config_tag::parser_status_allowed.

int parser_handler ( request_rec * ar ) [static]

Definition at line 114 of file mod_parser3.c.

References our_dconfig(), and pa_parser_handler().

void parser_module_init | ( | server_rec * | s,
 |  | pool * | p
 | ) | [static]

Definition at line 146 of file mod_parser3.c.

References p, pa_setup_module_cells(), and pa_version().

void parser_module_done | ( | server_rec * | s,
 |  | pool * | p
 | ) | [static]

Definition at line 169 of file mod_parser3.c.

References p, and pa_destroy_module_cells().

void* parser_create_dir_config | ( | pool * | p,
 |  | char * | dirspec
 | ) | [static]

Definition at line 185 of file mod_parser3.c.

References p.

void* parser_merge_dir_config | ( | pool * | p,
 |  | void * | parent_conf,
 |  | void * | newloc_conf
 | ) | [static]

Definition at line 219 of file mod_parser3.c.

References p, Parser_module_config_tag::parser_config_filespec, and Parser_module_config_tag::parser_status_allowed.

void* parser_create_server_config | ( | pool * | p,
 |  | server_rec * | s
 | ) | [static]

Definition at line 248 of file mod_parser3.c.

References p.

void* parser_merge_server_config | ( | pool * | p,
 |  | void * | server1_conf,
 |  | void * | server2_conf
 | ) | [static]

Definition at line 273 of file mod_parser3.c.

References p, Parser_module_config_tag::parser_config_filespec, and Parser_module_config_tag::parser_status_allowed.

int parser_translate_handler ( request_rec * r ) [static]

Definition at line 304 of file mod_parser3.c.

References our_dconfig().

int parser_check_user_id ( request_rec * r ) [static]

Definition at line 318 of file mod_parser3.c.

References our_dconfig().

int parser_auth_checker ( request_rec * r ) [static]

Definition at line 333 of file mod_parser3.c.

References our_dconfig().

int parser_access_checker ( request_rec * r ) [static]

Definition at line 347 of file mod_parser3.c.

References our_dconfig().

void pa_ap_log_rerror | ( | const char * | file,
 |  | int | line,
 |  | int | level,
 |  | const pa_request_rec * | s,
 |  | const char * | fmt,
 |  | ... |
 | ) |

Definition at line 481 of file mod_parser3.c.

References file, pa_request_rec_tag::real_request_rec, and str.

Referenced by SAPI::log().

void pa_ap_log_error | ( | const char * | file,
 |  | int | line,
 |  | int | level,
 |  | const pa_server_rec * | s,
 |  | const char * | fmt,
 |  | ... |
 | ) |

Definition at line 494 of file mod_parser3.c.

References file, pa_server_rec, and str.

Referenced by die_or_abort().

const char* pa_ap_table_get | ( | const pa_table * | t,
 |  | const char * | name
 | ) |

Definition at line 508 of file mod_parser3.c.

References pa_table.

Referenced by SAPI::get_env().

void pa_ap_table_addn | ( | pa_table * | t,
 |  | const char * | name,
 |  | const char * | val
 | ) |

Definition at line 511 of file mod_parser3.c.

References pa_table, and val.

Referenced by SAPI::add_header_attribute().

int pa_ap_table_size ( const pa_table * t )

Definition at line 515 of file mod_parser3.c.

References pa_table.

Referenced by SAPI::environment().

void pa_ap_table_do | ( | int(* | comp)(void *, const char *, const char *),
 |  | void * | rec,
 |  | const pa_table * | t,
 |  | ... |
 | ) |

Definition at line 519 of file mod_parser3.c.

References pa_table.

Referenced by SAPI::environment().

char* pa_ap_pstrdup | ( | pa_pool * | p,
 |  | const char * | s
 | ) |

Definition at line 524 of file mod_parser3.c.

References p, and pa_pool.

Referenced by SAPI::add_header_attribute().

int pa_ap_setup_client_block | ( | pa_request_rec * | r,
 |  | int | read_policy
 | ) |

Definition at line 530 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

int pa_ap_should_client_block ( pa_request_rec * r )

Definition at line 534 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

long pa_ap_get_client_block | ( | pa_request_rec * | r,
 |  | char * | buffer,
 |  | int | bufsiz
 | ) |

Definition at line 537 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

void pa_ap_send_http_header ( pa_request_rec * r )

Definition at line 541 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::send_header().

int pa_ap_rwrite | ( | const void * | buf,
 |  | int | nbyte,
 |  | pa_request_rec * | r
 | ) |

Definition at line 544 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::send_body().

void pa_ap_hard_timeout | ( | char * | s,
 |  | pa_request_rec * | r
 | ) |

Definition at line 551 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post(), SAPI::send_body(), and SAPI::send_header().

void pa_ap_reset_timeout ( pa_request_rec * r )

Definition at line 554 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

void pa_ap_kill_timeout ( pa_request_rec * r )

Definition at line 557 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::send_body(), and SAPI::send_header().

void pa_ap_add_cgi_vars ( pa_request_rec * r )

Definition at line 564 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by real_parser_handler().

void pa_ap_add_common_vars ( pa_request_rec * r )

Definition at line 567 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by real_parser_handler().

void pa_MD5Init ( PA_MD5_CTX * context )

Definition at line 574 of file mod_parser3.c.

References context, and PA_MD5_CTX.

Referenced by _md5().

void pa_MD5Update | ( | PA_MD5_CTX * | context,
 |  | const unsigned char * | input,
 |  | unsigned int | inputLen
 | ) |

Definition at line 575 of file mod_parser3.c.

References context, inputLen, and PA_MD5_CTX.

Referenced by _md5().

void pa_MD5Final | ( | unsigned char | digest[MD5_DIGESTSIZE],
 |  | PA_MD5_CTX * | context
 | ) |

Definition at line 577 of file mod_parser3.c.

References context, MD5_DIGESTSIZE, and PA_MD5_CTX.

void pa_MD5Encode | ( | const unsigned char * | password,
 |  | const unsigned char * | salt,
 |  | char * | result,
 |  | size_t | nbytes
 | ) |

Definition at line 579 of file mod_parser3.c.

References result, and salt.

Referenced by _crypt().

void pa_to64 | ( | char * | s,
 |  | unsigned long | v,
 |  | int | n
 | ) |

Definition at line 582 of file mod_parser3.c.

References v.

void(*)(int) pa_signal ( )

Definition at line 587 of file mod_parser3.c.

References PA_SIG_IGN, pa_signal(), and PA_SIGPIPE.

Referenced by pa_signal(), and SAPI::read_post().

Variable Documentation

const char* const IDENT_MOD_PARSER3_C = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 8 of file mod_parser3.c.

module MODULE_VAR_EXPORT parser3_module

Initial value:

{
    STANDARD_MODULE_STUFF,
    parser_module_init,
    parser_create_dir_config,
    parser_merge_dir_config,
    parser_create_server_config,
    parser_merge_server_config,
    parser_cmds,
    parser_handlers,
    parser_translate_handler,
    parser_check_user_id,
    parser_auth_checker,
    parser_access_checker,
    0,
    0,
    0

}

Definition at line 423 of file mod_parser3.c.

Referenced by our_dconfig().

const command_rec parser_cmds[] [static]

Initial value:

{
    {
        "ParserConfig",
            (const char* (*)(void))((void *)cmd_parser_config),
            (void*)0,
            (int)(OR_OPTIONS),
            TAKE1,
            "Parser config filespec"
    },
    {
        "ParserStatusAllowed",
            (const char* (*)(void))((void *)cmd_parser_status_allowed),
            (void*)0,
            (int)(ACCESS_CONF),
            NO_ARGS,
            "Parser status class can be used"
    },
    {NULL}
}

Definition at line 365 of file mod_parser3.c.

const handler_rec parser_handlers[] [static]

Initial value:

{
    {"parser3-handler", parser_handler},
    {NULL}
}

Definition at line 403 of file mod_parser3.c.


mod_parser3.c Source File

mod_parser3.c

Go to the documentation of this file.
00001
00008 static const char * const IDENT_MOD_PARSER3_C="$Date: 2005/08/09 08:14:53 $";
00009
00010 #ifdef WIN32
00011 #include <winsock2.h>
00012 #endif
00013
00014 #include "httpd.h"
00015 #include "http_config.h"
00016 #include "http_core.h"
00017 #include "http_log.h"
00018 #include "http_main.h"
00019 #include "http_protocol.h"
00020 #include "util_script.h"
00021 #include "ap_md5.h"
00022 #include "ap_alloc.h"
00023
00024 #include "pa_httpd.h"
00025
00026 /*
00027 * Declare ourselves so the configuration routines can find and know us.
00028 * We'll fill it in at the end of the module.
00029 */
00030 extern module MODULE_VAR_EXPORT parser3_module;
00031
00032 /*
00033 * Locate our directory configuration record for the current request.
00034 */
00035 static Parser_module_config *our_dconfig(request_rec *r) {
00036     return (Parser_module_config *)
00037         ap_get_module_config(r->per_dir_config, &parser3_module);
00038 }
00039
00040 static const char* cmd_parser_config(cmd_parms *cmd, void *mconfig, char *file_spec) {
00041     Parser_module_config *cfg = (Parser_module_config *) mconfig;
00042
00043     // remember assigned filespec into cfg
00044     cfg->parser_config_filespec=file_spec;
00045
00046     return NULL;
00047 }
00048 static const char* cmd_parser_status_allowed(cmd_parms *cmd, void *mconfig, char *file_spec) {
00049     //_asm int 3;
00050     Parser_module_config *cfg = (Parser_module_config *) mconfig;
00051
00052     cfg->parser_status_allowed=1;
00053
00054     return NULL;
00055 }
00056
00057
00058 /*--------------------------------------------------------------------------*/
00059 /*                                                                          */
00060 /* Now we declare our content handlers, which are invoked when the server   */
00061 /* encounters a document which our module is supposed to have a chance to   */
00062 /* see.  (See mod_mime's SetHandler and AddHandler directives, and the      */
00063 /* mod_info and mod_status examples, for more details.)                     */
00064 /*                                                                          */
00065 /* Since content handlers are dumping data directly into the connexion      */
00066 /* (using the r*() routines, such as rputs() and rprintf()) without         */
00067 /* intervention by other parts of the server, they need to make             */
00068 /* sure any accumulated HTTP headers are sent first.  This is done by       */
00069 /* calling send_http_header().  Otherwise, no header will be sent at all,   */
00070 /* and the output sent to the client will actually be HTTP-uncompliant.     */
00071 /*--------------------------------------------------------------------------*/
00072 /*
00073 * Sample content handler.  All this does is display the call list that has
00074 * been built up so far.
00075 *
00076 * The return value instructs the caller concerning what happened and what to
00077 * do next:
00078 *  OK ("we did our thing")
00079 *  DECLINED ("this isn't something with which we want to get involved")
00080 *  HTTP_mumble ("an error status should be reported")
00081 */
00082
00083
00084 /*--------------------------------------------------------------------------*/
00085 /*                                                                          */
00086 /* Now let's declare routines for each of the callback phase in order.      */
00087 /* (That's the order in which they're listed in the callback list, *not     */
00088 /* the order in which the server calls them!  See the command_rec           */
00089 /* declaration near the bottom of this file.)  Note that these may be       */
00090 /* called for situations that don't relate primarily to our function - in   */
00091 /* other words, the fixup handler shouldn't assume that the request has     */
00092 /* to do with "example" stuff.                                              */
00093 /*                                                                          */
00094 /* With the exception of the content handler, all of our routines will be   */
00095 /* called for each request, unless an earlier handler from another module   */
00096 /* aborted the sequence.                                                    */
00097 /*                                                                          */
00098 /* Handlers that are declared as "int" can return the following:            */
00099 /*                                                                          */
00100 /*  OK          Handler accepted the request and did its thing with it.     */
00101 /*  DECLINED    Handler took no action.                                     */
00102 /*  HTTP_mumble Handler looked at request and found it wanting.             */
00103 /*                                                                          */
00104 /* What the server does after calling a module handler depends upon the     */
00105 /* handler's return value.  In all cases, if the handler returns            */
00106 /* DECLINED, the server will continue to the next module with an handler    */
00107 /* for the current phase.  However, if the handler return a non-OK,         */
00108 /* non-DECLINED status, the server aborts the request right there.  If      */
00109 /* the handler returns OK, the server's next action is phase-specific;      */
00110 /* see the individual handler comments below for details.                   */
00111 /*                                                                          */
00112 /*--------------------------------------------------------------------------*/
00113
00114 static int parser_handler(request_rec *ar) {
00115     // record clone
00116     pa_request_rec lr={
00117         ar,
00118         ar->pool,
00119         ar->header_only,
00120         &ar->status,
00121         ar->method,
00122         ar->headers_out,
00123         ar->subprocess_env,
00124         &ar->content_type,
00125         ar->uri,
00126         ar->filename,
00127         ar->path_info,
00128         ar->args,
00129         &ar->finfo
00130     };
00131
00132     // config
00133     Parser_module_config *dcfg=our_dconfig(ar);
00134
00135     return pa_parser_handler(&lr, dcfg);
00136 }
00137
00138 /*
00139 * This function is called during server initialisation.  Any information
00140 * that needs to be recorded must be in static cells, since there's no
00141 * configuration record.
00142 *
00143 * There is no return value.
00144 */
00145
00146 static void parser_module_init(server_rec *s, pool *p) {
00147 #if MODULE_MAGIC_NUMBER >= 19980527
00148     ap_add_version_component(pa_version());
00149 #endif
00150
00151     /*
00152     * Set up any module cells that ought to be initialised.
00153     */
00154     pa_setup_module_cells();
00155 }
00156
00157 /*
00158  * This function is called when an heavy-weight process (such as a child) is
00159  * being run down or destroyed.  As with the child-initialisation function,
00160  * any information that needs to be recorded must be in static cells, since
00161  * there's no configuration record.
00162  *
00163  * There is no return value.
00164  */
00165
00166 /*
00167  * All our process-death routine does is add its trace to the log.
00168  */
00169 static void parser_module_done(server_rec *s, pool *p) {
00170     pa_destroy_module_cells();
00171 }
00172
00173 /*
00174 * This function gets called to create a per-directory configuration
00175 * record.  This will be called for the "default" server environment, and for
00176 * each directory for which the parser finds any of our directives applicable.
00177 * If a directory doesn't have any of our directives involved (i.e., they
00178 * aren't in the .htaccess file, or a <Location>, <Directory>, or related
00179 * block), this routine will *not* be called - the configuration for the
00180 * closest ancestor is used.
00181 *
00182 * The return value is a pointer to the created module-specific
00183 * structure.
00184 */
00185 static void *parser_create_dir_config(pool *p, char *dirspec) {
00186     //_asm int 3;
00187     /*
00188     * Allocate the space for our record from the pool supplied.
00189     */
00190     Parser_module_config *cfg=
00191         (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
00192         /*
00193         * Now fill in the defaults.  If there are any `parent' configuration
00194         * records, they'll get merged as part of a separate callback.
00195     */
00196
00197     return (void *) cfg;
00198 }
00199
00200 /*
00201 * This function gets called to merge two per-directory configuration
00202 * records.  This is typically done to cope with things like .htaccess files
00203 * or <Location> directives for directories that are beneath one for which a
00204 * configuration record was already created.  The routine has the
00205 * responsibility of creating a new record and merging the contents of the
00206 * other two into it appropriately.  If the module doesn't declare a merge
00207 * routine, the record for the closest ancestor location (that has one) is
00208 * used exclusively.
00209 *
00210 * The routine MUST NOT modify any of its arguments!
00211 *
00212 * The return value is a pointer to the created module-specific structure
00213 * containing the merged values.
00214
00215  20011126 paf: noticed, that this is called even on virtual root merge with something "parent",
00216  while thought that that is part of merge_server...
00217
00218 */
00219 static void *parser_merge_dir_config(pool *p, void *parent_conf,
00220                      void *newloc_conf) {
00221     //_asm int 3;
00222     Parser_module_config *merged_config =
00223         (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
00224     Parser_module_config *pconf = (Parser_module_config *) parent_conf;
00225     Parser_module_config *nconf = (Parser_module_config *) newloc_conf;
00226
00227     merged_config->parser_config_filespec = ap_pstrdup(p, nconf->parser_config_filespec?
00228         nconf->parser_config_filespec:pconf->parser_config_filespec);
00229     merged_config->parser_status_allowed=
00230         pconf->parser_status_allowed ||
00231         nconf->parser_status_allowed;
00232
00233         /*
00234         * Some things get copied directly from the more-specific record, rather
00235         * than getting merged.
00236     */
00237
00238     return (void *) merged_config;
00239 }
00240
00241 /*
00242 * This function gets called to create a per-server configuration
00243 * record.  It will always be called for the "default" server.
00244 *
00245 * The return value is a pointer to the created module-specific
00246 * structure.
00247 */
00248 static void *parser_create_server_config(pool *p, server_rec *s) {
00249     //_asm int 3;
00250     /*
00251     * As with the parser_create_dir_config() routine, we allocate and fill
00252     * in an empty record.
00253     */
00254     Parser_module_config *cfg=
00255         (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
00256
00257     return (void *) cfg;
00258 }
00259
00260 /*
00261 * This function gets called to merge two per-server configuration
00262 * records.  This is typically done to cope with things like virtual hosts and
00263 * the default server configuration  The routine has the responsibility of
00264 * creating a new record and merging the contents of the other two into it
00265 * appropriately.  If the module doesn't declare a merge routine, the more
00266 * specific existing record is used exclusively.
00267 *
00268 * The routine MUST NOT modify any of its arguments!
00269 *
00270 * The return value is a pointer to the created module-specific structure
00271 * containing the merged values.
00272 */
00273 static void *parser_merge_server_config(pool *p, void *server1_conf,
00274                     void *server2_conf)
00275 {
00276     //_asm int 3;
00277
00278     Parser_module_config *merged_config =
00279         (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
00280     Parser_module_config *s1conf = (Parser_module_config *) server1_conf;
00281     Parser_module_config *s2conf = (Parser_module_config *) server2_conf;
00282
00283     /*
00284     * Our inheritance rules are our own, and part of our module's semantics.
00285     * Basically, just note whence we came.
00286     */
00287     merged_config->parser_config_filespec = ap_pstrdup(p, s2conf->parser_config_filespec?
00288         s2conf->parser_config_filespec:s1conf->parser_config_filespec);
00289     merged_config->parser_status_allowed=
00290         s1conf->parser_status_allowed ||
00291         s2conf->parser_status_allowed;
00292
00293     return (void *) merged_config;
00294 }
00295
00296 /*
00297 * This routine gives our module an opportunity to translate the URI into an
00298 * actual filename.  If we don't do anything special, the server's default
00299 * rules (Alias directives and the like) will continue to be followed.
00300 *
00301 * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
00302 * further modules are called for this phase.
00303 */
00304 static int parser_translate_handler(request_rec *r) {
00305     Parser_module_config *cfg=our_dconfig(r);
00306     return DECLINED;
00307 }
00308
00309 /*
00310 * This routine is called to check the authentication information sent with
00311 * the request (such as looking up the user in a database and verifying that
00312 * the [encrypted] password sent matches the one in the database).
00313 *
00314 * The return value is OK, DECLINED, or some HTTP_mumble error (typically
00315 * HTTP_UNAUTHORIZED).  If we return OK, no other modules are given a chance
00316 * at the request during this phase.
00317 */
00318 static int parser_check_user_id(request_rec *r) {
00319     Parser_module_config *cfg=our_dconfig(r);
00320     return DECLINED;
00321 }
00322
00323 /*
00324 * This routine is called to check to see if the resource being requested
00325 * requires authorisation.
00326 *
00327 * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
00328 * other modules are called during this phase.
00329 *
00330 * If *all* modules return DECLINED, the request is aborted with a server
00331 * error.
00332 */
00333 static int parser_auth_checker(request_rec *r) {
00334     Parser_module_config *cfg=our_dconfig(r);
00335     return DECLINED;
00336 }
00337
00338 /*
00339 * This routine is called to check for any module-specific restrictions placed
00340 * upon the requested resource.  (See the mod_access module for an example.)
00341 *
00342 * The return value is OK, DECLINED, or HTTP_mumble.  All modules with an
00343 * handler for this phase are called regardless of whether their predecessors
00344 * return OK or DECLINED.  The first one to return any other status, however,
00345 * will abort the sequence (and the request) as usual.
00346 */
00347 static int parser_access_checker(request_rec *r) {
00348
00349     Parser_module_config *cfg=our_dconfig(r);
00350     return DECLINED;
00351 }
00352
00353 /*--------------------------------------------------------------------------*/
00354 /*                                                                          */
00355 /* All of the routines have been declared now.  Here's the list of          */
00356 /* directives specific to our module, and information about where they      */
00357 /* may appear and how the command parser should pass them to us for         */
00358 /* processing.  Note that care must be taken to ensure that there are NO    */
00359 /* collisions of directive names between modules.                           */
00360 /*                                                                          */
00361 /*--------------------------------------------------------------------------*/
00362 /*
00363 * List of directives specific to our module.
00364 */
00365 static const command_rec parser_cmds[] =
00366 {
00367     {
00368         "ParserConfig",              /* directive name */
00369             (const char* (*)(void))((void *)cmd_parser_config), // config action routine
00370             (void*)0,                   /* argument to include in call */
00371             (int)(OR_OPTIONS),             /* where available */
00372             TAKE1,                /* arguments */
00373             "Parser config filespec" // directive description
00374     },
00375     {
00376         "ParserStatusAllowed",              /* directive name */
00377             (const char* (*)(void))((void *)cmd_parser_status_allowed), // config action routine
00378             (void*)0,                   /* argument to include in call */
00379             (int)(ACCESS_CONF),             /* where available */
00380             NO_ARGS,                /* arguments */
00381             "Parser status class can be used" // directive description
00382     },
00383     {NULL}
00384 };
00385
00386 /*--------------------------------------------------------------------------*/
00387 /*                                                                          */
00388 /* Now the list of content handlers available from this module.             */
00389 /*                                                                          */
00390 /*--------------------------------------------------------------------------*/
00391 /*
00392 * List of content handlers our module supplies.  Each handler is defined by
00393 * two parts: a name by which it can be referenced (such as by
00394 * {Add,Set}Handler), and the actual routine name.  The list is terminated by
00395 * a NULL block, since it can be of variable length.
00396 *
00397 * Note that content-handlers are invoked on a most-specific to least-specific
00398 * basis; that is, a handler that is declared for "text/plain" will be
00399 * invoked before one that was declared for "text / *".  Note also that
00400 * if a content-handler returns anything except DECLINED, no other
00401 * content-handlers will be called.
00402 */
00403 static const handler_rec parser_handlers[] =
00404 {
00405     {"parser3-handler", parser_handler},
00406     {NULL}
00407 };
00408
00409 /*--------------------------------------------------------------------------*/
00410 /*                                                                          */
00411 /* Finally, the list of callback routines and data structures that          */
00412 /* provide the hooks into our module from the other parts of the server.    */
00413 /*                                                                          */
00414 /*--------------------------------------------------------------------------*/
00415 /*
00416 * Module definition for configuration.  If a particular callback is not
00417 * needed, replace its routine name below with the word NULL.
00418 *
00419 * The number in brackets indicates the order in which the routine is called
00420 * during request processing.  Note that not all routines are necessarily
00421 * called (such as if a resource doesn't have access restrictions).
00422 */
00423 module MODULE_VAR_EXPORT parser3_module =
00424 {
00425     STANDARD_MODULE_STUFF,
00426     parser_module_init,          /* module initializer */
00427     parser_create_dir_config,    /* per-directory config creator */
00428     parser_merge_dir_config,     /* dir config merger */
00429     parser_create_server_config, /* server config creator */
00430     parser_merge_server_config,  /* server config merger */
00431     parser_cmds,                 /* command table */
00432     parser_handlers,             /* [9] list of handlers */
00433     parser_translate_handler,    /* [2] filename-to-URI translation */
00434     parser_check_user_id,        /* [5] check/validate user_id */
00435     parser_auth_checker,         /* [6] check user_id is valid *here* */
00436     parser_access_checker,       /* [4] check access by host address */
00437     0,                           /* [7] MIME type checker/setter */
00438     0,                           /* [8] fixups */
00439     0                            /* [10] logger */
00440 #if MODULE_MAGIC_NUMBER >= 19970103
00441     ,0      /* [3] header parser */
00442 #endif
00443 #if MODULE_MAGIC_NUMBER >= 19970719
00444     ,0         /* process initializer */
00445 #endif
00446 #if MODULE_MAGIC_NUMBER >= 19970728
00447     ,parser_module_done         /* process exit/cleanup */
00448 #endif
00449 #if MODULE_MAGIC_NUMBER >= 19970902
00450     ,0   /* [1] post read_request handling */
00451 #endif
00452 };
00453
00454 #if defined(_MSC_VER)
00455 #   define APACHE_WIN32_SRC "../../../../win32/apache13/src"
00456 #   ifdef _DEBUG
00457 #       pragma comment(lib, APACHE_WIN32_SRC "/CoreD/ApacheCore.lib")
00458 #   else
00459 #       pragma comment(lib, APACHE_WIN32_SRC "/CoreR/ApacheCore.lib")
00460 #   endif
00461 #endif
00462
00463
00464 // interface to C++
00465
00466 #define PA_APLOG_EMERG  0   /* system is unusable */
00467 #define PA_APLOG_ALERT  1   /* action must be taken immediately */
00468 #define PA_APLOG_CRIT   2   /* critical conditions */
00469 #define PA_APLOG_ERR    3   /* error conditions */
00470 #define PA_APLOG_WARNING    4   /* warning conditions */
00471 #define PA_APLOG_NOTICE 5   /* normal but significant condition */
00472 #define PA_APLOG_INFO   6   /* informational */
00473 #define PA_APLOG_DEBUG  7   /* debug-level messages */
00474
00475 #define PA_APLOG_LEVELMASK  7   /* mask off the level value */
00476
00477 #define PA_APLOG_NOERRNO        (PA_APLOG_LEVELMASK + 1)
00478
00479 #define PA_APLOG_MARK   __FILE__,__LINE__
00480
00481 void pa_ap_log_rerror(const char *file, int line, int level,
00482               const pa_request_rec *s, const char *fmt, ...) {
00483     const char* str;
00484     va_list l;
00485     va_start(l, fmt);
00486     str=va_arg(l, const char*);
00487     va_end(l);
00488
00489     ap_log_rerror(file, line, level,
00490               (request_rec*)s->real_request_rec, "%s", str);
00491 }
00492
00493
00494 void pa_ap_log_error(const char *file, int line, int level,
00495              const pa_server_rec *s, const char *fmt, ...) {
00496     const char* str;
00497     va_list l;
00498     va_start(l, fmt);
00499     str=va_arg(l, const char*);
00500     va_end(l);
00501
00502     ap_log_error(file, line, level,
00503               (server_rec*)s, "%s", str);
00504 }
00505
00506 // ap_alloc.h
00507
00508 const char* pa_ap_table_get(const pa_table *t, const char *name) {
00509     return ap_table_get((const table*)t, name);
00510 }
00511 void pa_ap_table_addn(pa_table *t, const char *name, const char *val) {
00512     ap_table_addn((table*)t, name, val);
00513 }
00514
00515 int pa_ap_table_size(const pa_table *t) {
00516     return ap_table_elts((const table*)t)->nelts;
00517 }
00518
00519 void pa_ap_table_do(int (*comp) (void *, const char *, const char *),
00520             void *rec, const pa_table *t, ...) {
00521     ap_table_do(comp, rec, (table*)t, 0);
00522 }
00523
00524 char * pa_ap_pstrdup(pa_pool *p, const char *s) {
00525     return ap_pstrdup((pool*)p, s);
00526 }
00527
00528 // http_protocol.h
00529
00530 int pa_ap_setup_client_block(pa_request_rec *r, int read_policy) {
00531     return ap_setup_client_block((request_rec*)r->real_request_rec,
00532         read_policy);
00533 }
00534 int pa_ap_should_client_block(pa_request_rec *r) {
00535     return ap_should_client_block((request_rec*)r->real_request_rec);
00536 }
00537 long pa_ap_get_client_block(pa_request_rec *r, char *buffer, int bufsiz) {
00538     return ap_get_client_block((request_rec*)r->real_request_rec,
00539         buffer, bufsiz);
00540 }
00541 void pa_ap_send_http_header(pa_request_rec *r) {
00542     ap_send_http_header((request_rec*)r->real_request_rec);
00543 }
00544 int pa_ap_rwrite(const void *buf, int nbyte, pa_request_rec *r) {
00545     return ap_rwrite(buf, nbyte, (request_rec*)r->real_request_rec);
00546 }
00547
00548
00549 // http_main.h
00550
00551 void pa_ap_hard_timeout(char *s, pa_request_rec *r) {
00552     ap_hard_timeout(s, (request_rec*)r->real_request_rec);
00553 }
00554 void pa_ap_reset_timeout(pa_request_rec *r) {
00555     ap_reset_timeout((request_rec*)r->real_request_rec);
00556 }
00557 void pa_ap_kill_timeout(pa_request_rec *r) {
00558     ap_kill_timeout((request_rec*)r->real_request_rec);
00559 }
00560
00561
00562 // util_script.h
00563
00564 void pa_ap_add_cgi_vars(pa_request_rec *r) {
00565     ap_add_cgi_vars((request_rec*)r->real_request_rec);
00566 }
00567 void pa_ap_add_common_vars(pa_request_rec *r) {
00568     ap_add_common_vars((request_rec*)r->real_request_rec);
00569 }
00570
00571
00572 // ap_md5.h
00573
00574 void pa_MD5Init(PA_MD5_CTX *context) { ap_MD5Init((AP_MD5_CTX*)context); }
00575 void pa_MD5Update(PA_MD5_CTX *context, const unsigned char *input,
00576                   unsigned int inputLen) { ap_MD5Update((AP_MD5_CTX *)context, input, inputLen); }
00577 void pa_MD5Final(unsigned char digest[MD5_DIGESTSIZE],
00578                  PA_MD5_CTX *context) { ap_MD5Final(digest, (AP_MD5_CTX *)context); }
00579 void pa_MD5Encode(const unsigned char *password,
00580                   const unsigned char *salt,
00581                   char *result, size_t nbytes) { ap_MD5Encode(password, salt, result, nbytes); }
00582 void pa_to64(char *s, unsigned long v, int n) { ap_to64(s, v, n); }
00583
00584
00585 // signal.h
00586
00587 void (*pa_signal (int sig, void (*disp)(int)))(int) {
00588     if(sig==PA_SIGPIPE && disp==PA_SIG_IGN)
00589         return signal(SIGPIPE, SIG_IGN);
00590
00591     return 0;
00592 }


mod_parser3_core.C File Reference

Parser: apache 1.3 module, part, compiled by parser3project. More...

Include dependency graph for mod_parser3_core.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | SAPI_Info
SAPI func decl. More...

Functions

const char * | pa_version ()
void | pa_setup_module_cells ()
void | pa_destroy_module_cells ()
void | real_parser_handler (SAPI_Info &SAPI_info, Parser_module_config *dcfg)
main workhorse. More...

int | pa_parser_handler (pa_request_rec *r, Parser_module_config *dcfg)

Variables

const char *const | IDENT_MOD_PARSER3_MAIN_C = "$Date: 2005/12/09 07:18:07 $"

Detailed Description

Parser: apache 1.3 module, part, compiled by parser3project.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file mod_parser3_core.C.

Function Documentation

const char* pa_version ( )

Definition at line 30 of file mod_parser3_core.C.

References PARSER_VERSION.

Referenced by parser_module_init().

void pa_setup_module_cells ( )

Definition at line 34 of file mod_parser3_core.C.

References SAPI::abort(), pa_globals_init(), and pa_socks_init().

Referenced by parser_module_init().

void pa_destroy_module_cells ( )

Definition at line 52 of file mod_parser3_core.C.

References pa_globals_done(), and pa_socks_done().

Referenced by parser_module_done().

void die_or_abort | ( | const char * | fmt,
 |  | va_list | args,
 |  | bool | write_core
 | ) | [static]

Definition at line 77 of file mod_parser3_core.C.

References abort(), MAX_STRING, pa_ap_log_error(), remove_crlf(), size, and vsnprintf.

const char* mk_env_pair | ( | const char * | key,
 |  | const char * | value
 | ) | [static]

Definition at line 114 of file mod_parser3_core.C.

References result, and value.

int SAPI_environment_append | ( | void * | d,
 |  | const char * | k,
 |  | const char * | val
 | ) | [static]

Definition at line 119 of file mod_parser3_core.C.

References mk_env_pair(), and val.

Referenced by SAPI::environment().

void real_parser_handler | ( | SAPI_Info & | SAPI_info,
 |  | Parser_module_config * | dcfg
 | ) | [static]

main workhorse.

Todo:
intelligent cache-control

Definition at line 205 of file mod_parser3_core.C.

References pa_request_rec_tag::args, atoi(), Request_info::content_length, Request_info::content_type, Request_info::cookie, Request::core(), Request_info::document_root, pa_request_rec_tag::filename, GC_dont_gc, SAPI::get_env(), pa_request_rec_tag::header_only, String::L_HTML, String::L_OPTIMIZE_BIT, String::Language, Request_info::mail_received, pa_request_rec_tag::method, Request_info::method, pa_ap_add_cgi_vars(), pa_ap_add_common_vars(), Parser_module_config_tag::parser_config_filespec, Parser_module_config_tag::parser_status_allowed, Request_info::path_translated, Request_info::query_string, SAPI_Info::r, request, request_info, SAPI_info, and Request_info::uri.

int pa_parser_handler | ( | pa_request_rec * | r,
 |  | Parser_module_config * | dcfg
 | ) |

Test:
r->finfo.st_mode check seems to work only on win32

Definition at line 298 of file mod_parser3_core.C.

References SAPI::add_header_attribute(), pa_request_rec_tag::finfo, pa_request_rec_tag::header_only, SAPI::log(), MAX_NUMBER, MAX_STRING, PA_HTTP_NOT_FOUND, PA_OK, SAPI_Info::r, real_parser_handler(), SAPI::send_body(), SAPI::send_header(), and snprintf.

Referenced by parser_handler().

Variable Documentation

const char* const IDENT_MOD_PARSER3_MAIN_C = "$Date: 2005/12/09 07:18:07 $" [static]

Definition at line 8 of file mod_parser3_core.C.


mod_parser3_core.C Source File

mod_parser3_core.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_MOD_PARSER3_MAIN_C="$Date: 2005/12/09 07:18:07 $";
00009
00010 #include "pa_config_includes.h"
00011
00012 #include "pa_globals.h"
00013
00014 #include "pa_httpd.h"
00015
00016 #include "pa_common.h"
00017 #include "pa_sapi.h"
00018 #include "classes.h"
00019 #include "pa_request.h"
00020 #include "pa_version.h"
00021 #include "pa_socks.h"
00022
00023 #if _MSC_VER && !defined(_DEBUG)
00024 #   include <windows.h>
00025 #   define PA_SUPPRESS_SYSTEM_EXCEPTION
00026 #endif
00027
00028 // generals
00029
00030 const char* pa_version() {
00031     return "Parser/"PARSER_VERSION;
00032 }
00033
00034 void pa_setup_module_cells() {
00035     static bool  globals_inited=false;
00036     if(globals_inited)
00037         return;
00038     globals_inited=true;
00039
00041     try {
00042         // init socks
00043         pa_socks_init();
00044
00045         // init global variables
00046         pa_globals_init();
00047     } catch(const Exception& e) { // global problem
00048         SAPI::abort("setup_module_cells failed: %s", e.comment());
00049     }
00050 }
00051
00052 void pa_destroy_module_cells() {
00053     pa_globals_done();
00054
00055     pa_socks_done();
00056 }
00057
00058
00060
00061
00062 class SAPI_Info {
00063 public:
00064     pa_request_rec* r;
00065 };
00066
00067 void SAPI::log(SAPI_Info& SAPI_info, const char* fmt, ...) {
00068     va_list args;
00069     va_start(args,fmt);
00070     char buf[MAX_STRING];
00071     size_t size=vsnprintf(buf, MAX_STRING, fmt, args);
00072     remove_crlf(buf, buf+size);
00073     pa_ap_log_rerror(0, 0, PA_APLOG_ERR | PA_APLOG_NOERRNO, SAPI_info.r, "%s", buf);
00074     va_end(args);
00075 }
00076
00077 static void die_or_abort(const char* fmt, va_list args, bool write_core) {
00078     char buf[MAX_STRING];
00079     size_t size=vsnprintf(buf, MAX_STRING, fmt, args);
00080     remove_crlf(buf, buf+size);
00081     pa_ap_log_error(PA_APLOG_MARK, PA_APLOG_EMERG, 0, "%s", buf);
00082
00083     // exit & try to produce core dump
00084     if(write_core)
00085         abort();
00086     else
00087         exit(1);
00088 }
00089
00090 void SAPI::die(const char* fmt, ...) {
00091     va_list args;
00092     va_start(args, fmt);
00093     die_or_abort(fmt, args, false/*write core?*/);
00094     va_end(args);
00095 }
00096
00097 void SAPI::abort(const char* fmt, ...) {
00098     va_list args;
00099     va_start(args, fmt);
00100     die_or_abort(fmt, args, true/*write core?*/);
00101     va_end(args);
00102 }
00103
00104 char* SAPI::get_env(SAPI_Info& SAPI_info, const char* name) {
00105     const char* dont_return_me=pa_ap_table_get(SAPI_info.r->subprocess_env, name);
00106     return dont_return_me?pa_strdup(dont_return_me):0;
00107 }
00108
00109 #ifndef DOXYGEN
00110 struct SAPI_environment_append_info {
00111     const char** cur;
00112 };
00113 #endif
00114 static const char* mk_env_pair(const char* key, const char* value) {
00115     char *result=new(PointerFreeGC) char[strlen(key)+1/*=*/+strlen(value)+1/*0*/];
00116     strcpy(result, key); strcat(result, "="); strcat(result, value);
00117     return result;
00118 }
00119 static int SAPI_environment_append(void *d, const char* k, const char* val) {
00120     if( k && val ) {
00121         SAPI_environment_append_info& info=
00122             *static_cast<SAPI_environment_append_info *>(d);
00123         *info.cur++=mk_env_pair(k, val);
00124     }
00125     return 1/*true*/;
00126 }
00127 const char* const* SAPI::environment(SAPI_Info& SAPI_info) {
00128     const pa_table *t=SAPI_info.r->subprocess_env;
00129     const char** result=new(UseGC) const char*[pa_ap_table_size(t)+1/*0*/];
00130     SAPI_environment_append_info info={result};
00131     pa_ap_table_do(SAPI_environment_append, &info, t, 0); *info.cur=0; // mark EOE
00132     return result;
00133 }
00134
00135 size_t SAPI::read_post(SAPI_Info& SAPI_info, char *buf, size_t max_bytes) {
00136 /*    pa_ap_log_error(PA_APLOG_MARK, PA_APLOG_DEBUG, SAPI_info.r->server,
00137 "mod_parser3: SAPI::read_post(max=%u)", max_bytes);
00138     */
00139     int retval;
00140     if((retval = pa_ap_setup_client_block(SAPI_info.r, PA_REQUEST_CHUNKED_ERROR)))
00141         return 0;
00142     if(!pa_ap_should_client_block(SAPI_info.r))
00143         return 0;
00144
00145     uint total_read_bytes=0;
00146     void (*handler)(int)=pa_signal(PA_SIGPIPE, PA_SIG_IGN);
00147     while (total_read_bytes<max_bytes) {
00148         pa_ap_hard_timeout("Read POST information", SAPI_info.r); /* start timeout timer */
00149         uint read_bytes=
00150             pa_ap_get_client_block(SAPI_info.r, buf+total_read_bytes, max_bytes-total_read_bytes);
00151         pa_ap_reset_timeout(SAPI_info.r);
00152         if (read_bytes<=0)
00153             break;
00154         total_read_bytes+=read_bytes;
00155     }
00156     pa_signal(PA_SIGPIPE, handler);
00157     return total_read_bytes;
00158 }
00159
00161 void SAPI::add_header_attribute(SAPI_Info& SAPI_info,
00162                 const char* dont_store_key, const char* dont_store_value) {
00163     if(strcasecmp(dont_store_key, "location")==0)
00164         *SAPI_info.r->status=302;
00165
00166     if(strcasecmp(dont_store_key, "content-type")==0) {
00167     /* r->content_type, *not* r->headers_out("Content-type").  If you don't
00168     * set it, it will be filled in with the server's default type (typically
00169     * "text/plain").  You *must* also ensure that r->content_type is lower
00170     * case.
00171         */
00172         *SAPI_info.r->content_type = pa_ap_pstrdup(SAPI_info.r->pool, dont_store_value);
00173     } else if(strcasecmp(dont_store_key, "status")==0)
00174         *SAPI_info.r->status=atoi(dont_store_value);
00175     else
00176         pa_ap_table_addn(SAPI_info.r->headers_out,
00177         pa_ap_pstrdup(SAPI_info.r->pool, dont_store_key),
00178         pa_ap_pstrdup(SAPI_info.r->pool, dont_store_value));
00179 }
00180
00181 void SAPI::send_header(SAPI_Info& SAPI_info) {
00182     pa_ap_hard_timeout("Send header", SAPI_info.r);
00183     pa_ap_send_http_header(SAPI_info.r);
00184     pa_ap_kill_timeout(SAPI_info.r);
00185 }
00186
00187 size_t SAPI::send_body(SAPI_Info& SAPI_info, const void *buf, size_t size) {
00188     pa_ap_hard_timeout("Send body", SAPI_info.r);
00189     size = (size_t)pa_ap_rwrite(buf, size, SAPI_info.r);
00190     pa_ap_kill_timeout(SAPI_info.r);
00191     return size;
00192 }
00193
00195
00196 #if !defined(PA_DEBUG_DISABLE_GC) && !defined(WIN32)
00197 extern long GC_large_alloc_warn_suppressed;
00198 #endif
00199
00205 static void real_parser_handler(SAPI_Info& SAPI_info, Parser_module_config *dcfg) {
00206     // collect garbage from prev request
00207 #if !defined(PA_DEBUG_DISABLE_GC) && !defined(WIN32)
00208     {
00209         int saved=GC_dont_gc;
00210         GC_dont_gc=0;
00211         GC_gcollect();
00212         GC_dont_gc=saved;
00213         GC_large_alloc_warn_suppressed=0;
00214     }
00215 #endif
00216
00217     // populate env
00218     pa_ap_add_common_vars(SAPI_info.r);
00219     pa_ap_add_cgi_vars(SAPI_info.r);
00220
00221     // Request info
00222     Request_info request_info;  memset(&request_info, 0, sizeof(request_info));
00223
00224     request_info.document_root=SAPI::get_env(SAPI_info, "DOCUMENT_ROOT");
00225     request_info.path_translated=SAPI_info.r->filename;
00226     request_info.method=SAPI_info.r->method;
00227     request_info.query_string=SAPI_info.r->args;
00228     request_info.uri=SAPI::get_env(SAPI_info, "REQUEST_URI");
00229     request_info.content_type=SAPI::get_env(SAPI_info, "CONTENT_TYPE");
00230     const char* content_length=SAPI::get_env(SAPI_info, "CONTENT_LENGTH");
00231     request_info.content_length=content_length?atoi(content_length):0;
00232     request_info.cookie=SAPI::get_env(SAPI_info, "HTTP_COOKIE");
00233     request_info.mail_received=false;
00234
00235     //_asm int 3;
00236     // prepare to process request
00237     Request request(
00238         SAPI_info,
00239         request_info,
00240         String::Language(String::L_HTML|String::L_OPTIMIZE_BIT),
00241         dcfg->parser_status_allowed?true:false
00242         );
00243
00244     // process the request
00245     request.core(
00246         dcfg->parser_config_filespec, true, // /path/to/config
00247         SAPI_info.r->header_only!=0);
00248 }
00249
00250 #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION
00251 static const Exception
00252 call_real_parser_handler__do_PEH_return_it(
00253     SAPI_Info& SAPI_info, Parser_module_config *dcfg)
00254 {
00255     try {
00256         real_parser_handler(SAPI_info, dcfg);
00257     } catch(const Exception& e) {
00258         return e;
00259     }
00260
00261     return Exception();
00262 }
00263 static void call_real_parser_handler__supress_system_exception(
00264     SAPI_Info& SAPI_info, Parser_module_config *dcfg)
00265 {
00266     Exception parser_exception;
00267     LPEXCEPTION_POINTERS system_exception=0;
00268
00269     __try {
00270         parser_exception=call_real_parser_handler__do_PEH_return_it(
00271             SAPI_info, dcfg);
00272     } __except (
00273         (system_exception=GetExceptionInformation()),
00274         EXCEPTION_EXECUTE_HANDLER)
00275     {
00276
00277         if(system_exception)
00278             if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord)
00279                 throw Exception("system",
00280                     0,
00281                     "0x%08X at 0x%08X", er->ExceptionCode,  er->ExceptionAddress);
00282             else
00283                 throw Exception("system",
00284                     0,
00285                     "<no exception record>");
00286         else
00287             throw Exception("system",
00288                 0,
00289                 "<no exception information>");
00290     }
00291
00292     if(parser_exception)
00293         throw Exception(parser_exception);
00294 }
00295 #endif
00296
00298 int pa_parser_handler(pa_request_rec *r, Parser_module_config *dcfg) {
00299     //_asm int 3;
00300
00301     // SAPI info
00302     SAPI_Info SAPI_info; SAPI_info.r=r;
00303
00304     //_asm int 3;
00305     if(r->finfo->st_mode == 0)
00306         return PA_HTTP_NOT_FOUND;
00307
00308         /* A flag which modules can set, to indicate that the data being
00309         * returned is volatile, and clients should be told not to cache it.
00310     */
00311     //  r->no_cache=1;
00312
00313     try { // global try
00314 #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION
00315         call_real_parser_handler__supress_system_exception(
00316 #else
00317         real_parser_handler(
00318 #endif
00319             SAPI_info, dcfg);
00320
00321         // successful finish
00322     } catch(const Exception& e) { // global problem
00323         // don't allocate anything on pool here:
00324         //   possible pool' exception not catch-ed now
00325         //   and there could be out-of-memory exception
00326         char buf[MAX_STRING];
00327         snprintf(buf, MAX_STRING, "Unhandled exception %s",
00328             e.comment());
00329         // log it
00330         SAPI::log(SAPI_info, "%s", buf);
00331
00332         //
00333         int content_length=strlen(buf);
00334
00335         // prepare header
00336         SAPI::add_header_attribute(SAPI_info, "content-type", "text/plain");
00337         char content_length_cstr[MAX_NUMBER];
00338         snprintf(content_length_cstr, MAX_NUMBER, "%u", content_length);
00339         SAPI::add_header_attribute(SAPI_info, "content-length", content_length_cstr);
00340
00341         // send header
00342         SAPI::send_header(SAPI_info);
00343
00344         // send body
00345         if(!r->header_only)
00346             SAPI::send_body(SAPI_info, buf, content_length);
00347
00348         // unsuccessful finish
00349     }
00350
00351     /*
00352     * We did what we wanted to do, so tell the rest of the server we
00353     * succeeded.
00354     */
00355     return PA_OK;
00356 }


mtables.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | MTABLES_H 1
#define | costScale 1024
#define | sintScale 1024

Variables

int | cost []
int | sint []

Define Documentation

#define MTABLES_H 1

Definition at line 2 of file mtables.h.

#define costScale 1024

Definition at line 4 of file mtables.h.

Referenced by gdImage::Arc(), and gdImage::Sector().

#define sintScale 1024

Definition at line 368 of file mtables.h.

Referenced by gdImage::Arc(), and gdImage::Sector().

Variable Documentation

int cost[]

Definition at line 5 of file mtables.h.

Referenced by gdImage::Arc(), and gdImage::Sector().

int sint[]

Definition at line 369 of file mtables.h.

Referenced by gdImage::Arc(), and gdImage::Sector().


object.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


op.C File Reference

Parser: parser operators. More...

Include dependency graph for op.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | VClassMAIN
class | Untaint_lang_name2enum

Defines

#define | MAX_LOOPS 20000
#define | CASE_DEFAULT_VALUE "DEFAULT"
#define | PROCESS_MAIN_OPTION_NAME "main"
#define | PROCESS_FILE_OPTION_NAME "file"
#define | PROCESS_LINENO_OPTION_NAME "lineno"
#define | SWITCH_DATA_NAME "SWITCH-DATA"
#define | CACHE_DATA_NAME "CACHE-DATA"
#define | EXCEPTION_VAR_NAME "exception"
#define | CACHE_EXCEPTION_HANDLED_CACHE_NAME "cache"
#define | ULN(name, LANG) put(String::Body(name), (value_type)(String::L_##LANG));

Functions

const String | switch_data_name (SWITCH_DATA_NAME)
const String | cache_data_name (CACHE_DATA_NAME)
const String | exception_var_name (EXCEPTION_VAR_NAME)
void | _if (Request &r, MethodParams &params)
void | _untaint (Request &r, MethodParams &params)
void | _taint (Request &r, MethodParams &params)
void | _process (Request &r, MethodParams &params)
void | _rem (Request &, MethodParams &params)
void | _while (Request &r, MethodParams &params)
void | _use (Request &r, MethodParams &params)
void | _for (Request &r, MethodParams &params)
void | _eval (Request &r, MethodParams &params)
void | _connect (Request &r, MethodParams &params)
void | _switch (Request &r, MethodParams &params)
void | _case (Request &r, MethodParams &params)
template<class I> Try_catch_result | try_catch (Request &r, StringOrValue body_code(Request &, I), I info, Value *catch_code, bool could_be_handled_by_caller=false)
used by ^try and ^cache,
Returns:
$exception.handled[string] if any.
 More...

void | cache_delete (const String &file_spec)
StringOrValue | process_cache_body_code (Request &r, Value *body_code)
void | locked_process_and_cache_put_action (int f, void *context)
const String * | locked_process_and_cache_put (Request &r, Value &body_code, Value *catch_code, Cache_scope &scope, const String &file_spec)
Cache_get_result | cache_get (Request_charsets &charsets, const String &file_spec, time_t now)
time_t | as_expires (Request &r, MethodParams &params, int index, time_t now)
const String & | as_file_spec (Request &r, MethodParams &params, int index)
void | _cache (Request &r, MethodParams &params)
StringOrValue | process_try_body_code (Request &r, Value *body_code)
void | _try_operator (Request &r, MethodParams &params)
void | _throw_operator (Request &, MethodParams &params)
void | _sleep_operator (Request &r, MethodParams &params)
VStateless_class & VClassMAIN_create ()

Variables

const char *const | IDENT_OP_C = "$Date: 2005/12/01 15:51:06 $"
Untaint_lang_name2enum untaint_lang_name2enum
const int | DATA_STRING_SERIALIZED_VERSION = 0x0006

Detailed Description

Parser: parser operators.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file op.C.

Define Documentation

#define MAX_LOOPS 20000

Definition at line 25 of file op.C.

Referenced by _for(), and _while().

#define CASE_DEFAULT_VALUE "DEFAULT"

Definition at line 29 of file op.C.

Referenced by _case().

#define PROCESS_MAIN_OPTION_NAME "main"

Definition at line 30 of file op.C.

Referenced by _process().

#define PROCESS_FILE_OPTION_NAME "file"

Definition at line 31 of file op.C.

Referenced by _process().

#define PROCESS_LINENO_OPTION_NAME "lineno"

Definition at line 32 of file op.C.

Referenced by _process().

#define SWITCH_DATA_NAME "SWITCH-DATA"

Definition at line 43 of file op.C.

#define CACHE_DATA_NAME "CACHE-DATA"

Definition at line 44 of file op.C.

#define EXCEPTION_VAR_NAME "exception"

Definition at line 45 of file op.C.

Referenced by locked_process_and_cache_put_action().

#define CACHE_EXCEPTION_HANDLED_CACHE_NAME "cache"

Definition at line 58 of file op.C.

Referenced by locked_process_and_cache_put_action().

#define ULN | ( | name,
 |  | LANG | ) | put(String::Body(name), (value_type)(String::L_##LANG));

Function Documentation

const String switch_data_name ( SWITCH_DATA_NAME ) [static]

const String cache_data_name ( CACHE_DATA_NAME ) [static]

const String exception_var_name ( EXCEPTION_VAR_NAME ) [static]

void _if | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 86 of file op.C.

References MethodParams::as_bool(), Array< Value * >::count(), Array< Value * >::get(), Request::process(), and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _untaint | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 94 of file op.C.

References MethodParams::as_junction(), MethodParams::as_string(), Array< Value * >::count(), Hash< const String::Body, String::Language >::get(), String::L_AS_IS, String::Language, Request::process(), untaint_lang_name2enum, and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _taint | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 116 of file op.C.

References String::append(), MethodParams::as_no_junction(), Value::as_string(), MethodParams::as_string(), Array< Value * >::count(), Hash< const String::Body, String::Language >::get(), String::L_TAINTED, String::Language, result, untaint_lang_name2enum, and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _process | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 140 of file op.C.

References Request::absolute(), Value::as_int(), Value::as_string(), VMethodFrame::caller(), Request::connection(), Hash< const String::Body, Value * >::count(), String::cstr(), Request::execute(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_junction(), Value::get_last_derived_class(), VStateless_class::get_method(), Request::get_method_frame(), Value::get_string(), String::L_PASS_APPENDED, String::L_UNSPECIFIED, Method::parser_code, PROCESS_FILE_OPTION_NAME, PROCESS_LINENO_OPTION_NAME, PROCESS_MAIN_OPTION_NAME, Request::process_to_string(), pseudo_file_no__process, Request::register_file(), VMethodFrame::self(), uint, and Request::use_buf().

Referenced by VClassMAIN::VClassMAIN().

void _rem | ( | Request & | ,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 227 of file op.C.

References MethodParams::as_junction().

Referenced by VClassMAIN::VClassMAIN().

void _while | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 231 of file op.C.

References Value::as_bool(), MethodParams::as_junction(), Array< Value * >::count(), StringOrValue::get_string(), String::length(), MAX_LOOPS, Request::process(), Request::process_to_value(), and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _use | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 261 of file op.C.

References MethodParams::as_no_junction(), Value::as_string(), Request::main_class, and Request::use_file().

Referenced by VClassMAIN::VClassMAIN().

void _for | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 266 of file op.C.

References MethodParams::as_int(), MethodParams::as_junction(), MethodParams::as_string(), VMethodFrame::caller(), Array< Value * >::count(), Request::get_method_frame(), StringOrValue::get_string(), String::length(), MAX_LOOPS, Request::process(), VMethodFrame::put_element(), VInt::set_int(), and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _eval | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 297 of file op.C.

References Value::as_double(), Value::as_expr_result(), MethodParams::as_junction(), MethodParams::as_no_junction(), Value::as_string(), Array< Value * >::count(), String::cstrm(), format(), Request::process_to_value(), and Request::write_no_lang().

Referenced by VClassMAIN::VClassMAIN().

void _connect | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 309 of file op.C.

References MethodParams::as_junction(), MethodParams::as_no_junction(), Request::charsets, SQL_Connection::close(), SQL_Connection::commit(), String::Body::cstr(), Value::get_element(), VStateless_class::get_element(), Value::get_table(), Request::main_class, MAIN_SQL_DRIVERS_NAME, MAIN_SQL_NAME, Charset::NAME(), Request::process(), rethrow, SQL_Connection::rollback(), Request_charsets::source(), and Request::write_assign_lang().

Referenced by VClassMAIN::VClassMAIN().

void _switch | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 367 of file op.C.

References MethodParams::as_junction(), Request::classes_conf, data, Request::process(), Request::process_to_value(), and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _case | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 380 of file op.C.

References Value::as_double(), MethodParams::as_junction(), Value::as_string(), CASE_DEFAULT_VALUE, Request::classes_conf, Array< Value * >::count(), data, Hash< const String::Body, void * >::get(), Value::is_string(), Value::is_void(), Request::process_to_value(), and value.

Referenced by VClassMAIN::VClassMAIN().

template<class I>
Try_catch_result try_catch | ( | Request & | r,
 |  | StringOrValue body_code(Request &, I) | ,
 |  | I | info,
 |  | Value * | catch_code,
 |  | bool | could_be_handled_by_caller = false
 | ) | [static]

used by ^try and ^cache,

Returns:
$exception.handled[string] if any.

Definition at line 428 of file op.C.

References Value::as_bool(), Hash< const String::Body, Value * >::get(), Request::get_details(), Value::get_element(), Value::get_junction(), Value::get_string(), VHash::hash(), I, Value::is_string(), Junction::method_frame, Request::process(), VMethodFrame::put_element(), Request_context_saver::restore(), result, rethrow, and Request::Exception_details::vhash.

Referenced by _try_operator(), and locked_process_and_cache_put_action().

void cache_delete ( const String & file_spec )

Definition at line 494 of file op.C.

References file_delete().

Referenced by _cache(), and locked_process_and_cache_put().

StringOrValue process_cache_body_code | ( | Request & | r,
 |  | Value * | body_code
 | ) | [static]

Definition at line 514 of file op.C.

References Request::process_to_string().

void locked_process_and_cache_put_action | ( | int | f,
 |  | void * | context
 | ) | [static]

Definition at line 522 of file op.C.

References assert, CACHE_EXCEPTION_HANDLED_CACHE_NAME, context, DATA_STRING_SERIALIZED_VERSION, EXCEPTION_HANDLED_PART_NAME, EXCEPTION_VAR_NAME, String::Cm::length, result, String::Cm::str, and try_catch().

Referenced by locked_process_and_cache_put().

const String* locked_process_and_cache_put | ( | Request & | r,
 |  | Value & | body_code,
 |  | Value * | catch_code,
 |  | Cache_scope & | scope,
 |  | const String & | file_spec
 | ) |

Definition at line 560 of file op.C.

References cache_delete(), file_write_action_under_lock(), locked_process_and_cache_put_action(), and result.

Referenced by _cache().

Cache_get_result cache_get | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | time_t | now
 | ) | [static]

Definition at line 586 of file op.C.

References DATA_STRING_SERIALIZED_VERSION, String::deserialize(), file, file_read(), File_read_result::length, result, File_read_result::str, and File_read_result::success.

Referenced by _cache().

time_t as_expires | ( | Request & | r,
 |  | MethodParams & | params,
 |  | int | index,
 |  | time_t | now
 | ) | [static]

Definition at line 612 of file op.C.

References Value::as_double(), result, and VDATE_TYPE.

Referenced by _cache().

const String& as_file_spec | ( | Request & | r,
 |  | MethodParams & | params,
 |  | int | index
 | ) | [static]

Definition at line 622 of file op.C.

References Request::absolute(), and MethodParams::as_string().

Referenced by _cache().

void _cache | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 625 of file op.C.

References Request::absolute(), as_expires(), as_file_spec(), MethodParams::as_junction(), MethodParams::as_string(), cache_delete(), cache_get(), Request::charsets, Request::classes_conf, Array< Value * >::count(), Hash< const String::Body, void * >::get(), locked_process_and_cache_put(), pa_sleep(), Request::process_to_string(), Request::write_assign_lang(), and Request::write_no_lang().

Referenced by VClassMAIN::VClassMAIN().

StringOrValue process_try_body_code | ( | Request & | r,
 |  | Value * | body_code
 | ) | [static]

Definition at line 735 of file op.C.

References Request::process().

void _try_operator | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 738 of file op.C.

References MethodParams::as_junction(), result, try_catch(), and Request::write_pass_lang().

Referenced by VClassMAIN::VClassMAIN().

void _throw_operator | ( | Request & | ,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 755 of file op.C.

References MethodParams::as_string(), Value::as_string(), Array< Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), and value.

Referenced by VClassMAIN::VClassMAIN().

void _sleep_operator | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 784 of file op.C.

References MethodParams::as_double(), and pa_sleep().

Referenced by VClassMAIN::VClassMAIN().

VStateless_class& VClassMAIN_create ( )

Definition at line 865 of file op.C.

Variable Documentation

const char* const IDENT_OP_C = "$Date: 2005/12/01 15:51:06 $" [static]

Definition at line 8 of file op.C.

Untaint_lang_name2enum untaint_lang_name2enum

Referenced by _taint(), and _untaint().

const int DATA_STRING_SERIALIZED_VERSION = 0x0006

Definition at line 483 of file op.C.

Referenced by cache_get(), and locked_process_and_cache_put_action().


op.C Source File

op.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_OP_C="$Date: 2005/12/01 15:51:06 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_common.h"
00014 #include "pa_os.h"
00015 #include "pa_request.h"
00016 #include "pa_vint.h"
00017 #include "pa_sql_connection.h"
00018 #include "pa_vdate.h"
00019 #include "pa_vmethod_frame.h"
00020 #include "pa_vclass.h"
00021 #include "pa_charset.h"
00022
00023 // limits
00024
00025 #define MAX_LOOPS 20000
00026
00027 // defines
00028
00029 #define CASE_DEFAULT_VALUE "DEFAULT"
00030 #define PROCESS_MAIN_OPTION_NAME "main"
00031 #define PROCESS_FILE_OPTION_NAME "file"
00032 #define PROCESS_LINENO_OPTION_NAME "lineno"
00033
00034 // class
00035
00036 class VClassMAIN: public VClass {
00037 public:
00038     VClassMAIN();
00039 };
00040
00041 // defines for statics
00042
00043 #define SWITCH_DATA_NAME "SWITCH-DATA"
00044 #define CACHE_DATA_NAME "CACHE-DATA"
00045 #define EXCEPTION_VAR_NAME "exception"
00046
00047 // statics
00048
00049 //^switch ^case
00050 static const String switch_data_name(SWITCH_DATA_NAME);
00051 //^cache
00052 static const String cache_data_name(CACHE_DATA_NAME);
00053
00054 static const String exception_var_name(EXCEPTION_VAR_NAME);
00055
00056 // local defines
00057
00058 #define CACHE_EXCEPTION_HANDLED_CACHE_NAME "cache"
00059
00060 // helpers
00061
00062 class Untaint_lang_name2enum: public Hash<const String::Body, String::Language> {
00063 public:
00064     Untaint_lang_name2enum() {
00065         #define ULN(name, LANG) \
00066             put(String::Body(name), (value_type)(String::L_##LANG));
00067         ULN("as-is", AS_IS);
00068         ULN("optimized-as-is", AS_IS|String::L_OPTIMIZE_BIT);
00069         ULN("file-spec", FILE_SPEC);
00070         ULN("http-header", HTTP_HEADER);
00071         ULN("mail-header", MAIL_HEADER);
00072         ULN("uri", URI);
00073         ULN("sql", SQL);
00074         ULN("js", JS);
00075         ULN("xml", XML);
00076         ULN("optimized-xml", XML|String::L_OPTIMIZE_BIT);
00077         ULN("html", HTML);
00078         ULN("optimized-html", HTML|String::L_OPTIMIZE_BIT);
00079         ULN("regex", REGEX);
00080         #undef ULN
00081     }
00082 } untaint_lang_name2enum;
00083
00084 // methods
00085
00086 static void _if(Request& r, MethodParams& params) {
00087     bool condition=params.as_bool(0, "condition must be expression", r);
00088     if(condition)
00089         r.write_pass_lang(r.process(*params.get(1)));
00090     else if(params.count()>2)
00091         r.write_pass_lang(r.process(*params.get(2)));
00092 }
00093
00094 static void _untaint(Request& r, MethodParams& params) {
00095
00096     String::Language lang;
00097     if(params.count()==1)
00098         lang=String::L_AS_IS; // mark as simply 'tainted'. useful in html from sql
00099     else {
00100         const String& lang_name=params.as_string(0, "lang must be string");
00101         lang=untaint_lang_name2enum.get(lang_name);
00102         if(!lang)
00103             throw Exception(0,
00104                 &lang_name,
00105                 "invalid taint language");
00106     }
00107
00108     {
00109         Value& vbody=params.as_junction(params.count()-1, "body must be code");
00110
00111         Temp_lang temp_lang(r, lang); // set temporarily specified ^untaint[language;
00112         r.write_pass_lang(r.process(vbody)); // process marking tainted with that lang
00113     }
00114 }
00115
00116 static void _taint(Request& r, MethodParams& params) {
00117     String::Language lang;
00118     if(params.count()==1)
00119         lang=String::L_TAINTED; // mark as simply 'tainted'. useful in table:set
00120     else {
00121         const String& lang_name=params.as_string(0, "lang must be string");
00122         lang=untaint_lang_name2enum.get(lang_name);
00123         if(!lang)
00124             throw Exception(0,
00125                 &lang_name,
00126                 "invalid taint language");
00127     }
00128
00129     {
00130         Value& vbody=params.as_no_junction(params.count()-1, "body must not be code");
00131
00132         String result;
00133         result.append(
00134             vbody.as_string(),  // process marking tainted with that lang
00135             lang, true);  // force result language to specified
00136         r.write_pass_lang(result);
00137     }
00138 }
00139
00140 static void _process(Request& r, MethodParams& params) {
00141     Method* main_method;
00142
00143     size_t index=0;
00144     Value* target_self;
00145     Value& maybe_target_self=params[index];
00146     if(maybe_target_self.get_string() || maybe_target_self.get_junction())
00147         target_self=&r.get_method_frame()->caller()->self();
00148     else {
00149         target_self=&maybe_target_self;  index++;
00150     }
00151
00152     {
00153         VStateless_class *target_class=target_self->get_last_derived_class();
00154         if(!target_class)
00155             throw Exception("parser.runtime",
00156                 0,
00157                 "no target class");
00158
00159         // temporary remove language change
00160         Temp_lang temp_lang(r, String::L_PASS_APPENDED);
00161         // temporary zero @main so to maybe-replace it in processed code
00162         Temp_method temp_method_main(*target_class, main_method_name, 0);
00163         // temporary zero @auto so it wouldn't be auto-called in Request::use_buf
00164         Temp_method temp_method_auto(*target_class, auto_method_name, 0);
00165
00166         size_t options_index=index+1;
00167         HashStringValue* options=0;
00168         if(options_index<params.count()) {
00169             Value& voptions=params.as_no_junction(options_index, "options must not be code");
00170             options=voptions.get_hash();
00171             if(!options)
00172                 throw Exception("parser.runtime",
00173                     0,
00174                     "options must be hash");
00175         }
00176
00177         const String* main_alias=0;
00178         const String* file_alias=0;
00179         int line_no_alias_offset=0;
00180         if(options) {
00181             int valid_options=0;
00182             if(Value* vmain_alias=options->get(PROCESS_MAIN_OPTION_NAME)) {
00183                 valid_options++;
00184                 main_alias=&vmain_alias->as_string();
00185             }
00186             if(Value* vfile_alias=options->get(PROCESS_FILE_OPTION_NAME)) {
00187                 valid_options++;
00188                 file_alias=&vfile_alias->as_string();
00189             }
00190             if(Value* vline_no_alias_offset=options->get(PROCESS_LINENO_OPTION_NAME)) {
00191                 valid_options++;
00192                 line_no_alias_offset=vline_no_alias_offset->as_int();
00193             }
00194
00195             if(valid_options!=options->count())
00196                 throw Exception("parser.runtime",
00197                     0,
00198                     "called with invalid option");
00199         }
00200
00201         uint processe_file_no=file_alias?
00202             r.register_file(r.absolute(*file_alias))
00203             : pseudo_file_no__process;
00204         // process...{string}
00205         Value& vjunction=params.as_junction(index, "body must be code");
00206         // evaluate source to process
00207         const String& source=r.process_to_string(vjunction);
00208         r.use_buf(*target_class,
00209             source.cstr(String::L_UNSPECIFIED, r.connection(false)),
00210             main_alias,
00211             processe_file_no,
00212             line_no_alias_offset);
00213
00214         // main_method
00215         main_method=target_class->get_method(main_method_name);
00216     }
00217     // after restoring current-request-lang
00218     // maybe-execute @main[]
00219     if(main_method) {
00220         // temporarily set method_frame's self to target_self
00221         Temp_method_frame_self tmfs(*r.get_method_frame(), *target_self);
00222         // execute!
00223         r.execute(*main_method->parser_code);
00224     }
00225 }
00226
00227 static void _rem(Request&, MethodParams& params) {
00228     params.as_junction(0, "body must be code");
00229 }
00230
00231 static void _while(Request& r, MethodParams& params) {
00232     Value& vcondition=params.as_junction(0, "condition must be expression");
00233     Value& body_code=params.as_junction(1, "body must be code");
00234     Value* delim_maybe_code=params.count()>2?&params[2]:0;
00235
00236     // while...
00237     int endless_loop_count=0;
00238     bool need_delim=false;
00239     while(true) {
00240         if(++endless_loop_count>=MAX_LOOPS) // endless loop?
00241             throw Exception("parser.runtime",
00242                 0,
00243                 "endless loop detected");
00244
00245         bool condition=r.process_to_value(vcondition,
00246                 false/*don't intercept string*/).as_bool();
00247         if(!condition) // ...condition is true
00248             break;
00249
00250         StringOrValue sv_processed=r.process(body_code);
00251         const String* s_processed=sv_processed.get_string();
00252         if(delim_maybe_code && s_processed && s_processed->length()) { // delimiter set and we have body
00253             if(need_delim) // need delim & iteration produced string?
00254                 r.write_pass_lang(r.process(*delim_maybe_code));
00255             need_delim=true;
00256         }
00257         r.write_pass_lang(sv_processed);
00258     }
00259 }
00260
00261 static void _use(Request& r, MethodParams& params) {
00262     Value& vfile=params.as_no_junction(0, "file name must not be code");
00263     r.use_file(r.main_class, vfile.as_string());
00264 }
00265
00266 static void _for(Request& r, MethodParams& params) {
00267     const String& var_name=params.as_string(0, "var name must be string");
00268     int from=params.as_int(1, "from must be int", r);
00269     int to=params.as_int(2, "to must be int", r);
00270     Value&  body_code=params.as_junction(3, "body must be code");
00271     Value* delim_maybe_code=params.count()>4?&params[4]:0;
00272
00273     if(to-from>=MAX_LOOPS) // too long loop?
00274         throw Exception("parser.runtime",
00275             0,
00276             "endless loop detected");
00277
00278     bool need_delim=false;
00279     VInt* vint=new VInt(0);
00280
00281     VMethodFrame& caller=*r.get_method_frame()->caller();
00282     caller.put_element(caller, var_name, vint, false);
00283     for(int i=from; i<=to; i++) {
00284         vint->set_int(i);
00285
00286         StringOrValue sv_processed=r.process(body_code);
00287         const String* s_processed=sv_processed.get_string();
00288         if(delim_maybe_code && s_processed && s_processed->length()) { // delimiter set and we have body
00289             if(need_delim) // need delim & iteration produced string?
00290                 r.write_pass_lang(r.process(*delim_maybe_code));
00291             need_delim=true;
00292         }
00293         r.write_pass_lang(sv_processed);
00294     }
00295 }
00296
00297 static void _eval(Request& r, MethodParams& params) {
00298     Value& expr=params.as_junction(0, "need expression");
00299     // evaluate expresion
00300     Value& value_result=r.process_to_value(expr,
00301         true/*don't intercept string*/).as_expr_result();
00302     if(params.count()>1) {
00303         Value& fmt=params.as_no_junction(1, "fmt must not be code");
00304         r.write_no_lang(String(format(value_result.as_double(), fmt.as_string().cstrm())));
00305     } else
00306         r.write_no_lang(value_result);
00307 }
00308
00309 static void _connect(Request& r, MethodParams& params) {
00310 #ifdef RESOURCES_DEBUG
00311 struct timeval mt[2];
00312 #endif
00313     Value& url=params.as_no_junction(0, "url must not be code");
00314     Value& body_code=params.as_junction(1, "body must be code");
00315
00316     Table* protocol2driver_and_client=0;
00317     if(Value* sql=r.main_class.get_element(String(MAIN_SQL_NAME), r.main_class, false)) {
00318         if(Value* element=sql->get_element(String(MAIN_SQL_DRIVERS_NAME), *sql, false)) {
00319             protocol2driver_and_client=element->get_table();
00320         }
00321     }
00322
00323 #ifdef RESOURCES_DEBUG
00324 //measure:before
00325 gettimeofday(&mt[0],NULL);
00326 #endif
00327     // connect
00328     SQL_Connection* connection=SQL_driver_manager->get_connection(url.as_string(),
00329         protocol2driver_and_client,
00330         r.charsets.source().NAME().cstr());
00331
00332 #ifdef RESOURCES_DEBUG
00333 //measure:after connect
00334 gettimeofday(&mt[1],NULL);
00335
00336 double t[2];
00337 for(int i=0;i<2;i++)
00338     t[i]=mt[i].tv_sec+mt[i].tv_usec/1000000.0;
00339
00340 r.sql_connect_time+=t[1]-t[0];
00341 #endif
00342     Temp_connection temp_connection(r, connection);
00343     // execute body
00344     try {
00345         r.write_assign_lang(r.process(body_code));
00346         connection->commit();
00347         connection->close();
00348     } catch(...) { // process problem
00349         connection->rollback();
00350         connection->close();
00351         rethrow;
00352     }
00353 }
00354
00355 #ifndef DOXYGEN
00356 class Switch_data: public PA_Object {
00357 public:
00358     Request& r;
00359     Value& searching;
00360     Value* found;
00361     Value* _default;
00362 public:
00363     Switch_data(Request& ar, Value& asearching):
00364       r(ar), searching(asearching) {}
00365 };
00366 #endif
00367 static void _switch(Request& r, MethodParams& params) {
00368     Switch_data* data=new Switch_data(r, r.process_to_value(params[0]));
00369     Temp_hash_value<const String::Body, void*>
00370         switch_data_setter(r.classes_conf, switch_data_name, data);
00371
00372     Value& cases_code=params.as_junction(1, "switch cases must be code");
00373     // execution of found ^case[...]{code} must be in context of ^switch[...]{code}
00374     // because of stacked WWrapper used there as wcontext
00375     r.process(cases_code, true/*intercept_string*/);
00376     if(Value* selected_code=data->found? data->found: data->_default)
00377         r.write_pass_lang(r.process(*selected_code));
00378 }
00379
00380 static void _case(Request& r, MethodParams& params) {
00381     Switch_data* data=static_cast<Switch_data*>(r.classes_conf.get(switch_data_name));
00382     if(!data)
00383         throw Exception("parser.runtime",
00384             0,
00385             "without switch");
00386
00387     int count=params.count();
00388     Value& code=params.as_junction(--count, "case result must be code");
00389
00390     Value& searching=data->searching;
00391     bool we_are_searching_string_or_void=searching.is_string() || searching.is_void();
00392     for(int i=0; i<count; i++) {
00393         Value& value=r.process_to_value(params[i]);
00394
00395         if(value.is_string() && value.as_string() == CASE_DEFAULT_VALUE) {
00396             data->_default=&code;
00397             break;
00398         }
00399
00400         bool matches;
00401         if(we_are_searching_string_or_void)
00402             matches=searching.as_string() == value.as_string();
00403         else
00404             matches=searching.as_double() == value.as_double();
00405
00406         if(matches) {
00407             if(data->found)
00408                 throw Exception("parser.runtime",
00409                     0,
00410                     "duplicate found");
00411
00412             data->found=&code;
00413             break;
00414         }
00415     }
00416 }
00417 #ifndef DOXYGEN
00418 struct Try_catch_result {
00419     StringOrValue processed_code;
00420     const String* exception_should_be_handled;
00421
00422     Try_catch_result(): exception_should_be_handled(0) {}
00423 };
00424 #endif
00425
00427 template<class I>
00428 static Try_catch_result try_catch(Request& r,
00429           StringOrValue body_code(Request&, I), I info,
00430           Value* catch_code, bool could_be_handled_by_caller=false)
00431 {
00432     Try_catch_result result;
00433     if(!catch_code) {
00434         result.processed_code=body_code(r, info);
00435         return result;
00436     }
00437
00438     // taking snapshot of try-context
00439     Request_context_saver try_context(r);
00440     try {
00441         result.processed_code=body_code(r, info);
00442     } catch(const Exception& e) {
00443         Request_context_saver throw_context(r); // taking snapshot of throw-context [stack trace contains error]
00444         Request::Exception_details details=r.get_details(e);
00445         try_context.restore(); // restoring try-context to perform catch-code
00446
00447         Junction* junction=catch_code->get_junction();
00448         Value* method_frame=junction->method_frame;
00449         Value* saved_exception_var_value=method_frame->get_element(exception_var_name, *method_frame, false);
00450         VMethodFrame& frame=*junction->method_frame;
00451         frame.put_element(frame, exception_var_name, &details.vhash, false);
00452         result.processed_code=r.process(*catch_code);
00453
00454         // retriving $exception.handled, restoring $exception var
00455         Value* vhandled=details.vhash.hash().get(exception_handled_part_name);
00456         frame.put_element(frame, exception_var_name, saved_exception_var_value, false);
00457
00458         bool bhandled=false;
00459         if(vhandled) {
00460             if(vhandled->is_string()) { // not simple $exception.handled(1/0)?
00461                 if(could_be_handled_by_caller) { // and we can possibly handle it
00462                     result.exception_should_be_handled=vhandled->get_string(); // considering 'recovered' and let the caller recover
00463                     return result;
00464                 }
00465
00466                 bhandled=false;
00467             } else
00468                 bhandled=vhandled->as_bool();
00469         }
00470
00471         if(!bhandled) {
00472             throw_context.restore(); // restoring throw-context [exception were not handled]
00473             rethrow;
00474         }
00475     }
00476     return result;
00477 }
00478
00479 // cache--
00480
00481 // consts
00482
00483 const int DATA_STRING_SERIALIZED_VERSION=0x0006;
00484
00485 // helper types
00486
00487 #ifndef DOXYGEN
00488 struct Data_string_serialized_prolog {
00489     int version;
00490     time_t expires;
00491 };
00492 #endif
00493
00494 void cache_delete(const String& file_spec) {
00495     file_delete(file_spec, false/*fail_on_read_problem*/);
00496 }
00497
00498 #ifndef DOXYGEN
00499 struct Cache_scope {
00500 public:
00501     time_t expires;
00502     const String* body_from_disk;
00503 };
00504 struct Locked_process_and_cache_put_action_info {
00505     Request *r;
00506     Cache_scope *scope;
00507     Value* body_code; Value* catch_code;
00508     const String* processed_code;
00509 };
00510 #endif
00511
00512
00513
00514 static StringOrValue process_cache_body_code(Request& r, Value* body_code) {
00515     return StringOrValue(r.process_to_string(*body_code));
00516 }
00517
00518 /* @todo maybe network order worth spending some effort?
00519     don't bothering myself with network byte order,
00520     am not planning to be able to move resulting file across platforms
00521 */
00522 static void locked_process_and_cache_put_action(int f, void *context) {
00523     Locked_process_and_cache_put_action_info& info=
00524         *static_cast<Locked_process_and_cache_put_action_info *>(context);
00525
00526
00527     const String* body_from_disk=info.scope->body_from_disk;
00528     // body->process
00529     Try_catch_result result=try_catch(*info.r,
00530         process_cache_body_code, info.body_code,
00531         info.catch_code, body_from_disk!=0 /*we have something old=we can handle=recover later*/);
00532
00533     if(result.exception_should_be_handled) {
00534         if(*result.exception_should_be_handled==CACHE_EXCEPTION_HANDLED_CACHE_NAME) {
00535             assert(body_from_disk);
00536             info.processed_code=body_from_disk;
00537         } else
00538             throw Exception("parser.runtime",
00539                 result.exception_should_be_handled,
00540                 "$"EXCEPTION_VAR_NAME"."EXCEPTION_HANDLED_PART_NAME" value must be "
00541                 "either boolean or string '"CACHE_EXCEPTION_HANDLED_CACHE_NAME"'");
00542     } else
00543         info.processed_code=&result.processed_code.as_string();
00544
00545     // expiration time not spoiled by ^cache(0) or something?
00546     if(info.scope->expires > time(0)) {
00547         // string -serialize> buffer
00548         String::Cm serialized=info.processed_code->serialize(
00549             sizeof(Data_string_serialized_prolog));
00550         Data_string_serialized_prolog& prolog=
00551             *reinterpret_cast<Data_string_serialized_prolog *>(serialized.str);
00552         prolog.version=DATA_STRING_SERIALIZED_VERSION;
00553         prolog.expires=info.scope->expires;
00554
00555         // buffer -write> file
00556         write(f, serialized.str, serialized.length);
00557     } else // expired!
00558         info.scope->expires=0; // flag it so that could be easily checked by caller
00559 }
00560 const String* locked_process_and_cache_put(Request& r,
00561                        Value& body_code,
00562                        Value* catch_code,
00563                        Cache_scope& scope,
00564                        const String& file_spec)
00565 {
00566     Locked_process_and_cache_put_action_info info={&r, &scope, &body_code, catch_code, 0};
00567
00568     const String* result=file_write_action_under_lock(
00569         file_spec,
00570         "cache_put", locked_process_and_cache_put_action, &info,
00571         false/*as_text*/,
00572         false/*do_append*/,
00573         false/*block*/,
00574         false/*fail on lock problem*/) ? info.processed_code: 0;
00575     time_t now=time(0);
00576     if(scope.expires<=now)
00577         cache_delete(file_spec);
00578     return result;
00579 }
00580 #ifndef DOXYGEN
00581 struct Cache_get_result {
00582     const String* body;
00583     bool expired;
00584 };
00585 #endif
00586 static Cache_get_result cache_get(Request_charsets& charsets, const String& file_spec, time_t now) {
00587     Cache_get_result result={0, false};
00588
00589     File_read_result file=file_read(charsets, file_spec,
00590                false/*as_text*/,
00591                0, //no params
00592                false/*fail_on_read_problem*/);
00593     if(file.success && file.length/* ignore reads which are empty due to
00594             non-unary open+lockEX conflict with lockSH */) {
00595
00596         Data_string_serialized_prolog& prolog=
00597             *reinterpret_cast<Data_string_serialized_prolog *>(file.str);
00598
00599         String* body=new String;
00600         if(
00601             file.length>=sizeof(Data_string_serialized_prolog)
00602             && prolog.version==DATA_STRING_SERIALIZED_VERSION) {
00603             if(body->deserialize(sizeof(Data_string_serialized_prolog),  file.str, file.length)) {
00604                 result.body=body;
00605                 result.expired=prolog.expires <= now;
00606             }
00607         }
00608     }
00609
00610     return result;
00611 }
00612 static time_t as_expires(Request& r, MethodParams& params,
00613                         int index, time_t now) {
00614     time_t result;
00615     if(Value* vdate=params[index].as(VDATE_TYPE, false))
00616         result=static_cast<VDate*>(vdate)->get_time();
00617     else
00618         result=now+(time_t)params.as_double(index, "lifespan must be date or number", r);
00619
00620     return result;
00621 }
00622 static const String& as_file_spec(Request& r, MethodParams& params, int index) {
00623     return r.absolute(params.as_string(index, "filespec must be string"));
00624 }
00625 static void _cache(Request& r, MethodParams& params) {
00626     if(params.count()==0)
00627     {
00628         // return current expiration time
00629         Cache_scope* scope=static_cast<Cache_scope*>(r.classes_conf.get(cache_data_name));
00630         if(!scope)
00631             throw Exception("parser.runtime",
00632                 0,
00633                 "expire-time get without cache");
00634         r.write_no_lang(*new VDate(scope->expires));
00635         return;
00636     }
00637
00638     time_t now=time(0);
00639
00640     // ^cache[filename] ^cache(seconds) ^cache[expires date]
00641     if(params.count()==1) {
00642         if(params[0].is_string()) { // filename?
00643             cache_delete(as_file_spec(r, params, 0));
00644             return;
00645         }
00646
00647         // secods|expires date
00648         Cache_scope* scope=static_cast<Cache_scope*>(r.classes_conf.get(cache_data_name));
00649         if(!scope)
00650             throw Exception("parser.runtime",
00651                 0,
00652                 "expire-time reducing instruction without cache");
00653
00654         time_t expires=as_expires(r, params, 0, now);
00655         if(expires < scope->expires)
00656             scope->expires=expires;
00657
00658         return;
00659     } else if(params.count()<3)
00660         throw Exception("parser.runtime",
00661             0,
00662             "invalid number of parameters");
00663
00664     // file_spec, expires, body code
00665     const String& file_spec=r.absolute(params.as_string(0, "filespec must be string"));
00666
00667     Cache_scope scope={as_expires(r, params, 1, now), 0};
00668
00669     Temp_hash_value<const String::Body, void*>
00670         cache_scope_setter(r.classes_conf, cache_data_name, &scope);
00671     Value& body_code=params.as_junction(2, "body_code must be code");
00672     Value* catch_code=0;
00673     if(params.count()>3)
00674         catch_code=&params.as_junction(3, "catch_code must be code");
00675
00676     if(scope.expires>now) { // valid 'expires' specified? try cached copy...
00677         // hence we don't hope to have unary create/lockEX
00678         // we need some plan to live in a life like that, so...
00679         // worst races plan:
00680         // A        B
00681         // open
00682         //          |open
00683         // lockSH
00684         //          |nonblocking-lockEX fails
00685         // unlockSH
00686         // close, cache_get returns 0
00687         // open
00688         // nonblocking-lockEX succeeds; process, write, close
00689         //          |retry1: open
00690         // ...
00691         //          |lockSH succeeds; ...
00692
00693         for(int retry=0; retry<2; retry++) {
00694             Cache_get_result cached=cache_get(r.charsets, file_spec, now);
00695             if(cached.body) { // have cached copy
00696                 if(cached.expired)
00697                     scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[]
00698                 else // and it's not expired yet
00699                 {
00700                     // write it out
00701                     r.write_assign_lang(*cached.body);
00702                     // happy with it
00703                     return;
00704                 }
00705             }
00706
00707             // non-blocked lock; process; cache it
00708             if(const String* processed_body=
00709                 locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec)) {
00710                 // write it out
00711                 r.write_assign_lang(*processed_body);
00712                 // happy with it
00713                 return;
00714             } else { // somebody writing result right now
00715                 pa_sleep(0, 500000); // waiting half a second
00716                 retry=0; // prolonging our wait, than could cache_get it, without processing body_code
00717             }
00718         }
00719         throw Exception(0,
00720             &file_spec,
00721             "locking problem");
00722     } else {
00723         // instructed not to cache; forget cached copy
00724         cache_delete(file_spec);
00725         // process
00726         const String& processed_body=r.process_to_string(body_code);
00727         // write it out
00728         r.write_assign_lang(processed_body);
00729         // happy with it
00730         return;
00731     }
00732     // never reached
00733 }
00734
00735 static StringOrValue process_try_body_code(Request& r, Value* body_code) {
00736     return r.process(*body_code);
00737 }
00738 static void _try_operator(Request& r, MethodParams& params) {
00739     Value& body_code=params.as_junction(0, "body_code must be code");
00740     Value& catch_code=params.as_junction(1, "catch_code must be code");
00741
00742     Try_catch_result result=try_catch(r,
00743         process_try_body_code, &body_code,
00744         &catch_code);
00745
00746     if(result.exception_should_be_handled)
00747         throw Exception("parser.runtime",
00748             result.exception_should_be_handled,
00749             "catch block must set $exception.handled to some boolean value, not string");
00750
00751     // write out processed body_code or catch_code
00752     r.write_pass_lang(result.processed_code);
00753 }
00754
00755 static void _throw_operator(Request&, MethodParams& params) {
00756     if(params.count()==1) {
00757         if(HashStringValue *hash=params[0].get_hash()) {
00758             const char* type=0;
00759             if(Value* value=hash->get(exception_type_part_name))
00760                 type=value->as_string().cstr();
00761             const String* source=0;
00762             if(Value* value=hash->get(exception_source_part_name))
00763                 source=&value->as_string();
00764             const char* comment=0;
00765             if(Value* value=hash->get(exception_comment_part_name))
00766                 comment=value->as_string().cstr();
00767
00768             throw Exception(type,
00769                 source?source:0,
00770                 "%s", comment?comment:"");
00771         } else
00772             throw Exception("parser.runtime",
00773                 0,
00774                 "one-param version has hash param");
00775     } else {
00776         const char* type=params.as_string(0, "type must be string").cstr();
00777         const String& source=params.as_string(1, "source must be string");
00778         const char* comment=params.count()>2? params.as_string(2, "comment must be string").cstr()
00779             :0;
00780         throw Exception(type, &source, "%s", comment?comment:"");
00781     }
00782  }
00783
00784 static void _sleep_operator(Request& r, MethodParams& params) {
00785     double seconds=params.as_double(0, "seconds must be double", r);
00786     pa_sleep((int)trunc(seconds), (int)trunc(seconds*1000));
00787  }
00788
00789 #if defined(WIN32) && defined(_DEBUG)
00790 #   define PA_BPT
00791 static void _bpt(Request&, MethodParams&) {
00792     _asm int 3;
00793 }
00794 #endif
00795
00796 // constructor
00797
00798 VClassMAIN::VClassMAIN(): VClass() {
00799     set_name(*new String(MAIN_CLASS_NAME));
00800
00801 #ifdef PA_BPT
00802     // ^bpt[]
00803     add_native_method("bpt", Method::CT_ANY, _bpt, 0, 0);
00804 #endif
00805
00806     // ^if(condition){code-when-true}
00807     // ^if(condition){code-when-true}{code-when-false}
00808     add_native_method("if", Method::CT_ANY, _if, 2, 3);
00809
00810     // ^untaint[as-is|uri|sql|js|html|html-typo]{code}
00811     add_native_method("untaint", Method::CT_ANY, _untaint, 1, 2);
00812
00813     // ^taint[as-is|uri|sql|js|html|html-typo]{code}
00814     add_native_method("taint", Method::CT_ANY, _taint, 1, 2);
00815
00816     // ^process[code]
00817     add_native_method("process", Method::CT_ANY, _process, 1, 3);
00818
00819     // ^rem{code}
00820     add_native_method("rem", Method::CT_ANY, _rem, 1, 10000);
00821
00822     // ^while(condition){code}
00823     add_native_method("while", Method::CT_ANY, _while, 2, 3);
00824
00825     // ^use[file]
00826     add_native_method("use", Method::CT_ANY, _use, 1, 1);
00827
00828     // ^for[i](from-number;to-number-inclusive){code}[delim]
00829     add_native_method("for", Method::CT_ANY, _for, 3+1, 3+1+1);
00830
00831     // ^eval(expr)
00832     // ^eval(expr)[format]
00833     add_native_method("eval", Method::CT_ANY, _eval, 1, 2);
00834
00835     // ^connect[protocol://user:pass@host[:port]/database]{code with ^sql-s}
00836     add_native_method("connect", Method::CT_ANY, _connect, 2, 2);
00837
00838
00839     // ^cache[file_spec](time){code}[{catch code}] time=0 no cache
00840     // ^cache[file_spec] delete cache
00841     // ^cache[] get current expiration time
00842     add_native_method("cache", Method::CT_ANY, _cache, 0, 4);
00843
00844     // switch
00845
00846     // ^switch[value]{cases}
00847     add_native_method("switch", Method::CT_ANY, _switch, 2, 2);
00848
00849     // ^case[value]{code}
00850     add_native_method("case", Method::CT_ANY, _case, 2, 10000);
00851
00852     // try-catch
00853
00854     // ^try{code}{catch code}
00855     add_native_method("try", Method::CT_ANY, _try_operator, 2, 2);
00856     // ^throw[$exception hash]
00857     // ^throw[type;source;comment]
00858     add_native_method("throw", Method::CT_ANY, _throw_operator, 1, 3);
00859
00860     add_native_method("sleep", Method::CT_ANY, _sleep_operator, 1, 1);
00861 }
00862
00863 // constructor & configurator
00864
00865 VStateless_class& VClassMAIN_create() {
00866     return *new VClassMAIN;
00867 }


pa_array.h File Reference

Parser: Array & Array_iterator classes decls. More...

Include dependency graph for pa_array.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Array
Simple Array. More...

struct | Action_options
class | Array_iterator
Array iterator, usage:
    // Array<T> a;
    for(Array_iterator<T> i(a); i.has_next(); ) {
        T& element=i.next();
        ...
    }
. More...

Defines

#define | ARRAY_OPTION_LIMIT_ALL ((size_t)-1)

Variables

const char *const | IDENT_ARRAY_Y = "$Date: 2005/11/25 12:21:34 $"

Detailed Description

Parser: Array & Array_iterator classes decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_array.h.

Define Documentation

#define ARRAY_OPTION_LIMIT_ALL ((size_t)-1)

Definition at line 24 of file pa_array.h.

Referenced by Array< T >::Action_options::Action_options(), Array< T >::Action_options::adjust(), Array< Operation >::append(), and Table::Table().

Variable Documentation

const char* const IDENT_ARRAY_Y = "$Date: 2005/11/25 12:21:34 $" [static]

Definition at line 11 of file pa_array.h.


pa_array.h Source File

pa_array.h

Go to the documentation of this file.
00001
00008 #ifndef PA_ARRAY_H
00009 #define PA_ARRAY_H
00010
00011 static const char * const IDENT_ARRAY_Y="$Date: 2005/11/25 12:21:34 $";
00012
00013 // includes
00014
00015 #include "pa_memory.h"
00016 #include "pa_exception.h"
00017
00018 // forwards
00019
00020 template<typename T> class Array_iterator;
00021
00022 // defines
00023
00024 #define ARRAY_OPTION_LIMIT_ALL ((size_t)-1)
00025
00027 template<typename T> class Array: public PA_Object {
00028
00029     friend class Array_iterator<T>;
00030
00031 protected:
00032
00034     T *felements;
00035
00036     // allocated size
00037     size_t fallocated;
00038
00039     // array size
00040     size_t fused;
00041
00042 public:
00043     struct Action_options {
00044         size_t offset;
00045         size_t limit; //< ARRAY_OPTION_LIMIT_ALL means 'all'. zero limit means 'nothing'
00046         bool reverse;
00047         bool defined;
00048
00049         Action_options(
00050             size_t aoffset=0,
00051             size_t alimit=ARRAY_OPTION_LIMIT_ALL,
00052             bool areverse=false):
00053             offset(aoffset), limit(alimit), reverse(areverse),
00054             defined(false) {}
00055
00056         bool adjust(size_t count) {
00057             if(!count || !limit)
00058                 return false;
00059             size_t row=offset;
00060             if(row>=count)
00061                 return false;
00062             // max(limit)
00063             size_t m=reverse?
00064                 offset
00065                 :count-offset;
00066             if(!m)
00067                 return false;
00068             // fix limit
00069             if(limit==ARRAY_OPTION_LIMIT_ALL || limit>m)
00070                 limit=m;
00071
00072             return true;
00073         }
00074
00075
00076     };
00077
00078     typedef T element_type;
00079
00080     Array(size_t initial=3):
00081         fallocated(initial>3?initial:3),
00082         fused(0)
00083     {
00084         felements=static_cast<T*>(malloc(fallocated*sizeof(T)));
00085     }
00086
00088     size_t count() const { return fused; }
00090     Array& operator += (T src) {
00091         if(is_full())
00092             expand(+2);
00093
00094         felements[fused++]=src;
00095
00096         return *this;
00097     }
00098
00100     Array& append(const Array& src,
00101         size_t offset=0,
00102         size_t limit=ARRAY_OPTION_LIMIT_ALL, //< negative limit means 'all'. zero limit means 'nothing'
00103         bool reverse=false) {
00104
00105         size_t src_count=src.count();
00106         // skip tivials
00107         if(!src_count || !limit || offset>=src_count)
00108             return *this;
00109         // max(limit)
00110         size_t m=reverse?
00111             1+offset
00112             :src_count-offset;
00113         if(!m)
00114             return *this;
00115         // fix limit
00116         if(limit==ARRAY_OPTION_LIMIT_ALL || limit>m)
00117             limit=m;
00118
00119         ssize_t delta=reverse?
00120             (ssize_t)limit
00121             :limit-(fallocated-fused);
00122         if(delta>0)
00123             expand(delta);
00124
00125         T* from=&src.felements[offset];
00126         T* to=&felements[fused];
00127         if(reverse) { // reverse
00128             for(T* from_end=from-limit; from>from_end; --from)
00129                 *to++=*from;
00130
00131         } else { // forward
00132             for(T* from_end=from+limit; from<from_end; from++)
00133                 *to++=*from;
00134         }
00135
00136         fused+=limit;
00137         return *this;
00138     }
00139
00141     T get(size_t index) const {
00142         assert(index<count());
00143         return felements[index];
00144     }
00145
00147     T& get_ref(size_t index) const {
00148         assert(index<count());
00149         return felements[index];
00150     }
00151
00153     void put(size_t index, T element) {
00154         assert(index<count());
00155         felements[index]=element;
00156     }
00157
00158     T operator [](size_t index) const { return get(index); }
00159
00161     template<typename I> void for_each(void (*callback)(T, I), I info) const {
00162         T *last=felements+fused;
00163         for(T *current=felements; current<last; current++)
00164             callback(*current, info);
00165     }
00166
00168     template<typename I> void for_each_ref(void (*callback)(T&, I), I info) {
00169         T *last=felements+fused;
00170         for(T *current=felements; current<last; current++)
00171             callback(*current, info);
00172     }
00173
00175     template<typename I> T first_that(bool (*callback)(T, I), I info) const {
00176         T *last=felements+fused;
00177         for(T *current=felements; current<last; current++)
00178             if(callback(*current, info))
00179                 return *current;
00180
00181         return T(0);
00182     }
00183
00184 protected:
00185
00186     bool is_full() {
00187         return fused == fallocated;
00188     }
00189     void expand(size_t delta) {
00190         size_t new_allocated=fallocated+delta;
00191         felements = (T *)realloc(felements, new_allocated*sizeof(T));
00192         memset(&felements[fallocated], 0, delta*sizeof(T));
00193         fallocated=new_allocated;
00194     }
00195
00196 private: //disabled
00197
00198     Array(const Array&) {}
00199     Array& operator = (const Array&) { return *this; }
00200 };
00201
00202
00212 template<typename T> class Array_iterator {
00213
00214     const Array<T>& farray;
00215     T *fcurrent;
00216     T *flast;
00217
00218 public:
00219
00220     Array_iterator(const Array<T>& aarray): farray(aarray) {
00221         fcurrent=farray.felements;
00222         flast=farray.felements+farray.count();
00223     }
00224
00226     bool has_next() {
00227         return fcurrent<flast;
00228     }
00229
00231     const T next() {
00232         return *(fcurrent++);
00233     }
00234
00235 };
00236 #endif


pa_cache_managers.C File Reference

Parser: status press center implementation. More...

Include dependency graph for pa_cache_managers.C:

Include dependency graph

Go to the source code of this file.

Functions

void | delete_one (Cache_managers::key_type, Cache_managers::value_type avalue, int)
void | maybe_expire_one (Cache_managers::key_type, Cache_managers::value_type avalue, int)

Variables

const char *const | IDENT_CACHE_MANAGERS_C = "$Date: 2005/08/09 08:14:51 $"
Cache_managers * | cache_managers = 0
global. More...

Detailed Description

Parser: status press center implementation.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_cache_managers.C.

Function Documentation

void delete_one | ( | Cache_managers::key_type | ,
 |  | Cache_managers::value_type | avalue,
 |  | int |
 | ) | [static]

Definition at line 28 of file pa_cache_managers.C.

References Hash< const String::Body, Cache_manager * >::key_type, and Hash< const String::Body, Cache_manager * >::value_type.

Referenced by Cache_managers::~Cache_managers().

void maybe_expire_one | ( | Cache_managers::key_type | ,
 |  | Cache_managers::value_type | avalue,
 |  | int |
 | ) | [static]

Definition at line 38 of file pa_cache_managers.C.

References Hash< const String::Body, Cache_manager * >::key_type, and Hash< const String::Body, Cache_manager * >::value_type.

Referenced by Cache_managers::maybe_expire().

Variable Documentation

const char* const IDENT_CACHE_MANAGERS_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 8 of file pa_cache_managers.C.

Cache_managers* cache_managers = 0

global.

Definition at line 19 of file pa_cache_managers.C.


pa_cache_managers.C Source File

pa_cache_managers.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_CACHE_MANAGERS_C="$Date: 2005/08/09 08:14:51 $";
00009
00010 #include "pa_cache_managers.h"
00011
00012 #include "pa_sql_driver_manager.h"
00013 #ifdef XML
00014 #include "pa_stylesheet_manager.h"
00015 #endif
00016
00017 // globals
00018
00019 Cache_managers* cache_managers=0;
00020
00021 Cache_managers::Cache_managers() {
00022     put("sql", (SQL_driver_manager=new SQL_Driver_manager));
00023 #ifdef XML
00024     put("stylesheet", (stylesheet_manager=new Stylesheet_manager));
00025 #endif
00026 }
00027
00028 static void delete_one(Cache_managers::key_type /*akey*/, Cache_managers::value_type avalue,
00029                         int) {
00030     delete avalue;
00031 }
00032 Cache_managers::~Cache_managers() {
00033     for_each(delete_one, 0);
00034 }
00035
00036 // methods
00037
00038 static void maybe_expire_one(Cache_managers::key_type /*akey*/, Cache_managers::value_type avalue,
00039                                           int) {
00040     avalue->maybe_expire_cache();
00041 }
00042 void Cache_managers::maybe_expire() {
00043     for_each(maybe_expire_one, 0);
00044 }


pa_cache_managers.h File Reference

Parser: cache managers center decl. More...

Include dependency graph for pa_cache_managers.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Cache_manager
can return status and can expire it contents. More...

class | Cache_managers
maintains name=>Cache_manager association, can expire its contents. More...

Variables

const char *const | IDENT_CACHE_MANAGERS_H = "$Date: 2005/08/09 08:14:49 $"
Cache_managers * cache_managers
global. More...

Detailed Description

Parser: cache managers center decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Date:
2005/08/09 08:14:49

Definition in file pa_cache_managers.h.

Variable Documentation

const char* const IDENT_CACHE_MANAGERS_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 13 of file pa_cache_managers.h.

Cache_managers* cache_managers

global.

Definition at line 41 of file pa_cache_managers.h.


pa_cache_managers.h Source File

pa_cache_managers.h

Go to the documentation of this file.
00001
00010 #ifndef PA_CACHE_MANAGERS_H
00011 #define PA_CACHE_MANAGERS_H
00012
00013 static const char * const IDENT_CACHE_MANAGERS_H="$Date: 2005/08/09 08:14:49 $";
00014
00015 #include "pa_hash.h"
00016 #include "pa_value.h"
00017
00018 // defines
00019
00021 class Cache_manager: public PA_Object {
00022 public:
00024     virtual Value* get_status() =0;
00025     virtual void maybe_expire_cache() {}
00026     virtual ~Cache_manager() {}
00027 };
00028
00030 class Cache_managers: public Hash<const String::Body, Cache_manager*> {
00031 public:
00032     Cache_managers();
00033     virtual ~Cache_managers();
00034
00036     void maybe_expire();
00037
00038 };
00039
00041 extern Cache_managers* cache_managers;
00042
00043 #endif


pa_charset.C File Reference

Parser: Charset connection implementation. More...

Include dependency graph for pa_charset.C:

Include dependency graph

Go to the source code of this file.

Functions

void | prepare_case_tables (unsigned char *tables)
void | cstr2ctypes (unsigned char *tables, const unsigned char *cstr, unsigned char bit)
unsigned int | to_wchar_code (const char *cstr)
bool | to_bool (const char *cstr)
void | element2ctypes (unsigned char c, bool belongs, unsigned char *tables, unsigned char bit, int group_offset=-1)
void | element2case (unsigned char from, unsigned char to, unsigned char *tables)
int | sort_cmp_Trans_rec_intCh (const void *a, const void *b)
XMLByte | xlatOneTo (const XMLCh toXlat, const Charset::Tables &tables, XMLByte not_found)
int | transcodeToUTF8 (const XMLByte *srcData, size_t &srcLen, XMLByte *toFill, size_t &toFillLen, const Charset::Tables &tables)
int | transcodeFromUTF8 (const XMLByte *srcData, size_t &srcLen, XMLByte *toFill, size_t &toFillLen, const Charset::Tables &tables)
XMLCh | change_case_UTF8 (const XMLCh src, const Charset::UTF8CaseTable &table)
void | store_UTF8 (XMLCh src, XMLByte *&outPtr)
void | change_case_UTF8 (XMLCh src, XMLByte *&outPtr, const Charset::UTF8CaseTable &table)
void | change_case_UTF8 (const XMLByte *srcData, size_t srcLen, XMLByte *toFill, size_t toFillLen, const Charset::UTF8CaseTable &table)
void | transcode_pair (const String::Body, String::Body &avalue, Transcode_pair_info *info)

Variables

const char *const | IDENT_CHARSET_C = "$Date: 2005/12/16 10:15:12 $"
Charset::UTF8CaseTable::Rec UTF8CaseToUpperRecords []
Charset::UTF8CaseTable UTF8CaseToUpper
Charset::UTF8CaseTable::Rec UTF8CaseToLowerRecords []
Charset::UTF8CaseTable UTF8CaseToLower
unsigned char | pcre_default_tables []
const XMLByte | gUTFBytes [0x100]
const uint | gUTFOffsets [6]
const XMLByte | gFirstByteMark [7]

Detailed Description

Parser: Charset connection implementation.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan<paf@design.ru>(http://paf.design.ru)

Definition in file pa_charset.C.

Function Documentation

void prepare_case_tables ( unsigned char * tables ) [inline]

Definition at line 396 of file pa_charset.C.

void cstr2ctypes | ( | unsigned char * | tables,
 |  | const unsigned char * | cstr,
 |  | unsigned char | bit
 | ) | [inline]

Definition at line 402 of file pa_charset.C.

References xlatOneTo(), and XMLByte.

unsigned int to_wchar_code ( const char * cstr ) [inline]

Definition at line 411 of file pa_charset.C.

References uint.

bool to_bool ( const char * cstr ) [inline]

Definition at line 420 of file pa_charset.C.

void element2ctypes | ( | unsigned char | c,
 |  | bool | belongs,
 |  | unsigned char * | tables,
 |  | unsigned char | bit,
 |  | int | group_offset = -1
 | ) | [static]

Definition at line 423 of file pa_charset.C.

void element2case | ( | unsigned char | from,
 |  | unsigned char | to,
 |  | unsigned char * | tables
 | ) | [static]

Definition at line 434 of file pa_charset.C.

References String::C::length, String::C::str, and XMLByte.

int sort_cmp_Trans_rec_intCh | ( | const void * | a,
 |  | const void * | b
 | ) | [static]

Definition at line 535 of file pa_charset.C.

References change_case_UTF8(), and XMLByte.

XMLByte xlatOneTo | ( | const XMLCh | toXlat,
 |  | const Charset::Tables & | tables,
 |  | XMLByte | not_found
 | ) | [static]

Definition at line 549 of file pa_charset.C.

References uint.

Referenced by cstr2ctypes().

int transcodeToUTF8 | ( | const XMLByte * | srcData,
 |  | size_t & | srcLen,
 |  | XMLByte * | toFill,
 |  | size_t & | toFillLen,
 |  | const Charset::Tables & | tables
 | ) | [static]

Definition at line 629 of file pa_charset.C.

References MAX_CHARSETS.

int transcodeFromUTF8 | ( | const XMLByte * | srcData,
 |  | size_t & | srcLen,
 |  | XMLByte * | toFill,
 |  | size_t & | toFillLen,
 |  | const Charset::Tables & | tables
 | ) | [static]

Todo:
digital entites only when xml/html output [at output in html/xml mode, in html part of a letter]

Definition at line 712 of file pa_charset.C.

XMLCh change_case_UTF8 | ( | const XMLCh | src,
 |  | const Charset::UTF8CaseTable & | table
 | ) | [static]

Definition at line 813 of file pa_charset.C.

void store_UTF8 | ( | XMLCh | src,
 |  | XMLByte *& | outPtr
 | ) | [static]

Definition at line 833 of file pa_charset.C.

References String::L_CLEAN, and String::length().

void change_case_UTF8 | ( | XMLCh | src,
 |  | XMLByte *& | outPtr,
 |  | const Charset::UTF8CaseTable & | table
 | ) | [static]

Definition at line 881 of file pa_charset.C.

void change_case_UTF8 | ( | const XMLByte * | srcData,
 |  | size_t | srcLen,
 |  | XMLByte * | toFill,
 |  | size_t | toFillLen,
 |  | const Charset::UTF8CaseTable & | table
 | ) |

Definition at line 885 of file pa_charset.C.

Referenced by String::change_case(), and sort_cmp_Trans_rec_intCh().

void transcode_pair | ( | const String::Body | ,
 |  | String::Body & | avalue,
 |  | Transcode_pair_info * | info
 | ) | [static]

Definition at line 1212 of file pa_charset.C.

Variable Documentation

const char* const IDENT_CHARSET_C = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 8 of file pa_charset.C.

Charset::UTF8CaseTable::Rec UTF8CaseToUpperRecords[]

Definition at line 21 of file pa_charset.C.

Charset::UTF8CaseTable UTF8CaseToUpper

Initial value:

{
    sizeof(UTF8CaseToUpperRecords)sizeof(Charset::UTF8CaseTable::Rec),
    UTF8CaseToUpperRecords}

Definition at line 201 of file pa_charset.C.

Charset::UTF8CaseTable::Rec UTF8CaseToLowerRecords[]

Definition at line 205 of file pa_charset.C.

Charset::UTF8CaseTable UTF8CaseToLower

Initial value:

{
    sizeof(UTF8CaseToLowerRecords)sizeof(Charset::UTF8CaseTable::Rec),
    UTF8CaseToLowerRecords}

Definition at line 390 of file pa_charset.C.

unsigned char pcre_default_tables[]

Definition at line 447 of file pa_charset.C.

const XMLByte gUTFBytes[0x100] [static]

Initial value:

 {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    ,   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    ,   3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
}

Definition at line 602 of file pa_charset.C.

const uint gUTFOffsets[6] [static]

Initial value:

 {
    0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080
}

Definition at line 621 of file pa_charset.C.

const XMLByte gFirstByteMark[7] [static]

Initial value:

 {
    0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
}

Definition at line 625 of file pa_charset.C.


pa_charset.C Source File

pa_charset.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_CHARSET_C="$Date: 2005/12/16 10:15:12 $";
00009
00010 #include "pa_charset.h"
00011 #include "pa_charsets.h"
00012
00013 #ifdef XML
00014 #include "libxml/encoding.h"
00015 #endif
00016
00017 //#define PA_PATCHED_LIBXML_BACKWARD
00018
00019 // globals
00020
00021 Charset::UTF8CaseTable::Rec UTF8CaseToUpperRecords[]={
00022 #include "utf8-to-upper.inc"
00023 };
00024 Charset::UTF8CaseTable UTF8CaseToUpper={
00025     sizeof(UTF8CaseToUpperRecords)/sizeof(Charset::UTF8CaseTable::Rec),
00026     UTF8CaseToUpperRecords};
00027
00028 Charset::UTF8CaseTable::Rec UTF8CaseToLowerRecords[]={
00029 #include "utf8-to-lower.inc"
00030 };
00031 Charset::UTF8CaseTable UTF8CaseToLower={
00032     sizeof(UTF8CaseToLowerRecords)/sizeof(Charset::UTF8CaseTable::Rec),
00033     UTF8CaseToLowerRecords};
00034
00035 // helpers
00036
00037 inline void prepare_case_tables(unsigned char *tables) {
00038     unsigned char *lcc_table=tables+lcc_offset;
00039     unsigned char *fcc_table=tables+fcc_offset;
00040     for(int i=0; i<0x100; i++)
00041         lcc_table[i]=fcc_table[i]=(unsigned char)i;
00042 }
00043 inline void cstr2ctypes(unsigned char *tables, const unsigned char *cstr,
00044                         unsigned char bit) {
00045     unsigned char *ctypes_table=tables+ctypes_offset;
00046     ctypes_table[0]=bit;
00047     for(; *cstr; cstr++) {
00048         unsigned char c=*cstr;
00049         ctypes_table[c]|=bit;
00050     }
00051 }
00052 inline unsigned int to_wchar_code(const char* cstr) {
00053     if(!cstr || !*cstr)
00054         return 0;
00055     if(cstr[1]==0)
00056         return(unsigned int)(unsigned char)cstr[0];
00057
00058     char *error_pos;
00059     return(unsigned int)strtol(cstr, &error_pos, 0);
00060 }
00061 inline bool to_bool(const char* cstr) {
00062     return cstr && *cstr!=0;
00063 }
00064 static void element2ctypes(unsigned char c, bool belongs,
00065                            unsigned char *tables,  unsigned char bit, int group_offset=-1) {
00066     if(!belongs)
00067         return;
00068
00069     unsigned char *ctypes_table=tables+ctypes_offset;
00070
00071     ctypes_table[c]|=bit;
00072     if(group_offset>=0)
00073         tables[cbits_offset+group_offset+c/8] |= 1<<(c%8);
00074 }
00075 static void element2case(unsigned char from, unsigned char to,
00076                          unsigned char *tables) {
00077     if(!to)
00078         return;
00079
00080     unsigned char *lcc_table=tables+lcc_offset;
00081     unsigned char *fcc_table=tables+fcc_offset;
00082     lcc_table[from]=to;
00083     fcc_table[from]=to; fcc_table[to]=from;
00084 }
00085
00086 // methods
00087
00088 extern "C" unsigned char pcre_default_tables[]; // pcre/chartables.c
00089 Charset::Charset(Request_charsets* charsets, const String::Body ANAME, const String* afile_spec):
00090     FNAME(ANAME),
00091     FNAME_CSTR(ANAME.cstrm()) {
00092
00093     if(afile_spec) {
00094         fisUTF8=false;
00095         load_definition(*charsets, *afile_spec);
00096 #ifdef XML
00097         addEncoding(FNAME_CSTR);
00098 #endif
00099     } else {
00100         fisUTF8=true;
00101         // grab default onces [for UTF-8 so to be able to make a-z =>A-Z
00102         memcpy(pcre_tables, pcre_default_tables, sizeof(pcre_tables));
00103     }
00104
00105 #ifdef XML
00106     initTranscoder(FNAME, FNAME_CSTR);
00107 #endif
00108 }
00109
00110 void Charset::load_definition(Request_charsets& charsets, const String& afile_spec) {
00111     // pcre_tables
00112     // lowcase, flipcase, bits digit+word+whitespace, masks
00113
00114     // must not move this inside of prepare_case_tables
00115     // don't know the size there
00116     memset(pcre_tables, 0, sizeof(pcre_tables));
00117     prepare_case_tables(pcre_tables);
00118     cstr2ctypes(pcre_tables,(const unsigned char *)"*+?{^.$|()[", ctype_meta);
00119
00120     // charset
00121     memset(&tables, 0, sizeof(tables));
00122
00123     // loading text
00124     char *data=file_read_text(charsets, afile_spec);
00125
00126     // ignore header
00127     getrow(&data);
00128
00129     // parse cells
00130     char *row;
00131     while((row=getrow(&data))) {
00132         // remove empty&comment lines
00133         if(!*row || *row=='#')
00134             continue;
00135
00136         // char white-space digit   hex-digit   letter  word    lowercase   unicode1    unicode2
00137         unsigned char c=0;
00138         char *cell;
00139         for(int column=0; (cell=lsplit(&row, '\t')); column++) {
00140             switch(column) {
00141             case 0: c=(unsigned char)to_wchar_code(cell); break;
00142             // pcre_tables
00143             case 1: element2ctypes(c, to_bool(cell), pcre_tables, ctype_space, cbit_space); break;
00144             case 2: element2ctypes(c, to_bool(cell), pcre_tables, ctype_digit, cbit_digit); break;
00145             case 3: element2ctypes(c, to_bool(cell), pcre_tables, ctype_xdigit); break;
00146             case 4: element2ctypes(c, to_bool(cell), pcre_tables, ctype_letter); break;
00147             case 5: element2ctypes(c, to_bool(cell), pcre_tables, ctype_word, cbit_word); break;
00148             case 6: element2case(c, (unsigned char)to_wchar_code(cell), pcre_tables); break;
00149             case 7:
00150             case 8:
00151                 // charset
00152                 if(tables.toTableSize>MAX_CHARSET_UNI_CODES)
00153                     throw Exception("parser.runtime",
00154                         &afile_spec,
00155                         "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES);
00156
00157                 XMLCh unicode=(XMLCh)to_wchar_code(cell);
00158                 if(!unicode && column==7/*unicode1 column*/)
00159                     unicode=(XMLCh)c;
00160                 if(unicode) {
00161                     if(!tables.fromTable[c])
00162                         tables.fromTable[c]=unicode;
00163                     tables.toTable[tables.toTableSize].intCh=unicode;
00164                     tables.toTable[tables.toTableSize].extCh=(XMLByte)c;
00165                     tables.toTableSize++;
00166                 }
00167                 break;
00168             }
00169         }
00170     };
00171
00172     // sort by the Unicode code point
00173     sort_ToTable();
00174 }
00175
00176 static int sort_cmp_Trans_rec_intCh(const void *a, const void *b) {
00177     return
00178         static_cast<const Charset::Tables::Rec *>(a)->intCh-
00179         static_cast<const Charset::Tables::Rec *>(b)->intCh;
00180 }
00181
00182 void Charset::sort_ToTable() {
00183     _qsort(tables.toTable, tables.toTableSize, sizeof(*tables.toTable),
00184         sort_cmp_Trans_rec_intCh);
00185     //FILE *f=fopen("c:\\temp\\a", "wb");
00186     //fwrite(tables.toTable, tables.toTableSize, sizeof(*tables.toTable), f);
00187     //fclose(f);
00188 }
00189
00190 static XMLByte xlatOneTo(const XMLCh toXlat,
00191              const Charset::Tables& tables,
00192              XMLByte not_found) {
00193     int    lo = 0;
00194     int    hi = tables.toTableSize - 1;
00195     while(lo<=hi) {
00196         // Calc the mid point of the low and high offset.
00197         const unsigned int i = (lo + hi) / 2;
00198
00199         XMLCh cur=tables.toTable[i].intCh;
00200         if(toXlat==cur)
00201             return tables.toTable[i].extCh;
00202         if(toXlat>cur)
00203             lo = i+1;
00204         else
00205             hi = i-1;
00206     }
00207
00208     return not_found;
00209 }
00210
00211 String::C Charset::transcode(const String::C src,
00212     const Charset& source_charset,
00213     const Charset& dest_charset) {
00214     if(!src.length)
00215         return String::C("", 0);
00216
00217     switch((source_charset.isUTF8()?0x10:0x00)|(dest_charset.isUTF8()?0x01:0x00)) {
00218         default: // 0x00
00219             return source_charset.transcodeToCharset(src, dest_charset);
00220         case 0x01:
00221             return source_charset.transcodeToUTF8(src);
00222         case 0x10:
00223             return dest_charset.transcodeFromUTF8(src);
00224         case 0x11:
00225             return src;
00226     }
00227 }
00228
00229 // ---------------------------------------------------------------------------
00230 //  Local static data
00231 //
00232 //  gUTFBytes
00233 //      A list of counts of trailing bytes for each initial byte in the input.
00234 //
00235 //  gUTFOffsets
00236 //      A list of values to offset each result char type, according to how
00237 //      many source bytes when into making it.
00238 //
00239 //  gFirstByteMark
00240 //      A list of values to mask onto the first byte of an encoded sequence,
00241 //      indexed by the number of bytes used to create the sequence.
00242 // ---------------------------------------------------------------------------
00243 static const XMLByte gUTFBytes[0x100] = {
00244         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00245     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00246     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00247     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00248     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00249     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00250     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00251     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00252     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00253     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00254     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00255     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00256     ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
00257     ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
00258     ,   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
00259     ,   3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
00260 };
00261
00262 static const uint gUTFOffsets[6] = {
00263     0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080
00264 };
00265
00266 static const XMLByte gFirstByteMark[7] = {
00267     0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
00268 };
00269
00270 static int transcodeToUTF8(const XMLByte* srcData, size_t& srcLen,
00271                XMLByte *toFill, size_t& toFillLen,
00272                const Charset::Tables& tables) {
00273     const XMLByte* srcPtr=srcData;
00274     const XMLByte* srcEnd=srcData+srcLen;
00275     XMLByte* outPtr=toFill;
00276     XMLByte* outEnd=toFill+toFillLen;
00277
00278     while(srcPtr<srcEnd) {
00279         uint curVal = tables.fromTable[*srcPtr];
00280         if(!curVal) {
00281             // use the replacement character
00282             *outPtr++= '?';
00283             srcPtr++;
00284             continue;
00285         }
00286
00287         // Figure out how many bytes we need
00288         unsigned int encodedBytes;
00289         if(curVal<0x80)
00290             encodedBytes = 1;
00291         else if(curVal<0x800)
00292             encodedBytes = 2;
00293         else if(curVal<0x10000)
00294             encodedBytes = 3;
00295         else if(curVal<0x200000)
00296             encodedBytes = 4;
00297         else if(curVal<0x4000000)
00298             encodedBytes = 5;
00299         else if(curVal<= 0x7FFFFFFF)
00300             encodedBytes = 6;
00301         else {
00302             // use the replacement character
00303             *outPtr++= '?';
00304             srcPtr++;
00305             continue;
00306         }
00307
00308         //  If we cannot fully get this char into the output buffer
00309         if (outPtr + encodedBytes > outEnd)
00310             break;
00311
00312         // We can do it, so update the source index
00313         srcPtr++;
00314
00315         //  And spit out the bytes. We spit them out in reverse order
00316         //  here, so bump up the output pointer and work down as we go.
00317         outPtr+= encodedBytes;
00318         switch(encodedBytes) {
00319         case 6: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
00320             curVal>>= 6;
00321         case 5: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
00322             curVal>>= 6;
00323         case 4: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
00324             curVal>>= 6;
00325         case 3: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
00326             curVal>>= 6;
00327         case 2: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
00328             curVal>>= 6;
00329         case 1: *--outPtr = XMLByte(curVal | gFirstByteMark[encodedBytes]);
00330         }
00331
00332         // Add the encoded bytes back in again to indicate we've eaten them
00333         outPtr+= encodedBytes;
00334     }
00335
00336     // Update the bytes eaten
00337     srcLen = srcPtr - srcData;
00338
00339     // Return the characters read
00340     toFillLen = outPtr - toFill;
00341
00342     //return srcPtr==srcEnd?(int)toFillLen:-1;
00343 /*
00344 xmlCharEncodingInputFunc
00345 Returns :
00346 the number of byte written, or -1 by lack of space, or -2 if the transcoding failed. The value of inlen after return is the
00347 number of octets consumed as the return value is positive, else unpredictiable. The value of outlen after return is the number
00348 of ocetes consumed.
00349 */
00350     return 0;
00351 }
00353 static int transcodeFromUTF8(const XMLByte* srcData, size_t& srcLen,
00354                  XMLByte* toFill, size_t& toFillLen,
00355                  const Charset::Tables& tables) {
00356     const XMLByte* srcPtr=srcData;
00357     const XMLByte* srcEnd=srcData+srcLen;
00358     XMLByte* outPtr=toFill;
00359     XMLByte* outEnd=toFill+toFillLen;
00360
00361     //  We now loop until we either run out of input data, or room to store
00362     while ((srcPtr < srcEnd) && (outPtr < outEnd)) {
00363         // Get the next leading byte out
00364         const XMLByte firstByte =* srcPtr;
00365
00366         // Special-case ASCII, which is a leading byte value of<= 127
00367         if(firstByte<= 127) {
00368             *outPtr++= firstByte;
00369             srcPtr++;
00370             continue;
00371         }
00372
00373         // See how many trailing src bytes this sequence is going to require
00374         const unsigned int trailingBytes = gUTFBytes[firstByte];
00375
00376         //  If there are not enough source bytes to do this one, then we
00377         //  are done. Note that we done>= here because we are implicitly
00378         //  counting the 1 byte we get no matter what.
00379         if(srcPtr+trailingBytes>= srcEnd)
00380             break;
00381
00382         // Looks ok, so lets build up the value
00383         uint tmpVal=0;
00384         switch(trailingBytes) {
00385         case 5: tmpVal+=*srcPtr++; tmpVal<<=6;
00386         case 4: tmpVal+=*srcPtr++; tmpVal<<=6;
00387         case 3: tmpVal+=*srcPtr++; tmpVal<<=6;
00388         case 2: tmpVal+=*srcPtr++; tmpVal<<=6;
00389         case 1: tmpVal+=*srcPtr++; tmpVal<<=6;
00390         case 0: tmpVal+=*srcPtr++;
00391             break;
00392
00393         default:
00394             throw Exception(0,
00395                 0,
00396                 "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes); // never
00397         }
00398         tmpVal-=gUTFOffsets[trailingBytes];
00399
00400         //  If it will fit into a single char, then put it in. Otherwise
00401         //  fail [*encode it as a surrogate pair. If its not valid, use the
00402         //  replacement char.*]
00403         if(!(tmpVal & 0xFFFF0000)) {
00404             if(XMLByte xlat=xlatOneTo(tmpVal, tables, 0))
00405                 *outPtr++=xlat;
00406             else {
00407                 outPtr+=sprintf((char *)outPtr, "&#%u;", tmpVal); // &#decimal;
00408             }
00409         } else {
00410             const XMLByte* recoverPtr=srcPtr-trailingBytes-1;
00411             for(uint i=0; i<=trailingBytes; i++)
00412                 outPtr+=sprintf((char*)outPtr, "%%%02X", *recoverPtr++);
00413         }
00414     }
00415
00416     // Update the bytes eaten
00417     srcLen = srcPtr - srcData;
00418
00419     // Return the characters read
00420     toFillLen = outPtr - toFill;
00421
00422     //return srcPtr==srcEnd?(int)toFillLen:-1;
00423 /*
00424 xmlCharEncodingOutputFunc
00425 Returns :
00426 the number of byte written, or -1 by lack of space, or -2 if the transcoding failed. The value of inlen after return is the
00427 number of octets consumed as the return value is positive, else unpredictiable. The value of outlen after return is the number
00428 of ocetes consumed.
00429 */
00430     return 0;
00431 }
00432
00434 const String::C Charset::transcodeToUTF8(const String::C src) const {
00435     size_t src_length=src.length;
00436     size_t dest_length=src.length*6/*so that surly enough, max utf8 seq len=6*/;
00437 #ifndef NDEBUG
00438     size_t saved_dest_length=dest_length;
00439 #endif
00440     XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
00441
00442     if(::transcodeToUTF8(
00443         (XMLByte *)src.str, src_length,
00444         dest_body, dest_length,
00445         tables)<0)
00446         throw Exception(0,
00447             0,
00448             "Charset::transcodeToUTF8 buffer overflow");
00449
00450     assert(dest_length<=saved_dest_length); dest_body[dest_length]=0; // terminator
00451     return String::C((char*)dest_body, dest_length);
00452 }
00453
00454 static XMLCh change_case_UTF8(const XMLCh src, const Charset::UTF8CaseTable& table) {
00455     int    lo = 0;
00456     int    hi = table.size - 1;
00457     while(lo<=hi) {
00458         // Calc the mid point of the low and high offset.
00459         const unsigned int i = (lo + hi) / 2;
00460
00461         XMLCh cur=table.records[i].from;
00462         if(src==cur)
00463             return table.records[i].to;
00464         if(src>cur)
00465             lo = i+1;
00466         else
00467             hi = i-1;
00468     }
00469
00470     // not found
00471     return src;
00472 }
00473
00474 static void store_UTF8(XMLCh src, XMLByte*& outPtr ) {
00475     if(!src) {
00476         // use the replacement character
00477         *outPtr++= '?';
00478         return;
00479     }
00480
00481     // Figure out how many bytes we need
00482     unsigned int encodedBytes;
00483     if(src<0x80)
00484         encodedBytes = 1;
00485     else if(src<0x800)
00486         encodedBytes = 2;
00487     else if(src<0x10000)
00488         encodedBytes = 3;
00489     else if(src<0x200000)
00490         encodedBytes = 4;
00491     else if(src<0x4000000)
00492         encodedBytes = 5;
00493     else if(src<= 0x7FFFFFFF)
00494         encodedBytes = 6;
00495     else {
00496         // use the replacement character
00497         *outPtr++= '?';
00498         return;
00499     }
00500
00501     //  And spit out the bytes. We spit them out in reverse order
00502     //  here, so bump up the output pointer and work down as we go.
00503     outPtr+= encodedBytes;
00504     switch(encodedBytes) {
00505     case 6: *--outPtr = XMLByte((src | 0x80UL) & 0xBFUL);
00506         src>>= 6;
00507     case 5: *--outPtr = XMLByte((src | 0x80UL) & 0xBFUL);
00508         src>>= 6;
00509     case 4: *--outPtr = XMLByte((src | 0x80UL) & 0xBFUL);
00510         src>>= 6;
00511     case 3: *--outPtr = XMLByte((src | 0x80UL) & 0xBFUL);
00512         src>>= 6;
00513     case 2: *--outPtr = XMLByte((src | 0x80UL) & 0xBFUL);
00514         src>>= 6;
00515     case 1: *--outPtr = XMLByte(src | gFirstByteMark[encodedBytes]);
00516     }
00517
00518     // Add the encoded bytes back in again to indicate we've eaten them
00519     outPtr+= encodedBytes;
00520 }
00521
00522 static void change_case_UTF8(XMLCh src, XMLByte*& outPtr,
00523                         const Charset::UTF8CaseTable& table) {
00524     store_UTF8(change_case_UTF8(src, table), outPtr);
00525 };
00526 void change_case_UTF8(const XMLByte* srcData, size_t srcLen,
00527                       XMLByte* toFill, size_t toFillLen,
00528                       const Charset::UTF8CaseTable& table) {
00529     const XMLByte* srcPtr=srcData;
00530     const XMLByte* srcEnd=srcData+srcLen;
00531     XMLByte* outPtr=toFill;
00532     XMLByte* outEnd=toFill+toFillLen;
00533
00534     //  We now loop until we either run out of input data, or room to store
00535     while ((srcPtr < srcEnd) && (outPtr < outEnd)) {
00536         // Get the next leading byte out
00537         const XMLByte firstByte =* srcPtr;
00538
00539         if(firstByte<= 127) {
00540             change_case_UTF8(firstByte, outPtr, table);
00541             srcPtr++;
00542             continue;
00543         }
00544
00545         // See how many trailing src bytes this sequence is going to require
00546         const unsigned int trailingBytes = gUTFBytes[firstByte];
00547
00548         // Looks ok, so lets build up the value
00549         uint tmpVal=0;
00550         switch(trailingBytes) {
00551         case 5: tmpVal+=*srcPtr++; tmpVal<<=6;
00552         case 4: tmpVal+=*srcPtr++; tmpVal<<=6;
00553         case 3: tmpVal+=*srcPtr++; tmpVal<<=6;
00554         case 2: tmpVal+=*srcPtr++; tmpVal<<=6;
00555         case 1: tmpVal+=*srcPtr++; tmpVal<<=6;
00556         case 0: tmpVal+=*srcPtr++;
00557             break;
00558
00559         default:
00560             throw Exception(0,
00561                 0,
00562                 "change_case_UTF8 error: wrong trailingBytes value(%d)", trailingBytes);
00563         }
00564         tmpVal-=gUTFOffsets[trailingBytes];
00565
00566         //  If it will fit into a single char, then put it in. Otherwise
00567         //  fail [*encode it as a surrogate pair. If its not valid, use the
00568         //  replacement char.*]
00569         if(!(tmpVal & 0xFFFF0000))
00570             change_case_UTF8(tmpVal, outPtr, table);
00571         else
00572             throw Exception(0,
00573                 0,
00574                 "change_case_UTF8 error: too big tmpVal(0x%08X)", tmpVal);
00575     }
00576
00577     if(srcPtr!=outPtr)
00578         throw Exception(0,
00579             0,
00580             "change_case_UTF8 error: end pointers do not match");
00581 }
00582
00583
00584 const String::C Charset::transcodeFromUTF8(const String::C src) const {
00585     size_t src_length=src.length;
00586     size_t dest_length=src.length*6/*so that surly enough, "&#255;" has max ratio */;
00587 #ifndef NDEBUG
00588     size_t saved_dest_length=dest_length;
00589 #endif
00590     XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
00591
00592     if(::transcodeFromUTF8(
00593         (XMLByte *)src.str, src_length,
00594         dest_body, dest_length,
00595         tables)<0)
00596         throw Exception(0,
00597             0,
00598             "Charset::transcodeFromUTF8 buffer overflow");
00599
00600     assert(dest_length<=saved_dest_length); dest_body[dest_length]=0; // terminator
00601     return String::C((char*)dest_body, dest_length);
00602 }
00603
00605 const String::C Charset::transcodeToCharset(const String::C src,
00606                         const Charset& dest_charset) const {
00607     if(&dest_charset==this)
00608         return src;
00609     else {
00610         size_t dest_length=src.length;
00611         XMLByte* dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
00612
00613         XMLByte* output=dest_body;
00614         const XMLByte* input=(XMLByte *)src.str;
00615         while(XMLCh c=*input++) {
00616             XMLCh curVal = tables.fromTable[c];
00617             *output++=curVal?
00618                 xlatOneTo(curVal, dest_charset.tables, '?') // OK
00619                 :'?'; // use the replacement character
00620         }
00621
00622         dest_body[dest_length]=0; // terminator
00623         return String::C((char*)dest_body, dest_length);
00624     }
00625 }
00626
00627 #ifdef XML
00628
00629 static const Charset::Tables* tables[MAX_CHARSETS];
00630
00631 #ifdef PA_PATCHED_LIBXML_BACKWARD
00632
00633 #define declareXml256ioFuncs(i) \
00634     static int xml256CharEncodingInputFunc##i( \
00635         unsigned char *out, int *outlen, \
00636         const unsigned char *in, int *inlen, void*) { \
00637         return transcodeToUTF8( \
00638             in, *(size_t*)inlen, \
00639             out, *(size_t*)outlen, \
00640             *tables[i]); \
00641     } \
00642     static int xml256CharEncodingOutputFunc##i( \
00643         unsigned char *out, int *outlen, \
00644         const unsigned char *in, int *inlen, void*) { \
00645         return transcodeFromUTF8( \
00646             in, *(size_t*)inlen, \
00647             out, *(size_t*)outlen, \
00648             *tables[i]); \
00649     }
00650
00651 #else
00652
00653 #define declareXml256ioFuncs(i) \
00654     static int xml256CharEncodingInputFunc##i( \
00655         unsigned char *out, int *outlen, \
00656         const unsigned char *in, int *inlen) { \
00657         return transcodeToUTF8( \
00658             in, *(size_t*)inlen, \
00659             out, *(size_t*)outlen, \
00660             *tables[i]); \
00661     } \
00662     static int xml256CharEncodingOutputFunc##i( \
00663         unsigned char *out, int *outlen, \
00664         const unsigned char *in, int *inlen) { \
00665         return transcodeFromUTF8( \
00666             in, *(size_t*)inlen, \
00667             out, *(size_t*)outlen, \
00668             *tables[i]); \
00669     }
00670
00671 #endif
00672
00673
00674 declareXml256ioFuncs(0) declareXml256ioFuncs(1)
00675 declareXml256ioFuncs(2) declareXml256ioFuncs(3)
00676 declareXml256ioFuncs(4) declareXml256ioFuncs(5)
00677 declareXml256ioFuncs(6) declareXml256ioFuncs(7)
00678 declareXml256ioFuncs(8) declareXml256ioFuncs(9)
00679
00680 static xmlCharEncodingInputFunc inputFuncs[MAX_CHARSETS]={
00681     xml256CharEncodingInputFunc0,   xml256CharEncodingInputFunc1,
00682     xml256CharEncodingInputFunc2,   xml256CharEncodingInputFunc3,
00683     xml256CharEncodingInputFunc4,   xml256CharEncodingInputFunc5,
00684     xml256CharEncodingInputFunc6,   xml256CharEncodingInputFunc7,
00685     xml256CharEncodingInputFunc8,   xml256CharEncodingInputFunc9
00686 };
00687 static xmlCharEncodingOutputFunc outputFuncs[MAX_CHARSETS]={
00688     xml256CharEncodingOutputFunc0,  xml256CharEncodingOutputFunc1,
00689     xml256CharEncodingOutputFunc2,  xml256CharEncodingOutputFunc3,
00690     xml256CharEncodingOutputFunc4,  xml256CharEncodingOutputFunc5,
00691     xml256CharEncodingOutputFunc6,  xml256CharEncodingOutputFunc7,
00692     xml256CharEncodingOutputFunc8,  xml256CharEncodingOutputFunc9
00693 };
00694 static size_t handlers_count=0;
00695
00696 void Charset::addEncoding(char *name_cstr) {
00697     if(handlers_count==MAX_CHARSETS)
00698         throw Exception(0,
00699             0,
00700             "already allocated %d handlers, no space for new encoding '%s'",
00701                 MAX_CHARSETS, name_cstr);
00702
00703     xmlCharEncodingHandler* handler=new(UseGC) xmlCharEncodingHandler;
00704     {
00705         handler->name=name_cstr;
00706         handler->input=inputFuncs[handlers_count];
00707         handler->output=outputFuncs[handlers_count];
00708         ::tables[handlers_count]=&tables;
00709         handlers_count++;
00710     }
00711
00712     xmlRegisterCharEncodingHandler(handler);
00713
00714 }
00715
00716 void Charset::initTranscoder(const String::Body NAME, const char* name_cstr) {
00717     ftranscoder=xmlFindCharEncodingHandler(name_cstr);
00718     transcoder(NAME); // check right way
00719 }
00720
00721 xmlCharEncodingHandler& Charset::transcoder(const String::Body NAME) {
00722     if(!ftranscoder)
00723         throw Exception("parser.runtime",
00724             new String(NAME, String::L_TAINTED),
00725             "unsupported encoding");
00726     return *ftranscoder;
00727 }
00728
00729 String::C Charset::transcode_cstr(const xmlChar* s) {
00730     if(!s)
00731         return String::C("", 0);
00732
00733     int inlen=strlen((const char*)s);
00734     int outlen=inlen*6/*strlen("&#255;")*/; // max
00735 #ifndef NDEBUG
00736     int saved_outlen=outlen;
00737 #endif
00738     char *out=new(PointerFreeGC) char[outlen+1];
00739
00740     int error;
00741     if(xmlCharEncodingOutputFunc output=transcoder(FNAME).output) {
00742         error=output(
00743             (unsigned char*)out, &outlen,
00744             (const unsigned char*)s, &inlen
00745 #ifdef PA_PATCHED_LIBXML_BACKWARD
00746             ,0
00747 #endif
00748             );
00749     } else {
00750         memcpy(out, s, outlen=inlen);
00751         error=0;
00752     }
00753     if(error<0)
00754         throw Exception(0,
00755             0,
00756             "transcode_cstr failed (%d)", error);
00757
00758     assert(outlen<=saved_outlen); out[outlen]=0;
00759     return String::C(out, outlen);
00760 }
00761 const String& Charset::transcode(const xmlChar* s) {
00762     String::C cstr=transcode_cstr(s);
00763     return *new String(cstr.str, cstr.length, true);
00764 }
00765
00767 xmlChar* Charset::transcode_buf2xchar(const char* buf, size_t buf_size) {
00768     xmlChar* out;
00769     int outlen;
00770     int error;
00771 #ifndef NDEBUG
00772     int saved_outlen;
00773 #endif
00774     if(xmlCharEncodingInputFunc input=transcoder(FNAME).input) {
00775         outlen=buf_size*6/*max UTF8 bytes per char*/;
00776 #ifndef NDEBUG
00777         saved_outlen=outlen;
00778 #endif
00779         out=(xmlChar*)xmlMalloc(outlen+1);
00780         error=input(
00781             out, &outlen,
00782             (const unsigned char*)buf, (int*)&buf_size
00783 #ifdef PA_PATCHED_LIBXML_BACKWARD
00784             ,0
00785 #endif
00786             );
00787     } else {
00788         outlen=buf_size;
00789 #ifndef NDEBUG
00790         saved_outlen=outlen;
00791 #endif
00792         out=(xmlChar*)xmlMalloc(outlen+1);
00793         memcpy(out, buf, outlen);
00794         error=0;
00795     }
00796
00797     if(error<0)
00798         throw Exception(0,
00799             0,
00800             "transcode_buf failed (%d)", error);
00801
00802     assert(outlen<=saved_outlen); out[outlen]=0;
00803     return out;
00804 }
00805 xmlChar* Charset::transcode(const String& s) {
00806     const char* cstr=s.cstr(String::L_UNSPECIFIED);
00807
00808     return transcode_buf2xchar(cstr, strlen(cstr));
00809 }
00810 xmlChar* Charset::transcode(const String::Body s) {
00811     const char* cstr=s.cstr();
00812
00813     return transcode_buf2xchar(cstr, s.length());
00814 }
00815 #endif
00816
00817 String::Body Charset::transcode(const String::Body src,
00818     const Charset& source_transcoder,
00819     const Charset& dest_transcoder) {
00820
00821     const char *src_ptr=src.cstr();
00822     size_t src_size=strlen(src_ptr);
00823
00824     String::C dest=Charset::transcode(String::C(src_ptr, src_size),
00825         source_transcoder,
00826         dest_transcoder);
00827
00828     return String::Body(dest.str, dest.length);
00829 }
00830
00831 String& Charset::transcode(const String& src,
00832     const Charset& source_transcoder,
00833     const Charset& dest_transcoder) {
00834     if(!src.length())
00835         return *new String("", 0, false);
00836
00837     return *new String(transcode((String::Body)src, source_transcoder, dest_transcoder), String::L_CLEAN);
00838 }
00839
00840 void Charset::transcode(ArrayString& src,
00841     const Charset& source_transcoder,
00842     const Charset& dest_transcoder) {
00843     for(size_t i=0; i<src.count(); i++)
00844         src.put(i, &transcode(*src[i], source_transcoder, dest_transcoder));
00845 }
00846
00847 #ifndef DOXYGEN
00848 struct Transcode_pair_info {
00849     const Charset* source_transcoder;
00850     const Charset* dest_transcoder;
00851 };
00852 #endif
00853 static void transcode_pair(const String::Body /*akey*/,
00854              String::Body& avalue,
00855              Transcode_pair_info* info) {
00856     avalue=Charset::transcode(avalue,
00857         *info->source_transcoder,
00858         *info->dest_transcoder);
00859 }
00860 void Charset::transcode(HashStringString& src,
00861     const Charset& source_transcoder,
00862     const Charset& dest_transcoder) {
00863     Transcode_pair_info info={&source_transcoder, &dest_transcoder};
00864     src.for_each_ref(transcode_pair, &info);
00865 }


pa_charset.h File Reference

Parser: Charset connection decl. More...

Include dependency graph for pa_charset.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Namespaces

namespace | PCRE

Compounds

class | Charset
charset holds name & transcode tables registers libxml transcoders. More...

struct | Tables
struct | Rec
struct | UTF8CaseTable
struct | Rec

Defines

#define | MAX_CHARSETS 10
#define | MAX_CHARSET_UNI_CODES 500

Typedefs

typedef unsigned int | XMLCh
typedef unsigned char | XMLByte
typedef Hash< const String::Body,
String::Body > 		HashStringString

Functions

void | change_case_UTF8 (const XMLByte *srcData, size_t srcLen, XMLByte *toFill, size_t toFillLen, const Charset::UTF8CaseTable &table)

Variables

const char *const | IDENT_CHARSET_H = "$Date: 2005/12/16 10:15:12 $"
Charset::UTF8CaseTable UTF8CaseToUpper
Charset::UTF8CaseTable UTF8CaseToLower

Detailed Description

Parser: Charset connection decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_charset.h.

Define Documentation

#define MAX_CHARSETS 10

Definition at line 31 of file pa_charset.h.

Referenced by transcodeToUTF8().

#define MAX_CHARSET_UNI_CODES 500

Definition at line 33 of file pa_charset.h.

Typedef Documentation

typedef unsigned int XMLCh

Definition at line 36 of file pa_charset.h.

typedef unsigned char XMLByte

Definition at line 39 of file pa_charset.h.

Referenced by String::change_case(), cstr2ctypes(), element2case(), and sort_cmp_Trans_rec_intCh().

typedef Hash<const String::Body, String::Body> HashStringString

Definition at line 44 of file pa_charset.h.

Function Documentation

void change_case_UTF8 | ( | const XMLByte * | srcData,
 |  | size_t | srcLen,
 |  | XMLByte * | toFill,
 |  | size_t | toFillLen,
 |  | const Charset::UTF8CaseTable & | table
 | ) |

Definition at line 885 of file pa_charset.C.

Referenced by String::change_case(), and sort_cmp_Trans_rec_intCh().

Variable Documentation

const char* const IDENT_CHARSET_H = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 11 of file pa_charset.h.

Charset::UTF8CaseTable UTF8CaseToUpper

Definition at line 160 of file pa_charset.h.

Charset::UTF8CaseTable UTF8CaseToLower

Definition at line 161 of file pa_charset.h.


pa_charset.h Source File

pa_charset.h

Go to the documentation of this file.
00001
00008 #ifndef PA_CHARSET_H
00009 #define PA_CHARSET_H
00010
00011 static const char * const IDENT_CHARSET_H="$Date: 2005/12/16 10:15:12 $";
00012
00013
00014 #include "pa_exception.h"
00015 #include "pa_common.h"
00016 #include "pa_hash.h"
00017 #include "pa_array.h"
00018
00019 // hiding into namespace so to avoid stupid conflict
00020 namespace PCRE {
00021 #include "pcre.h"
00022 #   include "internal.h"
00023 };
00024
00025 #ifdef XML
00026 #include "libxml/encoding.h"
00027 #endif
00028
00029 // defines
00030
00031 #define MAX_CHARSETS 10
00032
00033 #define MAX_CHARSET_UNI_CODES 500
00034
00035 #   ifndef XMLCh
00036         typedef unsigned int XMLCh;
00037 #   endif
00038 #   ifndef XMLByte
00039         typedef unsigned char XMLByte;
00040 #   endif
00041
00042 // helpers
00043
00044 typedef Hash<const String::Body, String::Body> HashStringString;
00045
00049 class Charset: public PA_Object {
00050 public:
00051
00052     Charset(Request_charsets* charsets, const String::Body ANAME, const String* afile_spec);
00053
00054     const String::Body NAME() const { return FNAME; }
00055     const char* NAME_CSTR() const { return FNAME_CSTR; }
00056
00057     bool isUTF8() const { return fisUTF8; }
00058
00059     static String::C transcode(const String::C src,
00060         const Charset& source_transcoder,
00061         const Charset& dest_transcoder
00062     );
00063
00064     static String& transcode(const String& src,
00065         const Charset& source_transcoder,
00066         const Charset& dest_transcoder);
00067
00068     static String::Body transcode(const String::Body src,
00069         const Charset& source_transcoder,
00070         const Charset& dest_transcoder);
00071
00072     static void transcode(ArrayString& src,
00073         const Charset& source_transcoder,
00074         const Charset& dest_transcoder);
00075
00076     static void transcode(HashStringString& src,
00077         const Charset& source_transcoder,
00078         const Charset& dest_transcoder);
00079
00080 #ifdef XML
00081     xmlCharEncodingHandler& transcoder(const String::Body NAME);
00082 #endif
00083
00084 public:
00085
00086     unsigned char pcre_tables[tables_length];
00087
00088 private:
00089
00090     void load_definition(Request_charsets& charsets, const String& afile_spec);
00091     void sort_ToTable();
00092
00093     const String::C transcodeToUTF8(const String::C src) const;
00094     const String::C transcodeFromUTF8(const String::C src) const;
00095
00096     const String::C transcodeToCharset(const String::C src,
00097         const Charset& dest_transcoder) const;
00098
00099 public:
00100
00101     struct Tables {
00102         struct Rec {
00103             XMLCh intCh;
00104             XMLByte extCh;
00105         };
00106
00107         XMLCh fromTable[0x100];
00108         Rec toTable[MAX_CHARSET_UNI_CODES];
00109         uint toTableSize;
00110     };
00111
00112     struct UTF8CaseTable {
00113         struct Rec {
00114             XMLCh from, to;
00115         };
00116
00117         uint size;
00118         Rec* records;
00119     };
00120
00121 private:
00122
00123     const String::Body FNAME;
00124     char* FNAME_CSTR;
00125     bool fisUTF8;
00126     Tables tables;
00127
00128 #ifdef XML
00129
00130 private:
00131     void addEncoding(char* name_cstr);
00132     void initTranscoder(const String::Body name, const char* name_cstr);
00133
00134 public:
00136     String::C transcode_cstr(const xmlChar* s);
00138     const String& transcode(const xmlChar* s);
00139
00143     xmlChar* transcode_buf2xchar(const char* buf, size_t buf_size);
00145     xmlChar* transcode(const String& s);
00147     xmlChar* transcode(const String::Body s);
00148
00149 private:
00150
00151     xmlCharEncodingHandler* ftranscoder;
00152
00153 #endif
00154
00155 };
00156
00157
00158 // externs
00159
00160 extern Charset::UTF8CaseTable UTF8CaseToUpper;
00161 extern Charset::UTF8CaseTable UTF8CaseToLower;
00162 void change_case_UTF8(const XMLByte* srcData, size_t srcLen,
00163                       XMLByte* toFill, size_t toFillLen,
00164                       const Charset::UTF8CaseTable& table);
00165
00166 #endif


pa_charsets.C File Reference

Parser: sql driver manager implementation. More...

Include dependency graph for pa_charsets.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | CHARSET_UTF8_NAME "UTF-8"

Functions

Charset | UTF8_charset (0,*new String(CHARSET_UTF8_NAME), 0)

Variables

const char *const | IDENT_CHARSETS_C = "$Date: 2005/08/09 08:14:51 $"
Charsets charsets

Detailed Description

Parser: sql driver manager implementation.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_charsets.C.

Define Documentation

#define CHARSET_UTF8_NAME "UTF-8"

Definition at line 14 of file pa_charsets.C.

Function Documentation

Charset UTF8_charset | ( | 0 | ,
 |  | *new String(CHARSET_UTF8_NAME) | ,
 |  | 0 |
 | ) |

Variable Documentation

const char* const IDENT_CHARSETS_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 8 of file pa_charsets.C.

Charsets charsets

Definition at line 20 of file pa_charsets.C.

Referenced by text_value_to_string().


pa_charsets.C Source File

pa_charsets.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_CHARSETS_C="$Date: 2005/08/09 08:14:51 $";
00009
00010 #include "pa_charsets.h"
00011
00012 // defines for globals
00013
00014 #define CHARSET_UTF8_NAME "UTF-8"
00015
00016 // globals
00017
00018 Charset UTF8_charset(0, *new String(CHARSET_UTF8_NAME), 0/*no file=system*/);
00019
00020 Charsets charsets;
00021
00022 // methods
00023
00024 Charsets::Charsets() {
00025     put(UTF8_charset.NAME(), &UTF8_charset);
00026 }
00027
00028 Charset& Charsets::get(const String::Body ANAME) {
00029     if(Charset* result=Hash<key_type, value_type>::get(ANAME))
00030         return *result;
00031     else
00032         throw Exception("parser.runtime",
00033             new String(ANAME, String::L_TAINTED),
00034             "unknown charset");
00035 }
00036
00037 void Charsets::load_charset(Request_charsets& charsets, const String::Body ANAME, const String& afile_spec) {
00038     //we know that charset?
00039     if(Hash<key_type, value_type>::get(ANAME))
00040         return; // don't load it then
00041
00042     put(ANAME, new Charset(&charsets, ANAME, &afile_spec));
00043 }


pa_charsets.h File Reference

Parser: sql driver manager decl. More...

Include dependency graph for pa_charsets.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Charsets
convention: use UPPERCASE keys. More...

Variables

const char *const | IDENT_CHARSETS_H = "$Date: 2005/08/09 08:14:49 $"

Detailed Description

Parser: sql driver manager decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

global sql driver manager, must be thread-safe

Definition in file pa_charsets.h.

Variable Documentation

const char* const IDENT_CHARSETS_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 14 of file pa_charsets.h.

Charset UTF8_charset

globals.

Definition at line 31 of file pa_charsets.h.

Charsets charsets

globals.

Definition at line 32 of file pa_charsets.h.

Referenced by text_value_to_string().


pa_charsets.h Source File

pa_charsets.h

Go to the documentation of this file.
00001
00011 #ifndef PA_CHARSETS_H
00012 #define PA_CHARSETS_H
00013
00014 static const char * const IDENT_CHARSETS_H="$Date: 2005/08/09 08:14:49 $";
00015
00016 #include "pa_hash.h"
00017 #include "pa_charset.h"
00018
00020 class Charsets: public Hash<const String::Body, Charset*> {
00021 public:
00022
00023     Charsets();
00024
00025     Charset& get(const String::Body ANAME);
00026
00027     void load_charset(Request_charsets& charsets, const String::Body ANAME, const String& afile_spec);
00028 };
00029
00031 extern Charset UTF8_charset;
00032 extern Charsets charsets;
00034
00035 #endif


pa_common.C File Reference

Parser: commonly functions. More...

Include dependency graph for pa_common.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | _O_TEXT 0
#define | _O_BINARY 0
#define | FILE_STATUS_NAME "status"

Functions

const String | file_status_name (FILE_STATUS_NAME)
void | fix_line_breaks (char *str, size_t &length)
under WIN32 "t" mode fixes DOS chars OK, can't say that about other systems/ line break styles. More...

char * | file_read_text (Request_charsets &charsets, const String &file_spec, bool fail_on_read_problem, HashStringValue *params)
read specified text file using if fail_on_read_problem is true[default] throws an exception. More...

int | pa_get_valid_file_options_count (HashStringValue &options)
these options were handled but not checked elsewhere, now check them. More...

void | file_read_action (struct stat &finfo, int f, const String &file_spec, const char *, bool as_text, void *context)
File_read_result | file_read (Request_charsets &charsets, const String &file_spec, bool as_text, HashStringValue *params, bool fail_on_read_problem, char *buf, size_t offset, size_t count)
read specified file using if fail_on_read_problem is true[default] throws an exception. More...

bool | file_read_action_under_lock (const String &file_spec, const char *action_name, File_read_action action, void *context, bool as_text, bool fail_on_read_problem)
shared-lock specified file, do actions under lock. More...

void | create_dir_for_file (const String &file_spec)
bool | file_write_action_under_lock (const String &file_spec, const char *action_name, File_write_action action, void *context, bool as_text, bool do_append, bool do_block, bool fail_on_lock_problem)
lock specified file exclusively, do actions under lock. More...

void | file_write_action (int f, void *context)
void | file_write (const String &file_spec, const char *data, size_t size, bool as_text, bool do_append)
write data to specified file, throws an exception in case of problems. More...

void | rmdir (const String &file_spec, size_t pos_after)
bool | file_delete (const String &file_spec, bool fail_on_problem)
delete specified file throws an exception in case of problems. More...

void | file_move (const String &old_spec, const String &new_spec)
move specified file throws an exception in case of problems. More...

bool | entry_exists (const char *fname, struct stat *afinfo)
bool | entry_exists (const String &file_spec)
bool | entry_readable (const String &file_spec, bool need_dir)
bool | file_exist (const String &file_spec)
bool | dir_exists (const String &file_spec)
const String * | file_exist (const String &path, const String &name)
bool | file_executable (const String &file_spec)
bool | file_stat (const String &file_spec, size_t &rsize, time_t &ratime, time_t &rmtime, time_t &rctime, bool fail_on_read_problem)
char * | getrow (char **row_ref, char delim)
scans for delim[default
] in *row_ref,. More...

char * | lsplit (char *string, char delim)
char * | lsplit (char **string_ref, char delim)
char * | rsplit (char *string, char delim)
const char * | format (double value, char *fmt)
size_t | stdout_write (const void *buf, size_t size)
char * | unescape_chars (const char *cp, int len)
void | back_slashes_to_slashes (char *s)
bool | StrEqNc (const char *s1, const char *s2, bool strict)
bool | isLeap (int year)
int | getMonthDays (int year, int month)
void | remove_crlf (char *start, char *end)
int | __vsnprintf (char *b, size_t s, const char *f, va_list l)
must be last in this file. More...

int | __snprintf (char *b, size_t s, const char *f,...)
size_t | g_mime_utils_base64_encode_step (const unsigned char *in, size_t inlen, unsigned char *out, int *state, int *save)
g_mime_utils_base64_encode_step: @in: input stream @inlen: length of the input @out: output string @state: holds the number of bits that are stored in. More...

size_t | g_mime_utils_base64_encode_close (const unsigned char *in, size_t inlen, unsigned char *out, int *state, int *save)
g_mime_utils_base64_encode_close: @in: input stream @inlen: length of the input @out: output string @state: holds the number of bits that are stored in. More...

size_t | g_mime_utils_base64_decode_step (const unsigned char *in, size_t inlen, unsigned char *out, int *state, int *save)
g_mime_utils_base64_decode_step: @in: input stream @inlen: max length of data to decode @out: output stream @state: holds the number of bits that are stored in. More...

char * | pa_base64_encode (const char *in, size_t in_size)
void | pa_base64_decode (const char *in, size_t in_size, char *&result, size_t &result_size)

Variables

const char *const | IDENT_COMMON_C = "$Date: 2005/12/09 07:18:07 $"
char * | base64_alphabet
unsigned char | gmime_base64_rank [256]

Detailed Description

Parser: commonly functions.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

BASE64 part Authors: Michael Zucchi <notzed@ximian.com> Jeffrey Stedfast <fejj@ximian.com>

Copyright 2000-2004 Ximian, Inc. (www.ximian.com)

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.

Definition in file pa_common.C.

Define Documentation

#define _O_TEXT 0

Definition at line 41 of file pa_common.C.

#define _O_BINARY 0

Definition at line 44 of file pa_common.C.

Referenced by main().

#define FILE_STATUS_NAME "status"

Definition at line 59 of file pa_common.C.

Function Documentation

const String file_status_name ( FILE_STATUS_NAME )

void fix_line_breaks | ( | char * | str,
 |  | size_t & | length
 | ) |

under WIN32 "t" mode fixes DOS chars OK, can't say that about other systems/ line break styles.

Definition at line 67 of file pa_common.C.

References str.

Referenced by VForm::AppendFormEntry(), file_read(), and VFile::set().

char* file_read_text | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | bool | fail_on_read_problem = true,
 |  | HashStringValue * | options = 0
 | ) |

read specified text file using if fail_on_read_problem is true[default] throws an exception.

WARNING: charset is used for http header case conversion, it's not a charset of input file!

Returns:
true if read OK

Definition at line 93 of file pa_common.C.

References file, file_read(), File_read_result::str, and File_read_result::success.

Referenced by _load(), and Request::use_file().

int pa_get_valid_file_options_count ( HashStringValue & options )

these options were handled but not checked elsewhere, now check them.

Definition at line 103 of file pa_common.C.

References Hash< const String::Body, Value * >::get(), PA_COLUMN_ENCLOSER_NAME, PA_COLUMN_SEPARATOR_NAME, PA_SQL_LIMIT_NAME, PA_SQL_OFFSET_NAME, and result.

Referenced by file_read(), and pa_internal_file_read_http().

void file_read_action | ( | struct stat & | finfo,
 |  | int | f,
 |  | const String & | file_spec,
 |  | const char * | ,
 |  | bool | as_text,
 |  | void * | context
 | ) | [static]

Definition at line 123 of file pa_common.C.

References assert, context, SEEK_SET, and ssize_t.

Referenced by file_read().

File_read_result file_read | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | bool | as_text,
 |  | HashStringValue * | options = 0,
 |  | bool | fail_on_read_problem = true,
 |  | char * | buf = 0,
 |  | size_t | offset = 0,
 |  | size_t | size = 0
 | ) |

read specified file using if fail_on_read_problem is true[default] throws an exception.

WARNING: charset is used for http header case conversion, it's not a charset of input file!

Returns:
true if read OK

Definition at line 154 of file pa_common.C.

References Hash< const String::Body, Value * >::count(), file_read_action(), file_read_action_under_lock(), fix_line_breaks(), File_read_result::headers, File_read_result::length, offset, pa_get_valid_file_options_count(), pa_internal_file_read_http(), result, String::starts_with(), File_read_result::str, and File_read_result::success.

Referenced by _load(), cache_get(), file_read_text(), output_pieces(), and VForm::refill_fields_and_tables().

bool file_read_action_under_lock | ( | const String & | file_spec,
 |  | const char * | action_name,
 |  | File_read_action | action,
 |  | void * | context,
 |  | bool | as_text = false,
 |  | bool | fail_on_read_problem = true
 | ) |

shared-lock specified file, do actions under lock.

if fail_on_read_problem is true[default] throws an exception

Returns:
true if read OK

Definition at line 219 of file pa_common.C.

References context, String::cstr(), File_read_action, String::L_FILE_SPEC, pa_lock_shared_blocking(), pa_unlock(), and rethrow.

Referenced by _measure(), and file_read().

void create_dir_for_file ( const String & file_spec )

Definition at line 274 of file pa_common.C.

References String::cstr(), String::L_FILE_SPEC, String::mid(), String::pos(), and STRING_NOT_FOUND.

Referenced by file_move(), file_write_action_under_lock(), and VHashfile::open().

bool file_write_action_under_lock | ( | const String & | file_spec,
 |  | const char * | action_name,
 |  | File_write_action | action,
 |  | void * | context,
 |  | bool | as_text = false,
 |  | bool | do_append = false,
 |  | bool | do_block = true,
 |  | bool | fail_on_lock_problem = true
 | ) |

lock specified file exclusively, do actions under lock.

throws an exception in case of problems

if block=false does non-blocking lock

Returns:
true if locked OK, or false if non-blocking locking failed

Definition at line 283 of file pa_common.C.

References access, context, create_dir_for_file(), String::cstr(), File_write_action, String::L_FILE_SPEC, pa_lock_exclusive_blocking(), pa_lock_exclusive_nonblocking(), pa_unlock(), and rethrow.

Referenced by _lock(), file_write(), and locked_process_and_cache_put().

void file_write_action | ( | int | f,
 |  | void * | context
 | ) | [static]

Definition at line 340 of file pa_common.C.

References context.

Referenced by file_write().

void file_write | ( | const String & | file_spec,
 |  | const char * | data,
 |  | size_t | size,
 |  | bool | as_text,
 |  | bool | do_append
 | ) |

write data to specified file, throws an exception in case of problems.

Definition at line 350 of file pa_common.C.

References data, file_write_action(), file_write_action_under_lock(), and size.

Referenced by _save(), and VFile::save().

void rmdir | ( | const String & | file_spec,
 |  | size_t | pos_after
 | ) | [static]

Definition at line 364 of file pa_common.C.

References String::cstr(), String::L_FILE_SPEC, String::mid(), String::pos(), and STRING_NOT_FOUND.

Referenced by file_delete(), and file_move().

bool file_delete | ( | const String & | file_spec,
 |  | bool | fail_on_problem
 | ) |

delete specified file throws an exception in case of problems.

Definition at line 371 of file pa_common.C.

References String::cstr(), String::L_FILE_SPEC, and rmdir().

Referenced by _delete(), cache_delete(), and delete_file().

void file_move | ( | const String & | old_spec,
 |  | const String & | new_spec
 | ) |

move specified file throws an exception in case of problems.

Definition at line 385 of file pa_common.C.

References create_dir_for_file(), String::cstr(), String::L_FILE_SPEC, and rmdir().

Referenced by _move().

bool entry_exists | ( | const char * | fname,
 |  | struct stat * | afinfo
 | ) |

Definition at line 401 of file pa_common.C.

References result.

bool entry_exists ( const String & file_spec )

Definition at line 409 of file pa_common.C.

References String::cstr(), and String::L_FILE_SPEC.

Referenced by entry_readable(), VHashfile::open(), real_parser_handler(), and Request::use_file().

bool entry_readable | ( | const String & | file_spec,
 |  | bool | need_dir
 | ) | [static]

Definition at line 414 of file pa_common.C.

References access, String::cstrm(), entry_exists(), String::L_FILE_SPEC, R_OK, and size.

Referenced by dir_exists(), and file_exist().

bool file_exist ( const String & file_spec )

Definition at line 433 of file pa_common.C.

References entry_readable().

bool dir_exists ( const String & file_spec )

Definition at line 436 of file pa_common.C.

References entry_readable().

Referenced by Request::execute().

const String* file_exist | ( | const String & | path,
 |  | const String & | name
 | ) |

Definition at line 439 of file pa_common.C.

References result.

Referenced by _find(), Request::execute(), and Request::use_file().

bool file_executable ( const String & file_spec )

Definition at line 445 of file pa_common.C.

References access, String::cstr(), and String::L_FILE_SPEC.

Referenced by sendmail().

bool file_stat | ( | const String & | file_spec,
 |  | size_t & | rsize,
 |  | time_t & | ratime,
 |  | time_t & | rmtime,
 |  | time_t & | rctime,
 |  | bool | fail_on_read_problem
 | ) |

Definition at line 449 of file pa_common.C.

References String::cstr(), and String::L_FILE_SPEC.

Referenced by _stat(), and Request::output_result().

char* getrow | ( | char ** | row_ref,
 |  | char | delim = '\n'
 | ) |

scans for delim[default
] in *row_ref,.

Returns:
piece of line before it or end of string, if no delim found assigns *row_ref to point right after delimiter if there were one or to zero if no delim were found.

Definition at line 472 of file pa_common.C.

References delim, and result.

Referenced by skip_empty_and_comment_lines().

char* lsplit | ( | char * | string,
 |  | char | delim
 | ) |

Definition at line 484 of file pa_common.C.

References delim, and v.

char* lsplit | ( | char ** | string_ref,
 |  | char | delim
 | ) |

Definition at line 495 of file pa_common.C.

References delim, and result.

Referenced by _load(), CreateHiddenConsoleProcess(), cstr_to_time_t(), extractEmails(), SQL_Driver_manager::get_connection(), lsplit(), and pa_internal_file_read_http().

char* rsplit | ( | char * | string,
 |  | char | delim
 | ) |

Definition at line 502 of file pa_common.C.

References delim, and v.

Referenced by CreateHiddenConsoleProcess(), extractEmails(), log(), Request::output_result(), real_parser_handler(), Request::relative(), sendmail(), and VFile::set().

const char* format | ( | double | value,
 |  | char * | fmt
 | ) |

Todo:
less stupid type detection

Definition at line 514 of file pa_common.C.

References MAX_NUMBER, pa_strdup(), size, snprintf, uint, and value.

Referenced by _eval(), _string_format(), and pa_internal_file_read_http().

size_t stdout_write | ( | const void * | buf,
 |  | size_t | size
 | ) |

Definition at line 532 of file pa_common.C.

References size.

char* unescape_chars | ( | const char * | cp,
 |  | int | len
 | ) |

Definition at line 549 of file pa_common.C.

References uchar, and uint.

Referenced by VCookie::fill_fields(), and VForm::ParseFormInput().

void back_slashes_to_slashes ( char * s )

Definition at line 588 of file pa_common.C.

Referenced by full_file_spec(), and real_parser_handler().

bool StrEqNc | ( | const char * | s1,
 |  | const char * | s2,
 |  | bool | strict
 | ) |

Definition at line 604 of file pa_common.C.

Referenced by MForm::configure_admin(), and VForm::refill_fields_and_tables().

bool isLeap ( int year ) [static]

Definition at line 623 of file pa_common.C.

Referenced by getMonthDays().

int getMonthDays | ( | int | year,
 |  | int | month
 | ) |

Definition at line 629 of file pa_common.C.

References isLeap().

Referenced by fill_month_days().

void remove_crlf | ( | char * | start,
 |  | char * | end
 | ) |

Definition at line 647 of file pa_common.C.

References p.

Referenced by die_or_abort(), log(), and SAPI::log().

int __vsnprintf | ( | char * | b,
 |  | size_t | s,
 |  | const char * | f,
 |  | va_list | l
 | ) |

must be last in this file.

Definition at line 658 of file pa_common.C.

References vsnprintf.

Referenced by __snprintf().

int __snprintf | ( | char * | b,
 |  | size_t | s,
 |  | const char * | f,
 |  | ... |
 | ) |

Definition at line 703 of file pa_common.C.

References __vsnprintf().

size_t g_mime_utils_base64_encode_step | ( | const unsigned char * | in,
 |  | size_t | inlen,
 |  | unsigned char * | out,
 |  | int * | state,
 |  | int * | save
 | ) | [static]

g_mime_utils_base64_encode_step: @in: input stream @inlen: length of the input @out: output string @state: holds the number of bits that are stored in.

@save @save: leftover bits that have not yet been encoded

Base64 encodes a chunk of data. Performs an 'encode step', only encodes blocks of 3 characters to the output at a time, saves left-over state in state and save (initialise to 0 on first invocation).

Returns the number of bytes encoded.

Definition at line 752 of file pa_common.C.

References base64_alphabet.

Referenced by g_mime_utils_base64_encode_close().

size_t g_mime_utils_base64_encode_close | ( | const unsigned char * | in,
 |  | size_t | inlen,
 |  | unsigned char * | out,
 |  | int * | state,
 |  | int * | save
 | ) | [static]

g_mime_utils_base64_encode_close: @in: input stream @inlen: length of the input @out: output string @state: holds the number of bits that are stored in.

@save @save: leftover bits that have not yet been encoded

Base64 encodes the input stream to the output stream. Call this when finished encoding data with g_mime_utils_base64_encode_step to flush off the last little bit.

Returns the number of bytes encoded.

Definition at line 838 of file pa_common.C.

References base64_alphabet, and g_mime_utils_base64_encode_step().

Referenced by pa_base64_encode().

size_t g_mime_utils_base64_decode_step | ( | const unsigned char * | in,
 |  | size_t | inlen,
 |  | unsigned char * | out,
 |  | int * | state,
 |  | int * | save
 | ) |

g_mime_utils_base64_decode_step: @in: input stream @inlen: max length of data to decode @out: output stream @state: holds the number of bits that are stored in.

@save @save: leftover bits that have not yet been decoded

Decodes a chunk of base64 encoded data.

Returns the number of bytes decoded (which have been dumped in @out).

Definition at line 903 of file pa_common.C.

References gmime_base64_rank.

Referenced by pa_base64_decode().

char* pa_base64_encode | ( | const char * | in,
 |  | size_t | in_size
 | ) |

Definition at line 953 of file pa_common.C.

References assert, g_mime_utils_base64_encode_close(), and result.

Referenced by _base64(), and basic_authorization_field().

void pa_base64_decode | ( | const char * | in,
 |  | size_t | in_size,
 |  | char *& | result,
 |  | size_t & | result_size
 | ) |

Definition at line 969 of file pa_common.C.

References assert, g_mime_utils_base64_decode_step(), and result.

Referenced by _base64().

Variable Documentation

const char* const IDENT_COMMON_C = "$Date: 2005/12/09 07:18:07 $" [static]

Definition at line 29 of file pa_common.C.

char* base64_alphabet [static]

Initial value:

    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Definition at line 733 of file pa_common.C.

Referenced by g_mime_utils_base64_encode_close(), and g_mime_utils_base64_encode_step().

unsigned char gmime_base64_rank[256] [static]

Initial value:

 {
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
     52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
    255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
    255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
}

Definition at line 871 of file pa_common.C.

Referenced by g_mime_utils_base64_decode_step().


pa_common.C Source File

pa_common.C

Go to the documentation of this file.
00001
00029 static const char * const IDENT_COMMON_C="$Date: 2005/12/09 07:18:07 $";
00030
00031 #include "pa_common.h"
00032 #include "pa_exception.h"
00033 #include "pa_hash.h"
00034 #include "pa_globals.h"
00035 #include "pa_charsets.h"
00036 #include "pa_http.h"
00037
00038 // some maybe-undefined constants
00039
00040 #ifndef _O_TEXT
00041 #   define _O_TEXT 0
00042 #endif
00043 #ifndef _O_BINARY
00044 #   define _O_BINARY 0
00045 #endif
00046
00047 #ifdef HAVE_FTRUNCATE
00048 #   define PA_O_TRUNC 0
00049 #else
00050 #   ifdef _O_TRUNC
00051 #       define PA_O_TRUNC _O_TRUNC
00052 #   else
00053 #       error you must have either ftruncate function or _O_TRUNC bit declared
00054 #   endif
00055 #endif
00056
00057 // defines for globals
00058
00059 #define FILE_STATUS_NAME  "status"
00060
00061 // globals
00062
00063 const String file_status_name(FILE_STATUS_NAME);
00064
00065 // functions
00066
00067 void fix_line_breaks(char *str, size_t& length) {
00068     //_asm int 3;
00069     const char* const eob=str+length;
00070     char* dest=str;
00071     // fix DOS: \r\n -> \n
00072     // fix Macintosh: \r -> \n
00073     char* bol=str;
00074     while(char* eol=(char*)memchr(bol, '\r', eob -bol)) {
00075         size_t len=eol-bol;
00076         if(dest!=bol)
00077             memcpy(dest, bol, len);
00078         dest+=len;
00079         *dest++='\n';
00080
00081         if(&eol[1]<eob && eol[1]=='\n') { // \r, \n = DOS
00082             bol=eol+2;
00083             length--;
00084         } else // \r, not \n = Macintosh
00085             bol=eol+1;
00086     }
00087     // last piece without \r
00088     if(dest!=bol)
00089         memcpy(dest, bol, eob-bol);
00090     str[length]=0; // terminating
00091 }
00092
00093 char* file_read_text(Request_charsets& charsets,
00094              const String& file_spec,
00095              bool fail_on_read_problem,
00096              HashStringValue* params/*, HashStringValue* * out_fields*/) {
00097     File_read_result file=
00098         file_read(charsets, file_spec, true, params, fail_on_read_problem);
00099     return file.success?file.str:0;
00100 }
00101
00103 int pa_get_valid_file_options_count(HashStringValue& options)
00104 {
00105     int result=0;
00106     if(options.get(PA_SQL_LIMIT_NAME))
00107         result++;
00108     if(options.get(PA_SQL_OFFSET_NAME))
00109         result++;
00110     if(options.get(PA_COLUMN_SEPARATOR_NAME))
00111         result++;
00112     if(options.get(PA_COLUMN_ENCLOSER_NAME))
00113         result++;
00114     return result;
00115 }
00116
00117 #ifndef DOXYGEN
00118 struct File_read_action_info {
00119     char **data; size_t *data_size;
00120     char* buf; size_t offset; size_t count;
00121 };
00122 #endif
00123 static void file_read_action(
00124                  struct stat& finfo,
00125                  int f,
00126                  const String& file_spec, const char* /*fname*/, bool as_text,
00127                  void *context) {
00128     File_read_action_info& info=*static_cast<File_read_action_info *>(context);
00129     size_t to_read_size=info.count;
00130     if(!to_read_size)
00131         to_read_size=(size_t)finfo.st_size;
00132     assert( !(info.buf && as_text) );
00133     if(to_read_size) {
00134         if(info.offset)
00135             lseek(f, info.offset, SEEK_SET);
00136         *info.data=info.buf
00137             ? info.buf
00138             : new(PointerFreeGC) char[to_read_size+(as_text?1:0)];
00139         *info.data_size=(size_t)read(f, *info.data, to_read_size);
00140
00141         if(ssize_t(*info.data_size)<0 || *info.data_size>to_read_size)
00142             throw Exception(0,
00143                 &file_spec,
00144                 "read failed: actually read %u bytes count not in [0..%u] valid range",
00145                     *info.data_size, to_read_size);
00146     } else { // empty file
00147         // for both, text and binary: for text we need that terminator, for binary we need nonzero pointer to be able to save such files
00148         *info.data=new(PointerFreeGC) char[1];
00149         *(char*)(*info.data)=0;
00150         *info.data_size=0;
00151         return;
00152     }
00153 }
00154 File_read_result file_read(Request_charsets& charsets, const String& file_spec,
00155                bool as_text, HashStringValue *params,
00156                bool fail_on_read_problem,
00157                char* buf, size_t offset, size_t count) {
00158     File_read_result result={false, 0, 0, 0};
00159     if(file_spec.starts_with("http://")) {
00160         if(offset || count)
00161             throw Exception("parser.runtime",
00162                 0,
00163                 "offset and load options are not supported for HTTP:// file load");
00164
00165         // fail on read problem
00166         File_read_http_result http=pa_internal_file_read_http(charsets, file_spec, as_text, params);
00167         result.success=true;
00168         result.str=http.str;
00169         result.length=http.length;
00170         result.headers=http.headers;
00171     } else {
00172         if(params) {
00173             int valid_options=pa_get_valid_file_options_count(*params);
00174             if(valid_options!=params->count())
00175                 throw Exception("parser.runtime",
00176                     0,
00177                     "invalid option passed");
00178         }
00179
00180         File_read_action_info info={&result.str, &result.length,
00181             buf, offset, count};
00182         result.success=file_read_action_under_lock(file_spec,
00183             "read", file_read_action, &info,
00184             as_text, fail_on_read_problem);
00185     }
00186
00187     if(result.success && as_text) {
00188         // UTF-8 signature: EF BB BF
00189         if(result.length>=3) {
00190             char *in=(char *)result.str;
00191             if(strncmp(in, "\xEF\xBB\xBF", 3)==0) {
00192                 result.str=in+3; result.length-=3;// skip prefix
00193             }
00194         }
00195
00196         fix_line_breaks((char *)(result.str), result.length);
00197     }
00198
00199     return result;
00200 }
00201
00202 #ifdef PA_SAFE_MODE
00203 void check_safe_mode(struct stat finfo, const String& file_spec, const char* fname) {
00204     if(finfo.st_uid/*foreign?*/!=geteuid()
00205         && finfo.st_gid/*foreign?*/!=getegid())
00206         throw Exception("parser.runtime",
00207             &file_spec,
00208             "parser is in safe mode: "
00209             "reading files of foreign group and user disabled "
00210             "[recompile parser with --disable-safe-mode configure option], "
00211             "actual filename '%s', "
00212             "fuid(%d)!=euid(%d) or fgid(%d)!=egid(%d)",
00213                 fname,
00214                 finfo.st_uid, geteuid(),
00215                 finfo.st_gid, getegid());
00216 }
00217 #endif
00218
00219 bool file_read_action_under_lock(const String& file_spec,
00220                 const char* action_name, File_read_action action, void *context,
00221                 bool as_text,
00222                 bool fail_on_read_problem) {
00223     const char* fname=file_spec.cstr(String::L_FILE_SPEC);
00224     int f;
00225
00226     // first open, next stat:
00227     // directory update of NTFS hard links performed on open.
00228     // ex:
00229     //   a.html:^test[] and b.html hardlink to a.html
00230     //   user inserts ! before ^test in a.html
00231     //   directory entry of b.html in NTFS not updated at once,
00232     //   they delay update till open, so we would receive "!^test[" string
00233     //   if would do stat, next open.
00234     // later: it seems, even this does not help sometimes
00235     if((f=open(fname, O_RDONLY|(as_text?_O_TEXT:_O_BINARY)))>=0) {
00236         try {
00237             if(pa_lock_shared_blocking(f)!=0)
00238                 throw Exception("file.lock",
00239                         &file_spec,
00240                         "shared lock failed: %s (%d), actual filename '%s'",
00241                             strerror(errno), errno, fname);
00242
00243             struct stat finfo;
00244             if(stat(fname, &finfo)!=0)
00245                 throw Exception("file.missing", // hardly possible: we just opened it OK
00246                     &file_spec,
00247                     "stat failed: %s (%d), actual filename '%s'",
00248                         strerror(errno), errno, fname);
00249
00250 #ifdef PA_SAFE_MODE
00251             check_safe_mode(finfo, file_spec, fname);
00252 #endif
00253
00254             action(finfo, f, file_spec, fname, as_text, context);
00255         } catch(...) {
00256             pa_unlock(f);close(f);
00257             if(fail_on_read_problem)
00258                 rethrow;
00259             return false;
00260         }
00261
00262         pa_unlock(f);close(f);
00263         return true;
00264     } else {
00265         if(fail_on_read_problem)
00266             throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0,
00267                 &file_spec,
00268                 "%s failed: %s (%d), actual filename '%s'",
00269                     action_name, strerror(errno), errno, fname);
00270         return false;
00271     }
00272 }
00273
00274 void create_dir_for_file(const String& file_spec) {
00275     size_t pos_after=1;
00276     size_t pos_before;
00277     while((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND) {
00278         mkdir(file_spec.mid(0, pos_before).cstr(String::L_FILE_SPEC), 0775);
00279         pos_after=pos_before+1;
00280     }
00281 }
00282
00283 bool file_write_action_under_lock(
00284                 const String& file_spec,
00285                 const char* action_name, File_write_action action, void *context,
00286                 bool as_text,
00287                 bool do_append,
00288                 bool do_block,
00289                 bool fail_on_lock_problem) {
00290     const char* fname=file_spec.cstr(String::L_FILE_SPEC);
00291     int f;
00292     if(access(fname, W_OK)!=0) // no
00293         create_dir_for_file(file_spec);
00294
00295     if((f=open(fname,
00296         O_CREAT|O_RDWR
00297         |(as_text?_O_TEXT:_O_BINARY)
00298         |(do_append?O_APPEND:PA_O_TRUNC), 0664))>=0) {
00299         if((do_block?pa_lock_exclusive_blocking(f):pa_lock_exclusive_nonblocking(f))!=0) {
00300             Exception e("file.lock",
00301                 &file_spec,
00302                 "shared lock failed: %s (%d), actual filename '%s'",
00303                 strerror(errno), errno, fname);
00304             close(f);
00305             if(fail_on_lock_problem)
00306                 throw e;
00307             return false;
00308         }
00309
00310         try {
00311             action(f, context);
00312         } catch(...) {
00313 #ifdef HAVE_FTRUNCATE
00314             if(!do_append)
00315                 ftruncate(f, lseek(f, 0, SEEK_CUR)); // one can not use O_TRUNC, read lower
00316 #endif
00317             pa_unlock(f);close(f);
00318             rethrow;
00319         }
00320
00321 #ifdef HAVE_FTRUNCATE
00322         if(!do_append)
00323             ftruncate(f, lseek(f, 0, SEEK_CUR)); // O_TRUNC truncates even exclusevely write-locked file [thanks to Igor Milyakov <virtan@rotabanner.com> for discovering]
00324 #endif
00325         pa_unlock(f);close(f);
00326         return true;
00327     } else
00328         throw Exception(errno==EACCES?"file.access":0,
00329             &file_spec,
00330             "%s failed: %s (%d), actual filename '%s'",
00331                 action_name, strerror(errno), errno, fname);
00332     // here should be nothing, see rethrow above
00333 }
00334
00335 #ifndef DOXYGEN
00336 struct File_write_action_info {
00337     const char* str; size_t length;
00338 };
00339 #endif
00340 static void file_write_action(int f, void *context) {
00341     File_write_action_info& info=*static_cast<File_write_action_info *>(context);
00342     if(info.length) {
00343         int written=write(f, info.str, info.length);
00344         if(written<0)
00345             throw Exception(0,
00346                 0,
00347                 "write failed: %s (%d)",  strerror(errno), errno);
00348     }
00349 }
00350 void file_write(
00351                 const String& file_spec,
00352                 const char* data, size_t size,
00353                 bool as_text,
00354                 bool do_append) {
00355     File_write_action_info info={data, size};
00356     file_write_action_under_lock(
00357         file_spec,
00358         "write", file_write_action, &info,
00359         as_text,
00360         do_append);
00361 }
00362
00363 // throws nothing! [this is required in file_move & file_delete]
00364 static void rmdir(const String& file_spec, size_t pos_after) {
00365     size_t pos_before;
00366     if((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND)
00367         rmdir(file_spec, pos_before+1);
00368
00369     rmdir(file_spec.mid(0, pos_after-1/* / */).cstr(String::L_FILE_SPEC));
00370 }
00371 bool file_delete(const String& file_spec, bool fail_on_problem) {
00372     const char* fname=file_spec.cstr(String::L_FILE_SPEC);
00373     if(unlink(fname)!=0)
00374         if(fail_on_problem)
00375             throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0,
00376                 &file_spec,
00377                 "unlink failed: %s (%d), actual filename '%s'",
00378                     strerror(errno), errno, fname);
00379         else
00380             return false;
00381
00382     rmdir(file_spec, 1);
00383     return true;
00384 }
00385 void file_move(const String& old_spec, const String& new_spec) {
00386     const char* old_spec_cstr=old_spec.cstr(String::L_FILE_SPEC);
00387     const char* new_spec_cstr=new_spec.cstr(String::L_FILE_SPEC);
00388
00389     create_dir_for_file(new_spec);
00390
00391     if(rename(old_spec_cstr, new_spec_cstr)!=0)
00392         throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0,
00393             &old_spec,
00394             "rename failed: %s (%d), actual filename '%s' to '%s'",
00395                 strerror(errno), errno, old_spec_cstr, new_spec_cstr);
00396
00397     rmdir(old_spec, 1);
00398 }
00399
00400
00401 bool entry_exists(const char* fname, struct stat *afinfo) {
00402     struct stat lfinfo;
00403     bool result=stat(fname, &lfinfo)==0;
00404     if(afinfo)
00405         *afinfo=lfinfo;
00406     return result;
00407 }
00408
00409 bool entry_exists(const String& file_spec) {
00410     const char* fname=file_spec.cstr(String::L_FILE_SPEC);
00411     return entry_exists(fname, 0);
00412 }
00413
00414 static bool entry_readable(const String& file_spec, bool need_dir) {
00415     char* fname=file_spec.cstrm(String::L_FILE_SPEC);
00416     if(need_dir) {
00417         size_t size=strlen(fname);
00418         while(size) {
00419             char c=fname[size-1];
00420             if(c=='/' || c=='\\')
00421                 fname[--size]=0;
00422             else
00423                 break;
00424         }
00425     }
00426     struct stat finfo;
00427     if(access(fname, R_OK)==0 && entry_exists(fname, &finfo)) {
00428         bool is_dir=(finfo.st_mode&S_IFDIR) != 0;
00429         return is_dir==need_dir;
00430     }
00431     return false;
00432 }
00433 bool file_exist(const String& file_spec) {
00434     return entry_readable(file_spec, false);
00435 }
00436 bool dir_exists(const String& file_spec) {
00437     return entry_readable(file_spec, true);
00438 }
00439 const String* file_exist(const String& path, const String& name) {
00440     String& result=*new String(path);
00441     result << "/";
00442     result << name;
00443     return file_exist(result)?&result:0;
00444 }
00445 bool file_executable(const String& file_spec) {
00446     return access(file_spec.cstr(String::L_FILE_SPEC), X_OK)==0;
00447 }
00448
00449 bool file_stat(const String& file_spec,
00450                size_t& rsize,
00451                time_t& ratime,
00452                time_t& rmtime,
00453                time_t& rctime,
00454                bool fail_on_read_problem) {
00455     const char* fname=file_spec.cstr(String::L_FILE_SPEC);
00456     struct stat finfo;
00457     if(stat(fname, &finfo)!=0)
00458         if(fail_on_read_problem)
00459             throw Exception("file.missing",
00460                 &file_spec,
00461                 "getting file size failed: %s (%d), real filename '%s'",
00462                     strerror(errno), errno, fname);
00463         else
00464             return false;
00465     rsize=finfo.st_size;
00466     ratime=finfo.st_atime;
00467     rmtime=finfo.st_mtime;
00468     rctime=finfo.st_ctime;
00469     return true;
00470 }
00471
00472 char* getrow(char* *row_ref, char delim) {
00473     char* result=*row_ref;
00474     if(result) {
00475         *row_ref=strchr(result, delim);
00476         if(*row_ref)
00477             *((*row_ref)++)=0;
00478         else if(!*result)
00479             return 0;
00480     }
00481     return result;
00482 }
00483
00484 char* lsplit(char* string, char delim) {
00485     if(string) {
00486         char* v=strchr(string, delim);
00487         if(v) {
00488             *v=0;
00489             return v+1;
00490         }
00491     }
00492     return 0;
00493 }
00494
00495 char* lsplit(char* *string_ref, char delim) {
00496     char* result=*string_ref;
00497     char* next=lsplit(*string_ref, delim);
00498     *string_ref=next;
00499     return result;
00500 }
00501
00502 char* rsplit(char* string, char delim) {
00503     if(string) {
00504         char* v=strrchr(string, delim);
00505         if(v) {
00506             *v=0;
00507             return v+1;
00508         }
00509     }
00510     return NULL;
00511 }
00512
00514 const char* format(double value, char* fmt) {
00515     char local_buf[MAX_NUMBER];
00516     size_t size;
00517
00518     if(fmt)
00519         if(strpbrk(fmt, "diouxX"))
00520             if(strpbrk(fmt, "ouxX"))
00521                 size=snprintf(local_buf, sizeof(local_buf), fmt, (uint)value);
00522             else
00523                 size=snprintf(local_buf, sizeof(local_buf), fmt, (int)value);
00524         else
00525             size=snprintf(local_buf, sizeof(local_buf), fmt, value);
00526     else
00527         size=snprintf(local_buf, sizeof(local_buf), "%d", (int)value);
00528
00529     return pa_strdup(local_buf, size);
00530 }
00531
00532 size_t stdout_write(const void *buf, size_t size) {
00533 #ifdef WIN32
00534     size_t to_write = size;
00535     do{
00536         int chunk_written=fwrite(buf, 1, min((size_t)8*0x400, size), stdout);
00537         if(chunk_written<=0)
00538             break;
00539         size-=chunk_written;
00540         buf=((const char*)buf)+chunk_written;
00541     } while(size>0);
00542
00543     return to_write-size;
00544 #else
00545     return fwrite(buf, 1, size, stdout);
00546 #endif
00547 }
00548
00549 char* unescape_chars(const char* cp, int len) {
00550     char* s=new(PointerFreeGC) char[len + 1];
00551     enum EscapeState {
00552         EscapeRest,
00553         EscapeFirst,
00554         EscapeSecond
00555     } escapeState=EscapeRest;
00556     uint escapedValue=0;
00557     int srcPos=0;
00558     int dstPos=0;
00559     while(srcPos < len) {
00560         uchar ch=(uchar)cp[srcPos];
00561         switch(escapeState) {
00562             case EscapeRest:
00563             if(ch=='%') {
00564                 escapeState=EscapeFirst;
00565             } else if(ch=='+') {
00566                 s[dstPos++]=' ';
00567             } else {
00568                 s[dstPos++]=ch;
00569             }
00570             break;
00571             case EscapeFirst:
00572             escapedValue=hex_value[ch] << 4;
00573             escapeState=EscapeSecond;
00574             break;
00575             case EscapeSecond:
00576             escapedValue +=hex_value[ch];
00577             s[dstPos++]=(char)escapedValue;
00578             escapeState=EscapeRest;
00579             break;
00580         }
00581         srcPos++;
00582     }
00583     s[dstPos]=0;
00584     return s;
00585 }
00586
00587 #ifdef WIN32
00588 void back_slashes_to_slashes(char* s) {
00589     if(s)
00590         for(; *s; s++)
00591             if(*s=='\\')
00592                 *s='/';
00593 }
00594 /*
00595 void slashes_to_back_slashes(char* s) {
00596     if(s)
00597         for(; *s; s++)
00598             if(*s=='/')
00599                 *s='\\';
00600 }
00601 */
00602 #endif
00603
00604 bool StrEqNc(const char* s1, const char* s2, bool strict) {
00605     while(true) {
00606         if(!(*s1)) {
00607             if(!(*s2))
00608                 return true;
00609             else
00610                 return !strict;
00611         } else if(!(*s2))
00612             return !strict;
00613         if(isalpha((unsigned char)*s1)) {
00614             if(tolower((unsigned char)*s1) !=tolower((unsigned char)*s2))
00615                 return false;
00616         } else if((*s1) !=(*s2))
00617             return false;
00618         s1++;
00619         s2++;
00620     }
00621 }
00622
00623 static bool isLeap(int year) {
00624     return !(
00625              (year % 4) || ((year % 400) && !(year % 100))
00626             );
00627 }
00628
00629 int getMonthDays(int year, int month) {
00630     int monthDays[]={
00631         31,
00632         isLeap(year) ? 29 : 28,
00633         31,
00634         30,
00635         31,
00636         30,
00637         31,
00638         31,
00639         30,
00640         31,
00641         30,
00642         31
00643     };
00644     return monthDays[month];
00645 }
00646
00647 void remove_crlf(char* start, char* end) {
00648     for(char* p=start; p<end; p++)
00649         switch(*p) {
00650             case '\n': *p='|';  break;
00651             case '\r': *p=' ';  break;
00652         }
00653 }
00654
00655
00657 #undef vsnprintf
00658 int __vsnprintf(char* b, size_t s, const char* f, va_list l) {
00659     if(!s)
00660         return 0;
00661
00662     int r;
00663     // note: on win32& maybe somewhere else
00664     // vsnprintf do not writes terminating 0 in 'buffer full' case, reducing
00665     --s;
00666
00667     // clients do not check for negative 's', feature: ignore such prints
00668     if((ssize_t)s<0)
00669         return 0;
00670
00671 #if _MSC_VER
00672     /*
00673     win32:
00674     mk:@MSITStore:C:\Program%20Files\Microsoft%20Visual%20Studio\MSDN\2001APR\1033\vccore.chm::/html/_crt__vsnprintf.2c_._vsnwprintf.htm
00675
00676       if the number of bytes to write exceeds buffer, then count bytes are written and Ö1 is returned
00677     */
00678     r=_vsnprintf(b, s, f, l);
00679     if(r<0)
00680         r=s;
00681 #else
00682     r=vsnprintf(b, s, f, l);
00683     /*
00684     solaris:
00685     man vsnprintf
00686
00687       The snprintf() function returns  the  number  of  characters
00688     formatted, that is, the number of characters that would have
00689     been written to the buffer if it were large enough.  If  the
00690     value  of  n  is  0  on a call to snprintf(), an unspecified
00691     value less than 1 is returned.
00692     */
00693
00694     if(r<0)
00695         r=0;
00696     else if((size_t)r>s)
00697         r=s;
00698 #endif
00699     b[r]=0;
00700     return r;
00701 }
00702
00703 int __snprintf(char* b, size_t s, const char* f, ...) {
00704     va_list l;
00705     va_start(l, f);
00706     int r=__vsnprintf(b, s, f, l);
00707     va_end(l);
00708     return r;
00709 }
00710
00711 /* mime64 functions are from libgmime[http://spruce.sourceforge.net/gmime/] lib */
00712 /*
00713  *  Authors: Michael Zucchi <notzed@helixcode.com>
00714  *           Jeffrey Stedfast <fejj@helixcode.com>
00715  *
00716  *  Copyright 2000 Helix Code, Inc. (www.helixcode.com)
00717  *
00718  *  This program is free software; you can redistribute it and/or modify
00719  *  it under the terms of the GNU General Public License as published by
00720  *  the Free Software Foundation; either version 2 of the License, or
00721  *  (at your option) any later version.
00722  *
00723  *  This program is distributed in the hope that it will be useful,
00724  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00725  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00726  *  GNU General Public License for more details.
00727  *
00728  *  You should have received a copy of the GNU General Public License
00729  *  along with this program; if not, write to the Free Software
00730  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
00731  *
00732  */
00733 static char *base64_alphabet =
00734     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00735
00751 static size_t
00752 g_mime_utils_base64_encode_step (const unsigned char *in, size_t inlen, unsigned char *out, int *state, int *save)
00753 {
00754     register const unsigned char *inptr;
00755     register unsigned char *outptr;
00756
00757     if (inlen <= 0)
00758         return 0;
00759
00760     inptr = in;
00761     outptr = out;
00762
00763     if (inlen + ((unsigned char *)save)[0] > 2) {
00764         const unsigned char *inend = in + inlen - 2;
00765         register int c1 = 0, c2 = 0, c3 = 0;
00766         register int already;
00767
00768         already = *state;
00769
00770         switch (((char *)save)[0]) {
00771         case 1: c1 = ((unsigned char *)save)[1]; goto skip1;
00772         case 2: c1 = ((unsigned char *)save)[1];
00773             c2 = ((unsigned char *)save)[2]; goto skip2;
00774         }
00775
00776         /* yes, we jump into the loop, no i'm not going to change it, its beautiful! */
00777         while (inptr < inend) {
00778             c1 = *inptr++;
00779         skip1:
00780             c2 = *inptr++;
00781         skip2:
00782             c3 = *inptr++;
00783             *outptr++ = base64_alphabet [c1 >> 2];
00784             *outptr++ = base64_alphabet [(c2 >> 4) | ((c1 & 0x3) << 4)];
00785             *outptr++ = base64_alphabet [((c2 & 0x0f) << 2) | (c3 >> 6)];
00786             *outptr++ = base64_alphabet [c3 & 0x3f];
00787             /* this is a bit ugly ... */
00788             if ((++already) >= 19) {
00789                 *outptr++ = '\n';
00790                 already = 0;
00791             }
00792         }
00793
00794         ((unsigned char *)save)[0] = 0;
00795         inlen = 2 - (inptr - inend);
00796         *state = already;
00797     }
00798
00799     //d(printf ("state = %d, inlen = %d\n", (int)((char *)save)[0], inlen));
00800
00801     if (inlen > 0) {
00802         register char *saveout;
00803
00804         /* points to the slot for the next char to save */
00805         saveout = & (((char *)save)[1]) + ((char *)save)[0];
00806
00807         /* inlen can only be 0 1 or 2 */
00808         switch (inlen) {
00809         case 2: *saveout++ = *inptr++;
00810         case 1: *saveout++ = *inptr++;
00811         }
00812         *(char *)save = *(char *)save+(char)inlen;
00813     }
00814
00815     /*d(printf ("mode = %d\nc1 = %c\nc2 = %c\n",
00816           (int)((char *)save)[0],
00817           (int)((char *)save)[1],
00818           (int)((char *)save)[2]));*/
00819
00820     return (outptr - out);
00821 }
00822
00837 static size_t
00838 g_mime_utils_base64_encode_close (const unsigned char *in, size_t inlen, unsigned char *out, int *state, int *save)
00839 {
00840     unsigned char *outptr = out;
00841     int c1, c2;
00842
00843     if (inlen > 0)
00844         outptr += g_mime_utils_base64_encode_step (in, inlen, outptr, state, save);
00845
00846     c1 = ((unsigned char *)save)[1];
00847     c2 = ((unsigned char *)save)[2];
00848
00849     switch (((unsigned char *)save)[0]) {
00850     case 2:
00851         outptr[2] = base64_alphabet [(c2 & 0x0f) << 2];
00852         goto skip;
00853     case 1:
00854         outptr[2] = '=';
00855     skip:
00856         outptr[0] = base64_alphabet [c1 >> 2];
00857         outptr[1] = base64_alphabet [c2 >> 4 | ((c1 & 0x3) << 4)];
00858         outptr[3] = '=';
00859         outptr += 4;
00860         break;
00861     }
00862
00863     *outptr++ = 0;
00864
00865     *save = 0;
00866     *state = 0;
00867
00868     return (outptr - out);
00869 }
00870
00871 static unsigned char gmime_base64_rank[256] = {
00872     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00873     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00874     255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
00875      52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
00876     255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
00877      15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
00878     255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00879      41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
00880     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00881     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00882     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00883     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00884     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00885     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00886     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00887     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
00888 };
00889
00902 size_t
00903 g_mime_utils_base64_decode_step (const unsigned char *in, size_t inlen, unsigned char *out, int *state, int *save)
00904 {
00905     const unsigned char *inptr;
00906     unsigned char *outptr;
00907     const unsigned char *inend;
00908     int saved;
00909     unsigned char c;
00910     int i;
00911
00912     inend = in + inlen;
00913     outptr = out;
00914
00915     /* convert 4 base64 bytes to 3 normal bytes */
00916     saved = *save;
00917     i = *state;
00918     inptr = in;
00919     while (inptr < inend) {
00920         c = gmime_base64_rank[*inptr++];
00921         if (c != 0xff) {
00922             saved = (saved << 6) | c;
00923             i++;
00924             if (i == 4) {
00925                 *outptr++ = (unsigned char)saved >> 16;
00926                 *outptr++ = (unsigned char)saved >> 8;
00927                 *outptr++ = (unsigned char)saved;
00928                 i = 0;
00929             }
00930         }
00931     }
00932
00933     *save = saved;
00934     *state = i;
00935
00936     /* quick scan back for '=' on the end somewhere */
00937     /* fortunately we can drop 1 output char for each trailing = (upto 2) */
00938     i = 2;
00939     while (inptr > in && i) {
00940         inptr--;
00941         if (gmime_base64_rank[*inptr] != 0xff) {
00942             if (*inptr == '=' && outptr > out)
00943                 outptr--;
00944             i--;
00945         }
00946     }
00947
00948     /* if i != 0 then there is a truncation error! */
00949     return (outptr - out);
00950 }
00951
00952
00953 char* pa_base64_encode(const char *in, size_t in_size)
00954 {
00955     /* wont go to more than 2x size (overly conservative) */
00956     char* result=new(PointerFreeGC) char[in_size * 2 + 6];
00957     int state=0;
00958     int save=0;
00959 #ifndef NDEBUG
00960     size_t filled=
00961 #endif
00962         g_mime_utils_base64_encode_close ((const unsigned char*)in, in_size,
00963         (unsigned char*)result, &state, &save);
00964     assert(filled <= in_size * 2 + 6);
00965
00966     return result;
00967 }
00968
00969 void pa_base64_decode(const char *in, size_t in_size, char*& result, size_t& result_size)
00970 {
00971     /* wont go to more than had (overly conservative) */
00972     result=new(PointerFreeGC) char[in_size+1/*terminator*/];
00973     int state=0;
00974     int save=0;
00975     result_size=
00976         g_mime_utils_base64_decode_step ((const unsigned char*)in, in_size,
00977         (unsigned char*)result, &state, &save);
00978     assert(result_size <= in_size);
00979     result[result_size]=0; // for text files
00980 }


pa_common.h File Reference

Parser: commonly used functions. More...

Include dependency graph for pa_common.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | File_read_result

Defines

#define | vsnprintf __vsnprintf
#define | snprintf __snprintf
#define | _qsort(names, cnt, sizeof_names, func_addr) qsort(names,cnt,sizeof_names,func_addr)
#define | SECS_PER_DAY (60*60*24)
#define | PA_SQL_LIMIT_NAME "limit"
#define | PA_SQL_OFFSET_NAME "offset"
#define | PA_COLUMN_SEPARATOR_NAME "separator"
#define | PA_COLUMN_ENCLOSER_NAME "encloser"

Typedefs

typedef Hash< const String::Body,
Value * > 		HashStringValue
typedef void(* | File_read_action )(struct stat &finfo, int f, const String &file_spec, const char *fname, bool as_text, void *context)
typedef void(* | File_write_action )(int f, void *context)

Functions

int | __vsnprintf (char *, size_t, const char *, va_list)
must be last in this file. More...

int | __snprintf (char *, size_t, const char *,...)
void | fix_line_breaks (char *str, size_t &length)
under WIN32 "t" mode fixes DOS chars OK, can't say that about other systems/ line break styles. More...

int | pa_lock_shared_blocking (int fd)
int | pa_lock_exclusive_blocking (int fd)
int | pa_lock_exclusive_nonblocking (int fd)
int | pa_unlock (int fd)
void | create_dir_for_file (const String &file_spec)
bool | file_read_action_under_lock (const String &file_spec, const char *action_name, File_read_action action, void *context, bool as_text=false, bool fail_on_read_problem=true)
shared-lock specified file, do actions under lock. More...

char * | file_read_text (Request_charsets &charsets, const String &file_spec, bool fail_on_read_problem=true, HashStringValue *options=0)
read specified text file using if fail_on_read_problem is true[default] throws an exception. More...

File_read_result | file_read (Request_charsets &charsets, const String &file_spec, bool as_text, HashStringValue *options=0, bool fail_on_read_problem=true, char *buf=0, size_t offset=0, size_t size=0)
read specified file using if fail_on_read_problem is true[default] throws an exception. More...

bool | file_write_action_under_lock (const String &file_spec, const char *action_name, File_write_action action, void *context, bool as_text=false, bool do_append=false, bool do_block=true, bool fail_on_lock_problem=true)
lock specified file exclusively, do actions under lock. More...

void | file_write (const String &file_spec, const char *data, size_t size, bool as_text, bool do_append=false)
write data to specified file, throws an exception in case of problems. More...

bool | file_delete (const String &file_spec, bool fail_on_problem=true)
delete specified file throws an exception in case of problems. More...

void | file_move (const String &old_spec, const String &new_spec)
move specified file throws an exception in case of problems. More...

bool | entry_exists (const char *fname, struct stat *afinfo=0)
bool | entry_exists (const String &file_spec)
bool | file_exist (const String &file_spec)
bool | dir_exists (const String &file_spec)
const String * | file_exist (const String &path, const String &name)
bool | file_executable (const String &file_spec)
bool | file_stat (const String &file_spec, size_t &rsize, time_t &ratime, time_t &rmtime, time_t &rctime, bool fail_on_read_problem=true)
char * | getrow (char **row_ref, char delim='\n')
scans for delim[default
] in *row_ref,. More...

char * | lsplit (char *string, char delim)
char * | lsplit (char **string_ref, char delim)
char * | rsplit (char *string, char delim)
const char * | format (double value, char *fmt)
size_t | stdout_write (const void *buf, size_t size)
char * | unescape_chars (const char *cp, int len)
void | back_slashes_to_slashes (char *s)
bool | StrEqNc (const char *s1, const char *s2, bool strict=true)
int | getMonthDays (int year, int month)
void | remove_crlf (char *start, char *end)
char * | pa_base64_encode (const char *in, size_t in_size)
void | pa_base64_decode (const char *in, size_t in_size, char *&result, size_t &result_size)
int | pa_get_valid_file_options_count (HashStringValue &options)
these options were handled but not checked elsewhere, now check them. More...

Variables

const char *const | IDENT_COMMON_H = "$Date: 2005/11/24 14:00:34 $"
const String | file_status_name

Detailed Description

Parser: commonly used functions.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_common.h.

Define Documentation

#define vsnprintf __vsnprintf

Definition at line 22 of file pa_common.h.

Referenced by __vsnprintf(), die_or_abort(), Exception::Exception(), log(), and SAPI::log().

#define snprintf __snprintf

Definition at line 25 of file pa_common.h.

Referenced by _exec_cgi(), _save(), _uuid(), date_attribute(), die_or_abort(), fill_month_days(), findfirst(), String::Body::Format(), format(), full_file_spec(), Request::get_exception_cstr(), VInt::get_string(), VDouble::get_string(), HttpExtensionProc(), log(), main(), VMail::message_hash_to_string(), output_pieces(), output_sole_piece(), pa_parser_handler(), SMTP::prepare_message(), real_parser_handler(), set_tz(), and String::v().

#define _qsort | ( | names,
 |  | cnt,
 |  | sizeof_names,
 |  | func_addr | ) | qsort(names,cnt,sizeof_names,func_addr)

Definition at line 200 of file pa_common.h.

Referenced by _sort().

#define SECS_PER_DAY (60*60*24)

Definition at line 206 of file pa_common.h.

Referenced by _create(), _now(), VDate::as_double(), and fill_week_days().

#define PA_SQL_LIMIT_NAME "limit"

Definition at line 226 of file pa_common.h.

Referenced by pa_get_valid_file_options_count().

#define PA_SQL_OFFSET_NAME "offset"

Definition at line 227 of file pa_common.h.

Referenced by pa_get_valid_file_options_count().

#define PA_COLUMN_SEPARATOR_NAME "separator"

Definition at line 228 of file pa_common.h.

Referenced by TableSeparators::load(), and pa_get_valid_file_options_count().

#define PA_COLUMN_ENCLOSER_NAME "encloser"

Definition at line 229 of file pa_common.h.

Referenced by TableSeparators::load(), and pa_get_valid_file_options_count().

Typedef Documentation

typedef Hash<const String::Body , Value*> HashStringValue

Definition at line 17 of file pa_common.h.

typedef void(* File_read_action)( struct stat& finfo, int f, const String& file_spec, const char* fname, bool as_text, void *context)

Definition at line 74 of file pa_common.h.

Referenced by file_read_action_under_lock().

typedef void(* File_write_action)(int f, void *context)

Definition at line 125 of file pa_common.h.

Referenced by file_write_action_under_lock().

Function Documentation

int __vsnprintf | ( | char * | ,
 |  | size_t | ,
 |  | const char * | ,
 |  | va_list |
 | ) |

must be last in this file.

Definition at line 658 of file pa_common.C.

References vsnprintf.

Referenced by __snprintf().

int __snprintf | ( | char * | ,
 |  | size_t | ,
 |  | const char * | ,
 |  | ... |
 | ) |

Definition at line 703 of file pa_common.C.

void fix_line_breaks | ( | char * | str,
 |  | size_t & | length
 | ) |

under WIN32 "t" mode fixes DOS chars OK, can't say that about other systems/ line break styles.

Parameters:
length may change! used to speedup next actions

Definition at line 67 of file pa_common.C.

References str.

Referenced by VForm::AppendFormEntry(), file_read(), and VFile::set().

int pa_lock_shared_blocking ( int fd )

int pa_lock_exclusive_blocking ( int fd )

int pa_lock_exclusive_nonblocking ( int fd )

int pa_unlock ( int fd )

void create_dir_for_file ( const String & file_spec )

Definition at line 274 of file pa_common.C.

References String::cstr(), String::L_FILE_SPEC, String::mid(), String::pos(), and STRING_NOT_FOUND.

Referenced by file_move(), file_write_action_under_lock(), and VHashfile::open().

bool file_read_action_under_lock | ( | const String & | file_spec,
 |  | const char * | action_name,
 |  | File_read_action | action,
 |  | void * | context,
 |  | bool | as_text = false,
 |  | bool | fail_on_read_problem = true
 | ) |

shared-lock specified file, do actions under lock.

if fail_on_read_problem is true[default] throws an exception

Returns:
true if read OK

Definition at line 219 of file pa_common.C.

References context, String::cstr(), File_read_action, String::L_FILE_SPEC, pa_lock_shared_blocking(), pa_unlock(), and rethrow.

Referenced by _measure(), and file_read().

char* file_read_text | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | bool | fail_on_read_problem = true,
 |  | HashStringValue * | options = 0
 | ) |

read specified text file using if fail_on_read_problem is true[default] throws an exception.

WARNING: charset is used for http header case conversion, it's not a charset of input file!

Returns:
true if read OK

Definition at line 93 of file pa_common.C.

References file, file_read(), File_read_result::str, and File_read_result::success.

Referenced by _load(), and Request::use_file().

File_read_result file_read | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | bool | as_text,
 |  | HashStringValue * | options = 0,
 |  | bool | fail_on_read_problem = true,
 |  | char * | buf = 0,
 |  | size_t | offset = 0,
 |  | size_t | size = 0
 | ) |

read specified file using if fail_on_read_problem is true[default] throws an exception.

WARNING: charset is used for http header case conversion, it's not a charset of input file!

Returns:
true if read OK

Definition at line 154 of file pa_common.C.

References Hash< const String::Body, Value * >::count(), file_read_action(), file_read_action_under_lock(), fix_line_breaks(), File_read_result::headers, File_read_result::length, offset, pa_get_valid_file_options_count(), pa_internal_file_read_http(), result, String::starts_with(), File_read_result::str, and File_read_result::success.

Referenced by _load(), cache_get(), file_read_text(), output_pieces(), and VForm::refill_fields_and_tables().

bool file_write_action_under_lock | ( | const String & | file_spec,
 |  | const char * | action_name,
 |  | File_write_action | action,
 |  | void * | context,
 |  | bool | as_text = false,
 |  | bool | do_append = false,
 |  | bool | do_block = true,
 |  | bool | fail_on_lock_problem = true
 | ) |

lock specified file exclusively, do actions under lock.

throws an exception in case of problems

if block=false does non-blocking lock

Returns:
true if locked OK, or false if non-blocking locking failed

Definition at line 283 of file pa_common.C.

References access, context, create_dir_for_file(), String::cstr(), File_write_action, String::L_FILE_SPEC, pa_lock_exclusive_blocking(), pa_lock_exclusive_nonblocking(), pa_unlock(), and rethrow.

Referenced by _lock(), file_write(), and locked_process_and_cache_put().

void file_write | ( | const String & | file_spec,
 |  | const char * | data,
 |  | size_t | size,
 |  | bool | as_text,
 |  | bool | do_append = false
 | ) |

write data to specified file, throws an exception in case of problems.

Definition at line 350 of file pa_common.C.

References data, file_write_action(), file_write_action_under_lock(), and size.

Referenced by _save(), and VFile::save().

bool file_delete | ( | const String & | file_spec,
 |  | bool | fail_on_problem = true
 | ) |

delete specified file throws an exception in case of problems.

Definition at line 371 of file pa_common.C.

References String::cstr(), String::L_FILE_SPEC, and rmdir().

Referenced by _delete(), cache_delete(), and delete_file().

void file_move | ( | const String & | old_spec,
 |  | const String & | new_spec
 | ) |

move specified file throws an exception in case of problems.

Definition at line 385 of file pa_common.C.

References create_dir_for_file(), String::cstr(), String::L_FILE_SPEC, and rmdir().

Referenced by _move().

bool entry_exists | ( | const char * | fname,
 |  | struct stat * | afinfo = 0
 | ) |

Definition at line 401 of file pa_common.C.

bool entry_exists ( const String & file_spec )

Definition at line 409 of file pa_common.C.

References String::cstr(), and String::L_FILE_SPEC.

Referenced by entry_readable(), VHashfile::open(), real_parser_handler(), and Request::use_file().

bool file_exist ( const String & file_spec )

Definition at line 433 of file pa_common.C.

bool dir_exists ( const String & file_spec )

Definition at line 436 of file pa_common.C.

References entry_readable().

Referenced by Request::execute().

const String* file_exist | ( | const String & | path,
 |  | const String & | name
 | ) |

Definition at line 439 of file pa_common.C.

References result.

Referenced by _find(), Request::execute(), and Request::use_file().

bool file_executable ( const String & file_spec )

Definition at line 445 of file pa_common.C.

References access, String::cstr(), and String::L_FILE_SPEC.

Referenced by sendmail().

bool file_stat | ( | const String & | file_spec,
 |  | size_t & | rsize,
 |  | time_t & | ratime,
 |  | time_t & | rmtime,
 |  | time_t & | rctime,
 |  | bool | fail_on_read_problem = true
 | ) |

Definition at line 449 of file pa_common.C.

References String::cstr(), and String::L_FILE_SPEC.

Referenced by _stat(), and Request::output_result().

char* getrow | ( | char ** | row_ref,
 |  | char | delim = '\n'
 | ) |

scans for delim[default
] in *row_ref,.

Returns:
piece of line before it or end of string, if no delim found assigns *row_ref to point right after delimiter if there were one or to zero if no delim were found.

Definition at line 472 of file pa_common.C.

References delim, and result.

Referenced by skip_empty_and_comment_lines().

char* lsplit | ( | char * | string,
 |  | char | delim
 | ) |

Definition at line 484 of file pa_common.C.

char* lsplit | ( | char ** | string_ref,
 |  | char | delim
 | ) |

Definition at line 495 of file pa_common.C.

References delim, and result.

Referenced by _load(), CreateHiddenConsoleProcess(), cstr_to_time_t(), extractEmails(), SQL_Driver_manager::get_connection(), lsplit(), and pa_internal_file_read_http().

char* rsplit | ( | char * | string,
 |  | char | delim
 | ) |

Definition at line 502 of file pa_common.C.

References delim, and v.

Referenced by CreateHiddenConsoleProcess(), extractEmails(), log(), Request::output_result(), real_parser_handler(), Request::relative(), sendmail(), and VFile::set().

const char* format | ( | double | value,
 |  | char * | fmt
 | ) |

Todo:
less stupid type detection

Definition at line 514 of file pa_common.C.

References MAX_NUMBER, pa_strdup(), size, snprintf, uint, and value.

Referenced by _eval(), _string_format(), and pa_internal_file_read_http().

size_t stdout_write | ( | const void * | buf,
 |  | size_t | size
 | ) |

Definition at line 532 of file pa_common.C.

References size.

char* unescape_chars | ( | const char * | cp,
 |  | int | len
 | ) |

Definition at line 549 of file pa_common.C.

References uchar, and uint.

Referenced by VCookie::fill_fields(), and VForm::ParseFormInput().

void back_slashes_to_slashes ( char * s )

Definition at line 588 of file pa_common.C.

Referenced by full_file_spec(), and real_parser_handler().

bool StrEqNc | ( | const char * | s1,
 |  | const char * | s2,
 |  | bool | strict = true
 | ) |

Definition at line 604 of file pa_common.C.

Referenced by MForm::configure_admin(), and VForm::refill_fields_and_tables().

int getMonthDays | ( | int | year,
 |  | int | month
 | ) |

Definition at line 629 of file pa_common.C.

References isLeap().

Referenced by fill_month_days().

void remove_crlf | ( | char * | start,
 |  | char * | end
 | ) |

Definition at line 647 of file pa_common.C.

References p.

Referenced by die_or_abort(), SAPI::log(), and log().

char* pa_base64_encode | ( | const char * | in,
 |  | size_t | in_size
 | ) |

Definition at line 953 of file pa_common.C.

References assert, g_mime_utils_base64_encode_close(), and result.

Referenced by _base64(), and basic_authorization_field().

void pa_base64_decode | ( | const char * | in,
 |  | size_t | in_size,
 |  | char *& | result,
 |  | size_t & | result_size
 | ) |

Definition at line 969 of file pa_common.C.

References assert, g_mime_utils_base64_decode_step(), and result.

Referenced by _base64().

int pa_get_valid_file_options_count ( HashStringValue & options )

these options were handled but not checked elsewhere, now check them.

Definition at line 103 of file pa_common.C.

References Hash< const String::Body, Value * >::get(), PA_COLUMN_ENCLOSER_NAME, PA_COLUMN_SEPARATOR_NAME, PA_SQL_LIMIT_NAME, PA_SQL_OFFSET_NAME, and result.

Referenced by file_read(), and pa_internal_file_read_http().

Variable Documentation

const char* const IDENT_COMMON_H = "$Date: 2005/11/24 14:00:34 $" [static]

Definition at line 11 of file pa_common.h.

const String file_status_name

Definition at line 222 of file pa_common.h.


pa_common.h Source File

pa_common.h

Go to the documentation of this file.
00001
00008 #ifndef PA_COMMON_H
00009 #define PA_COMMON_H
00010
00011 static const char * const IDENT_COMMON_H="$Date: 2005/11/24 14:00:34 $";
00012
00013 #include "pa_string.h"
00014 #include "pa_hash.h"
00015
00016 class Value;
00017 typedef Hash<const String::Body , Value*> HashStringValue;
00018
00019 // replace system s*nprintf with our versions
00020 #undef vsnprintf
00021 int __vsnprintf(char *, size_t, const char* , va_list);
00022 #define vsnprintf __vsnprintf
00023 #undef snprintf
00024 int __snprintf(char *, size_t, const char* , ...);
00025 #define snprintf __snprintf
00026
00027 #if _MSC_VER
00028 /*
00029 inline int open( const char* filename, int oflag ) { return _open(filename, oflag); }
00030 inline int close( int handle ) { return _close(handle); }
00031 inline int read( int handle, void *buffer, unsigned int count ) { return _read(handle,buffer,count); }
00032 inline int write( int handle, const void *buffer, unsigned int count ) { return _write(handle,buffer,count); }
00033 inline int stat( const char* path, struct _stat *buffer ) { return _stat(path, buffer); }
00034 inline long lseek( int handle, long offset, int origin ) { return _lseek(handle, offset, origin); }
00035 */
00036
00037 //access
00038 #define F_OK 0
00039 #define X_OK 1
00040 #define W_OK 2
00041 #define R_OK 4
00042
00043 #ifndef strcasecmp
00044 #   define strcasecmp _stricmp
00045 #endif
00046 #ifndef strncasecmp
00047 #   define strncasecmp _strnicmp
00048 #endif
00049 #ifndef mkdir
00050 #   define mkdir(path, mode) _mkdir(path)
00051 #endif
00052
00053 #ifndef putenv
00054 #   define putenv _putenv
00055 #endif
00056
00057 #endif
00058
00062 void fix_line_breaks(
00063              char *str,
00064              size_t& length
00065              );
00066
00067 int pa_lock_shared_blocking(int fd);
00068 int pa_lock_exclusive_blocking(int fd);
00069 int pa_lock_exclusive_nonblocking(int fd);
00070 int pa_unlock(int fd);
00071
00072 void create_dir_for_file(const String& file_spec);
00073
00074 typedef void (*File_read_action)(
00075                  struct stat& finfo,
00076                  int f,
00077                  const String& file_spec, const char* fname, bool as_text,
00078                  void *context);
00079
00087 bool file_read_action_under_lock(const String& file_spec,
00088                 const char* action_name, File_read_action action, void *context,
00089                 bool as_text=false,
00090                 bool fail_on_read_problem=true);
00099 char *file_read_text(Request_charsets& charsets,
00100                      const String& file_spec,
00101                      bool fail_on_read_problem=true,
00102                      HashStringValue* options=0/*, HashStringValue* * out_fields=0*/);
00103
00104 struct File_read_result {
00105     bool success;
00106     char* str; size_t length;
00107     HashStringValue* headers;
00108 };
00109
00118 File_read_result file_read(Request_charsets& charsets,
00119                const String& file_spec,
00120                bool as_text,
00121                HashStringValue* options=0,
00122                bool fail_on_read_problem=true,
00123                char* buf=0, size_t offset=0, size_t size=0);
00124
00125 typedef void (*File_write_action)(int f, void *context);
00126
00135 bool file_write_action_under_lock(
00136                 const String& file_spec,
00137                 const char* action_name, File_write_action action, void *context,
00138                 bool as_text=false,
00139                 bool do_append=false,
00140                 bool do_block=true,
00141                 bool fail_on_lock_problem=true);
00142
00147 void file_write(
00148                 const String& file_spec,
00149                 const char* data, size_t size,
00150                 bool as_text,
00151                 bool do_append=false);
00152
00157 bool file_delete(const String& file_spec, bool fail_on_problem=true);
00162 void file_move(const String& old_spec, const String& new_spec);
00163
00164 bool entry_exists(const char* fname, struct stat *afinfo=0);
00165 bool entry_exists(const String& file_spec);
00166 bool file_exist(const String& file_spec);
00167 bool dir_exists(const String& file_spec);
00168 const String* file_exist(const String& path, const String& name);
00169 bool file_executable(const String& file_spec);
00170
00171 bool file_stat(const String& file_spec,
00172                size_t& rsize,
00173                time_t& ratime,
00174                time_t& rmtime,
00175                time_t& rctime,
00176                bool fail_on_read_problem=true);
00177
00184 char *getrow(char **row_ref,char delim='\n');
00185 char *lsplit(char *string, char delim);
00186 char *lsplit(char **string_ref,char delim);
00187 char *rsplit(char *string, char delim);
00188 const char* format(double value, char *fmt);
00189
00190 size_t stdout_write(const void *buf, size_t size);
00191
00192 char *unescape_chars(const char* cp, int len);
00193
00194 #ifdef WIN32
00195 void back_slashes_to_slashes(char *s);
00196 //void slashes_to_back_slashes(char *s);
00197 #endif
00198
00199 #ifndef _qsort
00200 #   define _qsort(names,cnt,sizeof_names,func_addr) \
00201         qsort(names,cnt,sizeof_names,func_addr)
00202 #endif
00203
00204 bool StrEqNc(const char* s1, const char* s2, bool strict=true);
00205
00206 #define SECS_PER_DAY (60*60*24)
00207 int getMonthDays(int year, int month);
00208
00209 void remove_crlf(char *start, char *end);
00210
00211 #ifdef PA_SAFE_MODE
00212 void check_safe_mode(struct stat finfo, const String& file_spec, const char* fname);
00213 #endif
00214
00215 char* pa_base64_encode(const char *in, size_t in_size);
00216 void pa_base64_decode(const char *in, size_t in_size, char*& result, size_t& result_size);
00217
00218 int pa_get_valid_file_options_count(HashStringValue& options);
00219
00220 // globals
00221
00222 extern const String file_status_name;
00223
00224 // global defines for file options which are handled but not checked elsewhere, we check them
00225
00226 #define PA_SQL_LIMIT_NAME "limit"
00227 #define PA_SQL_OFFSET_NAME "offset"
00228 #define PA_COLUMN_SEPARATOR_NAME "separator"
00229 #define PA_COLUMN_ENCLOSER_NAME "encloser"
00230
00231 #endif


pa_config_fixed.h File Reference

Parser: Configure file for autoconf-disabled platforms. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | inline __inline
#define | HAVE_ASSERT_H
#define | HAVE_STDARG_H
#define | HAVE_PROCESS_H
#define | HAVE_FCNTL_H
#define | HAVE_SYS_STAT_H
#define | HAVE_IO_H
#define | HAVE_STDDEF_H
#define | HAVE_STDIO_H
#define | HAVE_ERRNO_H
#define | HAVE_CTYPE_H
#define | HAVE_MATH_H
#define | HAVE_TIME_H
#define | HAVE_STRING_H
#define | HAVE_DIRECT_H
#define | HAVE_SETJMP_H
#define | HAVE_MEMORY_H
#define | HAVE_SYS_LOCKING_H
#define | HAVE_SYS_TYPES_H
#define | HAVE_WINSOCK_H
#define | HAVE__LOCKING
#define | HAVE_TIMEZONE
#define | HAVE_DAYLIGHT
#define | USE_SMTP
#define | PA_LITTLE_ENDIAN
#define | PA_WITH_SJLJ_EXCEPTIONS
#define | off_t _off_t
#define | ssize_t int
#define | XML

Variables

const char *const | IDENT_CONFIG_FIXED_H = "$Date: 2005/12/19 14:22:01 $"

Detailed Description

Parser: Configure file for autoconf-disabled platforms.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

tested only with MS Visual C++ V6

Definition in file pa_config_fixed.h.

Define Documentation

#define inline __inline

Definition at line 15 of file pa_config_fixed.h.

#define HAVE_ASSERT_H

Definition at line 16 of file pa_config_fixed.h.

#define HAVE_STDARG_H

Definition at line 17 of file pa_config_fixed.h.

#define HAVE_PROCESS_H

Definition at line 18 of file pa_config_fixed.h.

#define HAVE_FCNTL_H

Definition at line 19 of file pa_config_fixed.h.

#define HAVE_SYS_STAT_H

Definition at line 20 of file pa_config_fixed.h.

#define HAVE_IO_H

Definition at line 21 of file pa_config_fixed.h.

#define HAVE_STDDEF_H

Definition at line 22 of file pa_config_fixed.h.

#define HAVE_STDIO_H

Definition at line 23 of file pa_config_fixed.h.

#define HAVE_ERRNO_H

Definition at line 24 of file pa_config_fixed.h.

#define HAVE_CTYPE_H

Definition at line 25 of file pa_config_fixed.h.

#define HAVE_MATH_H

Definition at line 26 of file pa_config_fixed.h.

#define HAVE_TIME_H

Definition at line 27 of file pa_config_fixed.h.

#define HAVE_STRING_H

Definition at line 28 of file pa_config_fixed.h.

#define HAVE_DIRECT_H

Definition at line 29 of file pa_config_fixed.h.

#define HAVE_SETJMP_H

Definition at line 30 of file pa_config_fixed.h.

#define HAVE_MEMORY_H

Definition at line 31 of file pa_config_fixed.h.

#define HAVE_SYS_LOCKING_H

Definition at line 32 of file pa_config_fixed.h.

#define HAVE_SYS_TYPES_H

Definition at line 33 of file pa_config_fixed.h.

#define HAVE_WINSOCK_H

Definition at line 34 of file pa_config_fixed.h.

#define HAVE__LOCKING

Definition at line 35 of file pa_config_fixed.h.

#define HAVE_TIMEZONE

Definition at line 36 of file pa_config_fixed.h.

#define HAVE_DAYLIGHT

Definition at line 37 of file pa_config_fixed.h.

#define USE_SMTP

Definition at line 38 of file pa_config_fixed.h.

#define PA_LITTLE_ENDIAN

Definition at line 39 of file pa_config_fixed.h.

#define PA_WITH_SJLJ_EXCEPTIONS

Definition at line 40 of file pa_config_fixed.h.

#define off_t _off_t

Definition at line 43 of file pa_config_fixed.h.

#define ssize_t int

Definition at line 44 of file pa_config_fixed.h.

Referenced by _left(), _left_right(), _mid(), _right(), Array< Operation >::append(), gdGrowingBuf::append(), file_read_action(), and http_read_response().

#define XML

Definition at line 53 of file pa_config_fixed.h.

Referenced by Untaint_lang_name2enum::Untaint_lang_name2enum().

Variable Documentation

const char* const IDENT_CONFIG_FIXED_H = "$Date: 2005/12/19 14:22:01 $" [static]

Definition at line 13 of file pa_config_fixed.h.


pa_config_fixed.h Source File

pa_config_fixed.h

Go to the documentation of this file.
00001
00010 #ifndef PA_CONFIG_FIXED_H
00011 #define PA_CONFIG_FIXED_H
00012
00013 static const char * const IDENT_CONFIG_FIXED_H="$Date: 2005/12/19 14:22:01 $";
00014
00015 #define inline  __inline
00016 #define HAVE_ASSERT_H
00017 #define HAVE_STDARG_H
00018 #define HAVE_PROCESS_H
00019 #define HAVE_FCNTL_H
00020 #define HAVE_SYS_STAT_H
00021 #define HAVE_IO_H
00022 #define HAVE_STDDEF_H
00023 #define HAVE_STDIO_H
00024 #define HAVE_ERRNO_H
00025 #define HAVE_CTYPE_H
00026 #define HAVE_MATH_H
00027 #define HAVE_TIME_H
00028 #define HAVE_STRING_H
00029 #define HAVE_DIRECT_H
00030 #define HAVE_SETJMP_H
00031 #define HAVE_MEMORY_H
00032 #define HAVE_SYS_LOCKING_H
00033 #define HAVE_SYS_TYPES_H
00034 #define HAVE_WINSOCK_H
00035 #define HAVE__LOCKING
00036 #define HAVE_TIMEZONE
00037 #define HAVE_DAYLIGHT
00038 #define USE_SMTP
00039 #define PA_LITTLE_ENDIAN
00040 #define PA_WITH_SJLJ_EXCEPTIONS
00041
00042 //gmime
00043 #define off_t _off_t
00044 #define ssize_t int
00045
00046 // disable any execs (file::exec, file::cgi, unix mail:send)
00047 //#define NO_PA_EXECS
00048
00049 // has $mail:received
00050 //#define WITH_MAILRECEIVE
00051
00052 //xml-abled parser
00053 #define XML
00054 //#define XML_STATIC
00055 #ifdef XML_STATIC
00056 #   define LIBXML_STATIC
00057 #   define LIBXSLT_STATIC
00058 #   define LIBEXSLT_STATIC
00059 #endif
00060
00061 // if no access to console, but need asserts
00062 //#define PA_RELEASE_ASSERTS
00063
00064 #endif


pa_config_includes.h File Reference

Parser: includes all Configure-d headers. More...

Include dependency graph for pa_config_includes.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Detailed Description

Parser: includes all Configure-d headers.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

when used Configure [HAVE_CONFIG_H] it uses defines from Configure, fixed otherwise.

Definition in file pa_config_includes.h.


pa_config_includes.h Source File

pa_config_includes.h

Go to the documentation of this file.
00001
00011 #ifndef PA_CONFIG_INCLUDES_H
00012 #define PA_CONFIG_INCLUDES_H
00013
00014 #if _MSC_VER
00015 #   pragma warning(disable:4291)   // disable warning
00016 //  "no matching operator delete found; memory will not be freed if initialization throws an exception
00017 #endif
00018
00019 #if HAVE_CONFIG_H
00020 #   include "pa_config_auto.h"
00021 #else
00022 #   include "pa_config_fixed.h"
00023 #endif
00024
00025 #ifdef __cplusplus
00026 #   undef   inline
00027 #endif
00028
00029 #ifdef HAVE_ASSERT_H
00030 #   include <assert.h>
00031 #endif
00032
00033 #ifdef HAVE_CTYPE_H
00034 #   include <ctype.h>
00035 #endif
00036
00037 #ifdef HAVE_ERRNO_H
00038 #   include <errno.h>
00039 #endif
00040
00041 #ifdef HAVE_FCNTL_H
00042 #   include <fcntl.h>
00043 #endif
00044
00045 #ifdef HAVE_IO_H
00046 #   include <io.h>
00047 #endif
00048
00049 #ifdef HAVE_PROCESS_H
00050 #   include <process.h>
00051 #endif
00052
00053 #ifdef HAVE_STDARG_H
00054 #   include <stdarg.h>
00055 #endif
00056
00057 #ifdef HAVE_STDDEF_H
00058 #   include <stddef.h>
00059 #endif
00060
00061 #ifdef HAVE_STDIO_H
00062 #   include <stdio.h>
00063 #endif
00064
00065 #ifdef HAVE_SYS_STAT_H
00066 #   include <sys/stat.h>
00067 #endif
00068
00069 #if defined(HAVE_UNISTD_H) && !defined(NO_UNISTD_H)
00070 #   include <unistd.h>
00071 #endif
00072
00073 #ifdef HAVE_MATH_H
00074 #   include <math.h>
00075 #endif
00076
00077 #include <stdlib.h>
00078
00079 #ifdef HAVE_STRING_H
00080 #   include <string.h>
00081 #endif
00082
00083 #ifdef HAVE_DIRECT_H
00084 #   include <direct.h>
00085 #endif
00086
00087 #ifdef HAVE_SETJMP_H
00088 #   include <setjmp.h>
00089 #endif
00090
00091 #ifdef HAVE_MEMORY_H
00092 #   include <memory.h>
00093 #endif
00094
00095 #ifdef HAVE_NEW
00096 #include <new>
00097 #endif
00098
00099 #ifdef HAVE_SYS_FILE_H
00100 #include <sys/file.h>
00101 #endif
00102
00103 #ifdef HAVE_SYS_LOCKING_H
00104 #include <sys/locking.h>
00105 #endif
00106
00107 #ifdef HAVE_SYS_TYPES_H
00108 #include <sys/types.h>
00109 #endif
00110
00111 #ifdef HAVE_SYS_SELECT_H
00112 #include <sys/select.h>
00113 #endif
00114
00115 #ifdef HAVE_SIGNAL_H
00116 #include <signal.h>
00117 #endif
00118
00119 #ifdef HAVE_SYS_SOCKET_H
00120 #   include <sys/socket.h>
00121 #else
00122 #   if defined(HAVE_WINSOCK_H) && !defined(_MSC_VER) && !defined(CYGWIN)
00123 #       include <winsock.h>
00124 #   endif
00125 #endif
00126
00127 // must go anywhere after winsock [cygwin time.h checks for already inclusion of winsock.h]
00128 #if TIME_WITH_SYS_TIME
00129 #   include <sys/time.h>
00130 #   include <time.h>
00131 #else
00132 #   ifdef HAVE_SYS_TIME_H
00133 #       include <sys/time.h>
00134 #   else
00135 #       include <time.h>
00136 #   endif
00137 #endif
00138
00139
00140 #ifdef HAVE_NETINET_IN_H
00141 #include <netinet/in.h>
00142 #endif
00143
00144 #ifdef HAVE_ARPA_INET_H
00145 #include <arpa/inet.h>
00146 #endif
00147
00148 #ifdef HAVE_NETDB_H
00149 #include <netdb.h>
00150 #endif
00151
00152
00153 // math function replacements
00154
00155 #ifdef __cplusplus
00156
00157 #ifndef HAVE_TRUNC
00158 inline double trunc(double param) { return param > 0? floor(param) : ceil(param); }
00159 #endif
00160
00161 #ifndef HAVE_ROUND
00162 inline double round(double param) { return floor(param+0.5); }
00163 #endif
00164
00165 #ifndef HAVE_SIGN
00166 inline double sign(double param) { return param > 0 ? 1 : ( param < 0 ? -1 : 0 ); }
00167 #endif
00168
00169 #if !defined(max)
00170 inline int max(int a, int b) { return a>b?a:b; }
00171 inline int min(int a, int b){ return a<b?a:b; }
00172 inline size_t max(size_t a, size_t b) { return a>b?a:b; }
00173 inline size_t min(size_t a, size_t b){ return a<b?a:b; }
00174 #endif
00175
00176 #endif
00177
00178
00179 #if _MSC_VER
00180 // using this in calls to parent constructors
00181 #pragma warning(disable:4355)
00182
00183 //# pragma warning(disable:4065)   // switch statement contains 'default'
00184                                    // but no 'case' labels
00185 //# pragma warning(disable:4800)   // (bool)(1&2)
00186
00187 // assignment operator could not be generated
00188 //#pragma warning(disable:4512)
00189
00190 // identifier was truncated to '255' characters in the debug information
00191 #pragma warning(disable:4786)
00192
00193 // copy constructor could not be generated
00194 #pragma warning(disable:4511)
00195
00196 // assignment operator could not be generated
00197 #pragma warning(disable:4512)
00198
00199 // unreferenced local function has been removed
00200 #pragma warning(disable:4505)
00201
00202 // conditional expression is constant; while(true) OK
00203 #pragma warning(disable:4127)
00204
00205 // assignment within conditional expression if(type var=somethig) OK
00206 #pragma warning(disable:4706)
00207
00208 // memcpy deprecation
00209 #pragma warning(disable:4996)
00210
00211
00212 #if 0
00213 #ifdef _DEBUG
00214 #   define _CRTDBG_MAP_ALLOC
00215 // When the _CRTDBG_MAP_ALLOC flag is defined in the debug version of an application,
00216 // the base version of the heap functions are directly mapped to their debug versions
00217 #endif
00218 #endif
00219
00220 #endif
00221
00222 #ifdef PA_RELEASE_ASSERTS
00223 // this helps to remove warnings on helper-to-assert variables
00224 #undef NDEBUG
00225 // pa_globals.C
00226 void pa_release_assert(const char* str, const char* file, int line);
00227 #undef assert
00228 #define assert(exp) (void)( (exp) || (pa_release_assert(#exp, __FILE__, __LINE__), 0) )
00229 #endif
00230
00232 #if defined(_DEBUG) || defined(PA_RELEASE_ASSERTS)
00235 #define GC_DEBUG
00236 #endif
00237
00238 #endif


pa_dictionary.C File Reference

Parser: dictionary class impl. More...

Include dependency graph for pa_dictionary.C:

Include dependency graph

Go to the source code of this file.

Functions

void | pa_dictionary_add_first (Table::element_type row, Dictionary *self)
bool | starts (Dictionary::Subst subst, First_that_begins_info *info)

Variables

const char *const | IDENT_DICTIONARY_C = "$Date: 2005/08/09 08:14:52 $"

Detailed Description

Parser: dictionary class impl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_dictionary.C.

Function Documentation

void pa_dictionary_add_first | ( | Table::element_type | row,
 |  | Dictionary * | self
 | ) |

Definition at line 14 of file pa_dictionary.C.

References Dictionary::constructor_line, String::cstr(), Array< ArrayString * >::element_type, String::first_char(), String::is_empty(), Dictionary::starting_line_of, and Dictionary::substs.

bool starts | ( | Dictionary::Subst | subst,
 |  | First_that_begins_info * | info
 | ) | [static]

Definition at line 53 of file pa_dictionary.C.

References Dictionary::Subst::from, and Dictionary::Subst::from_length.

Referenced by Dictionary::first_that_begins().

Variable Documentation

const char* const IDENT_DICTIONARY_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_dictionary.C.


pa_dictionary.C Source File

pa_dictionary.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_DICTIONARY_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #include "pa_dictionary.h"
00011 #include "pa_exception.h"
00012
00013 // could not make this static: gcc complains "prev decl was extern"
00014 void pa_dictionary_add_first(Table::element_type row, Dictionary* self) {
00015     // get a=>b values
00016     const String* a=row->get(0);
00017     // empty 'a' check
00018     if(a->is_empty()) {
00019         throw Exception("parser.runtime",
00020             0, //&a,
00021             "dictionary table 'from' column elements must not be empty");
00022     }
00023     const String* b;
00024     if(row->count()>1) { // are there any b?
00025         b=row->get(1);
00026         if(b->is_empty())
00027             b=0;
00028     } else
00029         b=0;
00030
00031     // record simplier 'a' for quick comparisons in 'starts' extremely-tight-callback
00032     self->substs+=Dictionary::Subst(a->cstr(), b);
00033
00034     unsigned char c=(unsigned char)a->first_char();
00035     if(!self->starting_line_of[c])
00036         self->starting_line_of[c]=self->constructor_line;
00037
00038     self->constructor_line++;
00039 }
00040 Dictionary::Dictionary(Table& atable): substs(atable.count()) {
00041     // clear starting_lines
00042     memset(starting_line_of, 0, sizeof(starting_line_of));
00043     // grab first letters of first column of a table
00044     constructor_line=1;  atable.for_each(pa_dictionary_add_first, this);
00045 }
00046
00047 #ifndef DOXYGEN
00048 struct First_that_begins_info {
00049     int line;
00050     const char* str;
00051 };
00052 #endif
00053 static bool starts(Dictionary::Subst subst, First_that_begins_info* info) {
00054     // skip irrelevant lines
00055     if(info->line>1) {
00056         --info->line;
00057         return 0;
00058     }
00059
00060     return strncmp(subst.from, info->str, subst.from_length)==0;
00061 }
00062 Dictionary::Subst Dictionary::first_that_begins(const char* str) const {
00063     First_that_begins_info info;
00064     if((info.line=starting_line_of[(unsigned char)*str])) {
00065         info.str=str;
00066         return substs.first_that(starts, &info);
00067     } else
00068         return 0;
00069 }


pa_dictionary.h File Reference

Parser: dictionary class decl. More...

Include dependency graph for pa_dictionary.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Dictionary
simple dictionary, speding up lookups on contained two columned table. More...

struct | Subst

Variables

const char *const | IDENT_DICTIONARY_H = "$Date: 2005/08/09 08:14:49 $"

Detailed Description

Parser: dictionary class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_dictionary.h.

Variable Documentation

const char* const IDENT_DICTIONARY_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 11 of file pa_dictionary.h.


pa_dictionary.h Source File

pa_dictionary.h

Go to the documentation of this file.
00001
00008 #ifndef PA_DICTIONARY_H
00009 #define PA_DICTIONARY_H
00010
00011 static const char * const IDENT_DICTIONARY_H="$Date: 2005/08/09 08:14:49 $";
00012
00013 #include "pa_table.h"
00014
00016 class Dictionary: public PA_Object {
00017 public:
00018
00019     struct Subst {
00020         const char *from; size_t from_length;
00021         const String* to;
00022
00023         Subst(int): from(0) {}
00024         Subst(const char* afrom, const String* ato): from(afrom), to(ato) {
00025             from_length=strlen(afrom);
00026         }
00027         operator bool() { return from!=0; }
00028     };
00029
00031     Dictionary(Table& atable);
00032
00034     Subst first_that_begins(const char* str) const;
00035
00036 private:
00037
00038     Array<Subst> substs;
00039
00040 private:
00041     friend void pa_dictionary_add_first(Table::element_type row, Dictionary* self);
00042     //friend bool starts(FromTo row, First_that_begins_info* info);
00043
00044     int starting_line_of[0x100]; int constructor_line;
00045 };
00046
00047 #endif


pa_dir.C File Reference

Parser: directory scanning for different OS-es. More...

Include dependency graph for pa_dir.C:

Include dependency graph

Go to the source code of this file.

Functions

bool | findfirst (const char *_pathname, struct ffblk *_ffblk, int)
bool | findnext (struct ffblk *_ffblk)
void | findclose (struct ffblk *_ffblk)

Variables

const char *const | IDENT_DIR_C = "$Date: 2005/08/09 08:14:52 $"

Detailed Description

Parser: directory scanning for different OS-es.

Copyright (c) 2000,2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_dir.C.

Function Documentation

bool findfirst | ( | const char * | _pathname,
 |  | struct ffblk * | _ffblk,
 |  | int |
 | ) |

Definition at line 15 of file pa_dir.C.

References ffblk::handle, MAXPATH, and snprintf.

bool findnext ( struct ffblk * _ffblk )

Definition at line 23 of file pa_dir.C.

References ffblk::handle.

void findclose ( struct ffblk * _ffblk )

Definition at line 26 of file pa_dir.C.

References ffblk::handle.

Variable Documentation

const char* const IDENT_DIR_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_dir.C.


pa_dir.C Source File

pa_dir.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_DIR_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #include "pa_common.h"
00011 #include "pa_dir.h"
00012
00013 #ifdef WIN32
00014
00015 bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) {
00016     char mask[MAXPATH];
00017     snprintf(mask, MAXPATH, "%s/*.*", _pathname);
00018
00019     _ffblk->handle=FindFirstFile(mask, (_WIN32_FIND_DATAA *)_ffblk);
00020     return _ffblk->handle==INVALID_HANDLE_VALUE;
00021 }
00022
00023 bool findnext(struct ffblk *_ffblk) {
00024     return !FindNextFile(_ffblk->handle, (_WIN32_FIND_DATAA *)_ffblk);}
00025
00026 void findclose(struct ffblk *_ffblk) {
00027     FindClose(_ffblk->handle);
00028 }
00029
00030 #else
00031
00032 bool findfirst(const char* _pathname, struct ffblk *_ffblk, int /*_attrib*/) {
00033     strncpy(_ffblk->filePath, _pathname, MAXPATH-1); _ffblk->filePath[MAXPATH-1]=0;
00034     if(!(_ffblk->dir=opendir(_ffblk->filePath)))
00035         return true;
00036
00037     return findnext(_ffblk);
00038 }
00039
00040 bool findnext(struct ffblk *_ffblk) {
00041     while(true) {
00042         struct dirent *entry=readdir(_ffblk->dir);
00043         if(!entry)
00044             return true;
00045
00046         int maxsize=sizeof(_ffblk->ff_name)-1;
00047         strncpy(_ffblk->ff_name, entry->d_name, maxsize-1); _ffblk->ff_name[maxsize]=0;
00048
00049         char fileSpec[MAXPATH];
00050         snprintf(fileSpec, MAXPATH, "%s/%s",
00051             _ffblk->filePath,
00052             _ffblk->ff_name);
00053
00054         struct stat st;
00055
00056         _ffblk->ff_attrib =
00057             stat(fileSpec, &st) < 0 ? 0/*would fail later*/ : st.st_mode;
00058         return false;
00059     }
00060 }
00061
00062 void findclose(struct ffblk *_ffblk) {
00063     closedir(_ffblk->dir);
00064 }
00065
00066 #endif


pa_dir.h File Reference

Parser: directory scanning for different OS-es decls. More...

Include dependency graph for pa_dir.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | ffblk
win32/unix unified directory entry structure name for findfirst/next/close interface. More...

Defines

#define | MAXPATH MAX_PATH
#define | FA_DIREC FILE_ATTRIBUTE_DIRECTORY
#define | LOAD_DIR(dir, action)
main dir workhorse: calles win32/unix unified functions findfirst/next/close [skip . and ..]. More...

Functions

bool | findfirst (const char *_pathname, struct ffblk *_ffblk, int _attrib)
bool | findnext (struct ffblk *_ffblk)
void | findclose (struct ffblk *_ffblk)

Variables

const char *const | IDENT_DIR_H = "$Date: 2005/11/18 10:11:08 $"

Detailed Description

Parser: directory scanning for different OS-es decls.

Copyright (c) 2000,2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_dir.h.

Define Documentation

#define MAXPATH MAX_PATH

Definition at line 24 of file pa_dir.h.

Referenced by findfirst().

#define FA_DIREC FILE_ATTRIBUTE_DIRECTORY

Definition at line 25 of file pa_dir.h.

#define LOAD_DIR | ( | dir,
 |  | action | )

Value:

{\
    ffblk ffblk; \
    if(!findfirst(dir, &ffblk, 0)) { \
        do \
            if(*ffblk.ff_name && !(ffblk.ff_name[0]=='.' && (ffblk.ff_name[1]==0 || ffblk.ff_name[1]=='.' && ffblk.ff_name[2]==0)  )) {\
                action; \
            } \
        while(!findnext(&ffblk)); \
        findclose(&ffblk); \
    } \
}
main dir workhorse: calles win32/unix unified functions findfirst/next/close [skip . and ..].

Definition at line 77 of file pa_dir.h.

Referenced by _list().

Function Documentation

bool findfirst | ( | const char * | _pathname,
 |  | struct ffblk * | _ffblk,
 |  | int | _attrib
 | ) |

Definition at line 15 of file pa_dir.C.

References ffblk::handle, MAXPATH, and snprintf.

bool findnext ( struct ffblk * _ffblk )

Definition at line 23 of file pa_dir.C.

References ffblk::handle.

void findclose ( struct ffblk * _ffblk )

Definition at line 26 of file pa_dir.C.

References ffblk::handle.

Variable Documentation

const char* const IDENT_DIR_H = "$Date: 2005/11/18 10:11:08 $" [static]

Definition at line 11 of file pa_dir.h.


pa_dir.h Source File

pa_dir.h

Go to the documentation of this file.
00001
00008 #ifndef PA_DIR_H
00009 #define PA_DIR_H
00010
00011 static const char * const IDENT_DIR_H="$Date: 2005/11/18 10:11:08 $";
00012
00013 #include "pa_config_includes.h"
00014
00020 #ifdef WIN32
00021
00022 #include <windows.h>
00023
00024 #define MAXPATH MAX_PATH
00025 #define FA_DIREC FILE_ATTRIBUTE_DIRECTORY
00026
00027 struct ffblk {
00028     DWORD ff_attrib;/*dwFileAttributes;*/
00029     FILETIME ftCreationTime;
00030     FILETIME ftLastAccessTime;
00031     FILETIME ftLastWriteTime;
00032     DWORD nFileSizeHigh;
00033     DWORD nFileSizeLow;
00034     DWORD dwReserved0;
00035     DWORD dwReserved1;
00036     CHAR   ff_name[ MAX_PATH ];/*cFileName[ MAX_PATH ];*/
00037     CHAR   cAlternateFileName[ 14 ];
00038     /*helper*/
00039     HANDLE handle;
00040
00041 /*
00042
00043     unsigned char  ff_attrib __attribute__((packed));
00044   unsigned short ff_ftime __attribute__((packed));
00045   unsigned short ff_fdate __attribute__((packed));
00046   unsigned long  ff_fsize __attribute__((packed));
00047   char ff_name[260] __attribute__((packed));
00048  */
00049 };
00050
00051 #else
00052
00053 #include <strings.h>
00054 #include <sys/types.h>
00055 #include <dirent.h>
00056 #include <sys/stat.h>
00057
00058 #define MAXPATH 1000 /*NAME_MAX*/
00059 #define FA_DIREC S_IFDIR
00060
00061 struct ffblk {
00062     /*as if in windows :)*/
00063     unsigned char ff_attrib;
00064     char ff_name[ MAXPATH ];
00065     /*helpers*/
00066     DIR *dir;
00067     char filePath[MAXPATH];
00068 };
00069
00070 #endif
00071
00072 bool findfirst(const char* _pathname, struct ffblk *_ffblk, int _attrib);
00073 bool findnext(struct ffblk *_ffblk);
00074 void findclose(struct ffblk *_ffblk);
00075
00077 #define LOAD_DIR(dir,action) {\
00078     ffblk ffblk; \
00079     if(!findfirst(dir, &ffblk, 0)) { \
00080         do \
00081             if(*ffblk.ff_name && !(ffblk.ff_name[0]=='.' && (ffblk.ff_name[1]==0 || ffblk.ff_name[1]=='.' && ffblk.ff_name[2]==0)  )) {\
00082                 action; \
00083             } \
00084         while(!findnext(&ffblk)); \
00085         findclose(&ffblk); \
00086     } \
00087 }
00088
00089 #endif


pa_exception.C File Reference

Parser: exception class. More...

Include dependency graph for pa_exception.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_EXCEPTION_C = "$Date: 2005/08/09 08:14:52 $"

Detailed Description

Parser: exception class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_exception.C.

Variable Documentation

const char* const IDENT_EXCEPTION_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_exception.C.


pa_exception.C Source File

pa_exception.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_EXCEPTION_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #include "pa_common.h"
00011 #include "pa_exception.h"
00012 #include "pa_sapi.h"
00013 #include "pa_globals.h"
00014
00015
00016 // methods
00017
00018 Exception::Exception(): ftype(0), fproblem_source(0), fcomment(0) {}
00019 Exception::Exception(const Exception& src):
00020     ftype(src.ftype),
00021     fproblem_source(src.fproblem_source),
00022     fcomment(src.fcomment) {
00023 }
00024 Exception& Exception::operator =(const Exception& src) {
00025     ftype=src.ftype;
00026     fproblem_source=src.fproblem_source;
00027     fcomment=src.fcomment;
00028     return *this;
00029 }
00030
00031 Exception::Exception(const char* atype,
00032              const String* aproblem_source,
00033              const char* comment_fmt, ...) {
00034     ftype=atype;
00035     fproblem_source=aproblem_source;
00036
00037     if(comment_fmt) {
00038         fcomment=new(PointerFreeGC) char[MAX_STRING];
00039         va_list args;
00040         va_start(args, comment_fmt);
00041         vsnprintf(fcomment, MAX_STRING, comment_fmt, args);
00042 //      _asm int 3;
00043         va_end(args);
00044     } else
00045         fcomment=0;
00046 }
00047
00048 const String* Exception::problem_source() const {
00049     return fproblem_source && fproblem_source->length()?fproblem_source:0;
00050 }


pa_exception.h File Reference

Parser: exception decls. More...

Include dependency graph for pa_exception.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Exception

Variables

const char *const | IDENT_EXCEPTION_H = "$Date: 2005/08/09 08:14:49 $"

Detailed Description

Parser: exception decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_exception.h.

Variable Documentation

const char* const IDENT_EXCEPTION_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 11 of file pa_exception.h.


pa_exception.h Source File

pa_exception.h

Go to the documentation of this file.
00001
00008 #ifndef PA_EXCEPTION_H
00009 #define PA_EXCEPTION_H
00010
00011 static const char * const IDENT_EXCEPTION_H="$Date: 2005/08/09 08:14:49 $";
00012
00013 // includes
00014
00015 #include "pa_memory.h"
00016
00017 // forwards
00018
00019 class String;
00020
00021 // defines
00022
00023 class Exception {
00024 public:
00025
00026     Exception();
00027     Exception(
00028         const char* atype,
00029         const String* aproblem_source,
00030         const char* comment_fmt, ...);
00031     Exception(const Exception& src);
00032     operator bool() { return ftype || fproblem_source || fcomment; }
00033     Exception& operator =(const Exception& src);
00034
00036     const char* type(bool can_be_empty=false) const {
00037         if(can_be_empty)
00038             return ftype;
00039         else
00040             return ftype?ftype:"<no type>";
00041     }
00043     const String* problem_source() const;
00045     const char* comment(bool can_be_empty=false) const {
00046         const char* result=fcomment && *fcomment?fcomment:0;
00047         if(can_be_empty)
00048             return result;
00049         else
00050             return result?result:"<no comment>";
00051     }
00052
00053 protected:
00054
00055     const char* ftype;
00056     const String* fproblem_source;
00057     char* fcomment;
00058
00059 };
00060
00061 #endif


pa_exec.C File Reference

Parser: program executing for different OS-es. More...

Include dependency graph for pa_exec.C:

Include dependency graph

Go to the source code of this file.

Functions

DWORD | CreateHiddenConsoleProcess (LPCTSTR szCmdLine, LPCTSTR szScriptFileSpec, char *szEnv, PROCESS_INFORMATION *ppi, LPHANDLE phInWrite, LPHANDLE phOutRead, LPHANDLE phErrRead)
this func from http://www.ccas.ru/~posp/popov/spawn.htm. More...

void | read_pipe (String &result, HANDLE hOutRead, String::Language lang)
const char * | buildCommand (const char *file_spec_cstr, const ArrayString &argv)
void | append_env_pair (HashStringString::key_type key, HashStringString::value_type value, Append_env_pair_info *info)
PA_exec_result | pa_exec (bool, const String &file_spec, const HashStringString *env, const ArrayString &argv, String &in)

Variables

const char *const | IDENT_EXEC_C = "$Date: 2005/08/09 08:14:52 $"

Detailed Description

Parser: program executing for different OS-es.

Copyright(c) 2000,2001-2005 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Todo:
setrlimit

Definition in file pa_exec.C.

Function Documentation

DWORD CreateHiddenConsoleProcess | ( | LPCTSTR | szCmdLine,
 |  | LPCTSTR | szScriptFileSpec,
 |  | char * | szEnv,
 |  | PROCESS_INFORMATION * | ppi,
 |  | LPHANDLE | phInWrite,
 |  | LPHANDLE | phOutRead,
 |  | LPHANDLE | phErrRead
 | ) | [static]

this func from http://www.ccas.ru/~posp/popov/spawn.htm.

Definition at line 29 of file pa_exec.C.

References BOOL, dir, lsplit(), MAX_STRING, result, and rsplit().

Referenced by pa_exec().

void read_pipe | ( | String & | result,
 |  | HANDLE | hOutRead,
 |  | String::Language | lang
 | ) | [static]

Definition at line 114 of file pa_exec.C.

References String::append_know_length(), String::Language, MAX_STRING, result, and size.

Referenced by pa_exec().

const char* buildCommand | ( | const char * | file_spec_cstr,
 |  | const ArrayString & | argv
 | ) | [static]

Definition at line 125 of file pa_exec.C.

References Array< const String * >::count(), String::cstr(), MAX_STRING, pa_strdup(), result, rethrow, and size.

Referenced by pa_exec().

void append_env_pair | ( | HashStringString::key_type | key,
 |  | HashStringString::value_type | value,
 |  | Append_env_pair_info * | info
 | ) | [static]

Test:
maybe here and at argv construction --- cstr(String::L_UNSPECIFIED

Definition at line 306 of file pa_exec.C.

References String::Body::cstrm(), and value.

Referenced by pa_exec().

PA_exec_result pa_exec | ( | bool | ,
 |  | const String & | file_spec,
 |  | const HashStringString * | env,
 |  | const ArrayString & | argv,
 |  | String & | in
 | ) |

Definition at line 319 of file pa_exec.C.

References append_env_pair(), buildCommand(), Hash< K, V >::count(), Array< const String * >::count(), CreateHiddenConsoleProcess(), String::cstr(), String::cstrm(), PA_exec_result::err, Hash< K, V >::for_each(), String::L_AS_IS, String::L_FILE_SPEC, String::L_TAINTED, String::length(), MAX_STRING, PA_exec_result::out, read_pipe(), result, PA_exec_result::status, and str.

Referenced by _exec_cgi(), and sendmail().

Variable Documentation

const char* const IDENT_EXEC_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 10 of file pa_exec.C.


pa_exec.C Source File

pa_exec.C

Go to the documentation of this file.
00001
00010 static const char * const IDENT_EXEC_C="$Date: 2005/08/09 08:14:52 $";
00011
00012 #include "pa_config_includes.h"
00013
00014 #include "pa_exec.h"
00015 #include "pa_exception.h"
00016 #include "pa_common.h"
00017
00018 #ifdef WIN32
00019 #   include <windows.h>
00020 #else
00021 #   include <signal.h>
00022 #   include <sys/types.h>
00023 #   include <sys/wait.h>
00024 #endif
00025
00026 #ifdef WIN32
00027
00029 static DWORD CreateHiddenConsoleProcess(LPCTSTR szCmdLine,
00030                                         LPCTSTR szScriptFileSpec,
00031                                         char *szEnv,
00032                                         PROCESS_INFORMATION* ppi,
00033                                         LPHANDLE phInWrite,
00034                                         LPHANDLE phOutRead,
00035                                         LPHANDLE phErrRead)
00036 {
00037     DWORD result=0;
00038     BOOL fCreated;
00039     STARTUPINFO si;
00040     SECURITY_ATTRIBUTES sa={0};
00041     HANDLE hInRead;
00042     HANDLE hOutWrite;
00043     HANDLE hErrWrite;
00044
00045     // Create pipes
00046     // initialize security attributes for handle inheritance (for WinNT)
00047     sa.nLength=sizeof(sa);
00048     sa.bInheritHandle=TRUE;
00049     sa.lpSecurityDescriptor=NULL;
00050
00051     // create STDIN pipe
00052     if(!CreatePipe(&hInRead, phInWrite, &sa, 0))
00053         goto error;
00054
00055     // create STDOUT pipe
00056     if(!CreatePipe(phOutRead, &hOutWrite, &sa, 0))
00057         goto error;
00058
00059     // create STDERR pipe
00060     if(!CreatePipe(phErrRead, &hErrWrite, &sa, 0))
00061         goto error;
00062
00063     // process startup information
00064     memset(&si, 0, sizeof(si));
00065     si.cb=sizeof(si);
00066     si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
00067     // child process' console must be hidden for Win95 compatibility
00068     si.wShowWindow=SW_HIDE;
00069     // assign "other" sides of pipes
00070     si.hStdInput=hInRead;
00071     si.hStdOutput=hOutWrite;
00072     si.hStdError=hErrWrite;
00073
00074     // calculating script's directory
00075     char dir[MAX_STRING];
00076     strncpy(dir, szScriptFileSpec, MAX_STRING-1); dir[MAX_STRING-1]=0;
00077     lsplit(dir,' '); // trim arguments
00078     rsplit(dir,'/'); rsplit(dir,'\\'); // trim filename
00079
00080     // Create a child process (suspended)
00081     fCreated=CreateProcess(NULL,
00082         (LPTSTR)szCmdLine,
00083         NULL,
00084         NULL,
00085         TRUE,
00086         CREATE_NO_WINDOW,
00087         szEnv,
00088         dir,
00089         &si,
00090         ppi);
00091     if(!fCreated)
00092         result=GetLastError();
00093
00094     CloseHandle(hInRead);
00095     CloseHandle(hOutWrite);
00096     CloseHandle(hErrWrite);
00097
00098     if(!fCreated)
00099         goto error;
00100
00101     return result;
00102
00103 error:
00104     if(!result/*yet*/)
00105         result=GetLastError(); // get it
00106
00107     CloseHandle(*phInWrite);
00108     CloseHandle(*phOutRead);
00109     CloseHandle(*phErrRead);
00110
00111     return result;
00112 }
00113
00114 static void read_pipe(String& result, HANDLE hOutRead, String::Language lang){
00115     while(true) {
00116         char *buf=new(PointerFreeGC) char[MAX_STRING];
00117         unsigned long size;
00118         if(!ReadFile(hOutRead, buf, MAX_STRING-1, &size, NULL) || !size)
00119             break;
00120         buf[size]=0;
00121         result.append_know_length(buf, size, lang);
00122     }
00123 }
00124
00125 static const char* buildCommand(const char* file_spec_cstr, const ArrayString& argv) {
00126     const char* result=file_spec_cstr;
00127     if(FILE *f=fopen(file_spec_cstr, "r")) {
00128         try {
00129         char buf[MAX_STRING];
00130         size_t size=fread(buf, 1, MAX_STRING-1, f);
00131         if(size>2) {
00132             buf[size]=0;
00133             if(strncmp(buf, "#!", 2)==0) {
00134                 const char* begin=buf+2;
00135                 while(*begin==' ') // alx: were an old magic for some linux-es
00136                     begin++;
00137                 if(char *end=strchr(begin, '\n')) {
00138                     String string(pa_strdup(begin, end-begin));
00139                     string << " " << file_spec_cstr;
00140                     result=string.cstr();
00141                 }
00142             }
00143         }
00144         } catch(...) {
00145             fclose(f);
00146             rethrow;
00147         }
00148         fclose(f);
00149     }
00150     { // appending argv
00151         String string(result);
00152         for(size_t i=0; i<argv.count(); i++) {
00153             string << " ";
00154             string << *argv[i];
00155         }
00156
00157         result=string.cstr();
00158     }
00159
00160     return result;
00161 }
00162
00163 #else
00164
00165 static pid_t execve_piped(const char* file_spec_cstr,
00166             char * const argv[], char * const env[],
00167             int *pipe_in, int *pipe_out, int *pipe_err) {
00168     pid_t pid;
00169     int in_fds[2];
00170     int out_fds[2];
00171     int err_fds[2];
00172     int save_errno;
00173
00174     if(pipe_in && pipe(in_fds)<0) {
00175         save_errno=errno;
00176         errno=save_errno;
00177         return 0;
00178     }
00179
00180     if(pipe_out && pipe(out_fds)<0) {
00181         save_errno=errno;
00182         if(pipe_in) {
00183             close(in_fds[0]); close(in_fds[1]);
00184         }
00185         errno=save_errno;
00186         return 0;
00187     }
00188
00189     if(pipe_err && pipe(err_fds)<0) {
00190         save_errno=errno;
00191         if(pipe_in) {
00192             close(in_fds[0]); close(in_fds[1]);
00193         }
00194         if(pipe_out) {
00195             close(out_fds[0]); close(out_fds[1]);
00196         }
00197         errno=save_errno;
00198         return 0;
00199     }
00200
00201     if((pid=fork())<0) {
00202         save_errno=errno;
00203         if(pipe_in) {
00204             close(in_fds[0]); close(in_fds[1]);
00205         }
00206         if(pipe_out) {
00207             close(out_fds[0]); close(out_fds[1]);
00208         }
00209         if(pipe_err) {
00210             close(err_fds[0]); close(err_fds[1]);
00211         }
00212         errno=save_errno;
00213         return -1;
00214     }
00215
00216     if(!pid) {
00217         /* Child process */
00218
00219         if(pipe_out) {
00220             close(out_fds[0]);
00221             dup2(out_fds[1], STDOUT_FILENO);
00222             close(out_fds[1]);
00223         }
00224
00225         if(pipe_in) {
00226             close(in_fds[1]);
00227             dup2(in_fds[0], STDIN_FILENO);
00228             close(in_fds[0]);
00229         }
00230
00231         if(pipe_err) {
00232             close(err_fds[0]);
00233             dup2(err_fds[1], STDERR_FILENO);
00234             close(err_fds[1]);
00235         }
00236
00237         /* grabbed this from Apache source: */
00238         /*  HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */
00239         signal(SIGCHLD, SIG_DFL);   /* Was that it? */
00240
00241         // chdir to script's directory
00242         char dir[MAX_STRING];
00243         strncpy(dir, file_spec_cstr, MAX_STRING-1); dir[MAX_STRING-1]=0;
00244         rsplit(dir,'/'); // trim filename
00245         chdir(dir);
00246
00247         //  execute
00248         execve(file_spec_cstr, argv, env);
00249         exit(-errno);
00250     }
00251
00252     /* Parent process */
00253
00254     if(pipe_out) {
00255         close(out_fds[1]);
00256         *pipe_out=out_fds[0];
00257     }
00258
00259     if(pipe_in) {
00260         close(in_fds[0]);
00261         *pipe_in=in_fds[1];
00262     }
00263
00264     if(pipe_err) {
00265         close(err_fds[1]);
00266         *pipe_err=err_fds[0];
00267     }
00268
00269     return pid;
00270 }
00271
00272 static int get_exit_status(int pid) {
00273     int status;
00274     pid_t cid;
00275     while ((cid=waitpid(pid, &status, WUNTRACED)) == -1 && errno == EINTR);
00276     if(!cid)
00277         return -1;
00278     return WIFEXITED(status) ?
00279         WEXITSTATUS(status) : -2;
00280 }
00281
00282 static void read_pipe(String& result, int file, String::Language lang){
00283     while(true) {
00284         char *buf=new(PointerFreeGC) char[MAX_STRING];
00285         ssize_t length=read(file, buf, MAX_STRING-1);
00286         if(length<=0)
00287             break;
00288         buf[length]=0;
00289         result.append_know_length(buf, length, lang);
00290     }
00291 }
00292
00293 #endif
00294
00295 #ifndef DOXYGEN
00296 struct Append_env_pair_info {
00297 #ifdef WIN32
00298     String::Body& body;
00299     Append_env_pair_info(String::Body& abody): body(abody) {}
00300 #else
00301     char **env_ref;
00302 #endif
00303 };
00304 #endif
00305
00306 static void append_env_pair(HashStringString::key_type key, HashStringString::value_type value,
00307         Append_env_pair_info *info) {
00308 #ifdef WIN32
00309     info->body << key << "=" << value;
00310     info->body.append_know_length("\1", 1); // placeholder for of zero byte
00311 #else
00312     String::Body body;
00313     body << key << "=" << value.cstr();
00314
00315     *(info->env_ref++)=body.cstrm();
00316 #endif
00317 }
00318
00319 PA_exec_result pa_exec(
00320             bool
00321 #if defined(NO_PA_EXEC) || defined(PA_SAFE_MODE)
00322             forced_allow
00323 #endif
00324             ,
00325             const String& file_spec,
00326             const HashStringString* env,
00327             const ArrayString& argv,
00328             String& in) {
00329     PA_exec_result result;
00330
00331 #ifdef NO_PA_EXECS
00332     if(!forced_allow)
00333         throw Exception("parser.runtime",
00334             &file_spec,
00335             "parser execs are disabled [recompile parser without --disable-execs configure option]");
00336 #endif
00337
00338 #ifdef WIN32
00339
00340     PROCESS_INFORMATION pi;
00341     HANDLE hInWrite, hOutRead, hErrRead;
00342     const char* script_spec_cstr=file_spec.cstr(String::L_FILE_SPEC);
00343     const char* cmd=buildCommand(script_spec_cstr, argv);
00344     char* env_cstr=0;
00345     if(env) {
00346         String::Body body;
00347         Append_env_pair_info info(body);
00348         env->for_each(append_env_pair, &info);
00349         env_cstr=info.body.cstrm();
00350         for(char* replacer=env_cstr; *replacer; replacer++)
00351             if(*replacer=='\1')
00352                 *replacer=0;
00353     }
00354     if(DWORD error=CreateHiddenConsoleProcess(cmd, script_spec_cstr, env_cstr, &pi, &hInWrite, &hOutRead, &hErrRead)) {
00355         char szErrorDesc[MAX_STRING];
00356         const char* param="the file you tried to run";
00357         size_t error_size=FormatMessage(
00358             FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ARGUMENT_ARRAY , NULL, error,
00359             MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
00360             szErrorDesc, sizeof(szErrorDesc), (va_list *)&param);
00361         if(error_size>3) // ".\r\n"
00362             szErrorDesc[error_size-3]=0;
00363
00364         throw Exception(0,
00365             &file_spec,
00366             "exec failed - %s (%u). Consider adding shbang line (#!x:\\interpreter\\command line)",
00367                 error_size?szErrorDesc:"<unknown>", error);
00368     } else {
00369         const char* in_cstr=in.cstr();
00370         DWORD written_size;
00371         WriteFile(hInWrite, in_cstr, in.length(), &written_size, NULL);
00372         // EOF for stupid text reads
00373         // normally they should read CONTENT_LENGTH bytes,
00374         // without this char
00375         WriteFile(hInWrite, "\x1A", 1, &written_size, NULL);
00376         CloseHandle(hInWrite);
00377         read_pipe(result.out, hOutRead, String::L_AS_IS);
00378         CloseHandle(hOutRead);
00379         read_pipe(result.err, hErrRead, String::L_TAINTED);
00380         CloseHandle(hErrRead);
00381 /*
00382 from http://www.apache.org/websrc/cvsweb.cgi/apache-1.3/src/main/util_script.c?rev=1.151&content-type=text/vnd.viewcvs-markup
00383
00384     * We must close the handles to the new process and its main thread
00385     * to prevent handle and memory leaks.
00386 */
00387         CloseHandle(pi.hProcess);
00388         CloseHandle(pi.hThread);
00389     }
00390
00391 #else
00392
00393     // execve needs non const
00394     char* file_spec_cstr=file_spec.cstrm(String::L_FILE_SPEC);
00395
00396     int pipe_write, pipe_read, pipe_err;
00397
00398 #ifdef PA_SAFE_MODE
00399     if(!forced_allow) {
00400         struct stat finfo;
00401         if(stat(file_spec_cstr, &finfo)!=0)
00402             throw Exception("file.missing",
00403                 &file_spec,
00404                 "stat failed: %s (%d), actual filename '%s'",
00405                     strerror(errno), errno, file_spec_cstr);
00406
00407         check_safe_mode(finfo, file_spec, file_spec_cstr);
00408     }
00409 #endif
00410
00411     char* argv_cstrs[1+50+1]={file_spec_cstr, 0};
00412     const int argv_size=argv.count();
00413     const int argv_max=sizeof(argv_cstrs)/sizeof(argv_cstrs[0])-1-1;
00414     if(argv_size>argv_max)
00415         throw Exception("parser.runtime",
00416             &file_spec,
00417             "too many arguments (%d > max %d)", argv_size, argv_max);
00418     for(int i=0; i<argv_size; i++)
00419         argv_cstrs[1+i]=argv[i]->cstrm();
00420     argv_cstrs[1+argv_size]=0;
00421
00422     char **env_cstrs;
00423     if(env) {
00424         env_cstrs=new(PointerFreeGC) char *[env->count()+1/*0*/];
00425         Append_env_pair_info info={env_cstrs};
00426         env->for_each(append_env_pair, &info);
00427         *info.env_ref=0;
00428     } else
00429         env_cstrs=0;
00430
00431     pid_t pid=execve_piped(
00432         file_spec_cstr,
00433         argv_cstrs, env_cstrs,
00434         &pipe_write, &pipe_read, &pipe_err);
00435     if(pid>0) {
00436         // in child
00437         if(in.length()) {// there is some in data
00438             const char* in_cstr=in.cstr();
00439             write(pipe_write, in_cstr, in.length());
00440         }
00441         close(pipe_write);
00442         read_pipe(result.out, pipe_read, String::L_AS_IS);
00443         close(pipe_read);
00444         read_pipe(result.err, pipe_err, String::L_TAINTED);
00445         close(pipe_err);
00446
00447         result.status=get_exit_status(pid); // negative may mean "-errno[execl()]"
00448     } else {
00449         const char* str=strerror(errno);
00450         throw Exception(0,
00451             &file_spec,
00452             "%s error: %s (%d)", pid<0?"fork":"pipe", str?str:"<unknown>", errno);
00453     }
00454 #endif
00455
00456     return result;
00457 }


pa_exec.h File Reference

Parser: program executing for different OS-es decls. More...

Include dependency graph for pa_exec.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | PA_exec_result

Functions

PA_exec_result | pa_exec (bool forced_allow, const String &file_spec, const HashStringString *env, const ArrayString &argv, String &in)

Variables

const char *const | IDENT_EXEC_H = "$Date: 2005/08/09 08:14:49 $"

Detailed Description

Parser: program executing for different OS-es decls.

Copyright (c) 2000,2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_exec.h.

Function Documentation

PA_exec_result pa_exec | ( | bool | forced_allow,
 |  | const String & | file_spec,
 |  | const HashStringString * | env,
 |  | const ArrayString & | argv,
 |  | String & | in
 | ) |

Parameters:
forced_allow | allow execution regardles of --disable-execs
env | 0 | Hash of String
argv | 0 | Array of command line arguments

Definition at line 319 of file pa_exec.C.

References append_env_pair(), buildCommand(), Array< const String * >::count(), Hash< K, V >::count(), CreateHiddenConsoleProcess(), String::cstr(), String::cstrm(), PA_exec_result::err, Hash< K, V >::for_each(), String::L_AS_IS, String::L_FILE_SPEC, String::L_TAINTED, String::length(), MAX_STRING, PA_exec_result::out, read_pipe(), result, PA_exec_result::status, and str.

Referenced by _exec_cgi(), and sendmail().

Variable Documentation

const char* const IDENT_EXEC_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 11 of file pa_exec.h.


pa_exec.h Source File

pa_exec.h

Go to the documentation of this file.
00001
00008 #ifndef PA_EXEC_H
00009 #define PA_EXEC_H
00010
00011 static const char * const IDENT_EXEC_H="$Date: 2005/08/09 08:14:49 $";
00012
00013 #include "pa_string.h"
00014 #include "pa_hash.h"
00015 #include "pa_array.h"
00016 #include "pa_value.h"
00017 #include "pa_charset.h"
00018
00019 struct PA_exec_result {
00020     int status;
00021     String& out;
00022     String& err;
00023
00024     PA_exec_result(): status(0), out(*new String), err(*new String) {}
00025 };
00026
00027 PA_exec_result pa_exec(
00028             bool forced_allow,
00029             const String& file_spec,
00030             const HashStringString* env,
00031             const ArrayString& argv,
00032             String& in);
00033
00034 #endif


pa_globals.C File Reference

Parser: globals. More...

Include dependency graph for pa_globals.C:

Include dependency graph

Go to the source code of this file.

Functions

void | setup_hex_value ()
void | pa_register_thread_request (Request &r)
register request for local thread to retrive later with pa_get_request(). More...

Request & pa_thread_request ()
retrives request set by pa_set_request function, useful in contextless places [slow]. More...

void | pa_globals_destroy (void *)
void | pa_CORD_oom_fn (void)
void | gc_substitute_memory_management_functions ()
void | pa_globals_init ()
initialize global variables. More...

void | pa_globals_done ()
finalize global variables. More...

Variables

const char *const | IDENT_GLOBALS_C = "$Date: 2005/12/19 14:22:01 $"
short | hex_value [0x100]
hex_value[c] = hex value of c. More...

Hash< pa_thread_t, Request * > thread_request

Detailed Description

Parser: globals.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_globals.C.

Function Documentation

void setup_hex_value ( ) [static]

Definition at line 46 of file pa_globals.C.

References hex_value.

void pa_register_thread_request ( Request & r )

register request for local thread to retrive later with pa_get_request().

Definition at line 74 of file pa_globals.C.

References pa_get_thread_id(), and Hash< K, V >::put().

Referenced by Request::Request().

Request& pa_thread_request ( )

retrives request set by pa_set_request function, useful in contextless places [slow].

Definition at line 78 of file pa_globals.C.

References Hash< K, V >::get(), and pa_get_thread_id().

void pa_globals_destroy ( void * )

Definition at line 149 of file pa_globals.C.

void pa_CORD_oom_fn ( void )

Definition at line 269 of file pa_globals.C.

void gc_substitute_memory_management_functions ( ) [static]

Todo:
gc: libltdl: substitute lt_dlmalloc & co

Definition at line 276 of file pa_globals.C.

void pa_globals_init ( )

initialize global variables.

Test:
hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);

Definition at line 319 of file pa_globals.C.

Referenced by pa_setup_module_cells(), parser_init(), and real_parser_handler().

void pa_globals_done ( )

finalize global variables.

Definition at line 381 of file pa_globals.C.

Referenced by pa_destroy_module_cells(), parser_done(), and real_parser_handler().

Variable Documentation

const char* const IDENT_GLOBALS_C = "$Date: 2005/12/19 14:22:01 $" [static]

Definition at line 8 of file pa_globals.C.

short hex_value[0x100]

hex_value[c] = hex value of c.

Definition at line 44 of file pa_globals.C.

Referenced by setup_hex_value().

Hash<pa_thread_t, Request*> thread_request

Definition at line 73 of file pa_globals.C.


pa_globals.C Source File

pa_globals.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_GLOBALS_C="$Date: 2005/12/19 14:22:01 $";
00009
00010 #include "pa_config_includes.h"
00011
00012 #ifdef XML
00013 #include "libxml/xmlversion.h"
00014 #include "libxslt/extensions.h"
00015 #include "libxslt/xsltutils.h"
00016 extern "C" {
00017 #include "libexslt/exslt.h"
00018 };
00019 #endif
00020
00021 #include "pcre.h"
00022
00023 #include "pa_globals.h"
00024 #include "pa_string.h"
00025 #include "pa_sapi.h"
00026 #include "pa_threads.h"
00027 #include "pa_xml_io.h"
00028 #include "pa_common.h"
00029
00030 #include "pa_cache_managers.h"
00031
00032 // defines
00033
00034 //#define PA_DEBUG_XML_GC_MEMORY
00035
00036 //20051130 trying to remove this, author claims that fixed a lot there // 20040920 for now both workarounds needed. wait for new libxml/xsl versions
00037 // // there is a problem with testcase, it's unstable.
00038 // // see paf@six/bug20040920/cgi-bin/t for it-showed-bug-on-20040920-day
00039 // #define PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
00040 // #define PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
00041
00042 // globals
00043
00044 short hex_value[0x100];
00045
00046 static void setup_hex_value() {
00047     memset(hex_value, 0, sizeof(hex_value));
00048     hex_value['0'] = 0;
00049     hex_value['1'] = 1;
00050     hex_value['2'] = 2;
00051     hex_value['3'] = 3;
00052     hex_value['4'] = 4;
00053     hex_value['5'] = 5;
00054     hex_value['6'] = 6;
00055     hex_value['7'] = 7;
00056     hex_value['8'] = 8;
00057     hex_value['9'] = 9;
00058     hex_value['A'] = 10;
00059     hex_value['B'] = 11;
00060     hex_value['C'] = 12;
00061     hex_value['D'] = 13;
00062     hex_value['E'] = 14;
00063     hex_value['F'] = 15;
00064     hex_value['a'] = 10;
00065     hex_value['b'] = 11;
00066     hex_value['c'] = 12;
00067     hex_value['d'] = 13;
00068     hex_value['e'] = 14;
00069     hex_value['f'] = 15;
00070 }
00071
00072
00073 Hash<pa_thread_t, Request*> thread_request;
00074 void pa_register_thread_request(Request& r) {
00075     thread_request.put(pa_get_thread_id(), &r);
00076 }
00078 Request& pa_thread_request() {
00079     return *thread_request.get(pa_get_thread_id());
00080 }
00081
00082 #ifdef PA_RELEASE_ASSERTS
00083 void pa_release_assert(const char* str, const char* file, int line) {
00084     SAPI::die("%s at %s:%d", str, file, line);
00085 }
00086 #endif
00087
00088
00089 #ifdef XML
00090
00091 class XML_Generic_error_info {
00092 public:/*internal, actually*/
00093     char buf[MAX_STRING*5];
00094     size_t used;
00095 public:
00096     XML_Generic_error_info() {
00097         buf[used=0]=0;
00098     }
00099     const char* get() {
00100         return used? buf: 0;
00101     }
00102 };
00103
00104 static Hash<pa_thread_t, XML_Generic_error_info*> xml_generic_error_infos;
00105
00106 static void xmlParserGenericErrorFunc(void *  /*ctx*/, const char* msg, ...) {
00107 //_asm int 3;
00108     pa_thread_t thread_id=pa_get_thread_id();
00109
00110     XML_Generic_error_info* p;
00111     {
00112         SYNCHRONIZED;  // find+fill blocked
00113
00114         // first try to get existing for this thread_id
00115         p=xml_generic_error_infos.get(thread_id);
00116         if(!p) // occupy empty one
00117             xml_generic_error_infos.put(thread_id, (p=new(PointerFreeGC) XML_Generic_error_info));
00118     }
00119
00120     va_list args;
00121     va_start(args, msg);
00122     p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);
00123     va_end(args);
00124 }
00125
00126 bool xmlHaveGenericErrors() {
00127     pa_thread_t thread_id=pa_get_thread_id();
00128
00129     SYNCHRONIZED;  // find blocked
00130
00131     return xml_generic_error_infos.get(thread_id)!=0;
00132 }
00133
00134 const char* xmlGenericErrors() {
00135     pa_thread_t thread_id=pa_get_thread_id();
00136
00137     SYNCHRONIZED;  // find+free blocked
00138
00139     if(XML_Generic_error_info *p=xml_generic_error_infos.get(thread_id)) {
00140         xml_generic_error_infos.remove(thread_id);
00141         return p->get();
00142     }
00143
00144     return 0; // no errors for our thread_id registered
00145 }
00146
00147 #endif
00148
00149 void pa_globals_destroy(void *) {
00150 /*
00151     try {
00152 #ifdef XML
00153 #endif
00154     } catch(.../*const Exception& e* /) {
00155 //      SAPI::abort("pa_globals_destroy failed: %s", e.comment());
00156     }
00157 */
00158 }
00159
00160
00161 #ifdef XML
00162
00163 static char *pa_GC_strdup(const char *s) {
00164     if(!s)
00165         return 0;
00166
00167     size_t size=strlen(s)+1;
00168     char *result=(char *)GC_MALLOC_ATOMIC(size);
00169     if(!result)
00170         SAPI::abort("out of memory (while duplicating XML string [size=%d])", size);
00171
00172     memcpy(result, s, size);
00173 #ifdef PA_DEBUG_XML_GC_MEMORY
00174     fprintf(stderr, "pa_GC_strdup(%p=%s, length=%d)=0x%p\n", s, s, size, result);
00175 #endif
00176     return result;
00177 }
00178
00179 #ifdef PA_DEBUG_XML_GC_MEMORY
00180 void *pa_look_for[]={(void*)0x84ba980,(void*)0x8969460,(void*)0x0,(void*)0x0,
00181             (void*)0x0,(void*)0x0,(void*)0x0,(void*)0x0};
00182 bool pa_looked(void*p) {
00183     for(int i=0; i<8; i++)
00184         if(pa_look_for[i]==p) {
00185             __asm__("int $3");
00186             return true;
00187         }
00188     if((((int)p)&~0xFF)==0x89a7700) {
00189         __asm__("int $3");
00190         return true;
00191     }
00192     return false;
00193 }
00194 static void* pa_gc_malloc_log(size_t size){
00195     void *p=pa_gc_malloc(size);
00196         fprintf(stderr, "pa_gc_malloc_log(%d)=0x%p\n", size, p);
00197     if(pa_looked(p))
00198         fprintf(stderr,"catched debug malloc(%d)=0x%p\n", size, p);
00199     return p;
00200
00201 }
00202 static void* pa_gc_malloc_atomic_log(size_t size){
00203 #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
00204     void *p=pa_gc_malloc(size);
00205         fprintf(stderr, "pa_gc_malloc_atomicFAKE_log(%d)=0x%p\n", size, p);
00206 #else
00207     void *p=pa_gc_malloc_atomic(size);
00208         fprintf(stderr, "pa_gc_malloc_atomic_log(%d)=0x%p\n", size, p);
00209 #endif
00210     if(pa_looked(p))
00211         fprintf(stderr,"catched debug malloc atomic(%d)=0x%p\n", size, p);
00212     return p;
00213 }
00214 static void* pa_gc_realloc_log(void *ptr, size_t size){
00215     void *p=pa_gc_realloc(ptr, size);
00216         fprintf(stderr, "pa_gc_realloc_log(0x%p, %d)=0x%p\n", ptr, size, p);
00217     if(pa_looked(p))
00218         fprintf(stderr,"catched debug realloc(%d)=0x%p\n", size, p);
00219     return p;
00220 }
00221 static void pa_gc_free_log(void *p){
00222 #ifdef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
00223         fprintf(stderr, "pa_gc_freeIGNORE_log(0x%p)\n", p);
00224 #else
00225         fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
00226 #endif
00227     if(pa_looked(p))
00228         fprintf(stderr,"catched debug free(0x%p)\n", p);
00229 #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
00230         pa_gc_free(p);
00231 #endif
00232 }
00233 #else
00234
00235 inline void *check(void *result, const char *where, size_t size) {
00236     if(!result)
00237         SAPI::abort("out of memory (while %s [size=%d])", where, size);
00238
00239     return result;
00240 }
00241 static void* pa_gc_malloc_nonull(size_t size) {
00242     return check(pa_gc_malloc(size), "allocating XML compsite memory", size);
00243 }
00244 static void* pa_gc_malloc_atomic_nonull(size_t size) {
00245 #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
00246     return check(pa_gc_malloc(size), "allocating XML composite memory (asked atomic)", size);
00247 #else
00248     return check(pa_gc_malloc_atomic(size), "allocating XML atomic memory", size);
00249 #endif
00250 }
00251 static void* pa_gc_realloc_nonull(void* ptr, size_t size) {
00252     return check(pa_gc_realloc(ptr, size), "reallocating XML memory", size);
00253 }
00254
00255 static void pa_gc_free_maybeignore(
00256     void*
00257 #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
00258         ptr
00259 #endif
00260     ) {
00261 #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
00262     pa_gc_free(ptr);
00263 #endif
00264 }
00265
00266 #endif
00267 #endif
00268
00269 void pa_CORD_oom_fn(void) {
00270     SAPI::abort("out of memory (while expanding string)");
00271 }
00272
00276 static void gc_substitute_memory_management_functions() {
00277     // in libxml & libxslt
00278 #ifdef XML
00279     // asking to use GC memory
00280 #if LIBXML_VERSION >= 20507
00281 #ifdef PA_DEBUG_XML_GC_MEMORY
00282     xmlGcMemSetup(
00283         /*xmlFreeFunc */pa_gc_free_log,
00284         /*xmlMallocFunc */pa_gc_malloc_log,
00285         /*xmlMallocFunc */pa_gc_malloc_atomic_log,
00286         /*xmlReallocFunc */pa_gc_realloc_log,
00287         /*xmlStrdupFunc */pa_GC_strdup);
00288 #else
00289     xmlGcMemSetup(
00290         /*xmlFreeFunc */pa_gc_free_maybeignore,
00291         /*xmlMallocFunc */pa_gc_malloc_nonull,
00292         /*xmlMallocFunc */pa_gc_malloc_atomic_nonull,
00293         /*xmlReallocFunc */pa_gc_realloc_nonull,
00294         /*xmlStrdupFunc */pa_GC_strdup);
00295 #endif
00296
00297 #else
00298     xmlMemSetup(
00299         /*xmlFreeFunc */pa_gc_free_maybeignore,
00300         /*xmlMallocFunc */pa_gc_malloc,
00301         /*xmlReallocFunc */pa_gc_realloc,
00302         /*xmlStrdupFunc */pa_GC_strdup);
00303 #endif
00304
00305 #endif
00306
00307     // pcre
00308     pcre_malloc=pa_gc_malloc;
00309     pcre_free=pa_gc_free;
00310
00311
00312     // cord
00313     CORD_oom_fn=pa_CORD_oom_fn;
00314 }
00315
00319 void pa_globals_init() {
00320     // global variables
00321     cache_managers=new Cache_managers;
00322
00323
00324     // in various libraries
00325     gc_substitute_memory_management_functions();
00326
00327     // hex value
00328     setup_hex_value();
00329
00330 #ifdef XML
00331     // initializing xml libs
00332
00333     /*
00334     * Register the EXSLT extensions and the test module
00335     */
00336     exsltRegisterAll();
00337     xsltRegisterTestModule();
00338     xmlDefaultSAXHandlerInit();
00339     /*
00340     * disable CDATA from being built in the document tree
00341     */
00342     // never added yet  xmlDefaultSAXHandler.cdataBlock = NULL;
00343
00344     /*
00345      * Initialization function for the XML parser.
00346      * This is not reentrant. Call once before processing in case of
00347      * use in multithreaded programs.
00348     */
00349     xmlInitParser();
00350
00351     // 1. this is needed for proper parsing of stylesheets
00352     // there were a situation where honest entity ruined innocent xpath compilation
00353     // doc says "you sould turn it on on stylesheet load" without deepening into details
00354     // 2. when dom tree with entites goes under transform text nodes
00355     // got [erroreosly] cut on first entity occurance
00356     // --
00357     // that is why this is:
00358     xmlSubstituteEntitiesDefault(1);
00359
00360     // Bit in the loadsubset context field to tell to do ID/REFs lookups
00361     xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
00362     // Bit in the loadsubset context field to tell to do complete the elements attributes lists
00363     // with the ones defaulted from the DTDs
00364     xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
00365
00366     // validate each document after load/create (?)
00367     //xmlDoValidityCheckingDefaultValue = 1;
00368
00369 //regretfully this not only replaces entities on parse, but also on generate    xmlSubstituteEntitiesDefault(1);
00370     // never switched this on xmlIndentTreeOutput=1;
00371
00372     xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
00373     xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
00374 //  FILE *f=fopen("y:\\xslt.log", "wt");
00375 //  xsltSetGenericDebugFunc(f/*stderr*/, 0);
00376
00377     pa_xml_io_init();
00378 #endif
00379 }
00380
00381 void pa_globals_done() {
00382     delete cache_managers;  cache_managers=0;
00383 }
00384
00385 #ifdef _MSC_VER
00386
00387 #ifndef PA_DEBUG_DISABLE_GC
00388 #   define GC_LIB "../../../../win32/gc"
00389 #   ifdef _DEBUG
00390 #       pragma comment(lib, GC_LIB "/Debug/gc.lib")
00391 #   else
00392 #       pragma comment(lib, GC_LIB "/Release/gc.lib")
00393 #   endif
00394
00395 #endif
00396
00397 #define GNOME_LIBS "../../../../win32/gnome"
00398
00399 #ifdef WITH_MAILRECEIVE
00400 #   pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")
00401 #endif
00402
00403 #ifdef XML
00404 #   ifdef _DEBUG
00405
00406 #       ifdef LIBXML_STATIC
00407 #           pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2_a.lib")
00408 #       else
00409 #           pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2.lib")
00410 #       endif
00411
00412 #       ifdef LIBXSLT_STATIC
00413 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt_a.lib")
00414 #       else
00415 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt.lib")
00416 #       endif
00417 #       ifdef LIBEXSLT_STATIC
00418 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt_a.lib")
00419 #       else
00420 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt.lib")
00421 #       endif
00422
00423 #else
00424
00425 #       ifdef LIBXML_STATIC
00426 #           pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2_a.lib")
00427 #       else
00428 #           pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2.lib")
00429 #       endif
00430
00431 #       ifdef LIBXSLT_STATIC
00432 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt_a.lib")
00433 #       else
00434 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt.lib")
00435 #       endif
00436 #       ifdef LIBEXSLT_STATIC
00437 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt_a.lib")
00438 #       else
00439 #           pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt.lib")
00440 #       endif
00441
00442 #   endif
00443 #endif
00444
00445 #endif


pa_globals.h File Reference

Parser: global decls. More...

Include dependency graph for pa_globals.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

void | pa_globals_init ()
initialize global variables. More...

void | pa_globals_done ()
finalize global variables. More...

void | pa_register_thread_request (Request &)
register request for local thread to retrive later with pa_get_request(). More...

Request & pa_thread_request ()
retrives request set by pa_set_request function, useful in contextless places [slow]. More...

Variables

const char *const | IDENT_GLOBALS_H = "$Date: 2005/12/16 10:15:12 $"
short | hex_value [0x100]
hex_value[c] = hex value of c. More...

Detailed Description

Parser: global decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_globals.h.

Function Documentation

void pa_globals_init ( )

initialize global variables.

Test:
hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);

Definition at line 319 of file pa_globals.C.

Referenced by pa_setup_module_cells(), parser_init(), and real_parser_handler().

void pa_globals_done ( )

finalize global variables.

Definition at line 381 of file pa_globals.C.

Referenced by pa_destroy_module_cells(), parser_done(), and real_parser_handler().

void pa_register_thread_request ( Request & )

register request for local thread to retrive later with pa_get_request().

Definition at line 74 of file pa_globals.C.

References pa_get_thread_id(), and Hash< K, V >::put().

Referenced by Request::Request().

Request& pa_thread_request ( )

retrives request set by pa_set_request function, useful in contextless places [slow].

Definition at line 78 of file pa_globals.C.

References Hash< K, V >::get(), and pa_get_thread_id().

Variable Documentation

const char* const IDENT_GLOBALS_H = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 11 of file pa_globals.h.

short hex_value[0x100]

hex_value[c] = hex value of c.

Definition at line 26 of file pa_globals.h.

Referenced by setup_hex_value().


pa_globals.h Source File

pa_globals.h

Go to the documentation of this file.
00001
00008 #ifndef PA_GLOBALS_H
00009 #define PA_GLOBALS_H
00010
00011 static const char * const IDENT_GLOBALS_H="$Date: 2005/12/16 10:15:12 $";
00012
00013 #ifdef XML
00014 #   include "libxml/tree.h"
00015 #endif
00016
00017 class Request;
00018
00020 void pa_globals_init();
00021
00023 void pa_globals_done();
00024
00026 extern short hex_value[0x100];
00027
00028 #ifdef XML
00029
00030 bool xmlHaveGenericErrors();
00032 const char* xmlGenericErrors();
00033 #endif
00034
00036 void pa_register_thread_request(Request&);
00038 Request& pa_thread_request();
00039
00040 #endif


pa_hash.h File Reference

Parser: hash class decl. More...

Include dependency graph for pa_hash.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Hash
Simple hash. More...

class | Pair
pair storage. More...

class | Temp_hash_value
Auto-object used to temporarily substituting/removing hash values. More...

Functions

void | generic_hash_code (uint &result, char c)
useful generic hash function. More...

void | generic_hash_code (uint &result, const char *s)
useful generic hash function. More...

void | generic_hash_code (uint &result, const char *buf, size_t size)
useful generic hash function. More...

uint | hash_code (int self)
simple hash code of int. used by EXIF mapping. More...

Variables

const char *const | IDENT_HASH_H = "$Date: 2005/08/09 08:14:49 $"
const int | HASH_ALLOCATES_COUNT = 29
uint Hash_allocates [HASH_ALLOCATES_COUNT]
Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster. More...

Detailed Description

Parser: hash class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)

Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_hash.h.

Function Documentation

void generic_hash_code | ( | uint & | result,
 |  | char | c
 | ) | [inline]

useful generic hash function.

Definition at line 433 of file pa_hash.h.

References result, and uint.

void generic_hash_code | ( | uint & | result,
 |  | const char * | s
 | ) | [inline]

useful generic hash function.

Definition at line 441 of file pa_hash.h.

References result, and uint.

void generic_hash_code | ( | uint & | result,
 |  | const char * | buf,
 |  | size_t | size
 | ) | [inline]

useful generic hash function.

Definition at line 452 of file pa_hash.h.

References result, size, and uint.

Referenced by CORD_batched_iter_fn_generic_hash_code(), and hash_code().

uint hash_code ( int self ) [inline]

simple hash code of int. used by EXIF mapping.

Definition at line 464 of file pa_hash.h.

References generic_hash_code(), result, and uint.

Variable Documentation

const char* const IDENT_HASH_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 20 of file pa_hash.h.

const int HASH_ALLOCATES_COUNT = 29

Definition at line 25 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::expand().

uint Hash_allocates[HASH_ALLOCATES_COUNT] [static]

Initial value:

{
    5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963,
    16229, 32531, 65407, 130987, 262237, 524521, 1048793,
    2097397, 4194103, 8388857, 16777447, 33554201, 67108961,
    134217487, 268435697, 536870683, 1073741621, 2147483399}
Zend comment: Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster.

paf: HPUX ld could not handle static member: unsatisfied symbols

Definition at line 31 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::expand(), and Hash< const String::Body, void * >::Hash().


pa_hash.h Source File

pa_hash.h

Go to the documentation of this file.
00001
00009 /*
00010     The prime numbers used from zend_hash.c,
00011     the part of Zend scripting engine library,
00012     Copyrighted (C) 1999-2000    Zend Technologies Ltd.
00013     http://www.zend.com/license/0_92.txt
00014     For more information about Zend please visit http://www.zend.com/
00015 */
00016
00017 #ifndef PA_HASH_H
00018 #define PA_HASH_H
00019
00020 static const char * const IDENT_HASH_H="$Date: 2005/08/09 08:14:49 $";
00021
00022 #include "pa_memory.h"
00023 #include "pa_types.h"
00024
00025 const int HASH_ALLOCATES_COUNT=29;
00026
00031 static uint Hash_allocates[HASH_ALLOCATES_COUNT]={
00032     5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963,
00033     16229, 32531, 65407, 130987, 262237, 524521, 1048793,
00034     2097397, 4194103, 8388857, 16777447, 33554201, 67108961,
00035     134217487, 268435697, 536870683, 1073741621, 2147483399};
00036
00045 template<typename K, typename V> class Hash: public PA_Object {
00046 public:
00047
00048     typedef K key_type;
00049     typedef V value_type;
00050
00051     Hash() {
00052         allocated=Hash_allocates[allocates_index=0];
00053         threshold=allocated*THRESHOLD_PERCENT/100;
00054         fpairs_count=fused_refs=0;
00055         refs=new(UseGC) Pair*[allocated];
00056     }
00057
00058     Hash(const Hash& source) {
00059         allocates_index=source.allocates_index;
00060         allocated=source.allocated;
00061         threshold=source.threshold;
00062         fused_refs=source.fused_refs;
00063         fpairs_count=source.fpairs_count;
00064         refs=new(UseGC) Pair*[allocated];
00065
00066         // clone & rehash
00067         Pair **old_ref=source.refs;
00068         for(int index=0; index<allocated; index++)
00069             for(Pair *pair=*old_ref++; pair; ) {
00070                 Pair *next=pair->link;
00071
00072                 Pair **new_ref=&refs[index];
00073                 *new_ref=new Pair(pair->code, pair->key, pair->value, *new_ref);
00074
00075                 pair=next;
00076             }
00077     }
00078
00080     bool put(K key, V value) {
00081         if(!value) {
00082             remove(key);
00083             return false;
00084         }
00085         if(is_full())
00086             expand();
00087
00088         uint code=hash_code(key);
00089         uint index=code%allocated;
00090         Pair **ref=&refs[index];
00091         for(Pair *pair=*ref; pair; pair=pair->link)
00092             if(pair->code==code && pair->key==key) {
00093                 // found a pair with the same key
00094                 pair->value=value;
00095                 return true;
00096             }
00097
00098         // proper pair not found -- create&link_in new pair
00099         if(!*ref) // root cell were fused_refs?
00100             fused_refs++; // not, we'll use it and record the fact
00101         *ref=new Pair(code, key, value, *ref);
00102         fpairs_count++;
00103         return false;
00104     }
00105
00107     template<typename R, typename F, typename I> R replace_maybe_append(K key, V value, F prevent, I info) {
00108         if(!value) {
00109             // they can come here from somewhere (true with maybe_replace_maybe_append, keeping parallel)
00110             remove(key);
00111             // this has nothing to do with properties, doing no special property handling here
00112             return 0;
00113         }
00114
00115         if(is_full())
00116             expand();
00117
00118         uint code=hash_code(key);
00119         uint index=code%allocated;
00120         Pair **ref=&refs[index];
00121         for(Pair *pair=*ref; pair; pair=pair->link)
00122             if(pair->code==code && pair->key==key) {
00123                 // found a pair with the same key
00124                 pair->value=value;
00125                 return reinterpret_cast<R>(1);
00126             }
00127
00128         // proper pair not found
00129         // prevent-function intercepted append?
00130         if(R result=prevent(value, info))
00131             return result;
00132
00133         //create&link_in new pair
00134         if(!*ref) // root cell were fused_refs?
00135             fused_refs++; // not, we'll use it and record the fact
00136         *ref=new Pair(code, key, value, *ref);
00137         fpairs_count++;
00138         return 0;
00139     }
00140
00142     template<typename R, typename F1, typename F2, typename I>
00143         R maybe_replace_maybe_append(K key, V value, F1 prevent_replace, F2 prevent_append, I info)
00144     {
00145         if(!value) {
00146             // they can come here from Temp_value_element::dctor to restore some empty value
00147             remove(key);
00148             // this has nothing to do with properties, doing no special property handling here
00149             return 0;
00150         }
00151
00152         if(is_full())
00153             expand();
00154
00155         uint code=hash_code(key);
00156         uint index=code%allocated;
00157         Pair **ref=&refs[index];
00158         for(Pair *pair=*ref; pair; pair=pair->link)
00159             if(pair->code==code && pair->key==key) {
00160                 // found a pair with the same key
00161
00162                 // prevent-function intercepted replace?
00163                 if(R result=prevent_replace(pair->value, info))
00164                     return result;
00165
00166                 pair->value=value;
00167                 return reinterpret_cast<R>(1);
00168             }
00169
00170         // proper pair not found
00171         // prevent-function intercepted append?
00172         if(R result=prevent_append(value, info))
00173             return result;
00174
00175         //create&link_in new pair
00176         if(!*ref) // root cell were fused_refs?
00177             fused_refs++; // not, we'll use it and record the fact
00178         *ref=new Pair(code, key, value, *ref);
00179         fpairs_count++;
00180         return 0;
00181     }
00182
00184     template<typename R, typename F1, typename I>
00185         R maybe_replace_never_append(K key, V value, F1 prevent_replace, I info)
00186     {
00187         if(!value) {
00188             // they can come here from somewhere (true with maybe_replace_maybe_append, keeping parallel)
00189             remove(key);
00190             // this has nothing to do with properties, doing no special property handling here
00191             return 0;
00192         }
00193
00194         if(is_full())
00195             expand();
00196
00197         uint code=hash_code(key);
00198         uint index=code%allocated;
00199         Pair **ref=&refs[index];
00200         for(Pair *pair=*ref; pair; pair=pair->link)
00201             if(pair->code==code && pair->key==key) {
00202                 // found a pair with the same key
00203
00204                 // prevent-function intercepted replace?
00205                 if(R result=prevent_replace(pair->value, info))
00206                     return result;
00207
00208                 pair->value=value;
00209                 return reinterpret_cast<R>(1);
00210             }
00211
00212         return 0;
00213     }
00214
00216     bool remove(K key) {
00217         uint code=hash_code(key);
00218         uint index=code%allocated;
00219         for(Pair **ref=&refs[index]; *ref; ref=&(*ref)->link)
00220             if((*ref)->code==code && (*ref)->key==key) {
00221                 // found a pair with the same key
00222                 Pair *next=(*ref)->link;
00223                 delete *ref;
00224                 *ref=next;
00225                 --fpairs_count;
00226                 return true;
00227             }
00228
00229         return false;
00230     }
00231
00233     V get(K key) const {
00234         uint code=hash_code(key);
00235         uint index=code%allocated;
00236         for(Pair *pair=refs[index]; pair; pair=pair->link)
00237             if(pair->code==code && pair->key==key)
00238                 return pair->value;
00239
00240         return V(0);
00241     }
00242
00244     bool put_replaced(K key, V value) {
00245         if(!value) {
00246             remove(key);
00247             return false;
00248         }
00249         uint code=hash_code(key);
00250         uint index=code%allocated;
00251         for(Pair *pair=refs[index]; pair; pair=pair->link)
00252             if(pair->code==code && pair->key==key) {
00253                 // found a pair with the same key, replacing
00254                 pair->value=value;
00255                 return true;
00256             }
00257
00258         // proper pair not found
00259         return false;
00260     }
00261
00263     template<typename R, typename F> R maybe_put_replaced(K key, V value, F prevent) {
00264         if(!value) {
00265             // they can come here from Temp_value_element::dctor to restore some empty value
00266             remove(key);
00267             // this has nothing to do with properties, doing no special property handling here
00268             return 0;
00269         }
00270
00271         uint code=hash_code(key);
00272         uint index=code%allocated;
00273         for(Pair *pair=refs[index]; pair; pair=pair->link)
00274             if(pair->code==code && pair->key==key) {
00275                 // found a pair with the same key, replacing
00276                 // prevent-function intercepted put?
00277                 if(R result=prevent(pair->value))
00278                     return result;
00279
00280                 pair->value=value;
00281                 return reinterpret_cast<R>(1);
00282             }
00283
00284         // proper pair not found
00285         return 0;
00286     }
00287
00289     bool put_dont_replace(K key, V value) {
00290         if(!value) {
00291             remove(key);
00292             return false;
00293         }
00294         if(is_full())
00295             expand();
00296
00297         uint code=hash_code(key);
00298         uint index=code%allocated;
00299         Pair **ref=&refs[index];
00300         for(Pair *pair=*ref; pair; pair=pair->link)
00301             if(pair->code==code && pair->key==key) {
00302                 // found a pair with the same key, NOT replacing
00303                 return true;
00304             }
00305
00306         // proper pair not found -- create&link_in new pair
00307         if(!*ref) // root cell were fused_refs?
00308             fused_refs++; // not, we'll use it and record the fact
00309         *ref=new Pair(code, key, value, *ref);
00310         fpairs_count++;
00311         return false;
00312     }
00313
00317     void merge_dont_replace(const Hash& src) {
00318         for(int i=0; i<src.allocated; i++)
00319             for(Pair *pair=src.refs[i]; pair; pair=pair->link)
00320                 put_dont_replace(pair->key, pair->value);
00321     }
00322
00324     int count() const { return fpairs_count; }
00325
00327     template<typename I> void for_each(void callback(K, V, I), I info) const {
00328         Pair **ref=refs;
00329         for(int index=0; index<allocated; index++)
00330             for(Pair *pair=*ref++; pair; pair=pair->link)
00331                 callback(pair->key, pair->value, info);
00332     }
00333
00335     template<typename I> void for_each_ref(void callback(K, V&, I), I info) const {
00336         Pair **ref=refs;
00337         for(int index=0; index<allocated; index++)
00338             for(Pair *pair=*ref++; pair; pair=pair->link)
00339                 callback(pair->key, pair->value, info);
00340     }
00341
00343     template<typename I> V first_that(bool callback(K, V, I), I info) const {
00344         Pair **ref=refs;
00345         for(int index=0; index<allocated; index++)
00346             for(Pair *pair=*ref++; pair; pair=pair->link)
00347                 if(callback(pair->key, pair->value, info))
00348                     return pair->value;
00349
00350         return V(0);
00351     }
00352
00354     void clear() {
00355         memset(refs, 0, sizeof(*refs)*allocated);
00356         fpairs_count=fused_refs=0;
00357     }
00358
00359 private:
00360
00362     enum {
00363         THRESHOLD_PERCENT=75
00364     };
00365
00367     int allocates_index;
00368
00370     int allocated;
00371
00373     int threshold;
00374
00376     int fused_refs;
00377
00379     int fpairs_count;
00380
00382     class Pair: public PA_Allocated {
00383     public:
00384         uint code;
00385         K key;
00386         V value;
00387         Pair *link;
00388
00389         Pair(uint acode, K akey, V avalue, Pair *alink) :
00390             code(acode),
00391             key(akey),
00392             value(avalue),
00393             link(alink) {}
00394     } **refs;
00395
00397     bool is_full() { return fused_refs==threshold; }
00398
00400     void expand() {
00401         int old_allocated=allocated;
00402         Pair **old_refs=refs;
00403
00404         allocates_index=allocates_index+1<HASH_ALLOCATES_COUNT?allocates_index+1:HASH_ALLOCATES_COUNT-1;
00405         // allocated bigger refs array
00406         allocated=Hash_allocates[allocates_index];
00407         threshold=allocated*THRESHOLD_PERCENT/100;
00408         refs=new(UseGC) Pair*[allocated];
00409
00410         // rehash
00411         Pair **old_ref=old_refs;
00412         for(int old_index=0; old_index<old_allocated; old_index++)
00413             for(Pair *pair=*old_ref++; pair; ) {
00414                 Pair *next=pair->link;
00415
00416                 uint new_index=pair->code%allocated;
00417                 Pair **new_ref=&refs[new_index];
00418                 pair->link=*new_ref;
00419                 *new_ref=pair;
00420
00421                 pair=next;
00422             }
00423
00424         delete[] old_refs;
00425     }
00426
00427 private: //disabled
00428
00429     Hash& operator = (const Hash&) { return *this; }
00430 };
00431
00433 inline void generic_hash_code(uint& result, char c) {
00434     result=(result<<4)+c;
00435     if(uint g=(result&0xF0000000)) {
00436         result=result^(g>>24);
00437         result=result^g;
00438     }
00439 }
00441 inline void generic_hash_code(uint& result, const char* s) {
00442     while(char c=*s++) {
00443         result=(result<<4)+c;
00444         if(uint g=(result&0xF0000000)) {
00445             result=result^(g>>24);
00446             result=result^g;
00447         }
00448     }
00449 }
00450
00452 inline void generic_hash_code(uint& result, const char* buf, size_t size) {
00453     const char* end=buf+size;
00454     while(buf<end) {
00455         result=(result<<4)+*buf++;
00456         if(uint g=(result&0xF0000000)) {
00457             result=result^(g>>24);
00458             result=result^g;
00459         }
00460     }
00461 }
00462
00464 inline uint hash_code(int self) {
00465     uint result=0;
00466     generic_hash_code(result, (const char*)&self, sizeof(self));
00467     return result;
00468 }
00469
00471 template <typename K, typename V>
00472 class Temp_hash_value {
00473     Hash<K, V>& fhash;
00474     K fname;
00475     V saved_value;
00476 public:
00477     Temp_hash_value(Hash<K, V>& ahash, K aname, V avalue) :
00478         fhash(ahash),
00479         fname(aname),
00480         saved_value(ahash.get(aname)) {
00481         fhash.put(aname, avalue);
00482     }
00483     ~Temp_hash_value() {
00484         fhash.put(fname, saved_value);
00485     }
00486 };
00487
00488 #endif


pa_http.C File Reference

Parser: http support functions. More...

Include dependency graph for pa_http.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | HTTP_METHOD_NAME "method"
#define | HTTP_FORM_NAME "form"
#define | HTTP_BODY_NAME "body"
#define | HTTP_TIMEOUT_NAME "timeout"
#define | HTTP_HEADERS_NAME "headers"
#define | HTTP_ANY_STATUS_NAME "any-status"
#define | HTTP_CHARSET_NAME "charset"
#define | HTTP_TABLES_NAME "tables"
#define | HTTP_USER "user"
#define | HTTP_PASSWORD "password"
#define | DEFAULT_USER_AGENT "parser3"
#define | INADDR_NONE ((ulong) -1)
#define | CRLF "\r\n"

Functions

bool | set_addr (struct sockaddr_in *addr, const char *host, const short port)
size_t | guess_content_length (char *buf)
int | http_read_response (char *&response, size_t &response_size, int sock, bool fail_on_status_ne_200)
int | http_request (char *&response, size_t &response_size, const char *host, short port, const char *request, int timeout_secs, bool fail_on_status_ne_200)
void | http_pass_header (HashStringValue::key_type key, HashStringValue::value_type value, Http_pass_header_info *info)
Charset * | detect_charset (Charset &source_charset, const String &content_type_value)
const String * | basic_authorization_field (const char *user, const char *pass)
void | form_string_value2string (HashStringValue::key_type key, const String &value, String &result)
void | form_table_value2string (Table::element_type row, Form_table_value2string_info *info)
void | form_value2string (HashStringValue::key_type key, HashStringValue::value_type value, String *result)
const char * | pa_form2string (HashStringValue &form)
void | find_headers_end (char *p, char *&headers_end_at, char *&raw_body)
File_read_http_result | pa_internal_file_read_http (Request_charsets &charsets, const String &file_spec, bool as_text, HashStringValue *options)

Variables

const char *const | IDENT_HTTP_C = "$Date: 2005/11/28 11:32:47 $"

Detailed Description

Parser: http support functions.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_http.C.

Define Documentation

#define HTTP_METHOD_NAME "method"

Definition at line 17 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_FORM_NAME "form"

Definition at line 18 of file pa_http.C.

Referenced by form_value2string(), and pa_internal_file_read_http().

#define HTTP_BODY_NAME "body"

Definition at line 19 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_TIMEOUT_NAME "timeout"

Definition at line 20 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_HEADERS_NAME "headers"

Definition at line 21 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_ANY_STATUS_NAME "any-status"

Definition at line 22 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_CHARSET_NAME "charset"

Definition at line 23 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_TABLES_NAME "tables"

Definition at line 24 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_USER "user"

Definition at line 25 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define HTTP_PASSWORD "password"

Definition at line 26 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define DEFAULT_USER_AGENT "parser3"

Definition at line 28 of file pa_http.C.

Referenced by pa_internal_file_read_http().

#define INADDR_NONE ((ulong) -1)

Definition at line 31 of file pa_http.C.

Referenced by SMTP::ResolveHostname(), and set_addr().

#define CRLF "\r\n"

Definition at line 35 of file pa_http.C.

Referenced by http_pass_header(), and pa_internal_file_read_http().

Function Documentation

bool set_addr | ( | struct sockaddr_in * | addr,
 |  | const char * | host,
 |  | const short | port
 | ) | [static]

Definition at line 37 of file pa_http.C.

References INADDR_NONE, and ulong.

Referenced by http_request().

size_t guess_content_length ( char * buf )

Definition at line 57 of file pa_http.C.

References result.

Referenced by http_read_response().

int http_read_response | ( | char *& | response,
 |  | size_t & | response_size,
 |  | int | sock,
 |  | bool | fail_on_status_ne_200
 | ) | [static]

Definition at line 78 of file pa_http.C.

References String::as_int(), Array< const String * >::count(), Array< const String * >::get(), guess_content_length(), pa_malloc_atomic(), pa_realloc(), pa_socks_errno(), pa_socks_strerr(), pa_strdup(), result, String::split(), and ssize_t.

Referenced by http_request().

int http_request | ( | char *& | response,
 |  | size_t & | response_size,
 |  | const char * | host,
 |  | short | port,
 |  | const char * | request,
 |  | int | timeout_secs,
 |  | bool | fail_on_status_ne_200
 | ) | [static]

Definition at line 189 of file pa_http.C.

References http_read_response(), pa_socks_errno(), pa_socks_strerr(), request, result, rethrow, and set_addr().

Referenced by pa_internal_file_read_http().

void http_pass_header | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | Http_pass_header_info * | info
 | ) | [static]

Definition at line 288 of file pa_http.C.

References attributed_meaning_to_string(), String::CC_UPPER, CRLF, String::L_HTTP_HEADER, String::L_TAINTED, and value.

Referenced by pa_internal_file_read_http().

Charset* detect_charset | ( | Charset & | source_charset,
 |  | const String & | content_type_value
 | ) | [static]

Definition at line 300 of file pa_http.C.

References String::CC_UPPER, String::change_case(), String::Body::length(), String::Body::mid(), String::Body::pos(), and STRING_NOT_FOUND.

Referenced by pa_internal_file_read_http().

const String* basic_authorization_field | ( | const char * | user,
 |  | const char * | pass
 | ) | [static]

Definition at line 332 of file pa_http.C.

References String::cstr(), String::length(), pa_base64_encode(), and result.

Referenced by pa_internal_file_read_http().

void form_string_value2string | ( | HashStringValue::key_type | key,
 |  | const String & | value,
 |  | String & | result
 | ) | [static]

Definition at line 347 of file pa_http.C.

References String::append(), String::L_URI, result, and value.

Referenced by form_table_value2string(), and form_value2string().

void form_table_value2string | ( | Table::element_type | row,
 |  | Form_table_value2string_info * | info
 | ) | [static]

Definition at line 365 of file pa_http.C.

References Array< ArrayString * >::element_type, and form_string_value2string().

Referenced by form_value2string().

void form_value2string | ( | HashStringValue::key_type | key,
 |  | HashStringValue::value_type | value,
 |  | String * | result
 | ) | [static]

Definition at line 368 of file pa_http.C.

References Array< ArrayString * >::for_each(), form_string_value2string(), form_table_value2string(), HTTP_FORM_NAME, String::L_TAINTED, result, and value.

Referenced by pa_form2string().

const char* pa_form2string ( HashStringValue & form )

Definition at line 383 of file pa_http.C.

References String::cstr(), Hash< const String::Body, Value * >::for_each(), form_value2string(), and String::L_UNSPECIFIED.

Referenced by pa_internal_file_read_http().

void find_headers_end | ( | char * | p,
 |  | char *& | headers_end_at,
 |  | char *& | raw_body
 | ) | [static]

Definition at line 388 of file pa_http.C.

References p.

Referenced by pa_internal_file_read_http().

File_read_http_result pa_internal_file_read_http | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | bool | as_text,
 |  | HashStringValue * | options
 | ) |

Todo:
build .cookies field. use ^file.tables.SET-COOKIES.menu{ for now

Definition at line 408 of file pa_http.C.

References String::append(), ArrayString, Value::as_bool(), Value::as_int(), Value::as_string(), basic_authorization_field(), String::CC_UPPER, String::change_case(), change_case(), Table::columns_type, Array< const String * >::count(), Hash< const String::Body, Value * >::count(), CRLF, String::cstr(), DEFAULT_USER_AGENT, detect_charset(), find_headers_end(), Hash< const String::Body, Value * >::for_each(), format(), Array< const String * >::get(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_table(), VHash::hash(), HTTP_ANY_STATUS_NAME, HTTP_BODY_NAME, HTTP_CHARSET_NAME, HTTP_FORM_NAME, HTTP_HEADERS_NAME, HTTP_METHOD_NAME, http_pass_header(), HTTP_PASSWORD, http_request(), HTTP_TABLES_NAME, HTTP_TIMEOUT_NAME, HTTP_USER, Value::is_string(), String::L_UNSPECIFIED, String::L_URI, String::C::length, String::length(), lsplit(), MAX_STRING, String::mid(), pa_form2string(), pa_get_valid_file_options_count(), String::pos(), Hash< const String::Body, Value * >::put(), result, Request_charsets::source(), String::split(), String::C::str, STRING_NOT_FOUND, Charset::transcode(), String::trim(), and String::TRIM_BOTH.

Referenced by file_read().

Variable Documentation

const char* const IDENT_HTTP_C = "$Date: 2005/11/28 11:32:47 $" [static]

Definition at line 8 of file pa_http.C.


pa_http.C Source File

pa_http.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_HTTP_C="$Date: 2005/11/28 11:32:47 $";
00009
00010 #include "pa_http.h"
00011 #include "pa_common.h"
00012 #include "pa_charsets.h"
00013 #include "pa_request_charsets.h"
00014
00015 // defines
00016
00017 #define HTTP_METHOD_NAME  "method"
00018 #define HTTP_FORM_NAME  "form"
00019 #define HTTP_BODY_NAME  "body"
00020 #define HTTP_TIMEOUT_NAME    "timeout"
00021 #define HTTP_HEADERS_NAME "headers"
00022 #define HTTP_ANY_STATUS_NAME "any-status"
00023 #define HTTP_CHARSET_NAME "charset"
00024 #define HTTP_TABLES_NAME "tables"
00025 #define HTTP_USER "user"
00026 #define HTTP_PASSWORD "password"
00027
00028 #define DEFAULT_USER_AGENT "parser3"
00029
00030 #   ifndef INADDR_NONE
00031 #       define INADDR_NONE ((ulong) -1)
00032 #   endif
00033
00034 #undef CRLF
00035 #define CRLF "\r\n"
00036
00037 static bool set_addr(struct sockaddr_in *addr, const char* host, const short port){
00038     memset(addr, 0, sizeof(*addr));
00039     addr->sin_family=AF_INET;
00040     addr->sin_port=htons(port);
00041     if(host) {
00042         ulong packed_ip=inet_addr(host);
00043         if(packed_ip!=INADDR_NONE)
00044             memcpy(&addr->sin_addr, &packed_ip, sizeof(packed_ip));
00045         else {
00046             struct hostent *hostIP=gethostbyname(host);
00047             if(hostIP)
00048                 memcpy(&addr->sin_addr, hostIP->h_addr, hostIP->h_length);
00049             else
00050                 return false;
00051         }
00052     } else
00053         addr->sin_addr.s_addr=INADDR_ANY;
00054     return true;
00055 }
00056
00057 size_t guess_content_length(char* buf) {
00058     char* ptr;
00059     if((ptr=strstr(buf, "Content-Length:"))) // Apache
00060         goto found;
00061     if((ptr=strstr(buf, "content-length:"))) // Parser 3
00062         goto found;
00063     if((ptr=strstr(buf, "Content-length:"))) // maybe 1
00064         goto found;
00065     if((ptr=strstr(buf, "CONTENT-LENGTH:"))) // maybe 2
00066         goto found;
00067     return 0;
00068 found:
00069     char *error_pos;
00070     size_t result=(size_t)strtol(ptr+15/*strlen("CONTENT-LENGTH:")*/, &error_pos, 0);
00071
00072     const size_t reasonable_initial_max=0x400*0x400*10 /*10M*/;
00073     if(result>reasonable_initial_max) // sanity check
00074         return reasonable_initial_max;
00075     return 0;//result;
00076 }
00077
00078 static int http_read_response(char*& response, size_t& response_size, int sock, bool fail_on_status_ne_200) {
00079     int result=0;
00080     // fetching some to local buffer, guessing on possible content-length
00081     response_size=0x400*20; // initial size if content-length could not be determined
00082     const size_t preview_size=0x400*20;
00083     char preview_buf[preview_size+1/*terminator*/];  // 20K buffer to preview headers
00084     ssize_t received_size=recv(sock, preview_buf, preview_size, 0);
00085     if(received_size==0)
00086         goto done;
00087     if(received_size<0) {
00088         if(int no=pa_socks_errno())
00089             throw Exception("http.timeout",
00090                 0,
00091                 "error receiving response header: %s (%d)", pa_socks_strerr(no), no);
00092         goto done;
00093     }
00094     // terminator [helps futher string searches]
00095     preview_buf[received_size]=0;
00096     // checking status
00097     if(char* EOLat=strstr(preview_buf, "\n")) {
00098         const String status_line(pa_strdup(preview_buf, EOLat-preview_buf));
00099         ArrayString astatus;
00100         size_t pos_after=0;
00101         status_line.split(astatus, pos_after, " ");
00102         const String& status_code=*astatus.get(astatus.count()>1?1:0);
00103         result=status_code.as_int();
00104
00105         if(fail_on_status_ne_200 && result!=200)
00106             throw Exception("http.status",
00107                 &status_code,
00108                 "invalid HTTP response status");
00109     }
00110     // detecting response_size
00111     {
00112         if(size_t content_length=guess_content_length(preview_buf))
00113             response_size=preview_size+content_length; // a little more than needed, will adjust response_size by actual received size later
00114     }
00115
00116     // [gcc is happier this way, see goto above]
00117     {
00118         // allocating initial buf
00119         response=(char*)pa_malloc_atomic(response_size+1/*terminator*/); // just setting memory block type
00120         char* ptr=response;
00121         size_t todo_size=response_size;
00122         // coping part of already received body
00123         memcpy(ptr, preview_buf, received_size);
00124         ptr+=received_size;
00125         todo_size-=received_size;
00126
00127         // we use terminator byte for two purposes here:
00128         // 1. we return there zero always, not knowing: maybe they would want to create String form $file.body?
00129         //     invariant: all Strings should have zero-terminated buffers
00130         // 2. we use that out-of-size byte to detect if our content-length guess was wrong
00131         //    when recv gets more than we expected
00132         //    a) we know that the content-length guess was wrong
00133         //    b) we have space to put the first byte of extra data
00134         //    c) we use less code to detect normal situation: on last while-cycle recv expected to just return 0
00135         while(true) {
00136             received_size=recv(sock, ptr, todo_size+1/*there is always a place for terminator*/, 0);
00137             if(received_size==0) {
00138                 response_size-=todo_size; // in case we received less than expected, cut down the reported size
00139                 break;
00140             }
00141             if(received_size<0) {
00142                 if(int no=pa_socks_errno())
00143                     throw Exception("http.timeout",
00144                         0,
00145                         "error receiving response body: %s (%d)", pa_socks_strerr(no), no);
00146                 break;
00147             }
00148             // they've touched the terminator?
00149             if((size_t)received_size>todo_size)
00150             {
00151                 // that means that our guessed response_size was not big enough
00152                 const size_t grow_chunk_size=0x400*0x400; // 1M
00153                 response_size+=grow_chunk_size;
00154                 size_t ptr_offset=ptr-response;
00155                 response=(char*)pa_realloc(response, response_size+1/*terminator*/);
00156                 ptr=response+ptr_offset;
00157                 todo_size+=grow_chunk_size;
00158             }
00159             // can't do this before realloc: we need <todo_size check
00160             ptr+=received_size;
00161             todo_size-=received_size;
00162         }
00163     }
00164 done:
00165     if(result)
00166     {
00167         response[response_size]=0;
00168         return result;
00169     }
00170     else
00171         throw Exception("http.response",
00172             0,
00173             "bad response from host - no status found (size=%u)", response_size);
00174 }
00175
00176 /* ********************** request *************************** */
00177
00178 #if defined(SIGALRM) && defined(HAVE_SIGSETJMP) && defined(HAVE_SIGLONGJMP)
00179 #   define PA_USE_ALARM
00180 #endif
00181
00182 #ifdef PA_USE_ALARM
00183 static sigjmp_buf timeout_env;
00184 static void timeout_handler(int /*sig*/){
00185     siglongjmp(timeout_env, 1);
00186 }
00187 #endif
00188
00189 static int http_request(char*& response, size_t& response_size,
00190             const char* host, short port,
00191             const char* request,
00192             int timeout_secs,
00193             bool fail_on_status_ne_200) {
00194     if(!host)
00195         throw Exception("http.host",
00196             0,
00197             "zero hostname");  //never
00198
00199     volatile // to prevent makeing it register variable, because it will be clobbered by longjmp [thanks gcc warning]
00200         int sock=-1;
00201 #ifdef PA_USE_ALARM
00202     signal(SIGALRM, timeout_handler);
00203 #endif
00204 #ifdef PA_USE_ALARM
00205     if(sigsetjmp(timeout_env, 1)) {
00206         // stupid gcc [2.95.4] generated bad code
00207         // which failed to handle sigsetjmp+throw: crashed inside of pre-throw code.
00208         // rewritten simplier [athough duplicating closesocket code]
00209         if(sock>=0)
00210             closesocket(sock);
00211         throw Exception("http.timeout",
00212             0,
00213             "timeout occured while retrieving document");
00214         return 0; // never
00215     } else {
00216         alarm(timeout_secs);
00217 #endif
00218         try {
00219             int result;
00220             struct sockaddr_in dest;
00221
00222             if(!set_addr(&dest, host, port))
00223                 throw Exception("http.host",
00224                     0,
00225                     "can not resolve hostname \"%s\"", host);
00226
00227             if((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP/*0*/))<0) {
00228                 int no=pa_socks_errno();
00229                 throw Exception("http.connect",
00230                     0,
00231                     "can not make socket: %s (%d)", pa_socks_strerr(no), no);
00232             }
00233
00234             // To enable SO_DONTLINGER (that is, disable SO_LINGER)
00235             // l_onoff should be set to zero and setsockopt should be called
00236             linger dont_linger={0,0};
00237             setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char *)&dont_linger, sizeof(dont_linger));
00238
00239 #ifdef WIN32
00240 // SO_*TIMEO can be defined in .h but not implemlemented in protocol,
00241 // failing subsequently with Option not supported by protocol (99) message
00242 // could not suppress that, so leaving this only for win32
00243             int timeout_ms=timeout_secs*1000;
00244             setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout_ms, sizeof(timeout_ms));
00245             setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_ms, sizeof(timeout_ms));
00246 #endif
00247
00248             if(connect(sock, (struct sockaddr *)&dest, sizeof(dest))) {
00249                 int no=pa_socks_errno();
00250                 throw Exception("http.connect",
00251                     0,
00252                     "can not connect to host \"%s\": %s (%d)", host, pa_socks_strerr(no), no);
00253             }
00254             size_t request_size=strlen(request);
00255             if(send(sock, request, request_size, 0)!=(ssize_t)request_size) {
00256                 int no=pa_socks_errno();
00257                 throw Exception("http.timeout",
00258                     0,
00259                     "error sending request: %s (%d)", pa_socks_strerr(no), no);
00260             }
00261
00262             result=http_read_response(response, response_size, sock, fail_on_status_ne_200);
00263             closesocket(sock);
00264 #ifdef PA_USE_ALARM
00265             alarm(0);
00266 #endif
00267             return result;
00268         } catch(...) {
00269 #ifdef PA_USE_ALARM
00270             alarm(0);
00271 #endif
00272             if(sock>=0)
00273                 closesocket(sock);
00274             rethrow;
00275         }
00276 #ifdef PA_USE_ALARM
00277     }
00278 #endif
00279 }
00280
00281 #ifndef DOXYGEN
00282 struct Http_pass_header_info {
00283     Request_charsets* charsets;
00284     String* request;
00285     bool user_agent_specified;
00286 };
00287 #endif
00288 static void http_pass_header(HashStringValue::key_type key,
00289                  HashStringValue::value_type value,
00290                  Http_pass_header_info *info) {
00291     *info->request <<key<<": "
00292     << attributed_meaning_to_string(*value, String::L_HTTP_HEADER, false)
00293     << CRLF;
00294
00295     if(String(key, String::L_TAINTED).change_case(info->charsets->source(), String::CC_UPPER)=="USER-AGENT")
00296     info->user_agent_specified=true;
00297 }
00298
00299
00300 static Charset* detect_charset(Charset& source_charset, const String& content_type_value) {
00301     const String::Body CONTENT_TYPE_VALUE=
00302         content_type_value.change_case(source_charset, String::CC_UPPER);
00303     // content-type: xxx/xxx; source_charset=WE-NEED-THIS
00304     // content-type: xxx/xxx; source_charset="WE-NEED-THIS"
00305     // content-type: xxx/xxx; source_charset="WE-NEED-THIS";
00306     size_t before_charseteq_pos=CONTENT_TYPE_VALUE.pos("CHARSET=");
00307     if(before_charseteq_pos!=STRING_NOT_FOUND) {
00308         size_t charset_begin=before_charseteq_pos+8/*CHARSET="*/;
00309         size_t open_quote_pos=CONTENT_TYPE_VALUE.pos('"', charset_begin);
00310         bool quoted=open_quote_pos==charset_begin;
00311         if(quoted)
00312             charset_begin++; // skip opening '"'
00313         size_t charset_end=CONTENT_TYPE_VALUE.length();
00314         if(quoted) {
00315             size_t close_quote_pos=CONTENT_TYPE_VALUE.pos('"', charset_begin);
00316             if(close_quote_pos!=STRING_NOT_FOUND)
00317                 charset_end=close_quote_pos;
00318         } else {
00319             size_t delim_pos=CONTENT_TYPE_VALUE.pos(';', charset_begin);
00320             if(delim_pos!=STRING_NOT_FOUND)
00321                 charset_end=delim_pos;
00322         }
00323         const String::Body CHARSET_NAME_BODY=
00324             CONTENT_TYPE_VALUE.mid(charset_begin, charset_end);
00325
00326         return &charsets.get(CHARSET_NAME_BODY);
00327     }
00328
00329     return 0;
00330 }
00331
00332 static const String* basic_authorization_field(const char* user, const char* pass) {
00333     if(!user&& !pass)
00334         return 0;
00335
00336     String combined;
00337     if(user)
00338         combined<<user;
00339     combined<<":";
00340     if(pass)
00341         combined<<pass;
00342
00343     String* result=new String("Basic "); *result<<pa_base64_encode(combined.cstr(), combined.length());
00344     return result;
00345 }
00346
00347 static void form_string_value2string(
00348                                   HashStringValue::key_type key,
00349                                   const String& value,
00350                                   String& result)
00351 {
00352     result << String(key, String::L_URI) << "=";
00353     result.append(value, String::L_URI, true);
00354     result<< "&";
00355 }
00356 #ifndef DOXYGEN
00357 struct Form_table_value2string_info {
00358     HashStringValue::key_type key;
00359     String& result;
00360
00361     Form_table_value2string_info(HashStringValue::key_type akey, String& aresult):
00362         key(akey), result(aresult) {}
00363 };
00364 #endif
00365 static void form_table_value2string(Table::element_type row, Form_table_value2string_info* info) {
00366     form_string_value2string(info->key, *row->get(0), info->result);
00367 }
00368 static void form_value2string(
00369                                   HashStringValue::key_type key,
00370                                   HashStringValue::value_type value,
00371                                   String* result)
00372 {
00373     if(const String* svalue=value->get_string())
00374         form_string_value2string(key, *svalue, *result);
00375     else if(Table* tvalue=value->get_table()) {
00376         Form_table_value2string_info info(key, *result);
00377         tvalue->for_each(form_table_value2string, &info);
00378     } else
00379         throw Exception(0,
00380             new String(key, String::L_TAINTED),
00381             "is %s, "HTTP_FORM_NAME" option value must either string or table", value->type());
00382 }
00383 const char* pa_form2string(HashStringValue& form) {
00384     String string;
00385     form.for_each(form_value2string, &string);
00386     return string.cstr(String::L_UNSPECIFIED);
00387 }
00388 static void find_headers_end(char* p,
00389         char*& headers_end_at,
00390         char*& raw_body)
00391 {
00392     raw_body=p;
00393     // \n\n
00394     // \r\n\r\n
00395     while((p=strchr(p, '\n'))) {
00396         headers_end_at=++p; // \n>.<
00397         if(*p=='\r')  // \r\n>\r?<\n
00398             p++;
00399         if(*p=='\n') { // \r\n\r>\n?<
00400             raw_body=p+1;
00401             return;
00402         }
00403     }
00404     headers_end_at=0;
00405 }
00406
00408 File_read_http_result pa_internal_file_read_http(Request_charsets& charsets,
00409                         const String& file_spec,
00410                         bool as_text,
00411                         HashStringValue *options) {
00412     File_read_http_result result;
00413     char host[MAX_STRING];
00414     const char* uri;
00415     short port;
00416     const char* method="GET"; bool method_is_get;
00417     HashStringValue* form=0;
00418     const char* body_cstr=0;
00419     int timeout_secs=2;
00420     bool fail_on_status_ne_200=true;
00421     Value* vheaders=0;
00422     Charset *asked_remote_charset=0;
00423     const char* user_cstr=0;
00424     const char* password_cstr=0;
00425
00426     if(options) {
00427         int valid_options=pa_get_valid_file_options_count(*options);
00428
00429         if(Value* vmethod=options->get(HTTP_METHOD_NAME)) {
00430             valid_options++;
00431             method=vmethod->as_string().cstr();
00432         }
00433         if(Value* vform=options->get(HTTP_FORM_NAME)) {
00434             valid_options++;
00435             form=vform->get_hash();
00436         }
00437         if(Value* vbody=options->get(HTTP_BODY_NAME)) {
00438             valid_options++;
00439             body_cstr=vbody->as_string().cstr(String::L_UNSPECIFIED);
00440         }
00441         if(Value* vtimeout=options->get(HTTP_TIMEOUT_NAME)) {
00442             valid_options++;
00443             timeout_secs=vtimeout->as_int();
00444         }
00445         if((vheaders=options->get(HTTP_HEADERS_NAME))) {
00446             valid_options++;
00447         }
00448         if(Value* vany_status=options->get(HTTP_ANY_STATUS_NAME)) {
00449             valid_options++;
00450             fail_on_status_ne_200=!vany_status->as_bool();
00451         }
00452         if(Value* vcharset_name=options->get(HTTP_CHARSET_NAME)) {
00453             valid_options++;
00454             asked_remote_charset=&::charsets.get(vcharset_name->as_string().
00455                 change_case(charsets.source(), String::CC_UPPER));
00456         }
00457         if(Value* vuser=options->get(HTTP_USER)) {
00458             valid_options++;
00459             user_cstr=vuser->as_string().cstr();
00460         }
00461         if(Value* vpassword=options->get(HTTP_PASSWORD)) {
00462             valid_options++;
00463             password_cstr=vpassword->as_string().cstr();
00464         }
00465
00466         if(valid_options!=options->count())
00467             throw Exception("parser.runtime",
00468                 0,
00469                 "invalid option passed");
00470     }
00471     if(!asked_remote_charset) // defaulting to $request:charset
00472         asked_remote_charset=&charsets.source();
00473
00474     method_is_get=strcmp(method, "GET")==0;
00475     if(method_is_get && body_cstr)
00476         throw Exception("parser.runtime",
00477             0,
00478             "you can not use $."HTTP_BODY_NAME" option with method GET");
00479
00480     //preparing request
00481     String& connect_string=*new String;
00482     // not in ^sql{... L_SQL ...} spirit, but closer to ^file::load one
00483     connect_string.append(file_spec, String::L_URI); // tainted pieces -> URI pieces
00484
00485     String request_head_and_body;
00486     {
00487         // influence URLencoding of tainted pieces to String::L_URI lang
00488         Temp_client_charset temp(charsets, *asked_remote_charset);
00489
00490         const char* connect_string_cstr=connect_string.cstr(String::L_UNSPECIFIED);
00491
00492         const char* current=connect_string_cstr;
00493         if(strncmp(current, "http://", 7)!=0)
00494             throw Exception(0,
00495                 &connect_string,
00496                 "does not start with http://"); //never
00497         current+=7;
00498
00499         strncpy(host, current, sizeof(host)-1);  host[sizeof(host)-1]=0;
00500         char* host_uri=lsplit(host, '/');
00501         uri=host_uri?current+(host_uri-1-host):"/";
00502         char* port_cstr=lsplit(host, ':');
00503         char* error_pos=0;
00504         port=port_cstr?(short)strtol(port_cstr, &error_pos, 0):80;
00505
00506         bool uri_has_query_string=strchr(uri, '?')!=0;
00507
00508         //making request head
00509         String head;
00510         head << method;
00511         head << " " << uri;
00512         if(form)
00513             if(method_is_get)
00514                 head << (uri_has_query_string?"&":"?") << pa_form2string(*form);
00515         head <<" HTTP/1.0" CRLF
00516             "host: "<< host << CRLF;
00517         if(form && !method_is_get) {
00518             head << "content-type: application/x-www-form-urlencoded" CRLF;
00519             body_cstr = pa_form2string(*form);
00520         }
00521
00522         // http://www.ietf.org/rfc/rfc2617.txt
00523         if(const String* authorization_field_value=basic_authorization_field(user_cstr, password_cstr))
00524             head<<"authorization: "<<*authorization_field_value<<CRLF;
00525
00526         bool user_agent_specified=false;
00527         if(vheaders && !vheaders->is_string()) { // allow empty
00528             if(HashStringValue *headers=vheaders->get_hash()) {
00529                 Http_pass_header_info info={&charsets, &head, false};
00530                 headers->for_each(http_pass_header, &info);
00531                 user_agent_specified=info.user_agent_specified;
00532             } else
00533                 throw Exception("parser.runtime",
00534                     &connect_string,
00535                     "headers param must be hash");
00536         };
00537         if(!user_agent_specified) // defaulting
00538             head << "user-agent: " DEFAULT_USER_AGENT CRLF;
00539
00540         if(body_cstr) {
00541             // recode those pieces which are not in String::L_URI lang
00542             // [those violating HTTP standard, but widly used]
00543             body_cstr=Charset::transcode(
00544                 String::C(body_cstr, strlen(body_cstr)),
00545                 charsets.source(),
00546                 *asked_remote_charset);
00547
00548             head << "content-length: " << format(strlen(body_cstr), "%u") << CRLF;
00549         }
00550
00551         const char* head_cstr=head.cstr(String::L_UNSPECIFIED);
00552
00553         // recode those pieces which are not in String::L_URI lang
00554         // [those violating HTTP standard, but widly used]
00555         head_cstr=Charset::transcode(
00556             String::C(head_cstr, strlen(head_cstr)),
00557             charsets.source(),
00558             *asked_remote_charset);
00559
00560         // head + end of header
00561         request_head_and_body << head_cstr << CRLF;
00562         // body
00563         if(body_cstr)
00564             request_head_and_body << body_cstr;
00565     }
00566
00567     //sending request
00568     char* response;
00569     size_t response_size;
00570     int status_code=http_request(response, response_size,
00571         host, port, request_head_and_body.cstr(),
00572         timeout_secs, fail_on_status_ne_200);
00573
00574     //processing results
00575     char* raw_body; size_t raw_body_size;
00576     char* headers_end_at;
00577     find_headers_end(response,
00578         headers_end_at,
00579         raw_body);
00580     raw_body_size=response_size-(raw_body-response);
00581
00582     result.headers=new HashStringValue;
00583     VHash* vtables=new VHash;
00584     result.headers->put(HTTP_TABLES_NAME, vtables);
00585     Charset* real_remote_charset=0; // undetected, yet
00586
00587     if(headers_end_at) {
00588         *headers_end_at=0;
00589         const String header_block(String::C(response, headers_end_at-response), true);
00590
00591         ArrayString aheaders;
00592         HashStringValue& tables=vtables->hash();
00593
00594         size_t pos_after=0;
00595         header_block.split(aheaders, pos_after, "\n");
00596
00597         //processing headers
00598         size_t aheaders_count=aheaders.count();
00599         for(size_t i=1; i<aheaders_count; i++) {
00600             const String& line=*aheaders.get(i);
00601             size_t pos=line.pos(':');
00602             if(pos==STRING_NOT_FOUND || pos<1)
00603                 throw Exception("http.response",
00604                     &connect_string,
00605                     "bad response from host - bad header \"%s\"", line.cstr());
00606             const String::Body HEADER_NAME=
00607                 line.mid(0, pos).change_case(charsets.source(), String::CC_UPPER);
00608             const String& header_value=line.mid(pos+1, line.length()).trim(String::TRIM_BOTH, " \t\r");
00609             if(as_text && HEADER_NAME=="CONTENT-TYPE")
00610                 real_remote_charset=detect_charset(charsets.source(), header_value);
00611
00612             // tables
00613             {
00614                 Value *valready=(Value *)tables.get(HEADER_NAME);
00615                 bool existed=valready!=0;
00616                 Table *table;
00617                 if(existed) {
00618                     // second+ appearence
00619                     table=valready->get_table();
00620                 } else {
00621                     // first appearence
00622                     Table::columns_type columns =new ArrayString(1);
00623                     *columns+=new String("value");
00624                     table=new Table(columns);
00625                 }
00626                 // this string becomes next row
00627                 ArrayString& row=*new ArrayString(1);
00628                 row+=&header_value;
00629                 *table+=&row;
00630                 // not existed before? add it
00631                 if(!existed)
00632                     tables.put(HEADER_NAME, new VTable(table));
00633             }
00634
00635             result.headers->put(HEADER_NAME, new VString(header_value));
00636         }
00637     }
00638
00639     // output response
00640     String::C real_body=String::C(raw_body, raw_body_size);
00641     if(as_text && raw_body_size) { // must be checked because transcode returns CONST string in case length==0, which contradicts hacking few lines below
00642         // defaulting to used-asked charset [it's never empty!]
00643         if(!real_remote_charset)
00644             real_remote_charset=asked_remote_charset;
00645         real_body=Charset::transcode(real_body, *real_remote_charset, charsets.source());
00646     }
00647
00648     result.str=const_cast<char *>(real_body.str); // hacking a little
00649     result.length=real_body.length;
00650     result.headers->put(file_status_name, new VInt(status_code));
00651     return result;
00652 }


pa_http.h File Reference

Parser: commonly used functions. More...

Include dependency graph for pa_http.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

const char * | pa_form2string (HashStringValue &form)
File_read_http_result | pa_internal_file_read_http (Request_charsets &charsets, const String &file_spec, bool as_text, HashStringValue *options=0)

Variables

const char *const | IDENT_HTTP_H = "$Date: 2005/11/24 12:28:48 $"

Detailed Description

Parser: commonly used functions.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_http.h.

Function Documentation

const char* pa_form2string ( HashStringValue & form )

Definition at line 383 of file pa_http.C.

References String::cstr(), Hash< const String::Body, Value * >::for_each(), form_value2string(), and String::L_UNSPECIFIED.

Referenced by pa_internal_file_read_http().

File_read_http_result pa_internal_file_read_http | ( | Request_charsets & | charsets,
 |  | const String & | file_spec,
 |  | bool | as_text,
 |  | HashStringValue * | options
 | ) |

Todo:
build .cookies field. use ^file.tables.SET-COOKIES.menu{ for now

Definition at line 408 of file pa_http.C.

References String::append(), ArrayString, Value::as_bool(), Value::as_int(), Value::as_string(), basic_authorization_field(), String::CC_UPPER, change_case(), String::change_case(), Table::columns_type, Hash< const String::Body, Value * >::count(), Array< const String * >::count(), CRLF, String::cstr(), DEFAULT_USER_AGENT, detect_charset(), find_headers_end(), Hash< const String::Body, Value * >::for_each(), format(), Hash< const String::Body, Value * >::get(), Array< const String * >::get(), Value::get_hash(), Value::get_table(), VHash::hash(), HTTP_ANY_STATUS_NAME, HTTP_BODY_NAME, HTTP_CHARSET_NAME, HTTP_FORM_NAME, HTTP_HEADERS_NAME, HTTP_METHOD_NAME, http_pass_header(), HTTP_PASSWORD, http_request(), HTTP_TABLES_NAME, HTTP_TIMEOUT_NAME, HTTP_USER, Value::is_string(), String::L_UNSPECIFIED, String::L_URI, String::length(), String::C::length, lsplit(), MAX_STRING, String::mid(), pa_form2string(), pa_get_valid_file_options_count(), String::pos(), Hash< const String::Body, Value * >::put(), result, Request_charsets::source(), String::split(), String::C::str, STRING_NOT_FOUND, Charset::transcode(), String::trim(), and String::TRIM_BOTH.

Referenced by file_read().

Variable Documentation

const char* const IDENT_HTTP_H = "$Date: 2005/11/24 12:28:48 $" [static]

Definition at line 11 of file pa_http.h.


pa_http.h Source File

pa_http.h

Go to the documentation of this file.
00001
00008 #ifndef PA_HTTP_H
00009 #define PA_HTTP_H
00010
00011 static const char * const IDENT_HTTP_H="$Date: 2005/11/24 12:28:48 $";
00012
00013 #include "pa_vstring.h"
00014 #include "pa_vint.h"
00015 #include "pa_vhash.h"
00016 #include "pa_vtable.h"
00017 #include "pa_socks.h"
00018
00019 #ifdef CYGWIN
00020 #define _GNU_H_WINDOWS32_SOCKETS
00021 // for PASCAL
00022 #include <windows.h>
00023 // SOCKET
00024 typedef u_int   SOCKET;
00025 int PASCAL closesocket(SOCKET);
00026 #else
00027 #   if defined(WIN32)
00028 #       include <windows.h>
00029 #   else
00030 #       define closesocket close
00031 #   endif
00032 #endif
00033
00034 const char* pa_form2string(HashStringValue& form);
00035 #ifndef DOXYGEN
00036 struct File_read_http_result {
00037     char *str; size_t length;
00038     HashStringValue* headers;
00039 };
00040 #endif
00041
00042 File_read_http_result pa_internal_file_read_http(Request_charsets& charsets,
00043                         const String& file_spec,
00044                         bool as_text,
00045                         HashStringValue *options=0);
00046
00047 #endif


pa_httpd.h File Reference

Parser: http wrapper. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | pa_request_rec_tag
struct | Parser_module_config_tag
apache parser module configuration [httpd.conf + .htaccess-es]. More...

Defines

#define | PA_APLOG_EMERG 0
#define | PA_APLOG_ALERT 1
#define | PA_APLOG_CRIT 2
#define | PA_APLOG_ERR 3
#define | PA_APLOG_WARNING 4
#define | PA_APLOG_NOTICE 5
#define | PA_APLOG_INFO 6
#define | PA_APLOG_DEBUG 7
#define | PA_APLOG_LEVELMASK 7
#define | PA_APLOG_NOERRNO (PA_APLOG_LEVELMASK + 1)
#define | PA_APLOG_MARK __FILE__,__LINE__
#define | PA_REQUEST_NO_BODY 0
#define | PA_REQUEST_CHUNKED_ERROR 1
#define | PA_REQUEST_CHUNKED_DECHUNK 2
#define | PA_REQUEST_CHUNKED_PASS 3
#define | PA_HTTP_NOT_FOUND 404
#define | PA_OK 0
#define | PA_SIGPIPE 1
#define | PA_SIG_IGN (void (*)(int))1
#define | PA_MD5_DIGESTSIZE 16

Typedefs

typedef void | pa_pool
typedef void | pa_server_rec
typedef void | pa_table
typedef pa_request_rec_tag | pa_request_rec
typedef Parser_module_config_tag | Parser_module_config
apache parser module configuration [httpd.conf + .htaccess-es]. More...

typedef void | PA_MD5_CTX

Functions

const char * | pa_version ()
void | pa_setup_module_cells ()
void | pa_destroy_module_cells ()
int | pa_parser_handler (pa_request_rec *, Parser_module_config *)
void | pa_ap_log_rerror (const char *file, int line, int level, const pa_request_rec *s, const char *fmt,...)
void | pa_ap_log_error (const char *file, int line, int level, const pa_server_rec *s, const char *fmt,...)
const char * | pa_ap_table_get (const pa_table *, const char *)
void | pa_ap_table_addn (pa_table *, const char *name, const char *val)
int | pa_ap_table_size (const pa_table *)
void | pa_ap_table_do (int(*comp)(void *, const char *, const char *), void *rec, const pa_table *t,...)
char * | pa_ap_pstrdup (pa_pool *, const char *s)
int | pa_ap_setup_client_block (pa_request_rec *r, int read_policy)
int | pa_ap_should_client_block (pa_request_rec *r)
long | pa_ap_get_client_block (pa_request_rec *r, char *buffer, int bufsiz)
void | pa_ap_send_http_header (pa_request_rec *l)
int | pa_ap_rwrite (const void *buf, int nbyte, pa_request_rec *r)
void | pa_ap_hard_timeout (char *, pa_request_rec *)
void | pa_ap_reset_timeout (pa_request_rec *)
void | pa_ap_kill_timeout (pa_request_rec *)
void | pa_ap_add_cgi_vars (pa_request_rec *r)
void | pa_ap_add_common_vars (pa_request_rec *r)
void | pa_MD5Init (PA_MD5_CTX *context)
void | pa_MD5Update (PA_MD5_CTX *context, const unsigned char *input, unsigned int inputLen)
void | pa_MD5Final (unsigned char digest[PA_MD5_DIGESTSIZE], PA_MD5_CTX *context)
void | pa_MD5Encode (const unsigned char *password, const unsigned char *salt, char *result, size_t nbytes)
void | pa_to64 (char *s, unsigned long v, int n)

Variables

const char *const | IDENT_HTTPD_H = "$Date: 2004/04/01 11:43:54 $"
void(*)(int) | pa_signal (int sig, void(*disp)(int))

Detailed Description

Parser: http wrapper.

Copyright (c) 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_httpd.h.

Define Documentation

#define PA_APLOG_EMERG 0

Definition at line 58 of file pa_httpd.h.

#define PA_APLOG_ALERT 1

Definition at line 59 of file pa_httpd.h.

#define PA_APLOG_CRIT 2

Definition at line 60 of file pa_httpd.h.

#define PA_APLOG_ERR 3

Definition at line 61 of file pa_httpd.h.

#define PA_APLOG_WARNING 4

Definition at line 62 of file pa_httpd.h.

#define PA_APLOG_NOTICE 5

Definition at line 63 of file pa_httpd.h.

#define PA_APLOG_INFO 6

Definition at line 64 of file pa_httpd.h.

#define PA_APLOG_DEBUG 7

Definition at line 65 of file pa_httpd.h.

#define PA_APLOG_LEVELMASK 7

Definition at line 67 of file pa_httpd.h.

#define PA_APLOG_NOERRNO (PA_APLOG_LEVELMASK + 1)

Definition at line 69 of file pa_httpd.h.

#define PA_APLOG_MARK __FILE__,__LINE__

Definition at line 71 of file pa_httpd.h.

#define PA_REQUEST_NO_BODY 0

Definition at line 100 of file pa_httpd.h.

#define PA_REQUEST_CHUNKED_ERROR 1

Definition at line 101 of file pa_httpd.h.

Referenced by SAPI::read_post().

#define PA_REQUEST_CHUNKED_DECHUNK 2

Definition at line 102 of file pa_httpd.h.

#define PA_REQUEST_CHUNKED_PASS 3

Definition at line 103 of file pa_httpd.h.

#define PA_HTTP_NOT_FOUND 404

Definition at line 126 of file pa_httpd.h.

Referenced by pa_parser_handler().

#define PA_OK 0

Definition at line 127 of file pa_httpd.h.

Referenced by pa_parser_handler().

#define PA_SIGPIPE 1

Definition at line 131 of file pa_httpd.h.

Referenced by pa_signal(), and SAPI::read_post().

#define PA_SIG_IGN (void (*)(int))1

Definition at line 132 of file pa_httpd.h.

Referenced by pa_signal(), and SAPI::read_post().

#define PA_MD5_DIGESTSIZE 16

Definition at line 138 of file pa_httpd.h.

Typedef Documentation

typedef void pa_pool

Definition at line 19 of file pa_httpd.h.

Referenced by pa_ap_pstrdup().

typedef void pa_server_rec

Definition at line 20 of file pa_httpd.h.

Referenced by pa_ap_log_error().

typedef void pa_table

Definition at line 21 of file pa_httpd.h.

Referenced by SAPI::environment(), pa_ap_table_addn(), pa_ap_table_do(), pa_ap_table_get(), and pa_ap_table_size().

typedef struct pa_request_rec_tag pa_request_rec

typedef struct Parser_module_config_tag Parser_module_config

apache parser module configuration [httpd.conf + .htaccess-es].

typedef void PA_MD5_CTX

Definition at line 139 of file pa_httpd.h.

Referenced by _md5(), PA_API_EXPORT(), pa_MD5Final(), pa_MD5Init(), and pa_MD5Update().

Function Documentation

const char* pa_version ( )

Definition at line 30 of file mod_parser3_core.C.

References PARSER_VERSION.

Referenced by parser_module_init().

void pa_setup_module_cells ( )

Definition at line 34 of file mod_parser3_core.C.

References SAPI::abort(), pa_globals_init(), and pa_socks_init().

Referenced by parser_module_init().

void pa_destroy_module_cells ( )

Definition at line 52 of file mod_parser3_core.C.

References pa_globals_done(), and pa_socks_done().

Referenced by parser_module_done().

int pa_parser_handler | ( | pa_request_rec * | r,
 |  | Parser_module_config * | dcfg
 | ) |

Test:
r->finfo.st_mode check seems to work only on win32

Definition at line 298 of file mod_parser3_core.C.

References SAPI::add_header_attribute(), pa_request_rec_tag::finfo, pa_request_rec_tag::header_only, SAPI::log(), MAX_NUMBER, MAX_STRING, PA_HTTP_NOT_FOUND, PA_OK, SAPI_Info::r, real_parser_handler(), SAPI::send_body(), SAPI::send_header(), and snprintf.

Referenced by parser_handler().

void pa_ap_log_rerror | ( | const char * | file,
 |  | int | line,
 |  | int | level,
 |  | const pa_request_rec * | s,
 |  | const char * | fmt,
 |  | ... |
 | ) |

Definition at line 481 of file mod_parser3.c.

References file, pa_request_rec_tag::real_request_rec, and str.

Referenced by SAPI::log().

void pa_ap_log_error | ( | const char * | file,
 |  | int | line,
 |  | int | level,
 |  | const pa_server_rec * | s,
 |  | const char * | fmt,
 |  | ... |
 | ) |

Definition at line 494 of file mod_parser3.c.

References file, pa_server_rec, and str.

Referenced by die_or_abort().

const char* pa_ap_table_get | ( | const pa_table * | ,
 |  | const char * |
 | ) |

Definition at line 508 of file mod_parser3.c.

References pa_table.

Referenced by SAPI::get_env().

void pa_ap_table_addn | ( | pa_table * | ,
 |  | const char * | name,
 |  | const char * | val
 | ) |

Definition at line 511 of file mod_parser3.c.

References pa_table, and val.

Referenced by SAPI::add_header_attribute().

int pa_ap_table_size ( const pa_table * )

Definition at line 515 of file mod_parser3.c.

References pa_table.

Referenced by SAPI::environment().

void pa_ap_table_do | ( | int(* | comp)(void *, const char *, const char *),
 |  | void * | rec,
 |  | const pa_table * | t,
 |  | ... |
 | ) |

Definition at line 519 of file mod_parser3.c.

References pa_table.

Referenced by SAPI::environment().

char* pa_ap_pstrdup | ( | pa_pool * | ,
 |  | const char * | s
 | ) |

Definition at line 524 of file mod_parser3.c.

References p, and pa_pool.

Referenced by SAPI::add_header_attribute().

int pa_ap_setup_client_block | ( | pa_request_rec * | r,
 |  | int | read_policy
 | ) |

Definition at line 530 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

int pa_ap_should_client_block ( pa_request_rec * r )

Definition at line 534 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

long pa_ap_get_client_block | ( | pa_request_rec * | r,
 |  | char * | buffer,
 |  | int | bufsiz
 | ) |

Definition at line 537 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

void pa_ap_send_http_header ( pa_request_rec * l )

Definition at line 541 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::send_header().

int pa_ap_rwrite | ( | const void * | buf,
 |  | int | nbyte,
 |  | pa_request_rec * | r
 | ) |

Definition at line 544 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::send_body().

void pa_ap_hard_timeout | ( | char * | ,
 |  | pa_request_rec * |
 | ) |

Definition at line 551 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post(), SAPI::send_body(), and SAPI::send_header().

void pa_ap_reset_timeout ( pa_request_rec * )

Definition at line 554 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::read_post().

void pa_ap_kill_timeout ( pa_request_rec * )

Definition at line 557 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by SAPI::send_body(), and SAPI::send_header().

void pa_ap_add_cgi_vars ( pa_request_rec * r )

Definition at line 564 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by real_parser_handler().

void pa_ap_add_common_vars ( pa_request_rec * r )

Definition at line 567 of file mod_parser3.c.

References pa_request_rec_tag::real_request_rec.

Referenced by real_parser_handler().

void pa_MD5Init ( PA_MD5_CTX * context )

Definition at line 574 of file mod_parser3.c.

References context, and PA_MD5_CTX.

Referenced by _md5().

void pa_MD5Update | ( | PA_MD5_CTX * | context,
 |  | const unsigned char * | input,
 |  | unsigned int | inputLen
 | ) |

Definition at line 575 of file mod_parser3.c.

References context, inputLen, and PA_MD5_CTX.

Referenced by _md5().

void pa_MD5Final | ( | unsigned char | digest[PA_MD5_DIGESTSIZE],
 |  | PA_MD5_CTX * | context
 | ) |

Referenced by _md5().

void pa_MD5Encode | ( | const unsigned char * | password,
 |  | const unsigned char * | salt,
 |  | char * | result,
 |  | size_t | nbytes
 | ) |

Definition at line 579 of file mod_parser3.c.

References result, and salt.

Referenced by _crypt().

void pa_to64 | ( | char * | s,
 |  | unsigned long | v,
 |  | int | n
 | ) |

Definition at line 582 of file mod_parser3.c.

References v.

Variable Documentation

const char* const IDENT_HTTPD_H = "$Date: 2004/04/01 11:43:54 $" [static]

Definition at line 11 of file pa_httpd.h.

void(*)(int) pa_signal(int sig, void (*disp)(int))

Definition at line 134 of file pa_httpd.h.


pa_httpd.h Source File

pa_httpd.h

Go to the documentation of this file.
00001
00008 #ifndef PA_HTTPD_H
00009 #define PA_HTTPD_H
00010
00011 static const char * const IDENT_HTTPD_H="$Date: 2004/04/01 11:43:54 $";
00012
00013 #ifdef __cplusplus
00014 extern "C" {
00015 #endif
00016
00017 // import from c to c++
00018
00019 typedef void pa_pool;
00020 typedef void pa_server_rec;
00021 typedef void pa_table;
00022
00023 typedef struct pa_request_rec_tag {
00024     void* real_request_rec;
00025
00026     pa_pool* pool;
00027     int header_only;        /* HEAD request, as opposed to GET */
00028     int* status;
00029     const char *method;     /* GET, HEAD, POST, etc. */
00030
00031     pa_table *headers_out;
00032     void* subprocess_env;
00033     const char ** content_type;
00034
00035     char *uri;          /* the path portion of the URI */
00036     char *filename;     /* filename if found, otherwise NULL */
00037     char *path_info;
00038     char *args;         /* QUERY_ARGS, if any */
00039     struct stat* finfo;     /* ST_MODE set to zero if no such file */
00040 } pa_request_rec;
00041
00043 typedef struct Parser_module_config_tag {
00044     const char* parser_config_filespec;
00045     int parser_status_allowed;
00046 } Parser_module_config;
00047
00048 const char* pa_version();
00049 void pa_setup_module_cells();
00050 void pa_destroy_module_cells();
00051 int pa_parser_handler(pa_request_rec*, Parser_module_config*);
00052
00053 // export from c to c++
00054
00055
00056 // http_log.h
00057
00058 #define PA_APLOG_EMERG  0   /* system is unusable */
00059 #define PA_APLOG_ALERT  1   /* action must be taken immediately */
00060 #define PA_APLOG_CRIT   2   /* critical conditions */
00061 #define PA_APLOG_ERR    3   /* error conditions */
00062 #define PA_APLOG_WARNING    4   /* warning conditions */
00063 #define PA_APLOG_NOTICE 5   /* normal but significant condition */
00064 #define PA_APLOG_INFO   6   /* informational */
00065 #define PA_APLOG_DEBUG  7   /* debug-level messages */
00066
00067 #define PA_APLOG_LEVELMASK  7   /* mask off the level value */
00068
00069 #define PA_APLOG_NOERRNO        (PA_APLOG_LEVELMASK + 1)
00070
00071 #define PA_APLOG_MARK   __FILE__,__LINE__
00072
00073 void pa_ap_log_rerror(const char *file, int line, int level,
00074                  const pa_request_rec *s, const char *fmt, ...);
00075
00076
00077 void pa_ap_log_error(const char *file, int line, int level,
00078                  const pa_server_rec *s, const char *fmt, ...);
00079
00080 // ap_alloc.h
00081
00082 const char * pa_ap_table_get(const pa_table *, const char *);
00083 void pa_ap_table_addn(pa_table *, const char *name, const char *val);
00084
00085 int pa_ap_table_size(const pa_table *);
00086
00087 void pa_ap_table_do(int (*comp) (void *, const char *, const char *),
00088                                     void *rec, const pa_table *t,...);
00089
00090 char * pa_ap_pstrdup(pa_pool *, const char *s);
00091
00092 // http_protocol.h
00093
00094 /* Possible values for request_rec.read_body (set by handling module):
00095  *    REQUEST_NO_BODY          Send 413 error if message has any body
00096  *    REQUEST_CHUNKED_ERROR    Send 411 error if body without Content-Length
00097  *    REQUEST_CHUNKED_DECHUNK  If chunked, remove the chunks for me.
00098  *    REQUEST_CHUNKED_PASS     Pass the chunks to me without removal.
00099  */
00100 #define PA_REQUEST_NO_BODY          0
00101 #define PA_REQUEST_CHUNKED_ERROR    1
00102 #define PA_REQUEST_CHUNKED_DECHUNK  2
00103 #define PA_REQUEST_CHUNKED_PASS     3
00104
00105 int pa_ap_setup_client_block(pa_request_rec *r, int read_policy);
00106 int pa_ap_should_client_block(pa_request_rec *r);
00107 long pa_ap_get_client_block(pa_request_rec *r, char *buffer, int bufsiz);
00108 void pa_ap_send_http_header(pa_request_rec *l);
00109 int pa_ap_rwrite(const void *buf, int nbyte, pa_request_rec *r);
00110
00111
00112 // http_main.h
00113
00114 void pa_ap_hard_timeout(char *, pa_request_rec *);
00115 void pa_ap_reset_timeout(pa_request_rec *);
00116 void pa_ap_kill_timeout(pa_request_rec *);
00117
00118
00119 // util_script.h
00120
00121 void pa_ap_add_cgi_vars(pa_request_rec *r);
00122 void pa_ap_add_common_vars(pa_request_rec *r);
00123
00124 // httpd.h
00125
00126 #define PA_HTTP_NOT_FOUND                     404
00127 #define PA_OK 0         /* Module has handled this stage. */
00128
00129 // signal.h
00130
00131 #define PA_SIGPIPE 1 /* must translate to real one */
00132 #define PA_SIG_IGN (void (*)(int))1           /* must translate to real one */
00133
00134 void (*pa_signal (int sig, void (*disp)(int)))(int);
00135
00136 // ap_md5.h
00137
00138 #define PA_MD5_DIGESTSIZE 16
00139 typedef void PA_MD5_CTX;
00140
00141 void pa_MD5Init(PA_MD5_CTX *context);
00142 void pa_MD5Update(PA_MD5_CTX *context, const unsigned char *input,
00143                   unsigned int inputLen);
00144 void pa_MD5Final(unsigned char digest[PA_MD5_DIGESTSIZE],
00145                  PA_MD5_CTX *context);
00146 void pa_MD5Encode(const unsigned char *password,
00147                   const unsigned char *salt,
00148                   char *result, size_t nbytes);
00149 void pa_to64(char *s, unsigned long v, int n);
00150
00151
00152 #ifdef __cplusplus
00153 }
00154 #endif
00155
00156 #endif


pa_junction.h File Reference

Parser: Junction class decl. More...

Include dependency graph for pa_junction.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Junction
junction is some code joined with context of it's evaluation. More...

Variables

const char *const | IDENT_JUNCTION_H = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: Junction class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_junction.h.

Variable Documentation

const char* const IDENT_JUNCTION_H = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 11 of file pa_junction.h.


pa_junction.h Source File

pa_junction.h

Go to the documentation of this file.
00001
00008 #ifndef PA_JUNCTION_H
00009 #define PA_JUNCTION_H
00010
00011 static const char * const IDENT_JUNCTION_H="$Date: 2005/08/09 08:14:53 $";
00012
00013
00014 #include "pa_string.h"
00015 #include "pa_array.h"
00016 #include "pa_exception.h"
00017 #include "pa_operation.h"
00018 #include "pa_value.h"
00019
00050 class Junction {
00051 public:
00052
00054     Junction(Value& aself,
00055         const Method* amethod,
00056         VMethodFrame* amethod_frame,
00057         Value* arcontext,
00058         WContext* awcontext,
00059         ArrayOperation* acode);
00060
00062     Junction(Value& aself,
00063         const Method* amethod,
00064         bool ais_getter=false): self(aself),
00065         method(amethod),
00066         is_getter(ais_getter) {}
00067
00068
00069     void reattach(WContext *new_wcontext);
00070
00072     Value& self;
00074
00075     const Method* method;
00077
00078
00079     VMethodFrame* method_frame;
00080     Value* rcontext;
00081     WContext* wcontext;
00082     ArrayOperation* code;
00084
00085     bool is_getter;
00087 };
00088
00089 #endif


pa_md5.h File Reference

Parser: copied from apache 1.3.20 sources. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | PA_MD5_CTX

Defines

#define | PA_API_EXPORT(rtype) rtype
#define | MD5_DIGESTSIZE 16
#define | PA_MD5PW_ID "$apr1$"
#define | PA_MD5PW_IDLEN 6

Typedefs

typedef unsigned int | UINT4

Functions

PA_API_EXPORT (void) pa_MD5Init(PA_MD5_CTX *context)
PA_API_EXPORT (void) pa_MD5Encode(const unsigned char *password

Variables

const char *const | IDENT_MD5_H = "$Date: 2005/08/09 08:14:51 $"
const unsigned char * | input
const unsigned char unsigned
int 		inputLen
PA_MD5_CTX * context
const unsigned char * | salt
const unsigned char char * | result
const unsigned char char size_t | nbytes
unsigned long | v
unsigned long int | n

Detailed Description

Parser: copied from apache 1.3.20 sources.

Replaced ap_ to pa_ prefixes. linked into all targets but Apache-module target, where linked targets/apache/pa_md5c.c stub instead.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)

Definition in file pa_md5.h.

Define Documentation

#define PA_API_EXPORT ( rtype ) rtype

Definition at line 101 of file pa_md5.h.

#define MD5_DIGESTSIZE 16

Definition at line 111 of file pa_md5.h.

Referenced by pa_MD5Final().

#define PA_MD5PW_ID "$apr1$"

Definition at line 129 of file pa_md5.h.

Referenced by _crypt().

#define PA_MD5PW_IDLEN 6

Definition at line 130 of file pa_md5.h.

Referenced by _crypt().

Typedef Documentation

typedef unsigned int UINT4

Definition at line 114 of file pa_md5.h.

Function Documentation

PA_API_EXPORT ( void )

Definition at line 188 of file pa_md5c.c.

References context, and PA_MD5_CTX.

PA_API_EXPORT ( void ) const

Variable Documentation

const char* const IDENT_MD5_H = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 99 of file pa_md5.h.

const unsigned char* input

Definition at line 133 of file pa_md5.h.

const unsigned char unsigned int inputLen

Definition at line 133 of file pa_md5.h.

Referenced by pa_MD5Update().

PA_MD5_CTX* context

Definition at line 136 of file pa_md5.h.

Referenced by _md5(), file_measure_action(), file_read_action(), file_read_action_under_lock(), file_write_action(), file_write_action_under_lock(), locked_process_and_cache_put_action(), PA_API_EXPORT(), pa_MD5Final(), pa_MD5Init(), and pa_MD5Update().

const unsigned char* salt

Definition at line 138 of file pa_md5.h.

Referenced by calc_prefix_size(), and pa_MD5Encode().

const unsigned char char* result

Definition at line 138 of file pa_md5.h.

Referenced by _count(), _fullpath(), _hash(), _intersection(), _intersects(), _length(), _line(), _locate(), _match(), _sql(), _taint(), _try_operator(), _union(), Request::absolute(), VClass::add_property(), append_attribute_meaning(), VObject::as(), VClass::as(), as_expires(), Value::as_string(), StringOrValue::as_value(), VVoid::as_vfile(), VString::as_vfile(), attributed_meaning_to_string(), basic_authorization_field(), buildCommand(), cache_get(), String::change_case(), Table::column_name2index(), Exception::comment(), CORD_batched_iter_fn_generic_hash_code(), CORD_block_count(), CORD_block_count_proc(), CORD_block_iter(), CORD_cat(), CORD_cat_char_star(), CORD_catn(), CORD_cmp(), CORD_fprintf(), CORD_from_char_star(), CORD_from_fn(), CORD_iter5(), CORD_ncmp(), CORD_printf(), CORD_sprintf(), CORD_substr_checked(), CORD_substr_closure(), CORD_to_char_star(), CORD_vfprintf(), CORD_vprintf(), CORD_vsprintf(), Operation::Origin::create(), CreateHiddenConsoleProcess(), ec_append(), entry_exists(), SAPI::environment(), Request::execute(), Request::execute_method(), Request::execute_nonvirtual_method(), extract_conv_spec(), Request::Exception_trace::extract_origin(), extractEmail(), extractEmails(), VTable::fields_element(), file_exist(), file_read(), file_value_to_string(), fill_month_days(), fill_week_days(), form_string_value2string(), form_value2string(), generic_hash_code(), Charsets::get(), get_action_options(), SQL_Driver_manager::get_connection_from_cache(), MXnode::get_element(), VVoid::get_element(), VTable::get_element(), VString::get_element(), VResponse::get_element(), VObject::get_element(), VMemory::get_element(), VMath::get_element(), VMail::get_element(), VImage::get_element(), VHashfile::get_element(), VHash::get_element(), VForm::get_element(), VFile::get_element(), VEnv::get_element(), VDate::get_element(), VClass::get_element(), Request::get_exception_cstr(), VHashfile::get_hash(), VDate::get_localtime(), SQL_Driver_manager::get_status(), VXnode::get_vxdoc(), getrow(), grep_char(), guess_content_length(), String::Body::hash_code(), hash_code(), http_read_response(), http_request(), TableSeparators::load(), locked_process_and_cache_put(), locked_process_and_cache_put_action(), lsplit(), math1(), math2(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), VMail::message_hash_to_string(), methoded_array(), String::mid(), Request::mime_type_of(), mk_env_pair(), O(), OA(), SQL_Driver::operator new(), P(), pa_atod(), pa_atoi(), pa_base64_decode(), pa_base64_encode(), pa_exec(), pa_get_valid_file_options_count(), pa_internal_file_read_http(), pa_malloc(), pa_malloc_atomic(), pa_MD5Encode(), pa_realloc(), pa_strdup(), pa_uuencode(), parse_IFD_entry_formatted_value(), parse_IFD_entry_value(), VClass::prevent_append_if_exists_in_base(), VObject::prevent_append_if_exists_in_static_or_base(), Request::process(), VClass::put_element(), read_pipe(), regex_options(), Request::relative(), String::replace(), Hash< const String::Body, void * >::replace_maybe_append(), search_stop(), String::serialize(), VHashfile::serialize_value(), Request::set_connection(), VObject::set_derived(), Request::set_lang(), String::split(), split_list(), split_options(), Font::string_width(), VForm::strpart(), text_value_to_string(), SQL_Driver_services_impl::transcode(), String::trim(), try_catch(), SQL_Driver_services_impl::url_without_login(), and VL().

unsigned long v

Definition at line 140 of file pa_md5.h.

Referenced by lsplit(), Request::output_result(), pa_to64(), gdImage::ReadImage(), and rsplit().

unsigned long int n

Definition at line 140 of file pa_md5.h.


pa_md5.h Source File

pa_md5.h

Go to the documentation of this file.
00001
00009 /*
00010  * This is work is derived from material Copyright RSA Data Security, Inc.
00011  *
00012  * The RSA copyright statement and Licence for that original material is
00013  * included below. This is followed by the Apache copyright statement and
00014  * licence for the modifications made to that material.
00015  */
00016
00017 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00018    rights reserved.
00019
00020    License to copy and use this software is granted provided that it
00021    is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00022    Algorithm" in all material mentioning or referencing this software
00023    or this function.
00024
00025    License is also granted to make and use derivative works provided
00026    that such works are identified as "derived from the RSA Data
00027    Security, Inc. MD5 Message-Digest Algorithm" in all material
00028    mentioning or referencing the derived work.
00029
00030    RSA Data Security, Inc. makes no representations concerning either
00031    the merchantability of this software or the suitability of this
00032    software for any particular purpose. It is provided "as is"
00033    without express or implied warranty of any kind.
00034
00035    These notices must be retained in any copies of any part of this
00036    documentation and/or software.
00037  */
00038
00039 /* ====================================================================
00040  * Copyright (c) 1996-1999 The Apache Group.  All rights reserved.
00041  *
00042  * Redistribution and use in source and binary forms, with or without
00043  * modification, are permitted provided that the following conditions
00044  * are met:
00045  *
00046  * 1. Redistributions of source code must retain the above copyright
00047  *    notice, this list of conditions and the following disclaimer.
00048  *
00049  * 2. Redistributions in binary form must reproduce the above copyright
00050  *    notice, this list of conditions and the following disclaimer in
00051  *    the documentation and/or other materials provided with the
00052  *    distribution.
00053  *
00054  * 3. All advertising materials mentioning features or use of this
00055  *    software must display the following acknowledgment:
00056  *    "This product includes software developed by the Apache Group
00057  *    for use in the Apache HTTP server project (http://www.apache.org/)."
00058  *
00059  * 4. The names "Apache Server" and "Apache Group" must not be used to
00060  *    endorse or promote products derived from this software without
00061  *    prior written permission. For written permission, please contact
00062  *    apache@apache.org.
00063  *
00064  * 5. Products derived from this software may not be called "Apache"
00065  *    nor may "Apache" appear in their names without prior written
00066  *    permission of the Apache Group.
00067  *
00068  * 6. Redistributions of any form whatsoever must retain the following
00069  *    acknowledgment:
00070  *    "This product includes software developed by the Apache Group
00071  *    for use in the Apache HTTP server project (http://www.apache.org/)."
00072  *
00073  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
00074  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00075  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00076  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
00077  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00078  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00079  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00080  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00081  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00082  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00083  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00084  * OF THE POSSIBILITY OF SUCH DAMAGE.
00085  * ====================================================================
00086  *
00087  * This software consists of voluntary contributions made by many
00088  * individuals on behalf of the Apache Group and was originally based
00089  * on public domain software written at the National Center for
00090  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
00091  * For more information on the Apache Group and the Apache HTTP server
00092  * project, please see <http://www.apache.org/>.
00093  *
00094  */
00095
00096 #ifndef PA_MD5_H
00097 #define PA_MD5_H
00098
00099 static const char * const IDENT_MD5_H="$Date: 2005/08/09 08:14:51 $";
00100
00101 #define PA_API_EXPORT(rtype) rtype
00102
00103 #ifdef __cplusplus
00104 extern "C" {
00105 #endif
00106
00107 #ifndef APACHE_MD5_H
00108
00109 /* MD5.H - header file for MD5C.C */
00110
00111 #define MD5_DIGESTSIZE 16
00112
00113 /* UINT4 defines a four byte word */
00114 typedef unsigned int UINT4;
00115
00116 #endif
00117
00118 /* MD5 context. */
00119 typedef struct {
00120     UINT4 state[4];     /* state (ABCD) */
00121     UINT4 count[2];     /* number of bits, modulo 2^64 (lsb first) */
00122     unsigned char buffer[64];   /* input buffer */
00123 } PA_MD5_CTX;
00124
00125 /*
00126  * Define the Magic String prefix that identifies a password as being
00127  * hashed using our algorithm.
00128  */
00129 #define PA_MD5PW_ID "$apr1$"
00130 #define PA_MD5PW_IDLEN 6
00131
00132 PA_API_EXPORT(void) pa_MD5Init(PA_MD5_CTX *context);
00133 PA_API_EXPORT(void) pa_MD5Update(PA_MD5_CTX *context, const unsigned char *input,
00134                   unsigned int inputLen);
00135 PA_API_EXPORT(void) pa_MD5Final(unsigned char digest[MD5_DIGESTSIZE],
00136                  PA_MD5_CTX *context);
00137 PA_API_EXPORT(void) pa_MD5Encode(const unsigned char *password,
00138                   const unsigned char *salt,
00139                   char *result, size_t nbytes);
00140 PA_API_EXPORT(void) pa_to64(char *s, unsigned long v, int n);
00141
00142 #ifdef __cplusplus
00143 }
00144 #endif
00145
00146 #endif  /* !PA_MD5_H */


pa_md5c.c File Reference

Parser: copied from apache 1.3.20 sources. More...

Include dependency graph for pa_md5c.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | pa_pa_cpystrn(strDest, strSource, count) strncpy(strDest, strSource, count)
#define | S11 7
#define | S12 12
#define | S13 17
#define | S14 22
#define | S21 5
#define | S22 9
#define | S23 14
#define | S24 20
#define | S31 4
#define | S32 11
#define | S33 16
#define | S34 23
#define | S41 6
#define | S42 10
#define | S43 15
#define | S44 21
#define | F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define | G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define | H(x, y, z) ((x) ^ (y) ^ (z))
#define | I(x, y, z) ((y) ^ ((x) | (~z)))
#define | ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define | FF(a, b, c, d, x, s, ac)
#define | GG(a, b, c, d, x, s, ac)
#define | HH(a, b, c, d, x, s, ac)
#define | II(a, b, c, d, x, s, ac)

Functions

void | MD5Transform (UINT4 state[4], const unsigned char block[64])
void | Encode (unsigned char *output, const UINT4 *input, unsigned int len)
void | Decode (UINT4 *output, const unsigned char *input, unsigned int len)
PA_API_EXPORT (void) pa_MD5Init(PA_MD5_CTX *context)

Variables

const char *const | IDENT_MD5_C = "$Date: 2005/08/09 08:14:51 $"
unsigned char | PADDING [64]
const unsigned char * | input

Detailed Description

Parser: copied from apache 1.3.20 sources.

Replaced ap_ to pa_ prefixes. linked into all targets but Apache-module target, where linked targets/apache/pa_md5c.c stub instead.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)

Definition in file pa_md5c.c.

Define Documentation

#define pa_pa_cpystrn | ( | strDest,
 |  | strSource,
 |  | count | ) | strncpy(strDest, strSource, count)

Definition at line 116 of file pa_md5c.c.

#define S11 7

Definition at line 121 of file pa_md5c.c.

#define S12 12

Definition at line 122 of file pa_md5c.c.

#define S13 17

Definition at line 123 of file pa_md5c.c.

#define S14 22

Definition at line 124 of file pa_md5c.c.

#define S21 5

Definition at line 125 of file pa_md5c.c.

#define S22 9

Definition at line 126 of file pa_md5c.c.

#define S23 14

Definition at line 127 of file pa_md5c.c.

#define S24 20

Definition at line 128 of file pa_md5c.c.

#define S31 4

Definition at line 129 of file pa_md5c.c.

#define S32 11

Definition at line 130 of file pa_md5c.c.

#define S33 16

Definition at line 131 of file pa_md5c.c.

#define S34 23

Definition at line 132 of file pa_md5c.c.

#define S41 6

Definition at line 133 of file pa_md5c.c.

#define S42 10

Definition at line 134 of file pa_md5c.c.

#define S43 15

Definition at line 135 of file pa_md5c.c.

#define S44 21

Definition at line 136 of file pa_md5c.c.

#define F | ( | x,
 |  | y,
 |  | z | ) | (((x) & (y)) | ((~x) & (z)))

Definition at line 153 of file pa_md5c.c.

Referenced by Hash< const String::Body, void * >::maybe_put_replaced(), and Hash< const String::Body, void * >::replace_maybe_append().

#define G | ( | x,
 |  | y,
 |  | z | ) | (((x) & (z)) | ((y) & (~z)))

Definition at line 154 of file pa_md5c.c.

#define H | ( | x,
 |  | y,
 |  | z | ) | ((x) ^ (y) ^ (z))

Definition at line 155 of file pa_md5c.c.

#define I | ( | x,
 |  | y,
 |  | z | ) | ((y) ^ ((x) | (~z)))

Definition at line 156 of file pa_md5c.c.

Referenced by Hash< const String::Body, void * >::first_that(), Array< Operation >::first_that(), String::Body::for_each(), String::Languages::for_each(), Hash< const String::Body, void * >::for_each(), Array< Operation >::for_each(), Hash< const String::Body, void * >::for_each_ref(), Array< Operation >::for_each_ref(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::replace_maybe_append(), Table::table_first_that(), Table::table_for_each(), and try_catch().

#define ROTATE_LEFT | ( | x,
 |  | n | ) | (((x) << (n)) | ((x) >> (32-(n))))

Definition at line 160 of file pa_md5c.c.

#define FF | ( | a,
 |  | b,
 |  | c,
 |  | d,
 |  | x,
 |  | s,
 |  | ac | )

Value:

{ \
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }

Definition at line 165 of file pa_md5c.c.

#define GG | ( | a,
 |  | b,
 |  | c,
 |  | d,
 |  | x,
 |  | s,
 |  | ac | )

Value:

{ \
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }

Definition at line 170 of file pa_md5c.c.

#define HH | ( | a,
 |  | b,
 |  | c,
 |  | d,
 |  | x,
 |  | s,
 |  | ac | )

Value:

{ \
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }

Definition at line 175 of file pa_md5c.c.

#define II | ( | a,
 |  | b,
 |  | c,
 |  | d,
 |  | x,
 |  | s,
 |  | ac | )

Value:

{ \
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }

Definition at line 180 of file pa_md5c.c.

Function Documentation

void MD5Transform | ( | UINT4 | state[4],
 |  | const unsigned char | block[64]
 | ) | [static]

void Encode | ( | unsigned char * | output,
 |  | const UINT4 * | input,
 |  | unsigned int | len
 | ) | [static]

void Decode | ( | UINT4 * | output,
 |  | const unsigned char * | input,
 |  | unsigned int | len
 | ) | [static]

PA_API_EXPORT ( void )

Definition at line 188 of file pa_md5c.c.

References context, and PA_MD5_CTX.

Variable Documentation

const char* const IDENT_MD5_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 110 of file pa_md5c.c.

unsigned char PADDING[64] [static]

Initial value:

{
    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}

Definition at line 144 of file pa_md5c.c.

const unsigned char* input

Definition at line 202 of file pa_md5c.c.


pa_md5c.c Source File

pa_md5c.c

Go to the documentation of this file.
00001
00009 /*
00010  * This is work is derived from material Copyright RSA Data Security, Inc.
00011  *
00012  * The RSA copyright statement and Licence for that original material is
00013  * included below. This is followed by the Apache copyright statement and
00014  * licence for the modifications made to that material.
00015  */
00016
00017 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00018  */
00019
00020 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00021    rights reserved.
00022
00023    License to copy and use this software is granted provided that it
00024    is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00025    Algorithm" in all material mentioning or referencing this software
00026    or this function.
00027
00028    License is also granted to make and use derivative works provided
00029    that such works are identified as "derived from the RSA Data
00030    Security, Inc. MD5 Message-Digest Algorithm" in all material
00031    mentioning or referencing the derived work.
00032
00033    RSA Data Security, Inc. makes no representations concerning either
00034    the merchantability of this software or the suitability of this
00035    software for any particular purpose. It is provided "as is"
00036    without express or implied warranty of any kind.
00037
00038    These notices must be retained in any copies of any part of this
00039    documentation and/or software.
00040  */
00041
00042 /* ====================================================================
00043  * Copyright (c) 1996-1999 The Apache Group.  All rights reserved.
00044  *
00045  * Redistribution and use in source and binary forms, with or without
00046  * modification, are permitted provided that the following conditions
00047  * are met:
00048  *
00049  * 1. Redistributions of source code must retain the above copyright
00050  *    notice, this list of conditions and the following disclaimer.
00051  *
00052  * 2. Redistributions in binary form must reproduce the above copyright
00053  *    notice, this list of conditions and the following disclaimer in
00054  *    the documentation and/or other materials provided with the
00055  *    distribution.
00056  *
00057  * 3. All advertising materials mentioning features or use of this
00058  *    software must display the following acknowledgment:
00059  *    "This product includes software developed by the Apache Group
00060  *    for use in the Apache HTTP server project (http://www.apache.org/)."
00061  *
00062  * 4. The names "Apache Server" and "Apache Group" must not be used to
00063  *    endorse or promote products derived from this software without
00064  *    prior written permission. For written permission, please contact
00065  *    apache@apache.org.
00066  *
00067  * 5. Products derived from this software may not be called "Apache"
00068  *    nor may "Apache" appear in their names without prior written
00069  *    permission of the Apache Group.
00070  *
00071  * 6. Redistributions of any form whatsoever must retain the following
00072  *    acknowledgment:
00073  *    "This product includes software developed by the Apache Group
00074  *    for use in the Apache HTTP server project (http://www.apache.org/)."
00075  *
00076  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
00077  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00078  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00079  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
00080  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00081  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00082  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00083  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00084  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00085  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00086  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00087  * OF THE POSSIBILITY OF SUCH DAMAGE.
00088  * ====================================================================
00089  *
00090  * This software consists of voluntary contributions made by many
00091  * individuals on behalf of the Apache Group and was originally based
00092  * on public domain software written at the National Center for
00093  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
00094  * For more information on the Apache Group and the Apache HTTP server
00095  * project, please see <http://www.apache.org/>.
00096  *
00097  */
00098
00099 /*
00100  * The pa_MD5Encode() routine uses much code obtained from the FreeBSD 3.0
00101  * MD5 crypt() function, which is licenced as follows:
00102  * ----------------------------------------------------------------------------
00103  * "THE BEER-WARE LICENSE" (Revision 42):
00104  * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
00105  * can do whatever you want with this stuff. If we meet some day, and you think
00106  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
00107  * ----------------------------------------------------------------------------
00108  */
00109
00110 static const char * const IDENT_MD5_C="$Date: 2005/08/09 08:14:51 $";
00111
00112 #include <string.h>
00113
00114 #include "pa_md5.h"
00115
00116 #define pa_pa_cpystrn(strDest, strSource, count) strncpy(strDest, strSource, count)
00117
00118 /* Constants for MD5Transform routine.
00119  */
00120
00121 #define S11 7
00122 #define S12 12
00123 #define S13 17
00124 #define S14 22
00125 #define S21 5
00126 #define S22 9
00127 #define S23 14
00128 #define S24 20
00129 #define S31 4
00130 #define S32 11
00131 #define S33 16
00132 #define S34 23
00133 #define S41 6
00134 #define S42 10
00135 #define S43 15
00136 #define S44 21
00137
00138 static void MD5Transform(UINT4 state[4], const unsigned char block[64]);
00139 static void Encode(unsigned char *output, const UINT4 *input,
00140            unsigned int len);
00141 static void Decode(UINT4 *output, const unsigned char *input,
00142            unsigned int len);
00143
00144 static unsigned char PADDING[64] =
00145 {
00146     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00147     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00148     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00149 };
00150
00151 /* F, G, H and I are basic MD5 functions.
00152  */
00153 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00154 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00155 #define H(x, y, z) ((x) ^ (y) ^ (z))
00156 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00157
00158 /* ROTATE_LEFT rotates x left n bits.
00159  */
00160 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00161
00162 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00163    Rotation is separate from addition to prevent recomputation.
00164  */
00165 #define FF(a, b, c, d, x, s, ac) { \
00166  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00167  (a) = ROTATE_LEFT ((a), (s)); \
00168  (a) += (b); \
00169   }
00170 #define GG(a, b, c, d, x, s, ac) { \
00171  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00172  (a) = ROTATE_LEFT ((a), (s)); \
00173  (a) += (b); \
00174   }
00175 #define HH(a, b, c, d, x, s, ac) { \
00176  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00177  (a) = ROTATE_LEFT ((a), (s)); \
00178  (a) += (b); \
00179   }
00180 #define II(a, b, c, d, x, s, ac) { \
00181  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00182  (a) = ROTATE_LEFT ((a), (s)); \
00183  (a) += (b); \
00184   }
00185
00186 /* MD5 initialization. Begins an MD5 operation, writing a new context.
00187  */
00188 PA_API_EXPORT(void) pa_MD5Init(PA_MD5_CTX *context)
00189 {
00190     context->count[0] = context->count[1] = 0;
00191     /* Load magic initialization constants. */
00192     context->state[0] = 0x67452301;
00193     context->state[1] = 0xefcdab89;
00194     context->state[2] = 0x98badcfe;
00195     context->state[3] = 0x10325476;
00196 }
00197
00198 /* MD5 block update operation. Continues an MD5 message-digest
00199    operation, processing another message block, and updating the
00200    context.
00201  */
00202 PA_API_EXPORT(void) pa_MD5Update(PA_MD5_CTX *context, const unsigned char *input,
00203                   unsigned int inputLen)
00204 {
00205     unsigned int i, idx, partLen;
00206
00207     /* Compute number of bytes mod 64 */
00208     idx = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00209
00210     /* Update number of bits */
00211     if ((context->count[0] += ((UINT4) inputLen << 3))
00212     < ((UINT4) inputLen << 3)) {
00213     context->count[1]++;
00214     }
00215     context->count[1] += (UINT4) inputLen >> 29;
00216
00217     partLen = 64 - idx;
00218
00219     /* Transform as many times as possible. */
00220 #ifndef CHARSET_EBCDIC
00221     if (inputLen >= partLen) {
00222     memcpy(&context->buffer[idx], input, partLen);
00223     MD5Transform(context->state, context->buffer);
00224
00225     for (i = partLen; i + 63 < inputLen; i += 64) {
00226         MD5Transform(context->state, &input[i]);
00227     }
00228
00229     idx = 0;
00230     }
00231     else {
00232     i = 0;
00233     }
00234
00235     /* Buffer remaining input */
00236     memcpy(&context->buffer[idx], &input[i], inputLen - i);
00237 #else /*CHARSET_EBCDIC*/
00238     if (inputLen >= partLen) {
00239     ebcdic2ascii(&context->buffer[idx], input, partLen);
00240     MD5Transform(context->state, context->buffer);
00241
00242     for (i = partLen; i + 63 < inputLen; i += 64) {
00243         unsigned char inp_tmp[64];
00244         ebcdic2ascii(inp_tmp, &input[i], 64);
00245         MD5Transform(context->state, inp_tmp);
00246     }
00247
00248     idx = 0;
00249     }
00250     else {
00251     i = 0;
00252     }
00253
00254     /* Buffer remaining input */
00255     ebcdic2ascii(&context->buffer[idx], &input[i], inputLen - i);
00256 #endif /*CHARSET_EBCDIC*/
00257 }
00258
00259 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
00260    the message digest and zeroizing the context.
00261  */
00262 PA_API_EXPORT(void) pa_MD5Final(unsigned char digest[16], PA_MD5_CTX *context)
00263 {
00264     unsigned char bits[8];
00265     unsigned int idx, padLen;
00266
00267
00268     /* Save number of bits */
00269     Encode(bits, context->count, 8);
00270
00271 #ifdef CHARSET_EBCDIC
00272     /* XXX: @@@: In order to make this no more complex than necessary,
00273      * this kludge converts the bits[] array using the ascii-to-ebcdic
00274      * table, because the following pa_MD5Update() re-translates
00275      * its input (ebcdic-to-ascii).
00276      * Otherwise, we would have to pass a "conversion" flag to pa_MD5Update()
00277      */
00278     ascii2ebcdic(bits,bits,8);
00279
00280     /* Since everything is converted to ascii within pa_MD5Update(),
00281      * the initial 0x80 (PADDING[0]) must be stored as 0x20
00282      */
00283     PADDING[0] = os_toebcdic[0x80];
00284 #endif /*CHARSET_EBCDIC*/
00285
00286     /* Pad out to 56 mod 64. */
00287     idx = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00288     padLen = (idx < 56) ? (56 - idx) : (120 - idx);
00289     pa_MD5Update(context, (const unsigned char *)PADDING, padLen);
00290
00291     /* Append length (before padding) */
00292     pa_MD5Update(context, (const unsigned char *)bits, 8);
00293
00294     /* Store state in digest */
00295     Encode(digest, context->state, 16);
00296
00297     /* Zeroize sensitive information. */
00298     memset(context, 0, sizeof(*context));
00299 }
00300
00301 /* MD5 basic transformation. Transforms state based on block. */
00302 static void MD5Transform(UINT4 state[4], const unsigned char block[64])
00303 {
00304     UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00305
00306     Decode(x, block, 64);
00307
00308     /* Round 1 */
00309     FF(a, b, c, d, x[0], S11, 0xd76aa478);  /* 1 */
00310     FF(d, a, b, c, x[1], S12, 0xe8c7b756);  /* 2 */
00311     FF(c, d, a, b, x[2], S13, 0x242070db);  /* 3 */
00312     FF(b, c, d, a, x[3], S14, 0xc1bdceee);  /* 4 */
00313     FF(a, b, c, d, x[4], S11, 0xf57c0faf);  /* 5 */
00314     FF(d, a, b, c, x[5], S12, 0x4787c62a);  /* 6 */
00315     FF(c, d, a, b, x[6], S13, 0xa8304613);  /* 7 */
00316     FF(b, c, d, a, x[7], S14, 0xfd469501);  /* 8 */
00317     FF(a, b, c, d, x[8], S11, 0x698098d8);  /* 9 */
00318     FF(d, a, b, c, x[9], S12, 0x8b44f7af);  /* 10 */
00319     FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00320     FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00321     FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00322     FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00323     FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00324     FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00325
00326     /* Round 2 */
00327     GG(a, b, c, d, x[1], S21, 0xf61e2562);  /* 17 */
00328     GG(d, a, b, c, x[6], S22, 0xc040b340);  /* 18 */
00329     GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00330     GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);  /* 20 */
00331     GG(a, b, c, d, x[5], S21, 0xd62f105d);  /* 21 */
00332     GG(d, a, b, c, x[10], S22, 0x2441453);  /* 22 */
00333     GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00334     GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);  /* 24 */
00335     GG(a, b, c, d, x[9], S21, 0x21e1cde6);  /* 25 */
00336     GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00337     GG(c, d, a, b, x[3], S23, 0xf4d50d87);  /* 27 */
00338     GG(b, c, d, a, x[8], S24, 0x455a14ed);  /* 28 */
00339     GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00340     GG(d, a, b, c, x[2], S22, 0xfcefa3f8);  /* 30 */
00341     GG(c, d, a, b, x[7], S23, 0x676f02d9);  /* 31 */
00342     GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00343
00344     /* Round 3 */
00345     HH(a, b, c, d, x[5], S31, 0xfffa3942);  /* 33 */
00346     HH(d, a, b, c, x[8], S32, 0x8771f681);  /* 34 */
00347     HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00348     HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00349     HH(a, b, c, d, x[1], S31, 0xa4beea44);  /* 37 */
00350     HH(d, a, b, c, x[4], S32, 0x4bdecfa9);  /* 38 */
00351     HH(c, d, a, b, x[7], S33, 0xf6bb4b60);  /* 39 */
00352     HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00353     HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00354     HH(d, a, b, c, x[0], S32, 0xeaa127fa);  /* 42 */
00355     HH(c, d, a, b, x[3], S33, 0xd4ef3085);  /* 43 */
00356     HH(b, c, d, a, x[6], S34, 0x4881d05);   /* 44 */
00357     HH(a, b, c, d, x[9], S31, 0xd9d4d039);  /* 45 */
00358     HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00359     HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00360     HH(b, c, d, a, x[2], S34, 0xc4ac5665);  /* 48 */
00361
00362     /* Round 4 */
00363     II(a, b, c, d, x[0], S41, 0xf4292244);  /* 49 */
00364     II(d, a, b, c, x[7], S42, 0x432aff97);  /* 50 */
00365     II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00366     II(b, c, d, a, x[5], S44, 0xfc93a039);  /* 52 */
00367     II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00368     II(d, a, b, c, x[3], S42, 0x8f0ccc92);  /* 54 */
00369     II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00370     II(b, c, d, a, x[1], S44, 0x85845dd1);  /* 56 */
00371     II(a, b, c, d, x[8], S41, 0x6fa87e4f);  /* 57 */
00372     II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00373     II(c, d, a, b, x[6], S43, 0xa3014314);  /* 59 */
00374     II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00375     II(a, b, c, d, x[4], S41, 0xf7537e82);  /* 61 */
00376     II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00377     II(c, d, a, b, x[2], S43, 0x2ad7d2bb);  /* 63 */
00378     II(b, c, d, a, x[9], S44, 0xeb86d391);  /* 64 */
00379
00380     state[0] += a;
00381     state[1] += b;
00382     state[2] += c;
00383     state[3] += d;
00384
00385     /* Zeroize sensitive information. */
00386     memset(x, 0, sizeof(x));
00387 }
00388
00389 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
00390    a multiple of 4.
00391  */
00392 static void Encode(unsigned char *output, const UINT4 *input, unsigned int len)
00393 {
00394     unsigned int i, j;
00395     UINT4 k;
00396
00397     for (i = 0, j = 0; j < len; i++, j += 4) {
00398     k = input[i];
00399     output[j] = (unsigned char) (k & 0xff);
00400     output[j + 1] = (unsigned char) ((k >> 8) & 0xff);
00401     output[j + 2] = (unsigned char) ((k >> 16) & 0xff);
00402     output[j + 3] = (unsigned char) ((k >> 24) & 0xff);
00403     }
00404 }
00405
00406 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
00407  * a multiple of 4.
00408  */
00409 static void Decode(UINT4 *output, const unsigned char *input, unsigned int len)
00410 {
00411     unsigned int i, j;
00412
00413     for (i = 0, j = 0; j < len; i++, j += 4)
00414     output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
00415         (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
00416 }
00417
00418 /*
00419  * The following MD5 password encryption code was largely borrowed from
00420  * the FreeBSD 3.0 /usr/src/lib/libcrypt/crypt.c file, which is
00421  * licenced as stated at the top of this file.
00422  */
00423 PA_API_EXPORT(void) pa_to64(char *s, unsigned long v, int n)
00424 {
00425     static unsigned char itoa64[] =         /* 0 ... 63 => ASCII - 64 */
00426     "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00427
00428     while (--n >= 0) {
00429     *s++ = itoa64[v&0x3f];
00430     v >>= 6;
00431     }
00432 }
00433
00434 PA_API_EXPORT(void) pa_MD5Encode(const unsigned char *pw,
00435                   const unsigned char *salt,
00436                   char *result, size_t nbytes)
00437 {
00438     /*
00439      * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
00440      * plus 4 for the '$' separators, plus the password hash itself.
00441      * Let's leave a goodly amount of leeway.
00442      */
00443
00444     char passwd[120], *p;
00445     const unsigned char *sp, *ep;
00446     unsigned char final[16];
00447     int i;
00448     unsigned int sl;
00449     int pl;
00450     unsigned int pwlen;
00451     PA_MD5_CTX ctx, ctx1;
00452     unsigned long l;
00453
00454     /*
00455      * Refine the salt first.  It's possible we were given an already-hashed
00456      * string as the salt argument, so extract the actual salt value from it
00457      * if so.  Otherwise just use the string up to the first '$' as the salt.
00458      */
00459     sp = salt;
00460
00461     /*
00462      * If it starts with the magic string, then skip that.
00463      */
00464     if (strncmp((char *)sp, PA_MD5PW_ID, PA_MD5PW_IDLEN) == 0) {
00465     sp += PA_MD5PW_IDLEN;
00466     }
00467
00468     /*
00469      * It stops at the first '$' or 8 chars, whichever comes first
00470      */
00471     for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
00472     continue;
00473     }
00474
00475     /*
00476      * Get the length of the true salt
00477      */
00478     sl = ep - sp;
00479
00480     /*
00481      * 'Time to make the doughnuts..'
00482      */
00483     pa_MD5Init(&ctx);
00484
00485     pwlen = strlen((char *)pw);
00486     /*
00487      * The password first, since that is what is most unknown
00488      */
00489     pa_MD5Update(&ctx, pw, pwlen);
00490
00491     /*
00492      * Then our magic string
00493      */
00494     pa_MD5Update(&ctx, (const unsigned char *) PA_MD5PW_ID, PA_MD5PW_IDLEN);
00495
00496     /*
00497      * Then the raw salt
00498      */
00499     pa_MD5Update(&ctx, sp, sl);
00500
00501     /*
00502      * Then just as many characters of the MD5(pw, salt, pw)
00503      */
00504     pa_MD5Init(&ctx1);
00505     pa_MD5Update(&ctx1, pw, pwlen);
00506     pa_MD5Update(&ctx1, sp, sl);
00507     pa_MD5Update(&ctx1, pw, pwlen);
00508     pa_MD5Final(final, &ctx1);
00509     for(pl = pwlen; pl > 0; pl -= 16) {
00510     pa_MD5Update(&ctx, final, (pl > 16) ? 16 : (unsigned int) pl);
00511     }
00512
00513     /*
00514      * Don't leave anything around in vm they could use.
00515      */
00516     memset(final, 0, sizeof(final));
00517
00518     /*
00519      * Then something really weird...
00520      */
00521     for (i = pwlen; i != 0; i >>= 1) {
00522     if (i & 1) {
00523         pa_MD5Update(&ctx, final, 1);
00524     }
00525     else {
00526         pa_MD5Update(&ctx, pw, 1);
00527     }
00528     }
00529
00530     /*
00531      * Now make the output string.  We know our limitations, so we
00532      * can use the string routines without bounds checking.
00533      */
00534     pa_pa_cpystrn(passwd, PA_MD5PW_ID, PA_MD5PW_IDLEN + 1);
00535     pa_pa_cpystrn(passwd + PA_MD5PW_IDLEN, (char *)sp, sl + 1);
00536     passwd[PA_MD5PW_IDLEN + sl]     = '$';
00537     passwd[PA_MD5PW_IDLEN + sl + 1] = '\0';
00538
00539     pa_MD5Final(final, &ctx);
00540
00541     /*
00542      * And now, just to make sure things don't run too fast..
00543      * On a 60 Mhz Pentium this takes 34 msec, so you would
00544      * need 30 seconds to build a 1000 entry dictionary...
00545      */
00546     for (i = 0; i < 1000; i++) {
00547     pa_MD5Init(&ctx1);
00548     if (i & 1) {
00549         pa_MD5Update(&ctx1, pw, pwlen);
00550     }
00551     else {
00552         pa_MD5Update(&ctx1, final, 16);
00553     }
00554     if (i % 3) {
00555         pa_MD5Update(&ctx1, sp, sl);
00556     }
00557
00558     if (i % 7) {
00559         pa_MD5Update(&ctx1, pw, pwlen);
00560     }
00561
00562     if (i & 1) {
00563         pa_MD5Update(&ctx1, final, 16);
00564     }
00565     else {
00566         pa_MD5Update(&ctx1, pw, pwlen);
00567     }
00568     pa_MD5Final(final,&ctx1);
00569     }
00570
00571     p = passwd + strlen(passwd);
00572
00573     l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; pa_to64(p, l, 4); p += 4;
00574     l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; pa_to64(p, l, 4); p += 4;
00575     l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; pa_to64(p, l, 4); p += 4;
00576     l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; pa_to64(p, l, 4); p += 4;
00577     l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; pa_to64(p, l, 4); p += 4;
00578     l =                    final[11]                ; pa_to64(p, l, 2); p += 2;
00579     *p = '\0';
00580
00581     /*
00582      * Don't leave anything around in vm they could use.
00583      */
00584     memset(final, 0, sizeof(final));
00585
00586     pa_pa_cpystrn(result, passwd, nbytes - 1);
00587 }


pa_memory.C File Reference

Parser: memory reference counting classes. More...

Include dependency graph for pa_memory.C:

Include dependency graph

Go to the source code of this file.

Functions

void * | pa_fail_alloc (const char *what, size_t size)

Variables

const char *const | IDENT_MEMORY_C = "$Date: 2005/12/16 10:22:41 $"

Detailed Description

Parser: memory reference counting classes.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_memory.C.

Function Documentation

void* pa_fail_alloc | ( | const char * | what,
 |  | size_t | size
 | ) |

Definition at line 13 of file pa_memory.C.

References SAPI::die(), and size.

Referenced by pa_malloc(), pa_malloc_atomic(), pa_realloc(), and pa_strdup().

Variable Documentation

const char* const IDENT_MEMORY_C = "$Date: 2005/12/16 10:22:41 $" [static]

Definition at line 8 of file pa_memory.C.


pa_memory.C Source File

pa_memory.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_MEMORY_C="$Date: 2005/12/16 10:22:41 $";
00009
00010 #include "pa_sapi.h"
00011 #include "pa_common.h"
00012
00013 void *pa_fail_alloc(const char* what, size_t size) {
00014 #ifdef PA_DEBUG_DISABLE_GC
00015     SAPI::die("out of memory (in pa_fail_alloc)");
00016 #else
00017     SAPI::die("out of memory: failed to %s %u bytes. "
00018         "heap_used=%u, heap_free=%u, bytes_since_gc=%u, total_bytes=%u",
00019         what, size,
00020         GC_get_heap_size(),
00021         GC_get_free_bytes(),
00022         GC_get_bytes_since_gc(),
00023         GC_get_total_bytes()
00024         );
00025 #endif
00026     // never reached
00027     return 0;
00028 }
00029
00030
00031 #ifdef PA_DEBUG_GC_MEMORY
00032
00033 const size_t HEADTAIL_SIZE=4;
00034
00035 static size_t debug_size(size_t user_size) {
00036     return user_size+HEADTAIL_SIZE*2;
00037 }
00038
00039 const int BEFORE_MARK=0xBEF0BEF0;
00040 const int AFTER_MARK=0xAFEEAFEE;
00041
00042 #error this code is known not to work: it ruins something with nonGC_DEBUG realloc
00043
00044 static void* fill_return_user(void* aptr, size_t /*pure_size*/) {
00045     char* ptr=(char*)aptr;
00046     memcpy(ptr, &BEFORE_MARK, HEADTAIL_SIZE);
00047 //  memcpy(ptr+HEADTAIL_SIZE+pure_size, &AFTER_MARK, HEADTAIL_SIZE);
00048
00049     //if(ptr>=(char*)0x01c357e40 && ptr<=((char*)0x01c357e4+100))
00050         //printf("valid:0x%p\n", ptr);
00051
00052     return ptr+HEADTAIL_SIZE;
00053 }
00054 static void* check_return_debug(void* auser_ptr) {
00055     char* user_ptr=(char*)auser_ptr;
00056     char* ptr=user_ptr-HEADTAIL_SIZE;
00057
00058     assert(GC_size(ptr));
00059     assert(memcmp(ptr, &BEFORE_MARK, HEADTAIL_SIZE)==0);
00060 // don't know real size. can put it to head someday
00061 //  assert(memcmp(ptr+HEADTAIL_SIZE+pure_size, &AFTER_MARK, HEADTAIL_SIZE)==0);
00062
00063     return ptr;
00064 }
00065
00066
00067 void* pa_gc_malloc(size_t size) {
00068     size=debug_size(size);
00069     return fill_return_user(GC_MALLOC(size), size);
00070 }
00071
00072 void* pa_gc_malloc_atomic(size_t size) {
00073     size=debug_size(size);
00074     return fill_return_user(GC_MALLOC_ATOMIC(size), size);
00075 }
00076
00077 void* pa_gc_realloc(void* user_ptr, size_t size) {
00078     GC_is_visible(user_ptr);
00079
00080     //printf("realloc: 0x%p -> %u\n", ptr, size);
00081     size=debug_size(size);
00082     return fill_return_user(
00083         GC_realloc(
00084             check_return_debug(user_ptr),
00085             size),
00086         size);
00087 }
00088 void pa_gc_free(void* user_ptr) {
00089     GC_is_visible(user_ptr);
00090     check_return_debug(user_ptr);
00091     // ignore free
00092 }
00093
00094
00095 #endif


pa_memory.h File Reference

Parser: memory reference counting classes decls. More...

Include dependency graph for pa_memory.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | PA_Allocated
memory allocation/dallocation goes via pa_malloc/pa_free. More...

class | PA_Cleaned
Those who want their destructor called during finalization, must derive from this class [also]. More...

Defines

#define | UseGC ((int)1)
#define | PointerFreeGC (true)
#define | override
#define | rethrow throw

Typedefs

typedef PA_Allocated | PA_Object
Base for all Parser classes. More...

Functions

void * | pa_gc_malloc (size_t size)
void * | pa_gc_malloc_atomic (size_t size)
void * | pa_gc_realloc (void *ptr, size_t size)
void | pa_gc_free (void *ptr)
void * | pa_fail_alloc (const char *what, size_t size)
void * | pa_malloc (size_t size)
void * | pa_malloc_atomic (size_t size)
char * | pa_strdup (const char *auto_variable_never_null, size_t helper_length=0)
length may be null, which mean "autocalc it". More...

void | pa_free (void *ptr)
void * | pa_realloc (void *ptr, size_t size)
void * | operator new (size_t)
void * | operator new[] (size_t)
void * | operator new[] (size_t size, int)
void * | operator new[] (size_t size, bool)
void | operator delete[] (void *ptr)
void * | operator new (size_t size, int)
void * | operator new (size_t size, bool)
void | operator delete (void *ptr)

Variables

const char *const | IDENT_MEMORY_H = "$Date: 2005/12/16 10:15:12 $"

Detailed Description

Parser: memory reference counting classes decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)

Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_memory.h.

Define Documentation

#define UseGC ((int)1)

Definition at line 85 of file pa_memory.h.

#define PointerFreeGC (true)

Definition at line 86 of file pa_memory.h.

Referenced by String::serialize().

#define override

Definition at line 179 of file pa_memory.h.

Referenced by SQL_Driver_services_impl::_throw(), VXnode::as_bool(), VXdoc::as_bool(), VVoid::as_bool(), VTable::as_bool(), VString::as_bool(), VProperty::as_bool(), VJunction::as_bool(), VInt::as_bool(), VImage::as_bool(), VHash::as_bool(), VFile::as_bool(), VDouble::as_bool(), VDate::as_bool(), VClass::as_bool(), VBool::as_bool(), VVoid::as_double(), VTable::as_double(), VString::as_double(), VInt::as_double(), VHash::as_double(), VDouble::as_double(), VDate::as_double(), VBool::as_double(), VXnode::as_expr_result(), VXdoc::as_expr_result(), VVoid::as_expr_result(), VTable::as_expr_result(), VString::as_expr_result(), VProperty::as_expr_result(), VJunction::as_expr_result(), VInt::as_expr_result(), VImage::as_expr_result(), VHash::as_expr_result(), VFile::as_expr_result(), VDouble::as_expr_result(), VDate::as_expr_result(), VClass::as_expr_result(), VBool::as_expr_result(), VVoid::as_int(), VTable::as_int(), VString::as_int(), VInt::as_int(), VHash::as_int(), VDouble::as_int(), VBool::as_int(), VFile::as_vfile(), VStateless_class::base(), VObject::base(), VMethodFrame::base(), WContext::get_class(), VXnode::get_class(), VXdoc::get_class(), VVoid::get_class(), VTable::get_class(), VString::get_class(), VStateless_class::get_class(), VResponse::get_class(), VRequest::get_class(), VProperty::get_class(), VObject::get_class(), VMethodFrame::get_class(), VJunction::get_class(), VInt::get_class(), VImage::get_class(), VHashfile::get_class(), VHash::get_class(), VDouble::get_class(), VDate::get_class(), VCookie::get_class(), VBool::get_class(), WWrapper::get_element(), VVoid::get_element(), VString::get_element(), VStateless_object::get_element(), VMethodFrame::get_element(), VHashfile::get_element(), VHash::get_element(), VDate::get_element(), VCodeFrame::get_element(), VResponse::get_hash(), VHash::get_hash(), VJunction::get_junction(), VObject::get_last_derived_class(), VProperty::get_property(), WContext::get_string(), VVoid::get_string(), VString::get_string(), VMethodFrame::get_string(), VInt::get_string(), VDouble::get_string(), VTable::get_table(), VXdoc::get_vxdoc(), VXdoc::get_xmlnode(), VVoid::is_defined(), VTable::is_defined(), VString::is_defined(), VProperty::is_defined(), VJunction::is_defined(), VHash::is_defined(), VInt::is_evaluated_expr(), VDouble::is_evaluated_expr(), VBool::is_evaluated_expr(), VString::is_string(), VVoid::is_void(), SQL_Driver_services_impl::malloc(), SQL_Driver_services_impl::malloc_atomic(), WWrapper::put_element(), VVoid::put_element(), VStateless_object::put_element(), VMethodFrame::put_element(), VHashfile::put_element(), VHash::put_element(), VConsole::put_element(), VCodeFrame::put_element(), Methoded::put_element(), SQL_Driver_services_impl::realloc(), SQL_Driver_services_impl::request_charset(), VMethodFrame::result(), VObject::set_derived(), WWrapper::type(), WContext::type(), VXnode::type(), VXdoc::type(), VVoid::type(), VTable::type(), VString::type(), VResponse::type(), VRequest::type(), VProperty::type(), VMethodFrame::type(), VMail::type(), VJunction::type(), VInt::type(), VImage::type(), VHashfile::type(), VHash::type(), VFile::type(), VDouble::type(), VDate::type(), VCookie::type(), VCodeFrame::type(), VBool::type(), and VCodeFrame::write().

#define rethrow throw

Definition at line 180 of file pa_memory.h.

Referenced by _connect(), _double(), _int(), buildCommand(), Request::core(), Request::execute(), file_read_action_under_lock(), file_write_action_under_lock(), VMail::fill_received(), VHashfile::for_each(), http_request(), SQL_Connection::query(), and try_catch().

Typedef Documentation

typedef PA_Allocated PA_Object

Base for all Parser classes.

Definition at line 175 of file pa_memory.h.

Function Documentation

void* pa_gc_malloc ( size_t size ) [inline]

Definition at line 29 of file pa_memory.h.

References GC_MALLOC, and size.

Referenced by pa_malloc().

void* pa_gc_malloc_atomic ( size_t size ) [inline]

Definition at line 30 of file pa_memory.h.

References GC_MALLOC_ATOMIC, and size.

Referenced by pa_malloc_atomic(), and pa_strdup().

void* pa_gc_realloc | ( | void * | ptr,
 |  | size_t | size
 | ) | [inline]

Definition at line 31 of file pa_memory.h.

References GC_REALLOC, and size.

Referenced by pa_realloc().

void pa_gc_free ( void * ptr ) [inline]

Definition at line 32 of file pa_memory.h.

References GC_FREE.

Referenced by pa_free().

void* pa_fail_alloc | ( | const char * | what,
 |  | size_t | size
 | ) |

Definition at line 13 of file pa_memory.C.

References SAPI::die(), and size.

Referenced by pa_malloc(), pa_malloc_atomic(), pa_realloc(), and pa_strdup().

void* pa_malloc ( size_t size ) [inline]

Definition at line 42 of file pa_memory.h.

References pa_fail_alloc(), pa_gc_malloc(), result, and size.

Referenced by SQL_Driver_services_impl::malloc(), PA_Allocated::malloc(), PA_Allocated::operator new(), operator new(), and operator new[]().

void* pa_malloc_atomic ( size_t size ) [inline]

Definition at line 49 of file pa_memory.h.

References pa_fail_alloc(), pa_gc_malloc_atomic(), result, and size.

Referenced by http_read_response(), SQL_Driver_services_impl::malloc_atomic(), PA_Allocated::malloc_atomic(), operator new(), and operator new[]().

char* pa_strdup | ( | const char * | auto_variable_never_null,
 |  | size_t | helper_length = 0
 | ) | [inline]

length may be null, which mean "autocalc it".

Definition at line 56 of file pa_memory.h.

References pa_fail_alloc(), pa_gc_malloc_atomic(), result, and size.

Referenced by _crypt(), _exec_cgi(), _list(), add_connection_to_status_cache_table(), String::Body::append_strdup_know_length(), buildCommand(), VHashfile::deserialize_value(), VHashfile::for_each(), for_each_string_callback(), String::Body::Format(), format(), SAPI::get_env(), http_read_response(), pa_socks_strerr(), real_parser_handler(), and PA_Allocated::strdup().

void pa_free ( void * ptr ) [inline]

Definition at line 69 of file pa_memory.h.

References pa_gc_free().

Referenced by _save(), PA_Allocated::free(), PA_Allocated::operator delete(), operator delete(), and operator delete[]().

void* pa_realloc | ( | void * | ptr,
 |  | size_t | size
 | ) | [inline]

Definition at line 73 of file pa_memory.h.

References pa_fail_alloc(), pa_gc_realloc(), result, and size.

Referenced by http_read_response(), SQL_Driver_services_impl::realloc(), and PA_Allocated::realloc().

void* operator new ( size_t ) [inline]

Definition at line 81 of file pa_memory.h.

References abort().

void* operator new[] ( size_t ) [inline]

Definition at line 82 of file pa_memory.h.

References abort().

void* operator new[] | ( | size_t | size,
 |  | int |
 | ) | [inline]

Definition at line 89 of file pa_memory.h.

References pa_malloc(), and size.

void* operator new[] | ( | size_t | size,
 |  | bool |
 | ) | [inline]

Definition at line 92 of file pa_memory.h.

References pa_malloc_atomic(), and size.

void operator delete[] ( void * ptr ) [inline]

Definition at line 95 of file pa_memory.h.

References pa_free().

void* operator new | ( | size_t | size,
 |  | int |
 | ) | [inline]

Definition at line 101 of file pa_memory.h.

References pa_malloc(), and size.

void* operator new | ( | size_t | size,
 |  | bool |
 | ) | [inline]

Definition at line 104 of file pa_memory.h.

References pa_malloc_atomic(), and size.

void operator delete ( void * ptr ) [inline]

Definition at line 107 of file pa_memory.h.

References pa_free().

Variable Documentation

const char* const IDENT_MEMORY_H = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 12 of file pa_memory.h.


pa_memory.h Source File

pa_memory.h

Go to the documentation of this file.
00001
00009 #ifndef PA_MEMORY_H
00010 #define PA_MEMORY_H
00011
00012 static const char * const IDENT_MEMORY_H="$Date: 2005/12/16 10:15:12 $";
00013
00014 // include
00015
00016 #include "pa_config_includes.h"
00017 #include "gc.h"
00018
00019 // defines
00020
00021 //#define PA_DEBUG_GC_MEMORY
00022
00023 #ifdef PA_DEBUG_GC_MEMORY
00024 void* pa_gc_malloc(size_t size);
00025 void* pa_gc_malloc_atomic(size_t size);
00026 void* pa_gc_realloc(void* ptr, size_t size);
00027 void pa_gc_free(void* ptr);
00028 #else
00029 inline void* pa_gc_malloc(size_t size) { return GC_MALLOC(size); }
00030 inline void* pa_gc_malloc_atomic(size_t size) { return GC_MALLOC_ATOMIC(size); }
00031 inline void* pa_gc_realloc(void* ptr, size_t size) { return GC_REALLOC(ptr, size); }
00032 inline void pa_gc_free(void* ptr) { GC_FREE(ptr); }
00033 #endif
00034
00035
00036 // forwards
00037
00038 void *pa_fail_alloc(const char* what, size_t size);
00039
00040 // inlines
00041
00042 inline void *pa_malloc(size_t size) {
00043     if(void *result=pa_gc_malloc(size))
00044         return result;
00045
00046     return pa_fail_alloc("allocate", size);
00047 }
00048
00049 inline void *pa_malloc_atomic(size_t size) {
00050     if(void *result=pa_gc_malloc_atomic(size))
00051         return result;
00052
00053     return pa_fail_alloc("allocate clean", size);
00054 }
00056 inline char *pa_strdup(const char* auto_variable_never_null, size_t helper_length=0) {
00057     size_t known_length=(helper_length?helper_length:strlen(auto_variable_never_null));
00058
00059     size_t size=known_length+1;
00060     if(char *result=static_cast<char*>(pa_gc_malloc_atomic(size))) {
00061         memcpy(result, auto_variable_never_null, known_length);
00062         result[known_length]=0;
00063         return result;
00064     }
00065
00066     return static_cast<char*>(pa_fail_alloc("allocate clean", size));
00067 }
00068
00069 inline void pa_free(void *ptr) {
00070     pa_gc_free(ptr);
00071 }
00072
00073 inline void *pa_realloc(void *ptr, size_t size) {
00074     if(void *result=pa_gc_realloc(ptr, size))
00075         return result;
00076
00077     return pa_fail_alloc("reallocate to", size);
00078 }
00079
00080 //{@ these operators are disabled, one should explicitely specify either new(UseGC) or new(PointerFreeGC)
00081 inline void *operator new(size_t) { abort(); } // disabled
00082 inline void *operator new[] (size_t) { abort(); } // disabled
00083 //}@
00084
00085 #define UseGC ((int)1)
00086 #define PointerFreeGC (true)
00087
00088 //{@ Array-oriented
00089 inline void *operator new[] (size_t size, int) { // UseGC
00090     return pa_malloc(size);
00091 }
00092 inline void *operator new[] (size_t size, bool) { // PointerFreeGC
00093     return pa_malloc_atomic(size);
00094 }
00095 inline void operator delete[] (void *ptr) {
00096     pa_free(ptr);
00097 }
00098 //}@
00099
00100 //{@ Structure-oriented
00101 inline void *operator new (size_t size, int) { // UseGC
00102     return pa_malloc(size);
00103 }
00104 inline void *operator new (size_t size, bool) { // PointerFreeGC
00105     return pa_malloc_atomic(size);
00106 }
00107 inline void operator delete(void *ptr) {
00108     pa_free(ptr);
00109 }
00110 //}@
00111
00113 class PA_Allocated {
00114 public:
00116     static void *operator new(size_t size) {
00117         return pa_malloc(size);
00118     }
00119     static void operator delete(void *ptr) {
00120         pa_free(ptr);
00121     }
00122     static void *malloc(size_t size) {
00123         return pa_malloc(size);
00124     }
00125     static void *malloc_atomic(size_t size) {
00126         return pa_malloc_atomic(size);
00127     }
00128     static char *strdup(const char* auto_variable_never_null, size_t helper_length=0) {
00129         return pa_strdup(auto_variable_never_null, helper_length);
00130     }
00131     static void free(void *ptr) {
00132         pa_free(ptr);
00133     }
00134     static void *realloc(void *ptr, size_t size) {
00135         return pa_realloc(ptr, size);
00136     }
00137
00138 private: // disabled from accidental use
00139
00141     static void *calloc(size_t size);
00142
00143 };
00144
00146 class PA_Cleaned {
00147 #ifndef PA_DEBUG_DISABLE_GC
00148     static void cleanup( void* obj, void* displ ) {
00149         ((PA_Cleaned*) ((char*) obj + (ptrdiff_t) displ))->~PA_Cleaned();
00150     }
00151
00152 public:
00153     PA_Cleaned() {
00154         GC_finalization_proc oldProc;
00155         void* oldData;
00156         void* base = GC_base( (void *) this );
00157         if (0 != base)  {
00158             // Don't call the debug version, since this is a real base address.
00159             GC_register_finalizer_ignore_self(
00160                 base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base),
00161                 &oldProc, &oldData );
00162             if (0 != oldProc) {
00163                 GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );
00164             }
00165         }
00166     }
00167
00168     virtual ~PA_Cleaned() {
00169         GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );
00170     }
00171 #endif
00172 };
00173
00175 typedef PA_Allocated PA_Object;
00176
00177 // defines
00178
00179 #define override
00180 #define rethrow throw
00181
00182
00183 #endif


pa_method.h File Reference

Parser: Method class decl. More...

Include dependency graph for pa_method.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Method
class method. More...

class | Temp_value_element
Auto-object used for temporarily substituting/removing elements. More...

Typedefs

typedef void(* | NativeCodePtr )(Request &request, MethodParams &params)
native code method params can be NULL when method min&max params (see VStateless_class::add_native_method) counts are zero. More...

Variables

const char *const | IDENT_METHOD_H = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: Method class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_method.h.

Typedef Documentation

typedef void(* NativeCodePtr)(Request& request, MethodParams& params)

native code method params can be NULL when method min&max params (see VStateless_class::add_native_method) counts are zero.

Definition at line 26 of file pa_method.h.

Referenced by VStateless_class::add_native_method(), and Method::Method::Method().

Variable Documentation

const char* const IDENT_METHOD_H = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 11 of file pa_method.h.


pa_method.h Source File

pa_method.h

Go to the documentation of this file.
00001
00008 #ifndef PA_METHOD_H
00009 #define PA_METHOD_H
00010
00011 static const char * const IDENT_METHOD_H="$Date: 2005/08/09 08:14:53 $";
00012
00013
00014 /*#include "pa_string.h"
00015 #include "pa_array.h"
00016 #include "pa_exception.h"
00017 */
00018 #include "pa_operation.h"
00019
00026 typedef void (*NativeCodePtr)(Request& request, MethodParams& params);
00027
00028
00045 class Method: public PA_Object {
00046 public:
00047
00049     enum Call_type {
00050         CT_ANY,
00051         CT_STATIC,
00052         CT_DYNAMIC
00053     };
00054
00056     //const String& name;
00058     Call_type call_type;
00060
00061     int min_numbered_params_count, max_numbered_params_count;
00063
00064
00065     ArrayString* params_names;  ArrayString* locals_names;
00067
00068
00069     ArrayOperation* parser_code;/*OR*/NativeCodePtr native_code;
00071
00072     Method::Method(
00073         //const String& aname,
00074         Call_type call_type,
00075         int amin_numbered_params_count, int amax_numbered_params_count,
00076         ArrayString* aparams_names, ArrayString* alocals_names,
00077         ArrayOperation* aparser_code, NativeCodePtr anative_code) :
00078
00079         //name(aname),
00080         call_type(call_type),
00081         min_numbered_params_count(amin_numbered_params_count),
00082         max_numbered_params_count(amax_numbered_params_count),
00083         params_names(aparams_names), locals_names(alocals_names),
00084         parser_code(aparser_code), native_code(anative_code) {
00085     }
00086
00088     void check_actual_numbered_params(
00089         Value& self, /*const String& actual_name, */MethodParams* actual_numbered_params) const;
00090 };
00091
00093 class Temp_value_element {
00094     Value& fwhere;
00095     const String& fname;
00096     Value* saved;
00097 public:
00098     Temp_value_element(Value& awhere, const String& aname, Value* awhat) :
00099         fwhere(awhere),
00100         fname(aname),
00101         saved(awhere.get_element(aname, awhere, false)) {
00102         fwhere.put_element(fwhere, aname, awhat, false);
00103     }
00104     ~Temp_value_element() {
00105         fwhere.put_element(fwhere, fname, saved, false);
00106     }
00107 };
00108
00109
00110 #endif


pa_opcode.h File Reference

Parser: compiled code related decls. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Enumerations

enum OPCODE {
OP_VALUE, OP_CURLY_CODE__STORE_PARAM, OP_EXPR_CODE__STORE_PARAM, OP_NESTED_CODE,
OP_WITH_ROOT, OP_WITH_SELF, OP_WITH_READ, OP_WITH_WRITE,
OP_GET_CLASS, OP_CONSTRUCT_VALUE, OP_CONSTRUCT_EXPR, OP_CURLY_CODE__CONSTRUCT,
OP_WRITE_VALUE, OP_WRITE_EXPR_RESULT, OP_STRING__WRITE, OP_GET_ELEMENT_OR_OPERATOR,
OP_GET_ELEMENT, OP_GET_ELEMENT__WRITE, OP_OBJECT_POOL, OP_STRING_POOL,
OP_STORE_PARAM, OP_PREPARE_TO_CONSTRUCT_OBJECT, OP_PREPARE_TO_EXPRESSION, OP_CALL,
OP_CALL__WRITE, OP_NEG, OP_INV, OP_NOT,
OP_DEF, OP_IN, OP_FEXISTS, OP_DEXISTS,
OP_SUB, OP_ADD, OP_MUL, OP_DIV,
OP_MOD, OP_INTDIV, OP_BIN_SL, OP_BIN_SR,
OP_BIN_AND, OP_BIN_OR, OP_BIN_XOR, OP_LOG_AND,
OP_LOG_OR, OP_LOG_XOR, OP_NUM_LT, OP_NUM_GT,
OP_NUM_LE, OP_NUM_GE, OP_NUM_EQ, OP_NUM_NE,
OP_STR_LT, OP_STR_GT, OP_STR_LE, OP_STR_GE,
OP_STR_EQ, OP_STR_NE, OP_IS
}
Compiled operation code. More...

Variables

const char *const IDENT_OPCODE_H = "$Date: 2005/08/09 08:14:49 $"

Detailed Description

Parser: compiled code related decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)

Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_opcode.h.

Enumeration Type Documentation

enum OPCODE

Compiled operation code.

Enumeration values:
OP_VALUE
OP_CURLY_CODE__STORE_PARAM
OP_EXPR_CODE__STORE_PARAM
OP_NESTED_CODE
OP_WITH_ROOT
OP_WITH_SELF
OP_WITH_READ
OP_WITH_WRITE
OP_GET_CLASS
OP_CONSTRUCT_VALUE
OP_CONSTRUCT_EXPR
OP_CURLY_CODE__CONSTRUCT
OP_WRITE_VALUE
OP_WRITE_EXPR_RESULT
OP_STRING__WRITE
OP_GET_ELEMENT_OR_OPERATOR
OP_GET_ELEMENT
OP_GET_ELEMENT__WRITE
OP_OBJECT_POOL
OP_STRING_POOL
OP_STORE_PARAM
OP_PREPARE_TO_CONSTRUCT_OBJECT
OP_PREPARE_TO_EXPRESSION
OP_CALL
OP_CALL__WRITE
OP_NEG
OP_INV
OP_NOT
OP_DEF
OP_IN
OP_FEXISTS
OP_DEXISTS
OP_SUB
OP_ADD
OP_MUL
OP_DIV
OP_MOD
OP_INTDIV
OP_BIN_SL
OP_BIN_SR
OP_BIN_AND
OP_BIN_OR
OP_BIN_XOR
OP_LOG_AND
OP_LOG_OR
OP_LOG_XOR
OP_NUM_LT
OP_NUM_GT
OP_NUM_LE
OP_NUM_GE
OP_NUM_EQ
OP_NUM_NE
OP_STR_LT
OP_STR_GT
OP_STR_LE
OP_STR_GE
OP_STR_EQ
OP_STR_NE
OP_IS

Definition at line 15 of file pa_opcode.h.

Referenced by changetail_or_append(), Request::execute(), O(), OA(), and Operation::Operation().

Variable Documentation

const char* const IDENT_OPCODE_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 12 of file pa_opcode.h.


pa_opcode.h Source File

pa_opcode.h

Go to the documentation of this file.
00001
00009 #ifndef OPCODE_H
00010 #define OPCODE_H
00011
00012 static const char * const IDENT_OPCODE_H="$Date: 2005/08/09 08:14:49 $";
00013
00015 enum OPCODE {
00017
00018     OP_VALUE,  OP_CURLY_CODE__STORE_PARAM,  OP_EXPR_CODE__STORE_PARAM,
00019     OP_NESTED_CODE,
00021
00023
00024     OP_WITH_ROOT,   OP_WITH_SELF,   OP_WITH_READ,   OP_WITH_WRITE,
00025     OP_GET_CLASS,
00026     OP_CONSTRUCT_VALUE, OP_CONSTRUCT_EXPR, OP_CURLY_CODE__CONSTRUCT,
00027     OP_WRITE_VALUE,  OP_WRITE_EXPR_RESULT, OP_STRING__WRITE,
00028     OP_GET_ELEMENT_OR_OPERATOR, OP_GET_ELEMENT, OP_GET_ELEMENT__WRITE,
00029     OP_OBJECT_POOL, OP_STRING_POOL,
00030     OP_STORE_PARAM,
00031     OP_PREPARE_TO_CONSTRUCT_OBJECT, OP_PREPARE_TO_EXPRESSION,
00032     OP_CALL, OP_CALL__WRITE,
00034
00036
00037     OP_NEG, OP_INV, OP_NOT, OP_DEF, OP_IN, OP_FEXISTS, OP_DEXISTS,
00039
00041
00042     OP_SUB, OP_ADD, OP_MUL, OP_DIV, OP_MOD, OP_INTDIV,
00043     OP_BIN_SL, OP_BIN_SR,
00044     OP_BIN_AND, OP_BIN_OR, OP_BIN_XOR,
00045     OP_LOG_AND, OP_LOG_OR, OP_LOG_XOR,
00046     OP_NUM_LT, OP_NUM_GT, OP_NUM_LE, OP_NUM_GE, OP_NUM_EQ, OP_NUM_NE,
00047     OP_STR_LT, OP_STR_GT, OP_STR_LE, OP_STR_GE, OP_STR_EQ, OP_STR_NE,
00048     OP_IS
00050 };
00051
00052 #endif


pa_operation.h File Reference

Parser: compiled code related decls. More...

Include dependency graph for pa_operation.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

union | Operation
Parser source code got compiled into intermediate form of Operation-s, which are executed afterwards. More...

struct | Origin

Defines

#define | OPERATIONS_PER_OPVALUE 3

Typedefs

typedef Array< Operation > | ArrayOperation

Variables

const char *const | IDENT_OPERATION_H = "$Date: 2005/08/09 08:14:49 $"

Detailed Description

Parser: compiled code related decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)

Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_operation.h.

Define Documentation

#define OPERATIONS_PER_OPVALUE 3

Definition at line 63 of file pa_operation.h.

Typedef Documentation

typedef Array<Operation> ArrayOperation

Definition at line 21 of file pa_operation.h.

Variable Documentation

const char* const IDENT_OPERATION_H = "$Date: 2005/08/09 08:14:49 $" [static]

Definition at line 12 of file pa_operation.h.


pa_operation.h Source File

pa_operation.h

Go to the documentation of this file.
00001
00009 #ifndef OPERATION_H
00010 #define OPERATION_H
00011
00012 static const char * const IDENT_OPERATION_H="$Date: 2005/08/09 08:14:49 $";
00013
00014 #include "pa_array.h"
00015 #include "pa_opcode.h"
00016 #include "pa_value.h"
00017
00018 // forwards
00019
00020 union Operation;
00021 typedef Array<Operation> ArrayOperation;
00022
00035 union Operation {
00036     struct Origin {
00037         uint file_no:8;
00038         uint line:8+8;
00039         uint col:8;
00040
00041         static Origin create(uint afile_no, uint aline, uint acol) {
00042             Origin result={afile_no, aline, acol};
00043             return result;
00044         }
00045     };
00046
00047     OPCODE code;
00048     Origin origin;
00049     Value* value;
00050     ArrayOperation* ops;
00051
00053     Operation() {}
00054     Operation(OPCODE acode): code(acode) {}
00055     Operation(uint afile_no, uint aline, uint acol):
00056         origin(Origin::create(afile_no, aline, acol)) {}
00057     Operation(Value* avalue): value(avalue) {}
00058     Operation(ArrayOperation* aops): ops(aops) {}
00059 };
00060
00061 // defines
00062
00063 #define OPERATIONS_PER_OPVALUE 3
00064
00065 #endif


pa_os.C File Reference

Parser: commonly functions. More...

Include dependency graph for pa_os.C:

Include dependency graph

Go to the source code of this file.

Functions

int | pa_sleep (unsigned long secs, unsigned long usecs)
yields to OS for secs secs and usecs microseconds (1E-6). More...

Variables

const char *const | IDENT_COMMON_C = "$Date: 2005/08/09 08:14:52 $"

Detailed Description

Parser: commonly functions.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_os.C.

Function Documentation

int pa_sleep | ( | unsigned long | secs,
 |  | unsigned long | usecs
 | ) |

yields to OS for secs secs and usecs microseconds (1E-6).

Definition at line 60 of file pa_os.C.

Referenced by _cache(), and _sleep_operator().

Variable Documentation

const char* const IDENT_COMMON_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_os.C.


pa_os.C Source File

pa_os.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_COMMON_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #include "pa_config_includes.h"
00011 #include "pa_os.h"
00012
00013 #   if defined(WIN32)
00014 #       include <windows.h>
00015 #   endif
00016
00017 #ifdef HAVE_FLOCK
00018
00019 int pa_lock_shared_blocking(int fd) { return flock(fd, LOCK_SH); }
00020 int pa_lock_exclusive_blocking(int fd) { return flock(fd, LOCK_EX); }
00021 int pa_lock_exclusive_nonblocking(int fd) { return flock(fd, LOCK_EX || LOCK_NB); }
00022 int pa_unlock(int fd) { return flock(fd, LOCK_UN); }
00023
00024 #else
00025 #ifdef HAVE__LOCKING
00026
00027 #define FLOCK(operation) lseek(fd, 0, SEEK_SET);  return _locking(fd, operation, 1)
00028 int pa_lock_shared_blocking(int fd) { FLOCK(_LK_LOCK); }
00029 int pa_lock_exclusive_blocking(int fd) { FLOCK(_LK_LOCK); }
00030 int pa_lock_exclusive_nonblocking(int fd) { FLOCK(_LK_NBLCK); }
00031 int pa_unlock(int fd) { FLOCK(_LK_UNLCK); }
00032
00033 #else
00034 #ifdef HAVE_FCNTL
00035
00036 #define FLOCK(cmd, arg) struct flock ls={arg, SEEK_SET};  return fcntl(fd, cmd, &ls)
00037 int pa_lock_shared_blocking(int fd) { FLOCK(F_SETLKW, F_RDLCK); }
00038 int pa_lock_exclusive_blocking(int fd) { FLOCK(F_SETLKW, F_WRLCK); }
00039 int pa_lock_exclusive_nonblocking(int fd) { FLOCK(F_SETLK, F_RDLCK); }
00040 int pa_unlock(int fd) { FLOCK(F_SETLK, F_UNLCK); }
00041
00042 #else
00043 #ifdef HAVE_LOCKF
00044
00045 #define FLOCK(fd, operation) lseek(fd, 0, SEEK_SET);  return lockf(fd, operation, 1)
00046 int pa_lock_shared_blocking(int fd) { FLOCK(F_LOCK); } // on intel solaris man doesn't have doc on shared blocking
00047 int pa_lock_exclusive_blocking(int fd) { FLOCK(F_LOCK); }
00048 int pa_lock_exclusive_nonblocking(int fd) { FLOCK(F_TLOCK); }
00049 int pa_unlock(int fd) { FLOCK(F_TLOCK); }
00050
00051 #else
00052
00053 #error unable to find file locking func
00054
00055 #endif
00056 #endif
00057 #endif
00058 #endif
00059
00060 int pa_sleep(unsigned long secs, unsigned long usecs) {
00061     for (;  usecs >= 1000000; ++secs, usecs -= 1000000);
00062
00063 #ifdef WIN32
00064     Sleep(secs * 1000 + usecs / 1000);
00065     return 0;
00066 #else
00067     struct timeval t;
00068     t.tv_sec = secs;
00069     t.tv_usec = usecs;
00070     return (select(0, NULL, NULL, NULL, &t)<0 ? errno : 0);
00071 #endif
00072 }


pa_os.h File Reference

Parser: commonly used functions. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

int | pa_lock_shared_blocking (int fd)
int | pa_lock_exclusive_blocking (int fd)
int | pa_lock_exclusive_nonblocking (int fd)
int | pa_unlock (int fd)
int | pa_sleep (unsigned long secs, unsigned long usecs)
yields to OS for secs secs and usecs microseconds (1E-6). More...

Variables

const char *const | IDENT_OS_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: commonly used functions.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_os.h.

Function Documentation

int pa_lock_shared_blocking ( int fd )

Referenced by file_read_action_under_lock().

int pa_lock_exclusive_blocking ( int fd )

Referenced by file_write_action_under_lock().

int pa_lock_exclusive_nonblocking ( int fd )

Referenced by file_write_action_under_lock().

int pa_unlock ( int fd )

Referenced by file_read_action_under_lock(), and file_write_action_under_lock().

int pa_sleep | ( | unsigned long | secs,
 |  | unsigned long | usecs
 | ) |

yields to OS for secs secs and usecs microseconds (1E-6).

Definition at line 60 of file pa_os.C.

Referenced by _cache(), and _sleep_operator().

Variable Documentation

const char* const IDENT_OS_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_os.h.


pa_os.h Source File

pa_os.h

Go to the documentation of this file.
00001
00008 #ifndef PA_OS_H
00009 #define PA_OS_H
00010
00011 static const char * const IDENT_OS_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 int pa_lock_shared_blocking(int fd);
00014 int pa_lock_exclusive_blocking(int fd);
00015 int pa_lock_exclusive_nonblocking(int fd);
00016 int pa_unlock(int fd);
00017
00019 int pa_sleep(unsigned long secs, unsigned long usecs);
00020
00021 #endif


pa_pool.C File Reference

Parser: pool class. More...

Include dependency graph for pa_pool.C:

Include dependency graph

Go to the source code of this file.

Functions

void | cleanup (Pool::Cleanup item, int)
void | unregister_cleanup (Pool::Cleanup &item, void *cleanup_data)
void | cleanup (void *data)

Variables

const char *const | IDENT_POOL_C = "$Date: 2003/11/20 16:34:26 $"

Detailed Description

Parser: pool class.

Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_pool.C.

Function Documentation

void cleanup | ( | Pool::Cleanup | item,
 |  | int |
 | ) | [static]

Definition at line 20 of file pa_pool.C.

References Pool::Cleanup::cleanup, and Pool::Cleanup::data.

Referenced by Pooled::Pooled(), Pool::register_cleanup(), and Pool::~Pool().

void unregister_cleanup | ( | Pool::Cleanup & | item,
 |  | void * | cleanup_data
 | ) | [static]

Definition at line 36 of file pa_pool.C.

References Pool::Cleanup::cleanup, and Pool::Cleanup::data.

void cleanup ( void * data ) [static]

Definition at line 46 of file pa_pool.C.

References data.

Variable Documentation

const char* const IDENT_POOL_C = "$Date: 2003/11/20 16:34:26 $" [static]

Definition at line 8 of file pa_pool.C.


pa_pool.C Source File

pa_pool.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_POOL_C="$Date: 2003/11/20 16:34:26 $";
00009
00010 #include "pa_pool.h"
00011 #include "pa_exception.h"
00012 #include "pa_common.h"
00013 #include "pa_sapi.h"
00014 #include "pa_charset.h"
00015
00016 // Pool
00017
00018 Pool::Pool(){}
00019
00020 static void cleanup(Pool::Cleanup item, int) {
00021     if(item.cleanup)
00022         item.cleanup(item.data);
00023 }
00024 Pool::~Pool() {
00025     //__asm__("int3");
00026     //_asm int 3;
00027     //fprintf(stderr, "cleanups: %d\n", cleanups.size());
00028     // cleanups first, because they use some object's memory pointers
00029     cleanups.for_each(cleanup, 0);
00030 }
00031
00032 void Pool::register_cleanup(void (*cleanup) (void *), void *data) {
00033     cleanups+=Cleanup(cleanup, data);
00034 }
00035
00036 static void unregister_cleanup(Pool::Cleanup& item, void* cleanup_data) {
00037     if(item.data==cleanup_data)
00038         item.cleanup=0;
00039 }
00040 void Pool::unregister_cleanup(void *cleanup_data) {
00041     cleanups.for_each_ref(::unregister_cleanup, cleanup_data);
00042 }
00043
00044 // Pooled
00045
00046 static void cleanup(void *data) {
00047     static_cast<Pooled*>(data)->~Pooled();
00048 }
00049
00050 Pooled::Pooled(Pool& apool): fpool(apool) {
00051     fpool.register_cleanup(cleanup, this);
00052 }
00053
00055 Pooled::~Pooled() {
00056     fpool.unregister_cleanup(this);
00057 }


pa_pool.h File Reference

Parser: pool class decl. More...

Include dependency graph for pa_pool.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Pool
Pool mechanizm allows users not to free up allocated objects, leaving that problem to 'pools'. More...

struct | Cleanup
class | Pooled
Base for all classes that are allocated in 'pools'. More...

Variables

const char *const | IDENT_POOL_H = "$Date: 2003/11/20 16:32:12 $"

Detailed Description

Parser: pool class decl.

Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)

Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_pool.h.

Variable Documentation

const char* const IDENT_POOL_H = "$Date: 2003/11/20 16:32:12 $" [static]

Definition at line 12 of file pa_pool.h.


pa_pool.h Source File

pa_pool.h

Go to the documentation of this file.
00001
00009 #ifndef PA_POOL_H
00010 #define PA_POOL_H
00011
00012 static const char * const IDENT_POOL_H="$Date: 2003/11/20 16:32:12 $";
00013
00014 #include "pa_config_includes.h"
00015 #include "pa_array.h"
00016
00024 class Pool {
00025 public:
00026
00027     struct Cleanup {
00028         void (*cleanup) (void *);
00029         void *data;
00030
00031         Cleanup(void (*acleanup) (void *), void *adata): cleanup(acleanup), data(adata) {}
00032     };
00033
00034     Pool();
00035     ~Pool();
00036
00038     void register_cleanup(void (*cleanup) (void *), void *data);
00040     void unregister_cleanup(void *cleanup_data);
00041
00042 private:
00043
00044     Array<Cleanup> cleanups;
00045
00046 private:
00047
00048     //{
00050     bool real_register_cleanup(void (*cleanup) (void *), void *data);
00051     //}
00052
00053 private:
00054
00056     void fail_register_cleanup() const;
00057
00058 private: //disabled
00059
00060     Pool(const Pool&);
00061     Pool& operator= (const Pool&);
00062 };
00063
00068 class Pooled {
00069     // the pool i'm allocated on
00070     Pool& fpool;
00071 public:
00072
00073     Pooled(Pool& apool);
00074
00076     //Pool& pool() const { return *fpool; }
00077
00079     virtual ~Pooled();
00080
00081 };
00082
00083 #endif


pa_property.h File Reference

Parser: Property class decl. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Property
junction is getter and setter methods. More...

Variables

const char *const | IDENT_PROPERTY_H = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: Property class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_property.h.

Variable Documentation

const char* const IDENT_PROPERTY_H = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 11 of file pa_property.h.


pa_property.h Source File

pa_property.h

Go to the documentation of this file.
00001
00008 #ifndef PA_PROPERTY_H
00009 #define PA_PROPERTY_H
00010
00011 static const char * const IDENT_PROPERTY_H="$Date: 2005/08/09 08:14:53 $";
00012
00013 class Method;
00014
00020 class Property: public PA_Object {
00021 public:
00022     Method* getter;
00023     Method* setter;
00024 };
00025
00026 #endif


pa_request.C File Reference

Parser: request class main part. More...

Include dependency graph for pa_request.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | UNHANDLED_EXCEPTION_METHOD_NAME "unhandled_exception"
#define | MAIN_METHOD_NAME "main"
#define | AUTO_METHOD_NAME "auto"
#define | BODY_NAME "body"
#define | EXCEPTION_TYPE_PART_NAME "type"
#define | EXCEPTION_SOURCE_PART_NAME "source"
#define | EXCEPTION_COMMENT_PART_NAME "comment"
#define | CHARSETS_NAME "CHARSETS"
#define | MIME_TYPES_NAME "MIME-TYPES"
#define | ORIGINS_MODE_NAME "ORIGINS"
#define | CONF_METHOD_NAME "conf"
#define | POST_PROCESS_METHOD_NAME "postprocess"
#define | DOWNLOAD_NAME "download"
#define | CLASS_PATH_NAME "CLASS_PATH"
#define | RESPONSE_BODY_FILE_NAME "file"
#define | PA_URI_FORMAT "%s: "
#define | PA_ORIGIN_FILE_POS_FORMAT "%s(%d:%d): "
#define | PA_SOURCE_FORMAT "'%s' "
#define | PA_COMMENT_TYPE_FORMAT "%s [%s]"

Functions

const String | main_method_name (MAIN_METHOD_NAME)
const String | auto_method_name (AUTO_METHOD_NAME)
const String | content_disposition_name (CONTENT_DISPOSITION_NAME)
const String | content_disposition_value (CONTENT_DISPOSITION_VALUE)
const String | content_disposition_filename_name (CONTENT_DISPOSITION_FILENAME_NAME)
const String | body_name (BODY_NAME)
const String | exception_type_part_name (EXCEPTION_TYPE_PART_NAME)
const String | exception_source_part_name (EXCEPTION_SOURCE_PART_NAME)
const String | exception_comment_part_name (EXCEPTION_COMMENT_PART_NAME)
const String | exception_handled_part_name (EXCEPTION_HANDLED_PART_NAME)
const String | charsets_name (CHARSETS_NAME)
const String | main_class_name (MAIN_CLASS_NAME)
const String | mime_types_name (MIME_TYPES_NAME)
const String | origins_mode_name (ORIGINS_MODE_NAME)
const String | conf_method_name (CONF_METHOD_NAME)
const String | post_process_method_name (POST_PROCESS_METHOD_NAME)
const String | download_name (DOWNLOAD_NAME)
const String | class_path_name (CLASS_PATH_NAME)
const String | response_body_file_name (RESPONSE_BODY_FILE_NAME)
VStateless_class & VClassMAIN_create ()
void | load_charset (HashStringValue::key_type akey, HashStringValue::value_type avalue, Request_charsets *charsets)
void | add_header_attribute (HashStringValue::key_type aattribute, HashStringValue::value_type ameaning, Add_header_attribute_info *info)
void | output_sole_piece (Request &r, bool header_only, VFile &body_file, Value *body_file_content_type)
void | parse_range (const String *s, Array< Range > &ar)
void | output_pieces (Request &r, bool header_only, const String &filename, size_t content_length, Value &date, bool add_last_modified)

Variables

const char *const | IDENT_REQUEST_C = "$Date: 2005/12/16 10:15:12 $"
const char * | UNHANDLED_EXCEPTION_CONTENT_TYPE = "text/plain"
content type of exception response, when no @MAIN:exception handler defined. More...

const char * | DEFAULT_CONTENT_TYPE = "text/html"
content type of response when no $MAIN:defaults.content-type defined. More...

const char * | ORIGINS_CONTENT_TYPE = "text/plain"

Detailed Description

Parser: request class main part.

See also:
compile.C and execute.C.
Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_request.C.

Define Documentation

#define UNHANDLED_EXCEPTION_METHOD_NAME "unhandled_exception"

Definition at line 39 of file pa_request.C.

Referenced by Request::core().

#define MAIN_METHOD_NAME "main"

Definition at line 50 of file pa_request.C.

Referenced by Request::core().

#define AUTO_METHOD_NAME "auto"

Definition at line 51 of file pa_request.C.

#define BODY_NAME "body"

Definition at line 52 of file pa_request.C.

Referenced by add_header_attribute().

#define EXCEPTION_TYPE_PART_NAME "type"

Definition at line 53 of file pa_request.C.

#define EXCEPTION_SOURCE_PART_NAME "source"

Definition at line 54 of file pa_request.C.

#define EXCEPTION_COMMENT_PART_NAME "comment"

Definition at line 55 of file pa_request.C.

#define CHARSETS_NAME "CHARSETS"

Definition at line 72 of file pa_request.C.

Referenced by Request::configure_admin().

#define MIME_TYPES_NAME "MIME-TYPES"

Definition at line 73 of file pa_request.C.

Referenced by Request::mime_type_of().

#define ORIGINS_MODE_NAME "ORIGINS"

Definition at line 74 of file pa_request.C.

#define CONF_METHOD_NAME "conf"

Definition at line 75 of file pa_request.C.

#define POST_PROCESS_METHOD_NAME "postprocess"

Definition at line 76 of file pa_request.C.

#define DOWNLOAD_NAME "download"

Definition at line 77 of file pa_request.C.

Referenced by add_header_attribute().

#define CLASS_PATH_NAME "CLASS_PATH"

Definition at line 78 of file pa_request.C.

Referenced by Request::use_file().

#define RESPONSE_BODY_FILE_NAME "file"

Definition at line 79 of file pa_request.C.

#define PA_URI_FORMAT "%s: "

#define PA_ORIGIN_FILE_POS_FORMAT "%s(%d:%d): "

#define PA_SOURCE_FORMAT "'%s' "

#define PA_COMMENT_TYPE_FORMAT "%s [%s]"

Function Documentation

const String main_method_name ( MAIN_METHOD_NAME )

const String auto_method_name ( AUTO_METHOD_NAME )

const String content_disposition_name ( CONTENT_DISPOSITION_NAME )

const String content_disposition_value ( CONTENT_DISPOSITION_VALUE )

const String content_disposition_filename_name ( CONTENT_DISPOSITION_FILENAME_NAME )

const String body_name ( BODY_NAME )

const String exception_type_part_name ( EXCEPTION_TYPE_PART_NAME )

const String exception_source_part_name ( EXCEPTION_SOURCE_PART_NAME )

const String exception_comment_part_name ( EXCEPTION_COMMENT_PART_NAME )

const String exception_handled_part_name ( EXCEPTION_HANDLED_PART_NAME )

const String charsets_name ( CHARSETS_NAME ) [static]

const String main_class_name ( MAIN_CLASS_NAME ) [static]

const String mime_types_name ( MIME_TYPES_NAME ) [static]

const String origins_mode_name ( ORIGINS_MODE_NAME ) [static]

const String conf_method_name ( CONF_METHOD_NAME ) [static]

const String post_process_method_name ( POST_PROCESS_METHOD_NAME ) [static]

const String download_name ( DOWNLOAD_NAME ) [static]

const String class_path_name ( CLASS_PATH_NAME ) [static]

const String response_body_file_name ( RESPONSE_BODY_FILE_NAME ) [static]

VStateless_class& VClassMAIN_create ( )

Definition at line 865 of file op.C.

void load_charset | ( | HashStringValue::key_type | akey,
 |  | HashStringValue::value_type | avalue,
 |  | Request_charsets * | charsets
 | ) | [static]

Definition at line 199 of file pa_request.C.

References String::CC_UPPER, String::L_CLEAN, and Request_charsets::source().

Referenced by Request::configure_admin().

void add_header_attribute | ( | HashStringValue::key_type | aattribute,
 |  | HashStringValue::value_type | ameaning,
 |  | Add_header_attribute_info * | info
 | ) | [static]

Definition at line 658 of file pa_request.C.

References SAPI::add_header_attribute(), BODY_NAME, DOWNLOAD_NAME, String::L_HTTP_HEADER, and String::L_UNSPECIFIED.

Referenced by Request::output_result().

void output_sole_piece | ( | Request & | r,
 |  | bool | header_only,
 |  | VFile & | body_file,
 |  | Value * | body_file_content_type
 | ) | [static]

Definition at line 677 of file pa_request.C.

References SAPI::add_header_attribute(), Value::as_string(), Request::charsets, Request_charsets::client(), String::C::length, MAX_NUMBER, String::pos(), Request::sapi_info, SAPI::send_body(), SAPI::send_header(), snprintf, Request_charsets::source(), String::C::str, Charset::transcode(), VFile::value_ptr(), and VFile::value_size().

Referenced by Request::output_result().

void parse_range | ( | const String * | s,
 |  | Array< Range > & | ar
 | ) | [static]

Definition at line 708 of file pa_request.C.

References String::cstr(), p, and String::starts_with().

Referenced by output_pieces().

void output_pieces | ( | Request & | r,
 |  | bool | header_only,
 |  | const String & | filename,
 |  | size_t | content_length,
 |  | Value & | date,
 |  | bool | add_last_modified
 | ) | [static]

Definition at line 731 of file pa_request.C.

References Request::absolute(), SAPI::add_header_attribute(), attributed_meaning_to_string(), Request::charsets, Array< T >::count(), String::cstr(), file_read(), filename, SAPI::get_env(), Array< T >::get_ref(), String::L_AS_IS, File_read_result::length, offset, parse_range(), Request::sapi_info, SAPI::send_body(), SAPI::send_header(), size, snprintf, and File_read_result::str.

Referenced by Request::output_result().

Variable Documentation

const char* const IDENT_REQUEST_C = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 8 of file pa_request.C.

const char* UNHANDLED_EXCEPTION_CONTENT_TYPE = "text/plain"

content type of exception response, when no @MAIN:exception handler defined.

Definition at line 42 of file pa_request.C.

Referenced by Request::core().

const char* DEFAULT_CONTENT_TYPE = "text/html"

content type of response when no $MAIN:defaults.content-type defined.

Definition at line 45 of file pa_request.C.

Referenced by Request::output_result().

const char* ORIGINS_CONTENT_TYPE = "text/plain"

Definition at line 46 of file pa_request.C.


pa_request.C Source File

pa_request.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_REQUEST_C="$Date: 2005/12/16 10:15:12 $";
00009
00010 #include "pa_sapi.h"
00011 #include "pa_common.h"
00012 #include "pa_request.h"
00013 #include "pa_wwrapper.h"
00014 #include "pa_vclass.h"
00015 #include "pa_globals.h"
00016 #include "pa_vint.h"
00017 #include "pa_vmethod_frame.h"
00018 #include "pa_types.h"
00019 #include "pa_venv.h"
00020 #include "pa_vmath.h"
00021 #include "pa_vstatus.h"
00022 #include "pa_vrequest.h"
00023 #include "pa_vtable.h"
00024 #include "pa_vfile.h"
00025 #include "pa_dictionary.h"
00026 #include "pa_charset.h"
00027 #include "pa_charsets.h"
00028 #include "pa_cache_managers.h"
00029 #include "pa_vmail.h"
00030 #include "pa_vform.h"
00031 #include "pa_vcookie.h"
00032 #include "pa_vresponse.h"
00033 #include "pa_vmemory.h"
00034 #include "pa_vconsole.h"
00035 #include "pa_vdate.h"
00036
00037 // consts
00038
00039 #define UNHANDLED_EXCEPTION_METHOD_NAME "unhandled_exception"
00040
00042 const char* UNHANDLED_EXCEPTION_CONTENT_TYPE="text/plain";
00043
00045 const char* DEFAULT_CONTENT_TYPE="text/html";
00046 const char* ORIGINS_CONTENT_TYPE="text/plain";
00047
00048 // defines for globals
00049
00050 #define MAIN_METHOD_NAME "main"
00051 #define AUTO_METHOD_NAME "auto"
00052 #define BODY_NAME "body"
00053 #define EXCEPTION_TYPE_PART_NAME "type"
00054 #define EXCEPTION_SOURCE_PART_NAME "source"
00055 #define EXCEPTION_COMMENT_PART_NAME "comment"
00056
00057 // globals
00058
00059 const String main_method_name(MAIN_METHOD_NAME);
00060 const String auto_method_name(AUTO_METHOD_NAME);
00061 const String content_disposition_name(CONTENT_DISPOSITION_NAME);
00062 const String content_disposition_value(CONTENT_DISPOSITION_VALUE);
00063 const String content_disposition_filename_name(CONTENT_DISPOSITION_FILENAME_NAME);
00064 const String body_name(BODY_NAME);
00065 const String exception_type_part_name(EXCEPTION_TYPE_PART_NAME);
00066 const String exception_source_part_name(EXCEPTION_SOURCE_PART_NAME);
00067 const String exception_comment_part_name(EXCEPTION_COMMENT_PART_NAME);
00068 const String exception_handled_part_name(EXCEPTION_HANDLED_PART_NAME);
00069
00070 // defines for statics
00071
00072 #define CHARSETS_NAME "CHARSETS"
00073 #define MIME_TYPES_NAME "MIME-TYPES"
00074 #define ORIGINS_MODE_NAME "ORIGINS"
00075 #define CONF_METHOD_NAME "conf"
00076 #define POST_PROCESS_METHOD_NAME "postprocess"
00077 #define DOWNLOAD_NAME "download"
00078 #define CLASS_PATH_NAME "CLASS_PATH"
00079 #define RESPONSE_BODY_FILE_NAME "file"
00080
00081 // statics
00082
00083 static const String charsets_name(CHARSETS_NAME);
00084 static const String main_class_name(MAIN_CLASS_NAME);
00085 static const String mime_types_name(MIME_TYPES_NAME);
00086 static const String origins_mode_name(ORIGINS_MODE_NAME);
00087 static const String conf_method_name(CONF_METHOD_NAME);
00088 static const String post_process_method_name(POST_PROCESS_METHOD_NAME);
00089 static const String download_name(DOWNLOAD_NAME);
00090 static const String class_path_name(CLASS_PATH_NAME);
00091 static const String response_body_file_name(RESPONSE_BODY_FILE_NAME);
00092
00093 // defines
00094
00095 // op.C
00096 VStateless_class& VClassMAIN_create();
00097
00098 //
00099 Request::Request(SAPI_Info& asapi_info, Request_info& arequest_info,
00100                  String::Language adefault_lang, bool status_allowed):
00101     // private
00102     anti_endless_execute_recoursion(0),
00103
00104     // public
00105     method_frame(0),
00106     rcontext(0),
00107     wcontext(0),
00108     flang(adefault_lang),
00109     fconnection(0),
00110     finterrupted(false),
00111
00112     // public
00113 #ifdef RESOURCES_DEBUG
00114     sql_connect_time(0),
00115     sql_request_time(0),
00116 #endif
00117
00118     // public
00119     request_info(arequest_info),
00120     sapi_info(asapi_info),
00121     charsets(UTF8_charset, UTF8_charset, UTF8_charset), // default charsets
00122
00123     main_class(VClassMAIN_create()),
00124     form(*new VForm(charsets, arequest_info)),
00125     mail(*new VMail),
00126     response(*new VResponse(arequest_info, charsets)),
00127     cookie(*new VCookie),
00128
00129     // private
00130     configure_admin_done(false),
00131
00132     // private defaults
00133     fdefault_lang(adefault_lang),
00134     // private mime types
00135     mime_types(0)
00136 {
00137     pa_register_thread_request(*this);
00138
00139     // file_no=0 => unknown
00140     file_list+=String::Body("UNKNOWN");
00141     file_list+=String::Body("-body of process-"); // pseudo_file_no__process
00142
00143     // maybe expire old caches
00144     cache_managers->maybe_expire();
00145
00147     // MAIN class, operators
00148     classes().put(main_class.name(), &main_class);
00149     // classes:
00150     // table, file, random, mail, image, ...
00151     methoded_array().register_directly_used(*this);
00152
00154     // env class
00155     classes().put(String::Body(ENV_CLASS_NAME), new VEnv(asapi_info));
00156     // status class
00157     if(status_allowed)
00158         classes().put(String::Body(STATUS_CLASS_NAME), new VStatus());
00159     // request class
00160     classes().put(String::Body(REQUEST_CLASS_NAME), new VRequest(arequest_info, charsets));
00161     // cookie class
00162     classes().put(String::Body(COOKIE_CLASS_NAME), &cookie);
00163     // console class
00164     classes().put(String::Body(CONSOLE_CLASS_NAME), new VConsole());
00165
00167     // response class
00168     classes().put(response.get_class()->name(), &response);
00169
00171     // form class
00172     classes().put(form.get_class()->base_class()->name(), &form);
00173     // mail class
00174     classes().put(mail.get_class()->base_class()->name(), &mail);
00175     // math class
00176     {
00177         Value& math=*new VMath;
00178         classes().put(math.get_class()->base_class()->name(), &math);
00179     }
00180     // memory class
00181     {
00182         Value& memory=*new VMemory;
00183         classes().put(memory.get_class()->base_class()->name(), &memory);
00184     }
00185 }
00186
00187 Request::~Request() {
00188 #ifdef XML
00189     // if for some strange reason xml generic errors failed to be reported, free them up
00190     if(const char* xml_generic_errors=xmlGenericErrors()) {
00191         SAPI::log(sapi_info, "warning: unreported xmlGenericErrors: %s", xml_generic_errors);
00192         free((void *)xml_generic_errors);
00193     }
00194 #endif
00195 }
00196
00197 Value& Request::get_self() { return method_frame/*always have!*/->self(); }
00198
00199 static void load_charset(HashStringValue::key_type akey,
00200              HashStringValue::value_type avalue,
00201              Request_charsets* charsets) {
00202     const String::Body NAME=String(akey, String::L_CLEAN).change_case(charsets->source(), String::CC_UPPER);
00203     ::charsets.load_charset(*charsets, NAME, avalue->as_string());
00204 }
00205 void Request::configure_admin(VStateless_class& conf_class) {
00206     if(configure_admin_done)
00207         throw Exception("parser.runtime",
00208         0,
00209         "parser already configured");
00210     configure_admin_done=true;
00211
00212     // charsets must only be specified in method_frame config
00213     // so that users would not interfere
00214
00215     /* $MAIN:CHARSETS[
00216             $.charsetname1[/full/path/to/charset/file.cfg]
00217             ...
00218         ]
00219     */
00220     if(Value* vcharsets=conf_class.get_element(charsets_name, conf_class, false)) {
00221         if(!vcharsets->is_string())
00222             if(HashStringValue* charsets=vcharsets->get_hash())
00223                 charsets->for_each(load_charset, &this->charsets);
00224             else
00225                 throw Exception("parser.runtime",
00226                     0,
00227                     "$" MAIN_CLASS_NAME ":" CHARSETS_NAME " must be hash");
00228     }
00229
00230     // configure method_frame options
00231     //  until someone with less privileges have overriden them
00232     methoded_array().configure_admin(*this);
00233 }
00234
00235 const char* Request::get_exception_cstr(
00236                                         const Exception& e,
00237                                         Request::Exception_details& details) {
00238 #define PA_URI_FORMAT "%s: "
00239 #define PA_ORIGIN_FILE_POS_FORMAT "%s(%d:%d): "
00240 #define PA_SOURCE_FORMAT "'%s' "
00241 #define PA_COMMENT_TYPE_FORMAT "%s [%s]"
00242     char* result=new(PointerFreeGC) char[MAX_STRING];
00243
00244     if(details.problem_source) { // do we know the guy?
00245         if(details.trace) { // do whe know where he came from?
00246             Operation::Origin origin=details.trace.origin();
00247             snprintf(result, MAX_STRING,
00248                 PA_URI_FORMAT
00249                 PA_ORIGIN_FILE_POS_FORMAT
00250                 PA_SOURCE_FORMAT PA_COMMENT_TYPE_FORMAT,
00251                 request_info.uri,
00252                 file_list[origin.file_no].cstr(), 1+origin.line, 1+origin.col,
00253                 details.problem_source->cstr(),
00254                 e.comment(), e.type()
00255             );
00256         } else
00257             snprintf(result, MAX_STRING,
00258                 PA_URI_FORMAT
00259                 PA_SOURCE_FORMAT PA_COMMENT_TYPE_FORMAT,
00260                 request_info.uri,
00261                 details.problem_source->cstr(),
00262                 e.comment(), e.type()
00263             );
00264     } else
00265         snprintf(result, MAX_STRING,
00266             PA_URI_FORMAT
00267             PA_COMMENT_TYPE_FORMAT,
00268             request_info.uri,
00269             e.comment(), e.type()
00270         );
00271
00272     return result;
00273 }
00274
00275 void Request::configure() {
00276     // configure admin options if not configured yet
00277     if(!configure_admin_done)
00278         configure_admin(main_class);
00279
00280     // configure not-admin=user options
00281     methoded_array().configure_user(*this);
00282
00283     // $MAIN:MIME-TYPES
00284     if(Value* element=main_class.get_element(mime_types_name, main_class, false))
00285         if(Table *table=element->get_table())
00286             mime_types=table;
00287 }
00299 void Request::core(const char* config_filespec, bool config_fail_on_read_problem, bool header_only) {
00300 #ifdef RESOURCES_DEBUG
00301 //measures
00302 struct timeval mt[10];
00303 //measure:before all
00304 gettimeofday(&mt[0],NULL);
00305 #endif
00306     try {
00307         // filling cookies
00308         cookie.fill_fields(request_info);
00309
00310         // filling mail received
00311         mail.fill_received(*this);
00312
00313         // loading config
00314         if(config_filespec) {
00315             const String& filespec=*new String(config_filespec);
00316             use_file(main_class,
00317                 filespec, 0 /*main_alias*/,
00318                 true /*ignore class_path*/,
00319                 config_fail_on_read_problem,
00320                 true /*file must exist if 'fail on read problem' not set*/);
00321         }
00322
00323         // loading auto.p files from document_root/..
00324         // to the one beside requested file.
00325         // all assigned bases from upper dir
00326         {
00327             const char* after=request_info.path_translated;
00328             size_t drlen=strlen(request_info.document_root);
00329             if(memcmp(after, request_info.document_root, drlen)==0) {
00330                 after+=drlen;
00331                 if(after[-1]=='/')
00332                     --after;
00333             }
00334
00335             while(const char* before=strchr(after, '/')) {
00336                 String& sfile_spec=*new String;
00337                 if(after!=request_info.path_translated) {
00338                     sfile_spec.append_strdup(
00339                         request_info.path_translated, before-request_info.path_translated,
00340                         String::L_CLEAN);
00341                     sfile_spec << "/" AUTO_FILE_NAME;
00342
00343                     use_file(main_class,
00344                         sfile_spec,
00345                         0 /*main_alias*/,
00346                         true /*ignore class_path*/,
00347                         true /*fail on read problem*/,
00348                         false /*but ignore absence, sole user*/);
00349                 }
00350                 after=before+1;
00351             }
00352         }
00353
00354         try {
00355             // compile requested file
00356             String& spath_translated=*new String;
00357             spath_translated.append_help_length(request_info.path_translated, 0, String::L_TAINTED);
00358             use_file(main_class,
00359                 spath_translated,
00360                 0 /*main_alias*/,
00361                 true /*ignore class_path*/);
00362
00363             configure();
00364         } catch(...) {
00365             configure(); // configure anyway, useful in @unhandled_exception [say, if they would want to mail by SMTP something]
00366             rethrow;
00367         }
00368
00369 #ifdef RESOURCES_DEBUG
00370 //measure:after compile
00371 gettimeofday(&mt[1],NULL);
00372 #endif
00373         // execute @main[]
00374         const String* body_string=execute_virtual_method(main_class, main_method_name);
00375         if(!body_string)
00376             throw Exception("parser.runtime",
00377                 0,
00378                 "'"MAIN_METHOD_NAME"' method not found");
00379
00380 #ifdef RESOURCES_DEBUG
00381         //measure:after main
00382 gettimeofday(&mt[2],NULL);
00383 #endif
00384
00385         // extract response body
00386         Value* body_value=response.fields().get(download_name); // $response:download?
00387         bool as_attachment=body_value!=0;
00388         if(!body_value)
00389             body_value=response.fields().get(body_name); // $response:body
00390         if(!body_value)
00391             body_value=new VString(*body_string); // just result of ^main[]
00392         // ensure that body_value has no just L_TAINTED parts left
00393         if(body_value->is_string())
00394         {
00395             String& untainted=*new String();
00396             untainted.append(*body_value->get_string(), flang);
00397             body_value=new VString(untainted);
00398         }
00399
00400         // @postprocess
00401         if(Value* value=main_class.get_element(post_process_method_name, main_class, false))
00402             if(Junction* junction=value->get_junction())
00403                 if(const Method *method=junction->method) {
00404                     // preparing to pass parameters to
00405                     //  @postprocess[data]
00406                     VMethodFrame frame(/*method->name, */ *junction, 0/*no parent*/);
00407                     frame.set_self(main_class);
00408
00409                     frame.store_param(*body_value);
00410                     body_value=&execute_method(frame, *method).as_value();
00411                 }
00412
00413         VFile* body_file=body_value->as_vfile(
00414             String::L_UNSPECIFIED, &charsets);
00415
00416 #ifdef RESOURCES_DEBUG
00417 //measure:after postprocess
00418 gettimeofday(&mt[3],NULL);
00419 #endif
00420
00421         // OK. write out the result
00422         output_result(body_file, header_only, as_attachment);
00423
00424 #ifdef RESOURCES_DEBUG
00425         //measure:after output_result
00426 gettimeofday(&mt[9],NULL);
00427 t[9]=mt[9].tv_sec+mt[9].tv_usec/1000000.0;
00428
00429 double t[10];
00430 for(int i=0;i<10;i++)
00431     t[i]=mt[i].tv_sec+mt[i].tv_usec/1000000.0;
00432 //measure:log2 compile,main,postprocess,output
00433 SAPI::log("rmeasure: %s,%.2f,%.2f,%.2f %.2f,%.2f %.2f",
00434 request_info.uri,
00435 t[1]-t[0],
00436 t[2]-t[1],
00437 t[3]-t[2],
00438 sql_connect_time,sql_request_time,
00439 t[9]-t[3]
00440 );
00441 #endif
00442     } catch(const Exception& e) { // request handling problem
00443         try {
00444         // we're returning not result, but error explanation
00445
00446         Request::Exception_details details=get_details(e);
00447         const char* exception_cstr=get_exception_cstr(e, details);
00448
00449         // reset language to default
00450         flang=fdefault_lang;
00451
00452         // reset response
00453         response.fields().clear();
00454
00455         // this is what we'd return in $response:body
00456         const String* body_string=0;
00457
00458         // maybe we'd be lucky enough as to report an error
00459         // in a gracefull way...
00460         if(Value* value=main_class.get_element(
00461                 *new String(UNHANDLED_EXCEPTION_METHOD_NAME),
00462                 main_class,
00463                 false)) {
00464             if(Junction* junction=value->get_junction()) {
00465                 if(const Method *method=junction->method) {
00466 // preparing to pass parameters to
00467 //  @unhandled_exception[exception;stack]
00468 VMethodFrame frame(/*method->name, */ *junction, 0/*no caller*/);
00469 frame.set_self(main_class);
00470
00471 // $exception
00472 frame.store_param(details.vhash);
00473 // $stack[^table::set{name  origin}]
00474 Table::columns_type stack_trace_columns(new ArrayString);
00475 *stack_trace_columns+=new String("name");
00476 *stack_trace_columns+=new String("file");
00477 *stack_trace_columns+=new String("lineno");
00478 *stack_trace_columns+=new String("colno");
00479 Table& stack_trace=*new Table(stack_trace_columns);
00480 if(!exception_trace.is_empty()/*signed!*/)
00481 for(size_t i=exception_trace.bottom_index(); i<exception_trace.top_index(); i++) {
00482     Trace trace=exception_trace.get(i);
00483     Table::element_type row(new ArrayString);
00484
00485     *row+=trace.name(); // name column
00486     Operation::Origin origin=trace.origin();
00487     if(origin.file_no) {
00488         *row+=new String(file_list[origin.file_no], String::L_TAINTED); // 'file' column
00489         *row+=new String(String::Body::Format(1+origin.line), String::L_CLEAN); // 'lineno' column
00490         *row+=new String(String::Body::Format(1+origin.col), String::L_CLEAN); // 'colno' column
00491     }
00492     stack_trace+=row;
00493 }
00494 frame.store_param(*new VTable(&stack_trace));
00495
00496 // future $response:body=
00497 //   execute ^unhandled_exception[exception;stack]
00498 exception_trace.clear(); // forget all about previous life, in case there would be error inside of this method, error handled  would not be mislead by old stack contents (see extract_origin)
00499 body_string=&execute_method(frame, *method).as_string();
00500                 }
00501             }
00502         }
00503
00504         if(!body_string) {  // couldn't report an error beautifully?
00505             // doing that ugly
00506
00507             // future $response:content-type
00508             response.fields().put(content_type_name,
00509                 new VString(*new String(UNHANDLED_EXCEPTION_CONTENT_TYPE)));
00510             // future $response:body
00511             body_string=new String(exception_cstr);
00512         }
00513
00514         VString body_vstring(*body_string);
00515         VFile* body_file=body_vstring.as_vfile(String::L_UNSPECIFIED, &charsets);
00516
00517         // conditionally log it
00518         Value* vhandled=details.vhash.hash().get(exception_handled_part_name);
00519         if(!vhandled || !vhandled->as_bool()) {
00520             SAPI::log(sapi_info, "%s", exception_cstr);
00521         }
00522
00523         // ERROR. write it out
00524         output_result(body_file, header_only, false);
00525         } catch(const Exception& e) { // exception in unhandled exception
00526             Request::Exception_details details=get_details(e);
00527             const char* exception_cstr=get_exception_cstr(e, details);
00528             // unconditionally log the beast
00529             SAPI::log(sapi_info, "%s", exception_cstr);
00530
00531             throw Exception(0,
00532                 0,
00533                 "in %s",
00534                     exception_cstr);
00535         }
00536     }
00537 }
00538
00539 uint Request::register_file(String::Body file_spec) {
00540     file_list+=file_spec;
00541     return file_list.count()-1;
00542 }
00543
00544 void Request::use_file(VStateless_class& aclass,
00545                const String& file_name, const String* main_alias,
00546                bool ignore_class_path,
00547                bool fail_on_read_problem,
00548                bool fail_on_file_absence) {
00549     // cyclic dependence check
00550     if(used_files.get(file_name))
00551         return;
00552     used_files.put(file_name, true);
00553
00554     const String* file_spec;
00555     if(ignore_class_path) // ignore_class_path?
00556         file_spec=&file_name;
00557     else if(file_name.first_char()=='/') //absolute path? [no need to scan MAIN:CLASS_PATH]
00558         file_spec=&absolute(file_name);
00559     else {
00560         file_spec=0;
00561         if(Value* element=main_class.get_element(class_path_name, main_class, false)) {
00562             if(element->is_string()) {
00563                 file_spec=file_exist(absolute(element->as_string()), file_name); // found at class_path?
00564             } else if(Table *table=element->get_table()) {
00565                 int size=table->count();
00566                 for(int i=size; i--; ) {
00567                     const String& path=*(*table->get(i))[0];
00568                     if((file_spec=file_exist(absolute(path), file_name)))
00569                         break; // found along class_path
00570                 }
00571             } else
00572                 throw Exception("parser.runtime",
00573                     0,
00574                     "$" CLASS_PATH_NAME " must be string or table");
00575             if(!file_spec)
00576                 throw Exception("parser.runtime",
00577                     &file_name,
00578                     "not found along " MAIN_CLASS_NAME ":" CLASS_PATH_NAME);
00579         }
00580         if(!file_spec)
00581             throw Exception("parser.runtime",
00582                 &file_name,
00583                 "usage failed - no $" MAIN_CLASS_NAME  ":" CLASS_PATH_NAME " were specified");
00584     }
00585
00586     if(fail_on_read_problem && !fail_on_file_absence) // ignore file absence if asked for
00587         if(!entry_exists(*file_spec))
00588             return;
00589
00590     if(const char* source=file_read_text(charsets, *file_spec, fail_on_read_problem))
00591         use_buf(aclass, source, main_alias, register_file(*file_spec));
00592 }
00593
00594
00595 void Request::use_buf(VStateless_class& aclass,
00596               const char* source, const String* main_alias,
00597               uint file_no,
00598               int line_no_offset) {
00599     // temporary zero @conf so to maybe-replace it in compiled code
00600     Temp_method temp_method_conf(aclass, conf_method_name, 0);
00601     // temporary zero @auto so to maybe-replace it in compiled code
00602     Temp_method temp_method_auto(aclass, auto_method_name, 0);
00603
00604     // compile loaded class
00605     VStateless_class& cclass=compile(&aclass, source, main_alias, file_no, line_no_offset);
00606
00607     // locate and execute possible @conf[] static
00608     VString* vfilespec=
00609         new VString(*new String(file_list[file_no], String::L_TAINTED));
00610     Execute_nonvirtual_method_result executed=execute_nonvirtual_method(cclass,
00611         conf_method_name, vfilespec,
00612         false/*no string result needed*/);
00613     if(executed.method)
00614         configure_admin(cclass/*, executed.method->name*/);
00615
00616     // locate and execute possible @auto[] static
00617     execute_nonvirtual_method(cclass,
00618         auto_method_name, vfilespec,
00619         false/*no result needed*/);
00620 }
00621
00622 const String& Request::relative(const char* apath, const String& relative_name) {
00623     char *hpath=strdup(apath);
00624     String& result=*new String;
00625     if(rsplit(hpath, '/')) // if something/splitted
00626         result << hpath << "/";
00627     result << relative_name;
00628     return result;
00629 }
00630
00631 const String& Request::absolute(const String& relative_name) {
00632     if(relative_name.first_char()=='/') {
00633         String& result=*new String(strdup(request_info.document_root));
00634         result << relative_name;
00635         return result;
00636     } else
00637         if(relative_name.pos("://")!=STRING_NOT_FOUND // something like "http://xxx"
00638 #ifdef WIN32
00639             || relative_name.pos(":")==1  // DRIVE:
00640             || relative_name.starts_with("\\\\") // UNC1
00641             || relative_name.starts_with("//") // UNC2
00642 #endif
00643             )
00644             return relative_name;
00645         else
00646             return relative(request_info.path_translated, relative_name);
00647 }
00648
00649 #ifndef DOXYGEN
00650 class Add_header_attribute_info
00651 {
00652 public:
00653     Add_header_attribute_info(Request& ar) : r(ar), add_last_modified(true) {}
00654     Request& r;
00655     bool add_last_modified;
00656 };
00657 #endif
00658 static void add_header_attribute(
00659                  HashStringValue::key_type aattribute,
00660                  HashStringValue::value_type ameaning,
00661                  Add_header_attribute_info* info) {
00662     if(aattribute==BODY_NAME
00663         || aattribute==DOWNLOAD_NAME
00664         || aattribute==CHARSET_NAME)
00665         return;
00666
00667     const char* a=aattribute.cstr();
00668     SAPI::add_header_attribute(info->r.sapi_info,
00669         a,
00670         attributed_meaning_to_string(*ameaning, String::L_HTTP_HEADER, false).
00671             cstr(String::L_UNSPECIFIED));
00672
00673     if(strcasecmp(a, "last-modified")==0)
00674         info->add_last_modified = false;
00675 }
00676
00677 static void output_sole_piece(Request& r,
00678                               bool header_only,
00679                               VFile& body_file,
00680                               Value* body_file_content_type) {
00681     // transcode text body when "text/*" or simple result
00682     String::C output(body_file.value_ptr(), body_file.value_size());
00683     if(!body_file_content_type/*vstring.as_vfile*/ || body_file_content_type->as_string().pos("text/")==0)
00684         output=Charset::transcode(output,
00685             r.charsets.source(),
00686             r.charsets.client());
00687
00688     // prepare header: content-length
00689     char content_length_cstr[MAX_NUMBER];
00690     snprintf(content_length_cstr, MAX_NUMBER, "%u", output.length);
00691     SAPI::add_header_attribute(r.sapi_info, "content-length", content_length_cstr);
00692
00693     // send header
00694     SAPI::send_header(r.sapi_info);
00695
00696     // send body
00697     if(!header_only)
00698         SAPI::send_body(r.sapi_info, output.str, output.length);
00699 }
00700
00701 #ifndef DOXYGEN
00702 struct Range
00703 {
00704     size_t start;
00705     size_t end;
00706 };
00707 #endif
00708 static void parse_range(const String* s, Array<Range> &ar)
00709 {
00710     const char *p = s->cstr();
00711     if(s->starts_with("bytes="))
00712         p += 6;
00713     Range r;
00714     while(*p){
00715         r.start = (size_t)-1;
00716         r.end = (size_t)-1;
00717         if(*p >= '0' && *p <= '9'){
00718             r.start = atol(p);
00719             while(*p>='0' && *p<='9') ++p;
00720         }
00721         if(*p++ != '-') break;
00722         if(*p >= '0' && *p <= '9'){
00723             r.end = atol(p);
00724             while(*p>='0' && *p<='9') ++p;
00725         }
00726         if(*p == ',') ++p;
00727         ar += r;
00728     }
00729 }
00730
00731 static void output_pieces(Request& r,
00732                           bool header_only,
00733                           const String& filename,
00734                           size_t content_length,
00735                           Value& date,
00736                           bool add_last_modified)
00737 {
00738     SAPI::add_header_attribute(r.sapi_info, "Accept-Ranges", "bytes");
00739
00740     const size_t BUFSIZE = 10*0x400;
00741     char buf[BUFSIZE];
00742     const char *range = SAPI::get_env(r.sapi_info, "HTTP_RANGE");
00743     size_t offset=0;
00744     size_t part_length=content_length;
00745     if(range){
00746         Array<Range> ar;
00747         parse_range(new String(range), ar);
00748         size_t count = ar.count();
00749         if(count == 1){
00750             Range &rg = ar.get_ref(0);
00751             if(rg.start == (size_t)-1 && rg.end == (size_t)-1){
00752                 SAPI::add_header_attribute(r.sapi_info, "status", "416 Requested Range Not Satisfiable");
00753                 return;
00754             }
00755             if(rg.start == (size_t)-1 && rg.end != (size_t)-1){
00756                 rg.start = content_length - rg.end;
00757                 rg.end = content_length;
00758                 offset += rg.start;
00759                 part_length = rg.end-rg.start;
00760             }else if(rg.start != (size_t)-1 && rg.end == (size_t)-1){
00761                 rg.end = content_length-1;
00762                 offset += rg.start;
00763                 part_length -= rg.start;
00764             }
00765             if(part_length == 0){
00766                 SAPI::add_header_attribute(r.sapi_info, "status", "204 No Content");
00767                 return;
00768             }
00769             SAPI::add_header_attribute(r.sapi_info, "status", "206 Partial Content");
00770             snprintf(buf, BUFSIZE, "bytes %u-%u/%u", rg.start, rg.end, content_length);
00771             SAPI::add_header_attribute(r.sapi_info, "Content-Range", buf);
00772         }else if(count != 0){
00773             SAPI::add_header_attribute(r.sapi_info, "status", "501 Not Implemented");
00774             return;
00775         }
00776     }
00777
00778
00779     snprintf(buf, BUFSIZE, "%u", part_length);
00780     SAPI::add_header_attribute(r.sapi_info, "Content-Length", buf);
00781
00782     if(add_last_modified){
00783         const String &s = attributed_meaning_to_string(date, String::L_AS_IS, true);
00784         SAPI::add_header_attribute(r.sapi_info, "Last-Modified", s.cstr());
00785     }
00786     SAPI::send_header(r.sapi_info);
00787
00788     const String& filespec=r.absolute(filename);
00789
00790     size_t sent = 0;
00791     if(!header_only){
00792         size_t to_read = 0;
00793         size_t size = 0;
00794         do{
00795             to_read = part_length<BUFSIZE?part_length:BUFSIZE;
00796             File_read_result read_result=file_read(r.charsets, filespec,
00797                 false /*as text*/,  0/*params*/, true/*fail on problem*/,
00798                 buf, offset, to_read);
00799             to_read=read_result.length;
00800             if(to_read == 0)
00801                 break;
00802             offset += to_read;
00803
00804             size = SAPI::send_body(r.sapi_info, read_result.str, to_read);
00805             sent += size;
00806             if(size != to_read)
00807                 break;
00808             part_length -= to_read;
00809         }while(part_length);
00810     }
00811 }
00812
00813 void Request::output_result(VFile* body_file, bool header_only, bool as_attachment) {
00814     // header: cookies
00815     cookie.output_result(sapi_info);
00816
00817     // may be specified
00818     Value* body_file_content_type=body_file->fields().get(content_type_name);
00819
00820     // content-disposition
00821     Value* vfile_name=body_file->fields().get(name_name);
00822     if(!vfile_name) {
00823         vfile_name=body_file->fields().get(response_body_file_name);
00824         if(vfile_name)
00825         {
00826             const String& sfile_name=vfile_name->as_string();
00827
00828             char* name_cstr=sfile_name.cstrm();
00829             if(char *after_slash=rsplit(name_cstr, '\\'))
00830                 name_cstr=after_slash;
00831             if(char *after_slash=rsplit(name_cstr, '/'))
00832                 name_cstr=after_slash;
00833             vfile_name=new VString(*new String(name_cstr));
00834         }
00835     }
00836     if(vfile_name) {
00837         const String& sfile_name=vfile_name->as_string();
00838         if(sfile_name!=NONAME_DAT) {
00839             if(as_attachment)
00840             {
00841                 VHash& hash=*new VHash();
00842                 HashStringValue &h=hash.hash();
00843                 h.put(value_name, new VString(content_disposition_value));
00844                 h.put(content_disposition_filename_name, vfile_name);
00845                 response.fields().put(content_disposition_name, &hash);
00846             }
00847
00848             if(!body_file_content_type)
00849                 body_file_content_type=new VString(mime_type_of(sfile_name.cstr()));
00850         }
00851     }
00852
00853     // set content-type
00854     if(body_file_content_type) {
00855         // body file content type
00856         response.fields().put(content_type_name, body_file_content_type);
00857     } else {
00858         // default content type
00859         response.fields().put_dont_replace(content_type_name,
00860             new VString(*new String(DEFAULT_CONTENT_TYPE)));
00861     }
00862
00863     // prepare header: $response:fields without :body
00864     Add_header_attribute_info info(*this);
00865     response.fields().for_each(add_header_attribute, &info);
00866
00867     if(body_file_content_type)
00868         if(HashStringValue *hash=body_file_content_type->get_hash())
00869             body_file_content_type=hash->get(value_name);
00870
00871     if(Value* vresponse_body_file=body_file->fields().get(response_body_file_name)) {
00872         const String& sresponse_body_file=vresponse_body_file->as_string();
00873         size_t content_length=0;
00874         time_t atime=0, mtime=0, ctime=0;
00875         file_stat(absolute(sresponse_body_file),
00876             content_length,
00877             atime, mtime, ctime);
00878
00879         VDate* vdate=0;
00880         if(Value* v=body_file->fields().get("mdate")) {
00881             if(Value* vdatep=v->as(VDATE_TYPE, false))
00882                 vdate=static_cast<VDate*>(vdatep);
00883             else
00884                 throw Exception("parser.runtime", 0, "mdate must be a date");
00885         }
00886         if(!vdate)
00887             vdate=new VDate(mtime);
00888
00889         output_pieces(*this, header_only,
00890             sresponse_body_file,
00891             content_length,
00892             *vdate,
00893             info.add_last_modified);
00894     } else {
00895         output_sole_piece(*this, header_only,
00896             *body_file, body_file_content_type);
00897     }
00898 }
00899
00900 const String& Request::mime_type_of(const char* user_file_name_cstr) {
00901     if(mime_types)
00902         if(const char* cext=strrchr(user_file_name_cstr, '.')) {
00903             String sext(++cext);
00904             Table::Action_options options;
00905             if(mime_types->locate(0, sext.change_case(charsets.source(), String::CC_LOWER), options))
00906                     if(const String* result=mime_types->item(1))
00907                         return *result;
00908                 else
00909                     throw Exception("parser.runtime",
00910                         0,
00911                         MIME_TYPES_NAME  " table column elements must not be empty");
00912         }
00913
00914     return *new String("application/octet-stream");
00915 }
00916
00917 #ifdef XML
00918 xmlChar* Request::transcode(const String& s) {
00919     return charsets.source().transcode(s);
00920 }
00921
00922 xmlChar* Request::transcode(const String::Body s) {
00923     return charsets.source().transcode(s);
00924 }
00925
00926 const String& Request::transcode(const xmlChar* s) {
00927     return charsets.source().transcode(s);
00928 }
00929 #endif
00930
00931
00932 const Request::Trace Request::Exception_trace::extract_origin(const String*& problem_source) {
00933     Trace result;
00934     if(!is_empty()) {
00935         result=bottom_value();
00936         if(!problem_source) { // we don't know who trigged the bug?
00937             problem_source=result.name(); // consider the stack-top-guy (we usually know source of next-from-throw-point exception) did that
00938             fbottom++;
00939         } else if(result.name()==problem_source) // it is that same guy?
00940             fbottom++; // throw away that trace
00941         else {
00942             // stack top contains not us,
00943             //  leaving result intact
00944             //  it would help ^throw
00945         }
00946     }
00947
00948     return result;
00949 }
00950
00951 Request::Exception_details Request::get_details(const Exception& e) {
00952     const String* problem_source=e.problem_source();
00953     Trace trace=exception_trace.extract_origin(problem_source);
00954
00955     VHash& vhash=*new VHash;  HashStringValue& hash=vhash.hash();
00956
00957     // $.type
00958     if(const char* type=e.type(true))
00959         hash.put(exception_type_part_name, new VString(*new String(type)));
00960
00961     // $.source
00962     if(problem_source) {
00963         String& source=*new String;
00964         source.append(*problem_source, String::L_TAINTED, true/*forced*/);
00965
00966         hash.put(exception_source_part_name, new VString(source));
00967     }
00968
00969     // $.file lineno colno
00970     if(trace) {
00971         const Operation::Origin origin=trace.origin();
00972         hash.put(String::Body("file"),
00973             new VString(*new String(file_list[origin.file_no], String::L_TAINTED)));
00974         hash.put(String::Body("lineno"), new VInt(1+origin.line));
00975         hash.put(String::Body("colno"), new VInt(1+origin.col));
00976     }
00977
00978     // $.comment
00979     if(const char* comment=e.comment(true))
00980         hash.put(exception_comment_part_name,
00981             new VString(*new String(comment, 0, true/*tainted*/)));
00982
00983     // $.handled(0)
00984     hash.put(exception_handled_part_name, new VBool(false));
00985
00986     return Request::Exception_details(trace, problem_source, vhash);
00987 }


pa_request.h File Reference

Parser: request class decl. More...

Include dependency graph for pa_request.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Request
Main workhorse. More...

class | Trace
union | StackItem
class | Exception_trace
struct | Exception_details
struct | Execute_nonvirtual_method_result
class | Request_context_saver
Auto-object used to save request context across ^try body. More...

class | Temp_lang
Auto-object used for temporary changing Request::flang. More...

class | Temp_connection
Auto-object used for temporary changing Request::fconnection. More...

Defines

#define | DEFINE_DUAL(modification)
#define | GET_SELF(request, type) (static_cast<type &>(request.get_self()))
#define | CONTENT_DISPOSITION_NAME "content-disposition"
#define | CONTENT_DISPOSITION_VALUE "attachment"
#define | CONTENT_DISPOSITION_FILENAME_NAME "filename"
#define | EXCEPTION_HANDLED_PART_NAME "handled"
#define | MAIN_CLASS_NAME "MAIN"
#define | AUTO_FILE_NAME "auto.p"

Variables

const char *const | IDENT_REQUEST_H = "$Date: 2005/12/16 10:15:12 $"
const uint | ANTI_ENDLESS_EXECUTE_RECOURSION = 1000
const size_t | pseudo_file_no__process = 1
const String | main_method_name
const String | auto_method_name
const String | body_name
const String | content_disposition_name
const String | content_disposition_value
const String | content_disposition_filename_name
const String | exception_type_part_name
const String | exception_source_part_name
const String | exception_comment_part_name
const String | exception_handled_part_name

Detailed Description

Parser: request class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_request.h.

Define Documentation

#define DEFINE_DUAL ( modification )

Value:

void write_##modification##_lang(StringOrValue dual) { \
        if(const String* string=dual.get_string()) \
            write_##modification##_lang(*string); \
        else \
            write_##modification##_lang(*dual.get_value()); \
    }

Definition at line 235 of file pa_request.h.

#define GET_SELF | ( | request,
 |  | type | ) | (static_cast<type &>(request.get_self()))

Definition at line 328 of file pa_request.h.

Referenced by _append(), _arc(), _bar(), _base64(), _circle(), _clear(), _columns(), _copy(), _count(), _create(), _create_or_add(), _delete(), _double(), _exec_cgi(), _fill(), _flip(), _font(), _foreach(), _gif(), _hash(), _html(), _int(), _intersection(), _intersects(), _join(), _keys(), _left(), _length(), _line(), _load(), _locate(), _match(), _measure(), _menu(), _mid(), _normalize(), _now(), _offset(), _open(), _pixel(), _polybar(), _polygon(), _polyline(), _pos(), _rectangle(), _replace(), _right(), _roll(), _save(), _sector(), _select(), _send(), _sort(), _sql(), _sql_string(), _stat(), _sub(), _text(), _trim(), _union(), _unix_timestamp(), change_case(), split_with_options(), vdouble_op(), and vint_op().

#define CONTENT_DISPOSITION_NAME "content-disposition"

Definition at line 499 of file pa_request.h.

Referenced by file_value_to_string(), and store_message_element().

#define CONTENT_DISPOSITION_VALUE "attachment"

Definition at line 500 of file pa_request.h.

Referenced by file_value_to_string().

#define CONTENT_DISPOSITION_FILENAME_NAME "filename"

Definition at line 501 of file pa_request.h.

Referenced by file_value_to_string().

#define EXCEPTION_HANDLED_PART_NAME "handled"

Definition at line 502 of file pa_request.h.

Referenced by locked_process_and_cache_put_action().

#define MAIN_CLASS_NAME "MAIN"

Definition at line 521 of file pa_request.h.

Referenced by Request::configure_admin(), sendmail(), Request::use_file(), and VClassMAIN::VClassMAIN().

#define AUTO_FILE_NAME "auto.p"

Definition at line 522 of file pa_request.h.

Referenced by Request::core(), and real_parser_handler().

Variable Documentation

const char* const IDENT_REQUEST_H = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 11 of file pa_request.h.

const uint ANTI_ENDLESS_EXECUTE_RECOURSION = 1000

Definition at line 28 of file pa_request.h.

Referenced by Request::recoursion_checked_execute().

const size_t pseudo_file_no__process = 1

Definition at line 29 of file pa_request.h.

Referenced by _process().

const String main_method_name

Definition at line 507 of file pa_request.h.

const String auto_method_name

Definition at line 508 of file pa_request.h.

const String body_name

Definition at line 509 of file pa_request.h.

const String content_disposition_name

Definition at line 510 of file pa_request.h.

const String content_disposition_value

Definition at line 511 of file pa_request.h.

const String content_disposition_filename_name

Definition at line 512 of file pa_request.h.

const String exception_type_part_name

Definition at line 514 of file pa_request.h.

const String exception_source_part_name

Definition at line 515 of file pa_request.h.

const String exception_comment_part_name

Definition at line 516 of file pa_request.h.

const String exception_handled_part_name

Definition at line 517 of file pa_request.h.


pa_request.h Source File

pa_request.h

Go to the documentation of this file.
00001
00008 #ifndef PA_REQUEST_H
00009 #define PA_REQUEST_H
00010
00011 static const char * const IDENT_REQUEST_H="$Date: 2005/12/16 10:15:12 $";
00012
00013 #include "pa_pool.h"
00014 #include "pa_hash.h"
00015 #include "pa_wcontext.h"
00016 #include "pa_value.h"
00017 #include "pa_stack.h"
00018 #include "pa_request_info.h"
00019 #include "pa_request_charsets.h"
00020 #include "pa_sapi.h"
00021
00022 #ifdef RESOURCES_DEBUG
00023 #include <sys/resource.h>
00024 #endif
00025
00026 // consts
00027
00028 const uint ANTI_ENDLESS_EXECUTE_RECOURSION=1000;
00029 const size_t pseudo_file_no__process=1;
00030
00031 // forwards
00032
00033 class Temp_lang;
00034 class Methoded;
00035 class VMethodFrame;
00036 class VMail;
00037 class VForm;
00038 class VResponse;
00039 class VCookie;
00040 class VStateless_class;
00041
00043 class Request: public PA_Object {
00044     friend class Temp_lang;
00045     friend class Temp_connection;
00046     friend class Request_context_saver;
00047     friend class Temp_request_self;
00048     friend class Exception_trace;
00049
00050 public:
00051     class Trace {
00052         const String* fname;
00053         Operation::Origin forigin;
00054     public:
00055         Trace(): fname(0) {}
00056         void clear() { fname=0; }
00057         operator bool() const { return fname!=0; }
00058
00059         Trace(const String* aname, const Operation::Origin aorigin):
00060             fname(aname), forigin(aorigin) {}
00061
00062         const String* name() const { return fname; }
00063         const Operation::Origin origin() const { return forigin; }
00064     };
00065
00066 private:
00067     Pool fpool;
00068 public:
00069     Pool& pool() { return fpool; }
00070
00071 private:
00072     union StackItem {
00073         Value* fvalue;
00074         ArrayOperation* fops;
00075         VMethodFrame* fmethod_frame;
00076     public:
00077         Value& value() const { return *fvalue; }
00078         const String& string() const {
00079             return fvalue->as_string();
00080         }
00081         ArrayOperation& ops() const { return *fops; }
00082         VMethodFrame& method_frame() const { return *fmethod_frame; }
00083
00085         StackItem() {}
00086         StackItem(Value& avalue): fvalue(&avalue) {}
00087         StackItem(ArrayOperation& aops): fops(&aops) {}
00088         StackItem(VMethodFrame& amethod_frame): fmethod_frame(&amethod_frame) {}
00089     };
00090
00091     class Exception_trace: public Stack<Trace> {
00092         size_t fbottom;
00093     public:
00094         Exception_trace(): fbottom(0) {}
00095
00096         size_t bottom_index() { return fbottom; }
00097         void set_bottom_index(size_t abottom) { fbottom=abottom; }
00098         element_type bottom_value() { return get(bottom_index()); }
00099
00100         void clear() {
00101             ftop=fbottom=0;
00102         }
00103
00104         bool is_empty() {
00105             return ftop==fbottom;
00106         }
00107
00108         const element_type extract_origin(const String*& problem_source);
00109     };
00110
00112
00114     HashStringValue fclasses;
00115
00117     Hash<const String::Body, bool> used_files;
00119     Array<String::Body> file_list;
00120
00124     uint anti_endless_execute_recoursion;
00125
00127
00129     Stack<StackItem> stack;
00130
00132     Exception_trace exception_trace;
00133 public:
00134
00136
00137     VMethodFrame* method_frame;
00138     Value* rcontext;
00139     WContext* wcontext;
00141     String::Language flang;
00143     SQL_Connection* fconnection;
00145
00146     bool finterrupted;
00147
00148 public:
00149     uint register_file(String::Body file_spec);
00150
00151     struct Exception_details {
00152         const Trace trace;
00153         const String* problem_source;
00154         VHash& vhash;
00155
00156         Exception_details(
00157             const Trace atrace,
00158             const String* aproblem_source,
00159             VHash& avhash): trace(atrace), problem_source(aproblem_source), vhash(avhash) {}
00160     };
00161     Exception_details get_details(const Exception& e);
00162     const char* get_exception_cstr(const Exception& e, Exception_details& details);
00163
00165     void wipe_unused_execution_stack() {
00166         stack.wipe_unused();
00167     }
00168
00169 #ifdef RESOURCES_DEBUG
00170
00171     double sql_connect_time;
00172     double sql_request_time;
00173 #endif
00174
00175     Request(SAPI_Info& asapi_info, Request_info& arequest_info,
00176         String::Language adefault_lang,
00177         bool status_allowed
00178     );
00179     ~Request();
00180
00182     HashStringValue& classes() { return fclasses; }
00183
00189     void core(
00190         const char* config_filespec,
00191         bool config_fail_on_read_problem,
00192         bool header_only);
00193
00195     void execute(ArrayOperation& ops); // execute.C
00197     void recoursion_checked_execute(/*const String& name, */ArrayOperation& ops) {
00198         // anti_endless_execute_recoursion
00199         if(++anti_endless_execute_recoursion==ANTI_ENDLESS_EXECUTE_RECOURSION) {
00200             anti_endless_execute_recoursion=0; // give @exception a chance
00201             throw Exception("parser.runtime",
00202                 0, //&name,
00203                 "call canceled - endless recursion detected");
00204         }
00205         execute(ops); // execute it
00206         anti_endless_execute_recoursion--;
00207     }
00208
00210     void use_file(VStateless_class& aclass,
00211         const String& file_name,
00212         const String* main_alias=0,
00213         bool ignore_class_path=false,
00214         bool fail_on_read_problem=true,
00215         bool fail_on_file_absence=true); // pa_request.C
00217     void use_buf(VStateless_class& aclass,
00218         const char* source,
00219         const String* main_alias,
00220         uint file_no,
00221         int line_no_offset=0); // pa_request.C
00222
00224     StringOrValue process(Value& input_value, bool intercept_string=true); // execute.C
00226     const String& process_to_string(Value& input_value) {
00227         return process(input_value, true/*intercept_string*/).as_string();
00228     }
00229     Value& process_to_value(Value& input_value, bool intercept_string=true) {
00230         return process(input_value, intercept_string).as_value();
00231     }
00233
00234
00235 #define DEFINE_DUAL(modification) \
00236     void write_##modification##_lang(StringOrValue dual) { \
00237         if(const String* string=dual.get_string()) \
00238             write_##modification##_lang(*string); \
00239         else \
00240             write_##modification##_lang(*dual.get_value()); \
00241     }
00242
00244     void write_no_lang(const String& astring) {
00245         wcontext->write(astring,
00246             (String::Language)(String::L_CLEAN | flang&String::L_OPTIMIZE_BIT));
00247     }
00249     void write_no_lang(Value& avalue) {
00250         if(wcontext->get_in_expression())
00251             wcontext->write(avalue);
00252         else
00253             wcontext->write(avalue,
00254                 (String::Language)(String::L_CLEAN | flang&String::L_OPTIMIZE_BIT));
00255     }
00256
00258     void write_pass_lang(const String& astring) {
00259         wcontext->write(astring, String::L_PASS_APPENDED);
00260     }
00262     void write_pass_lang(Value& avalue) {
00263         wcontext->write(avalue, String::L_PASS_APPENDED);
00264     }
00265     DEFINE_DUAL(pass)
00266
00268     void write_assign_lang(Value& avalue) {
00269         wcontext->write(avalue, flang);
00270     }
00272     void write_assign_lang(const String& astring) {
00273         wcontext->write(astring, flang);
00274     }
00275     DEFINE_DUAL(assign)
00276
00278     const String& relative(const char* apath, const String& relative_name);
00279
00281     const String& absolute(const String& relative_name);
00282
00284     const String& mime_type_of(const char* user_file_name_cstr);
00285
00287     SQL_Connection* connection(bool fail_on_error=true) {
00288         if(fail_on_error && !fconnection)
00289             throw Exception("parser.runtime",
00290                 0,
00291                 "outside of 'connect' operator");
00292
00293         return fconnection;
00294     }
00295
00296     void set_interrupted(bool ainterrupted) { finterrupted=ainterrupted; }
00297     bool get_interrupted() { return finterrupted; }
00298
00299 public:
00300
00302     Request_info& request_info;
00303
00305     SAPI_Info& sapi_info;
00306
00308     Request_charsets charsets;
00309
00311     VStateless_class& main_class;
00313     VForm& form;
00315     VMail& mail;
00317     VResponse& response;
00319     VCookie& cookie;
00320
00322     Hash<const String::Body, void*> classes_conf;
00323
00324 public: // status read methods
00325
00326     VMethodFrame *get_method_frame() { return method_frame; }
00327     Value& get_self();
00328 #define GET_SELF(request, type) (static_cast<type &>(request.get_self()))
00329     /* for strange reason call to this:
00330         r.get_self<VHash>()
00331         refuses to compile
00332
00333     template<typename T> T& get_self() {
00334         return *static_cast<T*>(get_self().get());
00335     }
00336     */
00337
00339     const String* execute_virtual_method(Value& aself, const String& method_name);
00340
00342     StringOrValue execute_method(VMethodFrame& amethodFrame, const Method& method);
00343     //{ for @conf[filespec] and @auto[filespec] and parser://method/call
00344     const String* execute_method(Value& aself,
00345         const Method& method, VString* optional_param,
00346         bool do_return_string);
00347     struct Execute_nonvirtual_method_result {
00348         const String* string;
00349         Method* method;
00350         Execute_nonvirtual_method_result(): string(0), method(0) {}
00351     };
00352     Execute_nonvirtual_method_result execute_nonvirtual_method(VStateless_class& aclass,
00353         const String& method_name, VString* optional_param,
00354         bool do_return_string);
00355     //}
00356
00357 #ifdef XML
00358 public: // charset helpers
00359
00361     xmlChar* transcode(const String& s);
00363     xmlChar* transcode(const String::Body s);
00365     const String& transcode(const xmlChar* s);
00366
00367 #endif
00368
00369 private:
00370
00372     bool configure_admin_done;
00373
00374     void configure_admin(VStateless_class& conf_class);
00375
00376     void configure();
00377
00378 private: // compile.C
00379
00380     VStateless_class& compile(VStateless_class* aclass,
00381         const char* source, const String* main_alias,
00382         uint file_no,
00383         int line_no_offset);
00384
00385 private: // execute.C
00386
00387     void put_element(Value& ncontext, const String& name, Value& value);
00388     Value& get_element(Value& ncontext, const String& name, bool can_call_operator);
00389
00390 private: // defaults
00391
00392     const String::Language fdefault_lang;
00393
00394 private: // mime types
00395
00397     Table *mime_types;
00398
00399 private: // lang manipulation
00400
00401     String::Language set_lang(String::Language alang) {
00402         String::Language result=flang;
00403         flang=alang;
00404         return result;
00405     }
00406     void restore_lang(String::Language alang) {
00407         flang=alang;
00408     }
00409
00410 private: // connection manipulation
00411
00412     SQL_Connection* set_connection(SQL_Connection* aconnection) {
00413         SQL_Connection* result=fconnection;
00414         fconnection=aconnection;
00415         return result;
00416     }
00417     void restore_connection(SQL_Connection* aconnection) {
00418         fconnection=aconnection;
00419     }
00420
00421 private:
00422
00423     void output_result(VFile* body_file, bool header_only, bool as_attachment);
00424 };
00425
00427 class Request_context_saver {
00428     Request& fr;
00429
00431     size_t exception_trace_top;
00432     size_t exception_trace_bottom;
00434     size_t stack;
00435     uint anti_endless_execute_recoursion;
00437     VMethodFrame* method_frame;
00438     Value* rcontext;
00439     WContext* wcontext;
00441     String::Language flang;
00443     SQL_Connection* fconnection;
00444
00445 public:
00446     Request_context_saver(Request& ar) :
00447         fr(ar),
00448         exception_trace_top(ar.exception_trace.top_index()),
00449         exception_trace_bottom(ar.exception_trace.bottom_index()),
00450         stack(ar.stack.top_index()),
00451         anti_endless_execute_recoursion(ar.anti_endless_execute_recoursion),
00452         method_frame(ar.method_frame),
00453         rcontext(ar.rcontext),
00454         wcontext(ar.wcontext),
00455         flang(ar.flang),
00456         fconnection(ar.fconnection) {}
00457     void restore() {
00458         fr.exception_trace.set_top_index(exception_trace_top);
00459         fr.exception_trace.set_bottom_index(exception_trace_bottom);
00460         fr.stack.set_top_index(stack);
00461         fr.anti_endless_execute_recoursion=anti_endless_execute_recoursion;
00462         fr.method_frame=method_frame, fr.rcontext=rcontext; fr.wcontext=wcontext;
00463         fr.flang=flang;
00464         fr.fconnection=fconnection;
00465     }
00466 };
00467
00469 class Temp_lang {
00470     Request& frequest;
00471     String::Language saved_lang;
00472 public:
00473     Temp_lang(Request& arequest, String::Language alang) :
00474         frequest(arequest),
00475         saved_lang(arequest.set_lang(alang)) {
00476     }
00477     ~Temp_lang() {
00478         frequest.restore_lang(saved_lang);
00479     }
00480 };
00481
00483 class Temp_connection {
00484     Request& frequest;
00485     SQL_Connection* saved_connection;
00486 public:
00487     Temp_connection(Request& arequest, SQL_Connection* aconnection) :
00488         frequest(arequest),
00489         saved_connection(arequest.set_connection(aconnection)) {
00490     }
00491     ~Temp_connection() {
00492         frequest.restore_connection(saved_connection);
00493     }
00494 };
00495
00496
00497 // defines for externs
00498
00499 #define CONTENT_DISPOSITION_NAME "content-disposition"
00500 #define CONTENT_DISPOSITION_VALUE "attachment"
00501 #define CONTENT_DISPOSITION_FILENAME_NAME "filename"
00502 #define EXCEPTION_HANDLED_PART_NAME "handled"
00503
00504
00505 // externs
00506
00507 extern const String main_method_name;
00508 extern const String auto_method_name;
00509 extern const String body_name;
00510 extern const String content_disposition_name;
00511 extern const String content_disposition_value;
00512 extern const String content_disposition_filename_name;
00513
00514 extern const String exception_type_part_name;
00515 extern const String exception_source_part_name;
00516 extern const String exception_comment_part_name;
00517 extern const String exception_handled_part_name;
00518
00519 // defines for statics
00520
00521 #define MAIN_CLASS_NAME "MAIN"
00522 #define AUTO_FILE_NAME "auto.p"
00523
00524 #endif


pa_request_charsets.h File Reference

Parser: request charsets class decl. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Request_charsets
class | Temp_client_charset

Variables

const char *const | IDENT_REQUEST_CHARSETS_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: request charsets class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_request_charsets.h.

Variable Documentation

const char* const IDENT_REQUEST_CHARSETS_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_request_charsets.h.


pa_request_charsets.h Source File

pa_request_charsets.h

Go to the documentation of this file.
00001
00008 #ifndef PA_REQUEST_CHARSETS_H
00009 #define PA_REQUEST_CHARSETS_H
00010
00011 static const char * const IDENT_REQUEST_CHARSETS_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 class Request_charsets {
00014     friend class Temp_client_charset;
00015
00016     Charset *fsource;
00017     Charset *fclient;
00018     Charset *fmail;
00019 public:
00020     Request_charsets(
00021         Charset& asource,
00022         Charset& aclient,
00023         Charset& amail):
00024         fsource(&asource),
00025         fclient(&aclient),
00026         fmail(&amail) {}
00027
00028     Charset& source() const { return *fsource; } void set_source(Charset& asource) { fsource=&asource; }
00029     Charset& client() const { return *fclient; } void set_client(Charset& aclient) { fclient=&aclient; }
00030     Charset& mail() const { return *fmail; } void set_mail(Charset& amail) { fmail=&amail; }
00031 };
00032
00033 class Temp_client_charset {
00034     Request_charsets& fcharsets;
00035     Charset &fclient;
00036 public:
00037
00038     Temp_client_charset(Request_charsets& acharsets, Charset& aclient):
00039         fcharsets(acharsets),
00040         fclient(acharsets.client()) {
00041         fcharsets.set_client(aclient);
00042     }
00043     ~Temp_client_charset(){
00044         fcharsets.set_client(fclient);
00045     }
00046 };
00047
00048 #endif


pa_request_info.h File Reference

Parser: request info class decl. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Request_info
some information from web server. More...

Variables

const char *const | IDENT_REQUEST_INFO_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: request info class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_request_info.h.

Variable Documentation

const char* const IDENT_REQUEST_INFO_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_request_info.h.


pa_request_info.h Source File

pa_request_info.h

Go to the documentation of this file.
00001
00008 #ifndef PA_REQUEST_INFO_H
00009 #define PA_REQUEST_INFO_H
00010
00011 static const char * const IDENT_REQUEST_INFO_H="$Date: 2005/08/09 08:14:50 $";
00012
00014 class Request_info {
00015 public:
00017     const char* document_root;
00018     const char* path_translated;
00019     const char* method;
00020     const char* query_string;
00021     const char* uri;
00022     const char* content_type;
00023     size_t content_length;
00024     const char* cookie;
00025     bool mail_received;
00027
00028     const char* post_data;  size_t post_size;
00030 };
00031
00032 #endif


pa_sapi.h File Reference

Parser: web server api interface object decl. More...

Include dependency graph for pa_sapi.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | SAPI
target web-Server API. More...

Variables

const char *const | IDENT_SAPI_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: web server api interface object decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_sapi.h.

Variable Documentation

const char* const IDENT_SAPI_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_sapi.h.


pa_sapi.h Source File

pa_sapi.h

Go to the documentation of this file.
00001
00008 #ifndef PA_SAPI_H
00009 #define PA_SAPI_H
00010
00011 static const char * const IDENT_SAPI_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 // includes
00014
00015
00016 #include "pa_types.h"
00017 #include "pa_array.h"
00018
00019 // forwards
00020 class SAPI_Info;
00021
00023 struct SAPI {
00025     static void log(SAPI_Info& info, const char* fmt, ...);
00027     static void die(const char* fmt, ...);
00029     static void abort(const char* fmt, ...);
00031     static const char* const* environment(SAPI_Info& info);
00033     static char* get_env(SAPI_Info& info, const char* name);
00035     static size_t read_post(SAPI_Info& info, char *buf, size_t max_bytes);
00037     static void add_header_attribute(SAPI_Info& info,
00038         const char* dont_store_key, const char* dont_store_value);
00040     static void send_header(SAPI_Info& info);
00042     static size_t send_body(SAPI_Info& info, const void *buf, size_t size);
00043 };
00044
00045 #endif


pa_socks.C File Reference

Parser: socks initialization/finalization. More...

Include dependency graph for pa_socks.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | NO_UNISTD_H

Functions

void | pa_socks_init ()
void | pa_socks_done ()
const char * | pa_socks_strerr (int no)
int | pa_socks_errno ()

Variables

const char *const | IDENT_SOCKS_C = "$Date: 2005/08/09 08:14:52 $"
WSADATA | wsaData

Detailed Description

Parser: socks initialization/finalization.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_socks.C.

Define Documentation

#define NO_UNISTD_H

Definition at line 10 of file pa_socks.C.

Function Documentation

void pa_socks_init ( )

Definition at line 43 of file pa_socks.C.

References wsaData.

Referenced by pa_setup_module_cells(), parser_init(), and real_parser_handler().

void pa_socks_done ( )

Definition at line 59 of file pa_socks.C.

References wsaData.

Referenced by pa_destroy_module_cells(), parser_done(), and real_parser_handler().

const char* pa_socks_strerr ( int no )

Definition at line 72 of file pa_socks.C.

References MAX_STRING, and pa_strdup().

Referenced by http_read_response(), and http_request().

int pa_socks_errno ( )

Definition at line 89 of file pa_socks.C.

Referenced by http_read_response(), and http_request().

Variable Documentation

const char* const IDENT_SOCKS_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_socks.C.

WSADATA wsaData

Definition at line 41 of file pa_socks.C.

Referenced by pa_socks_done(), and pa_socks_init().


pa_socks.C Source File

pa_socks.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_SOCKS_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #define NO_UNISTD_H
00011 #include "pa_config_includes.h"
00012
00013 #ifdef WIN32
00014 #include "pa_exception.h"
00015 #include "pa_socks.h"
00016 #include "pa_string.h"
00017
00018 // in cygwin: for pascal
00019 // in MSVC: for everything
00020 #include <windows.h>
00021
00022 #ifdef CYGWIN
00023 // WSADATA
00024 #define WSADESCRIPTION_LEN  256
00025 #define WSASYS_STATUS_LEN   128
00026 typedef struct WSAData {
00027     WORD    wVersion;
00028     WORD    wHighVersion;
00029     char    szDescription[WSADESCRIPTION_LEN+1];
00030     char    szSystemStatus[WSASYS_STATUS_LEN+1];
00031     unsigned short  iMaxSockets;
00032     unsigned short  iMaxUdpDg;
00033     char *  lpVendorInfo;
00034 } WSADATA;
00035 typedef WSADATA *LPWSADATA;
00036
00037 int PASCAL WSAStartup(WORD,LPWSADATA);
00038 int PASCAL WSACleanup(void);
00039 #endif
00040
00041 WSADATA wsaData;
00042
00043 void pa_socks_init() {
00044     WORD wVersionRequested;
00045     int err;
00046     wVersionRequested = MAKEWORD( 1, 1 );
00047     //wVersionRequested = MAKEWORD( 2, 2 );
00048     err = WSAStartup( wVersionRequested, &wsaData );
00049     if ( err != 0 ) {
00050         /* Tell the user that we could not find a usable */
00051         /* WinSock DLL.                                  */
00052         throw Exception(0,
00053             0,
00054             "can not WSAStartup, err=%d",
00055                 err);
00056     }
00057 }
00058
00059 void pa_socks_done() {
00060     /* Confirm that the WinSock DLL supports 2.2.*/
00061     /* Note that if the DLL supports versions greater    */
00062     /* than 2.2 in addition to 2.2, it will still return */
00063     /* 2.2 in wVersion since that is the version we      */
00064     /* requested.                                        */
00065     if ( LOBYTE( wsaData.wVersion ) == 2 ||
00066         HIBYTE( wsaData.wVersion ) == 2 ) {
00067         WSACleanup( );
00068         return;
00069     }
00070 }
00071
00072 const char* pa_socks_strerr(int no) {
00073     char buf[MAX_STRING];
00074     buf[0]=0;
00075     size_t error_size=FormatMessage(
00076         FORMAT_MESSAGE_FROM_SYSTEM |
00077         FORMAT_MESSAGE_IGNORE_INSERTS,
00078         NULL,
00079         no,
00080         0, // Default language
00081         (LPTSTR) &buf,
00082         sizeof(buf),
00083         NULL
00084     );
00085     if(error_size>3) // ".\r\n"
00086         buf[error_size-3]=0;
00087     return buf[0]? pa_strdup(buf): "unknown error";
00088 }
00089 int pa_socks_errno() {
00090     return WSAGetLastError();
00091 }
00092
00093 #else
00094
00095 void pa_socks_init() {}
00096 void pa_socks_done() {}
00097
00098 const char* pa_socks_strerr(int no) {
00099     return strerror(no);
00100 }
00101 int pa_socks_errno() {
00102     return errno;
00103 }
00104
00105 #endif


pa_socks.h File Reference

Parser: socks initialization/finalization decls. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

void | pa_socks_init ()
void | pa_socks_done ()
int | pa_socks_errno ()
const char * | pa_socks_strerr (int no)

Variables

const char *const | IDENT_SOCKS_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: socks initialization/finalization decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_socks.h.

Function Documentation

void pa_socks_init ( )

Definition at line 43 of file pa_socks.C.

References wsaData.

Referenced by pa_setup_module_cells(), parser_init(), and real_parser_handler().

void pa_socks_done ( )

Definition at line 59 of file pa_socks.C.

References wsaData.

Referenced by pa_destroy_module_cells(), parser_done(), and real_parser_handler().

int pa_socks_errno ( )

Definition at line 89 of file pa_socks.C.

Referenced by http_read_response(), and http_request().

const char* pa_socks_strerr ( int no )

Definition at line 72 of file pa_socks.C.

References MAX_STRING, and pa_strdup().

Referenced by http_read_response(), and http_request().

Variable Documentation

const char* const IDENT_SOCKS_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_socks.h.


pa_socks.h Source File

pa_socks.h

Go to the documentation of this file.
00001
00008 #ifndef PA_SOCKS_H
00009 #define PA_SOCKS_H
00010
00011 static const char * const IDENT_SOCKS_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 void pa_socks_init();
00014 void pa_socks_done();
00015
00016 int pa_socks_errno();
00017 const char* pa_socks_strerr(int no);
00018
00019 #endif


pa_sql_connection.h File Reference

Parser: sql fconnection decl. More...

Include dependency graph for pa_sql_connection.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | SQL_Driver_services_impl
SQL_Driver_services Pooled implementation. More...

class | SQL_Connection
SQL connection. handy wrapper around low level SQL_Driver. More...

Defines

#define | SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions)
See also:
SQL_Driver_services_impl::_throw.
 More...

Variables

const char *const | IDENT_SQL_CONNECTION_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: sql fconnection decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_sql_connection.h.

Define Documentation

#define SQL_CONNECTION_SERVICED_FUNC_GUARDED ( actions )

Value:

use(); \
        actions
See also:
SQL_Driver_services_impl::_throw.

Definition at line 21 of file pa_sql_connection.h.

Referenced by SQL_Connection::commit(), SQL_Connection::connect(), SQL_Connection::ping(), SQL_Connection::query(), SQL_Connection::quote(), and SQL_Connection::rollback().

Variable Documentation

const char* const IDENT_SQL_CONNECTION_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_sql_connection.h.


pa_sql_connection.h Source File

pa_sql_connection.h

Go to the documentation of this file.
00001
00008 #ifndef PA_SQL_CONNECTION_H
00009 #define PA_SQL_CONNECTION_H
00010
00011 static const char * const IDENT_SQL_CONNECTION_H="$Date: 2005/08/09 08:14:50 $";
00012
00013
00014 #include "pa_sql_driver.h"
00015 #include "pa_sql_driver_manager.h"
00016
00017 // defines
00018
00020 #ifdef PA_WITH_SJLJ_EXCEPTIONS
00021     #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \
00022         use(); \
00023         actions
00024 #else
00025     #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \
00026         use(); \
00027         if(!setjmp(fservices.mark)) { \
00028             actions; \
00029         } else \
00030             fservices.propagate_exception();
00031 #endif
00032
00034 class SQL_Driver_services_impl: public SQL_Driver_services {
00035     const String* furl;
00036     Exception fexception;
00037     const char* frequest_charset;
00038 public:
00039     SQL_Driver_services_impl(const char* arequest_charset): furl(0), frequest_charset(arequest_charset) {}
00040     void set_url(const String& aurl) { furl=&aurl;}
00041     const String& url_without_login() const;
00042
00043     override void* malloc(size_t size) { return pa_malloc(size); }
00044     override void* malloc_atomic(size_t size) { return pa_malloc_atomic(size); }
00045     override void* realloc(void *ptr, size_t size) { return pa_realloc(ptr, size); }
00046
00047     override const char* request_charset() { return frequest_charset; }
00048     override void transcode(const char* src, size_t src_length,
00049         const char*& dst, size_t& dst_length,
00050         const char* charset_from_name,
00051         const char* charset_to_name
00052         );
00053
00064     override void _throw(const SQL_Error& aexception) {
00065         // converting SQL_exception to parser Exception
00066         // hiding passwords and addresses from accidental show [imagine user forgot @exception]
00067 #ifdef PA_WITH_SJLJ_EXCEPTIONS
00068         throw
00069 #else
00070         fexception=
00071 #endif
00072         Exception(aexception.type(),
00073                 &url_without_login(),
00074                 aexception.comment());
00075
00076 #ifndef PA_WITH_SJLJ_EXCEPTIONS
00077         longjmp(mark, 1);
00078 #endif
00079     }
00080     virtual void propagate_exception() {
00081 #ifndef PA_WITH_SJLJ_EXCEPTIONS
00082         throw fexception;
00083 #endif
00084     }
00085 };
00086
00088 class SQL_Connection: public PA_Object {
00089     const String&  furl;
00090     SQL_Driver& fdriver;
00091     SQL_Driver_services_impl fservices;
00092     void *fconnection;
00093     time_t time_used;
00094
00095 public:
00096
00097     SQL_Connection(const String& aurl, SQL_Driver& adriver, const char* arequest_charset):
00098         furl(aurl),
00099         fdriver(adriver),
00100         fservices(arequest_charset),
00101         fconnection(0),
00102         time_used(0) {
00103     }
00104
00105     SQL_Driver_services_impl& services() { return fservices; }
00106
00107     const String& get_url() { return furl; }
00108
00109     void set_url() {
00110         fservices.set_url(furl);
00111     }
00112     void use() {
00113         time_used=time(0); // they started to use at this time
00114     }
00115     bool expired(time_t older_dies) {
00116         return time_used<older_dies;
00117     }
00118     time_t get_time_used() { return time_used; }
00119
00120     bool connected() { return fconnection!=0; }
00121     void connect(char *used_only_in_connect_url_cstr) {
00122         SQL_CONNECTION_SERVICED_FUNC_GUARDED(
00123             fdriver.connect(used_only_in_connect_url_cstr, fservices, &fconnection)
00124         );
00125     }
00126     void disconnect() {
00127         fdriver.disconnect(fconnection); fconnection=0;
00128     }
00129     bool ping() {
00130         SQL_CONNECTION_SERVICED_FUNC_GUARDED(
00131             return fdriver.ping(fconnection)
00132         );
00133     }
00134     const char* quote(const char* str, unsigned int length) {
00135         SQL_CONNECTION_SERVICED_FUNC_GUARDED(
00136             return fdriver.quote(fconnection, str, length)
00137         );
00138     }
00139
00140     void query(
00141         const char* statement,
00142         size_t placeholders_count, SQL_Driver::Placeholder* placeholders,
00143         unsigned long offset, unsigned long limit,
00144         SQL_Driver_query_event_handlers& handlers,
00145         const String& source) {
00146         try {
00147             SQL_CONNECTION_SERVICED_FUNC_GUARDED(
00148                 fdriver.query(fconnection,
00149                     statement,
00150                     placeholders_count, placeholders,
00151                     offset, limit,
00152                     handlers)
00153             );
00154         } catch(const Exception& e) { // query problem
00155             if(strcmp(e.type(), "sql.connect")==0) { // if it is _throw exception,
00156                 // give more specific source [were url]
00157                 throw Exception("sql.execute",
00158                     &source,
00159                     "%s", e.comment());
00160             } else
00161                 rethrow;
00162         }
00163     }
00164
00165     void commit() {
00166         SQL_CONNECTION_SERVICED_FUNC_GUARDED(
00167             fdriver.commit(fconnection)
00168         );
00169     }
00170     void rollback() {
00171         SQL_CONNECTION_SERVICED_FUNC_GUARDED(
00172             fdriver.rollback(fconnection)
00173         );
00174     }
00175
00177     void close() {
00178         SQL_driver_manager->close_connection(furl, this);
00179     }
00180
00181 };
00182
00183 #endif


pa_sql_driver.h File Reference

Parser: sql driver interface. More...

Include dependency graph for pa_sql_driver.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | SQL_Error
fields are freed elsewhere. More...

class | SQL_Driver_services
service functions for SQL driver to use. More...

class | SQL_Driver_query_event_handlers
events, occuring when SQL_Driver::query()-ing. More...

class | SQL_Driver
SQL driver API. More...

struct | Placeholder
to pass IN and OUT int/double NOT in string format. More...

Defines

#define | SQL_DRIVER_API_VERSION 9
#define | SQL_DRIVER_CREATE create
#define | SQL_DRIVER_CREATE_NAME "create"

Typedefs

typedef SQL_Driver *(* | SQL_Driver_create_func )()

Variables

const char *const | IDENT_SQL_DRIVER_H = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: sql driver interface.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

driver dynamic library must look like this:

        class X_SQL_Driver: public SQL_Driver {
        public:

            X_SQL_Driver() : SQL_driver() {}

            int api_version() { return SQL_DRIVER_API_VERSION; }

            //...
        };

        extern "C" SQL_Driver *create() {
            return new X_SQL_Driver();
        }

Definition in file pa_sql_driver.h.

Define Documentation

#define SQL_DRIVER_API_VERSION 9

Definition at line 39 of file pa_sql_driver.h.

Referenced by SQL_Driver_manager::get_connection().

#define SQL_DRIVER_CREATE create

Definition at line 40 of file pa_sql_driver.h.

#define SQL_DRIVER_CREATE_NAME "create"

Definition at line 41 of file pa_sql_driver.h.

Referenced by SQL_Driver_manager::get_connection().

Typedef Documentation

typedef SQL_Driver*(* SQL_Driver_create_func)()

Definition at line 166 of file pa_sql_driver.h.

Referenced by SQL_Driver_manager::get_connection().

Variable Documentation

const char* const IDENT_SQL_DRIVER_H = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 29 of file pa_sql_driver.h.


pa_sql_driver.h Source File

pa_sql_driver.h

Go to the documentation of this file.
00001
00026 #ifndef PA_SQL_DRIVER_H
00027 #define PA_SQL_DRIVER_H
00028
00029 static const char * const IDENT_SQL_DRIVER_H="$Date: 2005/08/09 08:14:53 $";
00030
00031 #include <sys/types.h>
00032 #include <setjmp.h>
00033 #include <stdlib.h>
00034
00035 /*
00036     1..8 not logged
00037     9 introducing placeholders
00038 */
00039 #define SQL_DRIVER_API_VERSION 9
00040 #define SQL_DRIVER_CREATE create /* used in driver implementation */
00041 #define SQL_DRIVER_CREATE_NAME "create" /* could not figure out how to # it :( */
00042
00044 class SQL_Error {
00045     bool fdefined;
00046     const char* ftype;
00047     const char* fcomment;
00048 public:
00049     SQL_Error():
00050         fdefined(false) {}
00051     SQL_Error(
00052         const char* atype,
00053         const char* acomment):
00054         fdefined(true),
00055         ftype(atype),
00056         fcomment(acomment) {}
00057     SQL_Error(const char* acomment):
00058         fdefined(true),
00059         ftype(0),
00060         fcomment(acomment) {}
00061     SQL_Error& operator =(const SQL_Error& src) {
00062         fdefined=src.fdefined;
00063         ftype=src.ftype;
00064         fcomment=src.fcomment;
00065         return *this;
00066     }
00067
00068     bool defined() const { return fdefined; }
00069     const char* type() const { return ftype; }
00070     const char* comment() const { return fcomment; }
00071 };
00072
00074 class SQL_Driver_services {
00075 public:
00077     virtual void *malloc(size_t size) =0;
00079     virtual void *malloc_atomic(size_t size) =0;
00081     virtual void *realloc(void *ptr, size_t size) =0;
00083     virtual const char* request_charset() =0;
00087     virtual void transcode(const char* src, size_t src_length,
00088         const char*& dst, size_t& dst_length,
00089         const char* charset_from_name,
00090         const char* charset_to_name
00091         ) =0;
00093     virtual void _throw(const SQL_Error& e) =0;
00095     virtual void propagate_exception() =0;
00097     void _throw(const char* comment) { _throw(SQL_Error("sql.connect", comment)); }
00098 public:
00100     jmp_buf mark;
00101 };
00102
00108 class SQL_Driver_query_event_handlers {
00109 public:
00110     virtual bool add_column(SQL_Error& error, const char* str, size_t length) =0;
00111     virtual bool before_rows(SQL_Error& error) =0;
00112     virtual bool add_row(SQL_Error& error) =0;
00113     virtual bool add_row_cell(SQL_Error& error, const char* str, size_t length) =0;
00114 };
00115
00117 class SQL_Driver {
00118 public:
00119
00122     struct Placeholder {
00123         const char* name;
00124         const char* value;
00125         bool is_null;
00126         bool were_updated;
00127     };
00128
00132     static void *operator new(size_t size) {
00133         void *result=::malloc(size);
00134         if(!result)
00135             abort();
00136
00137         return result;
00138     }
00140     virtual int api_version() =0;
00142     virtual const char* initialize(char *dlopen_file_spec) =0;
00149     virtual void connect(char *url_cstr,
00150         SQL_Driver_services& services, void **connection) =0;
00151     virtual void disconnect(void *connection) =0;
00152     virtual void commit(void *connection) =0;
00153     virtual void rollback(void *connection) =0;
00155     virtual bool ping(void *connection) =0;
00157     virtual const char* quote(void *connection,
00158         const char* str, unsigned int length) =0;
00159     virtual void query(void *connection,
00160         const char* statement,
00161         size_t placeholders_count, Placeholder* placeholders,
00162         unsigned long offset, unsigned long limit,
00163         SQL_Driver_query_event_handlers& handlers) =0;
00164 };
00165
00166 typedef SQL_Driver *(*SQL_Driver_create_func)();
00167
00168 #endif


pa_sql_driver_manager.C File Reference

Parser: sql driver manager implementation. More...

Include dependency graph for pa_sql_driver_manager.C:

Include dependency graph

Go to the source code of this file.

Functions

void | expire_connection (SQL_Connection &connection, time_t older_dies)
void | expire_connections (SQL_Driver_manager::connection_cache_type::key_type, SQL_Driver_manager::connection_cache_type::value_type stack, time_t older_dies)
void | add_connection_to_status_cache_table (SQL_Connection &connection, Table *table)
void | add_connections_to_status_cache_table (SQL_Driver_manager::connection_cache_type::key_type, SQL_Driver_manager::connection_cache_type::value_type stack, Table *table)

Variables

const char *const | IDENT_SQL_DRIVER_MANAGER_C = "$Date: 2005/08/09 08:14:52 $"
SQL_Driver_manager * | SQL_driver_manager = 0
global. More...

const time_t | EXPIRE_UNUSED_CONNECTION_SECONDS = 60
const time_t | CHECK_EXPIRED_CONNECTIONS_SECONDS = EXPIRE_UNUSED_CONNECTION_SECONDS*2

Detailed Description

Parser: sql driver manager implementation.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_sql_driver_manager.C.

Function Documentation

void expire_connection | ( | SQL_Connection & | connection,
 |  | time_t | older_dies
 | ) | [static]

Definition at line 91 of file pa_sql_driver_manager.C.

References SQL_Connection::connected(), SQL_Connection::disconnect(), and SQL_Connection::expired().

Referenced by expire_connections().

void expire_connections | ( | SQL_Driver_manager::connection_cache_type::key_type | ,
 |  | SQL_Driver_manager::connection_cache_type::value_type | stack,
 |  | time_t | older_dies
 | ) | [static]

Definition at line 95 of file pa_sql_driver_manager.C.

References expire_connection().

Referenced by SQL_Driver_manager::maybe_expire_cache(), and SQL_Driver_manager::~SQL_Driver_manager().

void add_connection_to_status_cache_table | ( | SQL_Connection & | connection,
 |  | Table * | table
 | ) | [static]

Definition at line 295 of file pa_sql_driver_manager.C.

References SQL_Connection::connected(), SQL_Connection::get_time_used(), pa_strdup(), SQL_Connection::services(), and SQL_Driver_services_impl::url_without_login().

Referenced by add_connections_to_status_cache_table().

void add_connections_to_status_cache_table | ( | SQL_Driver_manager::connection_cache_type::key_type | ,
 |  | SQL_Driver_manager::connection_cache_type::value_type | stack,
 |  | Table * | table
 | ) | [static]

Definition at line 308 of file pa_sql_driver_manager.C.

References add_connection_to_status_cache_table(), Array_iterator< T >::has_next(), and Array_iterator< T >::next().

Referenced by SQL_Driver_manager::get_status().

Variable Documentation

const char* const IDENT_SQL_DRIVER_MANAGER_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_sql_driver_manager.C.

SQL_Driver_manager* SQL_driver_manager = 0

global.

Definition at line 22 of file pa_sql_driver_manager.C.

const time_t EXPIRE_UNUSED_CONNECTION_SECONDS = 60

Definition at line 26 of file pa_sql_driver_manager.C.

Referenced by SQL_Driver_manager::maybe_expire_cache().

const time_t CHECK_EXPIRED_CONNECTIONS_SECONDS = EXPIRE_UNUSED_CONNECTION_SECONDS*2

Definition at line 27 of file pa_sql_driver_manager.C.

Referenced by SQL_Driver_manager::maybe_expire_cache().


pa_sql_driver_manager.C Source File

pa_sql_driver_manager.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_SQL_DRIVER_MANAGER_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #include "pa_sql_driver_manager.h"
00011 #include "ltdl.h"
00012 #include "pa_threads.h"
00013 #include "pa_sql_connection.h"
00014 #include "pa_exception.h"
00015 #include "pa_common.h"
00016 #include "pa_vhash.h"
00017 #include "pa_vtable.h"
00018 #include "pa_charsets.h"
00019
00020 // globals
00021
00022 SQL_Driver_manager* SQL_driver_manager=0;
00023
00024 // consts
00025
00026 const time_t EXPIRE_UNUSED_CONNECTION_SECONDS=60;
00027 const time_t CHECK_EXPIRED_CONNECTIONS_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2;
00028
00029 // helpers
00030
00031 const String& SQL_Driver_services_impl::url_without_login() const {
00032     String& result=*new String;
00033     result << furl->mid(0, furl->pos(':')) << "://****";
00034
00035     size_t at_pos=0;
00036     size_t new_at_pos;
00037     while( (new_at_pos=furl->pos('@', at_pos+1))!=STRING_NOT_FOUND)
00038         at_pos=new_at_pos;
00039     if(at_pos)
00040         result << furl->mid(at_pos, furl->length());
00041
00042     return result;
00043 }
00044
00045 void SQL_Driver_services_impl::transcode(const char* src, size_t src_length,
00046     const char*& dst, size_t& dst_length,
00047     const char* charset_from_name,
00048     const char* charset_to_name
00049     )
00050 {
00051     try {
00052         // to speed up sql transcode [lots of charsets::get-s -- twice for each cell]
00053         // without complicating sql driver API
00054         // we need to cache couple of name->charset pairs
00055         // assuming pointers to names are are NOT to local vars
00056
00057         struct cache_record {
00058             const char* name;
00059             Charset* object;
00060         } cache[2]={{0,0}, {0,0}};
00061
00062         Charset* charset_from_object;
00063         Charset* charset_to_object;
00064         if(charset_from_name==cache[0].name) {
00065             charset_from_object=cache[0].object;
00066         } else {
00067             cache[0].name=charset_from_name;
00068             cache[0].object=charset_from_object=&charsets.get(charset_from_name);
00069         }
00070         if(charset_to_name==cache[1].name) {
00071             charset_to_object=cache[1].object;
00072         } else {
00073             cache[1].name=charset_to_name;
00074             cache[1].object=charset_to_object=&charsets.get(charset_to_name);
00075         }
00076
00077         String::C result=Charset::transcode(String::C(src, src_length),
00078             *charset_from_object,
00079             *charset_to_object);
00080         dst=result.str;
00081         dst_length=result.length;
00082     } catch(const Exception& e) {
00083         _throw(SQL_Error(e.type(), e.comment()));
00084     } catch(...) {
00085         _throw(SQL_Error(0, "unknown error while transcoding in sql driver"));
00086     }
00087 }
00088
00089 // helpers
00090
00091 static void expire_connection(SQL_Connection& connection, time_t older_dies) {
00092     if(connection.connected() && connection.expired(older_dies))
00093         connection.disconnect();
00094 }
00095 static void expire_connections(SQL_Driver_manager::connection_cache_type::key_type /*key*/,
00096                    SQL_Driver_manager::connection_cache_type::value_type stack,
00097                    time_t older_dies) {
00098     for(size_t i=0; i<stack->top_index(); i++)
00099         expire_connection(*stack->get(i), older_dies);
00100 }
00101
00102 // SQL_Driver_manager
00103
00104 SQL_Driver_manager::SQL_Driver_manager():
00105     is_dlinited(false), prev_expiration_pass_time(0) {
00106 }
00107
00108 SQL_Driver_manager::~SQL_Driver_manager() {
00109     connection_cache.for_each(expire_connections, time(0)+(time_t)10/*=in future=expire all*/);
00110
00111     if(is_dlinited)
00112         lt_dlexit();
00113 }
00114
00116 SQL_Connection* SQL_Driver_manager::get_connection(const String& aurl,
00117                            Table *protocol2driver_and_client,
00118                            const char* arequest_charset) {
00119     // we have table for locating protocol's library
00120     if(!protocol2driver_and_client)
00121         throw Exception("parser.runtime",
00122             &aurl,
00123             "$"MAIN_SQL_NAME":"MAIN_SQL_DRIVERS_NAME" table must be defined");
00124
00125     // first trying to get cached connection
00126     SQL_Connection* connection=get_connection_from_cache(aurl);
00127     if(connection) {
00128         connection->set_url();
00129         if(!connection->ping()) { // we have some cached connection, is it pingable?
00130             connection->disconnect(); // kill unpingabe=dead connection
00131             connection=0;
00132         }
00133     }
00134
00135     char *url_cstr;
00136     if(connection)
00137         url_cstr=0; // calm, compiler
00138     else { // no cached connection or it were unpingabe: connect/reconnect
00139         url_cstr=aurl.cstrm();
00140         if(!strstr(url_cstr, "://"))
00141             throw Exception("parser.runtime",
00142                 aurl.length()?&aurl:0,
00143                 "connection string must start with protocol://");
00144
00145
00146         char *protocol_cstr=lsplit(&url_cstr, ':');
00147         // skip "//" after ':'
00148         while(*url_cstr=='/')
00149             url_cstr++;
00150         const String& protocol=*new String(protocol_cstr);
00151
00152         SQL_Driver *driver;
00153         // first trying to get cached driver
00154         if(!(driver=get_driver_from_cache(protocol))) {
00155             // no cached
00156             const String* library=0;
00157             const String* dlopen_file_spec=0;
00158             Table::Action_options options;
00159             if(protocol2driver_and_client->locate(0, protocol, options)) {
00160                 if(!(library=protocol2driver_and_client->item(1)) || library->length()==0)
00161                     throw Exception("parser.runtime",
00162                         0,
00163                         "driver library column for protocol '%s' is empty",
00164                             protocol_cstr);
00165                 dlopen_file_spec=protocol2driver_and_client->item(2);
00166             } else
00167                 throw Exception("parser.runtime",
00168                     &aurl,
00169                     "undefined protocol '%s'",
00170                         protocol_cstr);
00171
00172             if(!is_dlinited) {
00173                 if(lt_dlinit())
00174                     throw Exception(0,
00175                         library,
00176                         "prepare to dynamic loading failed, %s", lt_dlerror());
00177
00178                 is_dlinited=true;
00179             }
00180
00181             const char* filename=library->cstr(String::L_FILE_SPEC);
00182             lt_dlhandle handle=lt_dlopen(filename);
00183             if (!handle) {
00184                 const char* error=lt_dlerror();
00185                 throw Exception(0,
00186                     library,
00187                     error?error:"can not open the module");
00188             }
00189
00190             SQL_Driver_create_func create=(SQL_Driver_create_func)lt_dlsym(handle,
00191                 SQL_DRIVER_CREATE_NAME);
00192             if(!create)
00193                 throw Exception(0,
00194                     library,
00195                     "function '"SQL_DRIVER_CREATE_NAME"' was not found");
00196
00197             // create library-driver!
00198             driver=(*create)();
00199
00200             // validate driver api version
00201             int driver_api_version=driver->api_version();
00202             if(driver_api_version!=SQL_DRIVER_API_VERSION)
00203                 throw Exception(0,
00204                     library,
00205                     "driver implements API version 0x%04X not equal to 0x%04X",
00206                         driver_api_version, SQL_DRIVER_API_VERSION);
00207
00208             // initialise by connecting to sql client dynamic link library
00209             char* dlopen_file_spec_cstr=
00210                 dlopen_file_spec && dlopen_file_spec->length()?
00211                 dlopen_file_spec->cstrm(String::L_AS_IS):0;
00212             if(const char* error=driver->initialize(dlopen_file_spec_cstr))
00213                 throw Exception(0,
00214                     library,
00215                     "driver failed to initialize client library '%s', %s",
00216                         dlopen_file_spec_cstr?dlopen_file_spec_cstr:"unspecifed",
00217                         error);
00218
00219             // cache it
00220             put_driver_to_cache(protocol, driver);
00221         }
00222
00223         connection=new SQL_Connection(aurl, *driver, arequest_charset);
00224         // associate with pool[request]  (deassociates at close)
00225         connection->set_url();
00226     }
00227
00228     // if not connected yet, do that now, when connection has services
00229     if(!connection->connected())
00230         connection->connect(url_cstr);
00231     // return autoclosing object for it
00232     return connection;
00233 }
00234
00235 void SQL_Driver_manager::close_connection(connection_cache_type::key_type url,
00236                       SQL_Connection* connection) {
00237     put_connection_to_cache(url, connection);
00238 }
00239
00240
00241 // driver cache
00242
00243 SQL_Driver *SQL_Driver_manager::get_driver_from_cache(driver_cache_type::key_type protocol) {
00244     SYNCHRONIZED;
00245
00246     return driver_cache.get(protocol);
00247 }
00248
00249 void SQL_Driver_manager::put_driver_to_cache(
00250                                              driver_cache_type::key_type protocol,
00251                                              driver_cache_type::value_type driver) {
00252     SYNCHRONIZED;
00253
00254     driver_cache.put(protocol, driver);
00255 }
00256
00257 // connection cache
00259 SQL_Connection* SQL_Driver_manager::get_connection_from_cache(connection_cache_type::key_type url) {
00260     SYNCHRONIZED;
00261
00262     if(connection_cache_type::value_type connections=connection_cache.get(url))
00263         while(!connections->is_empty()) { // there are cached connections to that 'url'
00264             SQL_Connection* result=connections->pop();
00265             if(result->connected()) // not expired?
00266                 return result;
00267         }
00268
00269     return 0;
00270 }
00271
00272 void SQL_Driver_manager::put_connection_to_cache(
00273                          connection_cache_type::key_type url,
00274                          SQL_Connection* connection) {
00275     SYNCHRONIZED;
00276
00277     connection_cache_type::value_type connections=connection_cache.get(url);
00278     if(!connections) { // there are no cached connections to that 'url' yet?
00279         connections=new connection_cache_element_base_type;
00280         connection_cache.put(url, connections);
00281     }
00282     connections->push(connection);
00283 }
00284
00285 void SQL_Driver_manager::maybe_expire_cache() {
00286     time_t now=time(0);
00287
00288     if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTIONS_SECONDS) {
00289         connection_cache.for_each(expire_connections, time_t(now-EXPIRE_UNUSED_CONNECTION_SECONDS));
00290
00291         prev_expiration_pass_time=now;
00292     }
00293 }
00294
00295 static void add_connection_to_status_cache_table(SQL_Connection& connection, Table* table) {
00296     if(connection.connected()) {
00297         ArrayString& row=*new ArrayString;
00298
00299         // url
00300         row+=&connection.services().url_without_login();
00301         // time
00302         time_t time_used=connection.get_time_used();
00303         row+=new String(pa_strdup(ctime(&time_used)));
00304
00305         *table+=&row;
00306     }
00307 }
00308 static void add_connections_to_status_cache_table(
00309     SQL_Driver_manager::connection_cache_type::key_type /*key*/,
00310     SQL_Driver_manager::connection_cache_type::value_type stack, Table* table)
00311 {
00312     for(Array_iterator<SQL_Connection*> i(*stack); i.has_next(); )
00313         add_connection_to_status_cache_table(*i.next(), table);
00314 }
00315
00316 Value* SQL_Driver_manager::get_status() {
00317     Value* result=new VHash;
00318
00319     // cache
00320     {
00321         ArrayString& columns=*new ArrayString;
00322         columns+=new String("url");
00323         columns+=new String("time");
00324         Table& table=*new Table(&columns, connection_cache.count());
00325
00326         connection_cache.for_each(add_connections_to_status_cache_table, &table);
00327
00328         result->get_hash()->put(*new String("cache"), new VTable(&table));
00329     }
00330
00331     return result;
00332 }


pa_sql_driver_manager.h File Reference

Parser: sql driver manager decl. More...

Include dependency graph for pa_sql_driver_manager.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | SQL_Driver_manager
sql driver manager. More...

Defines

#define | MAIN_SQL_NAME "SQL"
#define | MAIN_SQL_DRIVERS_NAME "drivers"

Variables

const char *const | IDENT_SQL_DRIVER_MANAGER_H = "$Date: 2005/08/09 08:14:50 $"
SQL_Driver_manager * SQL_driver_manager
global. More...

Detailed Description

Parser: sql driver manager decl.

global sql driver manager, must be thread-safe

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_sql_driver_manager.h.

Define Documentation

#define MAIN_SQL_NAME "SQL"

Definition at line 24 of file pa_sql_driver_manager.h.

Referenced by _connect(), and SQL_Driver_manager::get_connection().

#define MAIN_SQL_DRIVERS_NAME "drivers"

Definition at line 25 of file pa_sql_driver_manager.h.

Referenced by _connect(), and SQL_Driver_manager::get_connection().

Variable Documentation

const char* const IDENT_SQL_DRIVER_MANAGER_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 12 of file pa_sql_driver_manager.h.

SQL_Driver_manager* SQL_driver_manager

global.

Definition at line 88 of file pa_sql_driver_manager.h.


pa_sql_driver_manager.h Source File

pa_sql_driver_manager.h

Go to the documentation of this file.
00001
00009 #ifndef PA_SQL_DRIVER_MANAGER_H
00010 #define PA_SQL_DRIVER_MANAGER_H
00011
00012 static const char * const IDENT_SQL_DRIVER_MANAGER_H="$Date: 2005/08/09 08:14:50 $";
00013
00014
00015 #include "pa_sql_driver.h"
00016 #include "pa_hash.h"
00017 #include "pa_table.h"
00018 #include "pa_string.h"
00019 #include "pa_cache_managers.h"
00020 #include "pa_stack.h"
00021
00022 // defines
00023
00024 #define MAIN_SQL_NAME "SQL"
00025 #define MAIN_SQL_DRIVERS_NAME "drivers"
00026
00027 // forwards
00028
00029 class SQL_Connection;
00030
00032 class SQL_Driver_manager: public Cache_manager {
00033 public:
00034
00035     typedef Hash<const String::Body, SQL_Driver *> driver_cache_type;
00036     typedef Stack<SQL_Connection*> connection_cache_element_base_type;
00037     typedef Hash<const String::Body, connection_cache_element_base_type*> connection_cache_type;
00038
00039 private:
00040
00041     friend class SQL_Connection;
00042
00043     bool is_dlinited;
00044     driver_cache_type driver_cache;
00045     connection_cache_type connection_cache;
00046
00047 public:
00048
00049     SQL_Driver_manager();
00050     override ~SQL_Driver_manager();
00051
00057     SQL_Connection* get_connection(const String& aurl,
00058         Table *protocol2driver_and_client,
00059         const char* arequest_charset);
00060
00061 private: // driver cache
00062
00063     SQL_Driver *get_driver_from_cache(driver_cache_type::key_type protocol);
00064     void put_driver_to_cache(driver_cache_type::key_type protocol, driver_cache_type::value_type driver);
00065
00066 private: // connection cache
00067
00068     SQL_Connection* get_connection_from_cache(connection_cache_type::key_type url);
00069     void put_connection_to_cache(connection_cache_type::key_type url,
00070         SQL_Connection* connection);
00071 private:
00072     time_t prev_expiration_pass_time;
00073
00074 private: // for SQL_Connection
00075
00077     void close_connection(connection_cache_type::key_type url,
00078         SQL_Connection* connection);
00079
00080 public: // Cache_manager
00081
00082     override Value* get_status();
00083     override void maybe_expire_cache();
00084
00085 };
00086
00088 extern SQL_Driver_manager* SQL_driver_manager;
00089
00090 #endif


pa_stack.h File Reference

Parser: stack class decl. More...

Include dependency graph for pa_stack.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Stack
simple stack based on Array. More...

Variables

const char *const | IDENT_STACK_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: stack class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_stack.h.

Variable Documentation

const char* const IDENT_STACK_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_stack.h.


pa_stack.h Source File

pa_stack.h

Go to the documentation of this file.
00001
00008 #ifndef PA_STACK_H
00009 #define PA_STACK_H
00010
00011 static const char * const IDENT_STACK_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 #include "pa_config_includes.h"
00014 #include "pa_array.h"
00015
00017 template<typename T> class Stack: public Array<T> {
00018 public:
00019
00020     Stack(): ftop(0) {}
00021
00022     void push(T item) {
00023         if(ftop<this->count()) // cell is already allocated?
00024             put(ftop, item); // use it
00025         else
00026             *this+=item; // append it
00027         ftop++;
00028     }
00029
00030     T pop() {
00031         return this->get(--ftop);
00032     }
00033
00034     bool is_empty() { return ftop==0; }
00035     size_t top_index() { return ftop; }
00036     void set_top_index(size_t atop) { ftop=atop; }
00037     T top_value() {
00038         assert(!is_empty());
00039         return this->get(ftop-1);
00040     }
00041
00043     void wipe_unused() {
00044         if(size_t above_top_size=this->fused-ftop)
00045             memset(&this->felements[ftop], 0, above_top_size*sizeof(T));
00046     }
00047
00048 protected:
00049
00050     // deepest used index+1
00051     size_t ftop;
00052 };
00053
00054 #endif


pa_string.C File Reference

Parser: string class. More...

Include dependency graph for pa_string.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | String_match_table_template_columns

Functions

int | pa_atoi (const char *str, const String *problem_source)
double | pa_atod (const char *str, const String *problem_source)
int | CORD_range_contains_chr_greater_then_proc (char c, size_t size, void *client_data)
int | CORD_range_contains_chr_greater_then (CORD x, size_t i, size_t n, int c)
int | CORD_block_count_proc (char, size_t, void *client_data)
size_t | CORD_block_count (CORD x)
Table string_match_table_template (new String_match_table_template_columns)
int | CORD_batched_iter_fn_generic_hash_code (char c, void *client_data)
int | CORD_batched_iter_fn_generic_hash_code (const char *s, void *client_data)
void | regex_options (const String *options, int *result, bool &need_pre_post_match)
int | serialize_body_char (char c, char **cur)
int | serialize_body_piece (const char *s, char **cur)
int | serialize_lang_piece (char alang, size_t asize, char **cur)

Variables

const char *const | IDENT_STRING_C = "$Date: 2005/12/09 07:39:19 $"
const int | MAX_MATCH_GROUPS = 100
String::match uses this as replace & global search table columns. More...

Detailed Description

Parser: string class.

See also:
untalength_t.C.
Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_string.C.

Function Documentation

int pa_atoi | ( | const char * | str,
 |  | const String * | problem_source
 | ) |

Definition at line 20 of file pa_string.C.

References result, and str.

Referenced by String::as_int(), and cstr_to_time_t().

double pa_atod | ( | const char * | str,
 |  | const String * | problem_source
 | ) |

Definition at line 61 of file pa_string.C.

References result, and str.

Referenced by String::as_double().

int CORD_range_contains_chr_greater_then_proc | ( | char | c,
 |  | size_t | size,
 |  | void * | client_data
 | ) | [static]

Definition at line 110 of file pa_string.C.

References size.

Referenced by CORD_range_contains_chr_greater_then().

int CORD_range_contains_chr_greater_then | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | n,
 |  | int | c
 | ) |

Definition at line 119 of file pa_string.C.

References CORD, CORD_block_iter(), CORD_range_contains_chr_greater_then_proc(), and chr_data::target.

Referenced by String::Languages::check_lang().

int CORD_block_count_proc | ( | char | ,
 |  | size_t | ,
 |  | void * | client_data
 | ) | [static]

Definition at line 128 of file pa_string.C.

References result.

Referenced by CORD_block_count().

size_t CORD_block_count ( CORD x )

Definition at line 134 of file pa_string.C.

References CORD, CORD_block_count_proc(), CORD_block_iter(), and result.

Referenced by String::Languages::count().

Table string_match_table_template ( new String_match_table_template_columns )

int CORD_batched_iter_fn_generic_hash_code | ( | char | c,
 |  | void * | client_data
 | ) | [static]

Definition at line 220 of file pa_string.C.

References generic_hash_code(), result, and uint.

Referenced by String::Body::hash_code().

int CORD_batched_iter_fn_generic_hash_code | ( | const char * | s,
 |  | void * | client_data
 | ) | [static]

Definition at line 225 of file pa_string.C.

References generic_hash_code(), result, and uint.

void regex_options | ( | const String * | options,
 |  | int * | result,
 |  | bool & | need_pre_post_match
 | ) | [static]

Definition at line 367 of file pa_string.C.

References String::is_empty(), PCRE_CASELESS, PCRE_DOLLAR_ENDONLY, PCRE_DOTALL, PCRE_EXTENDED, PCRE_EXTRA, PCRE_MULTILINE, String::pos(), result, and STRING_NOT_FOUND.

Referenced by String::match().

int serialize_body_char | ( | char | c,
 |  | char ** | cur
 | ) | [static]

Definition at line 593 of file pa_string.C.

Referenced by String::serialize().

int serialize_body_piece | ( | const char * | s,
 |  | char ** | cur
 | ) | [static]

Definition at line 597 of file pa_string.C.

Referenced by String::serialize().

int serialize_lang_piece | ( | char | alang,
 |  | size_t | asize,
 |  | char ** | cur
 | ) | [static]

Definition at line 602 of file pa_string.C.

Referenced by String::serialize().

Variable Documentation

const char* const IDENT_STRING_C = "$Date: 2005/12/09 07:39:19 $" [static]

Definition at line 8 of file pa_string.C.

const int MAX_MATCH_GROUPS = 100

String::match uses this as replace & global search table columns.

Definition at line 145 of file pa_string.C.

Referenced by String::match(), and String_match_table_template_columns::String_match_table_template_columns().


pa_string.C Source File

pa_string.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_STRING_C="$Date: 2005/12/09 07:39:19 $";
00009
00010 #include "pcre.h"
00011
00012 #include "pa_string.h"
00013 #include "pa_exception.h"
00014 #include "pa_table.h"
00015 #include "pa_dictionary.h"
00016 #include "pa_charset.h"
00017
00018 const String String::Empty;
00019
00020 int pa_atoi(const char* str, const String* problem_source) {
00021     if(!str)
00022         return 0;
00023
00024     while(*str && isspace((unsigned char)*str))
00025         str++;
00026     if(!*str)
00027         return 0;
00028
00029     int result;
00030     char *error_pos;
00031     bool negative=false;
00032     if(str[0]=='-') {
00033         negative=true;
00034         str++;
00035     } else if(str[0]=='+') {
00036         str++;
00037     }
00038     // 0xABC
00039     if(str[0]=='0')
00040         if(str[1]=='x' || str[1]=='X')
00041             result=(int)(unsigned long)strtol(str, &error_pos, 0);
00042         else {
00043              // skip leading 0000, to disable octal interpretation
00044             do str++; while(*str=='0');
00045             result=(int)strtol(str, &error_pos, 0);
00046         }
00047     else
00048         result=(int)strtol(str, &error_pos, 0);
00049     if(negative)
00050         result=-result;
00051
00052     while(char c=*error_pos++)
00053         if(!isspace((unsigned char)c))
00054             throw Exception("number.format",
00055                 problem_source,
00056                 problem_source?"invalid number (int)": "'%s' is invalid number (int)", str);
00057
00058     return result;
00059 }
00060
00061 double pa_atod(const char* str, const String* problem_source) {
00062     if(!str)
00063         return 0;
00064
00065     while(*str && isspace((unsigned char)*str))
00066         str++;
00067     if(!*str)
00068         return 0;
00069
00070     double result;
00071     char *error_pos;
00072     bool negative=false;
00073     if(str[0]=='-') {
00074         negative=true;
00075         str++;
00076     } else if(str[0]=='+') {
00077         str++;
00078     }
00079     // 0xABC
00080     if(str[0]=='0')
00081         if(str[1]=='x' || str[1]=='X')
00082             result=(double)(unsigned long)strtol(str, &error_pos, 0);
00083         else {
00084              // skip leading 0000, to disable octal interpretation
00085             do str++; while(*str=='0');
00086             result=(double)strtod(str, &error_pos);
00087         }
00088     else
00089         result=(double)strtod(str, &error_pos);
00090     if(negative)
00091         result=-result;
00092
00093     while(char c=*error_pos++)
00094         if(!isspace((unsigned char)c))
00095             throw Exception("number.format",
00096                 problem_source,
00097                 problem_source?"invalid number (double)": "'%s' is invalid number (double)", str);
00098
00099     return result;
00100 }
00101
00102 // cord lib extension
00103
00104 #ifndef DOXYGEN
00105 typedef struct {
00106     ssize_t countdown;
00107     int target; /* Character we're looking for  */
00108 } chr_data;
00109 #endif
00110 static int CORD_range_contains_chr_greater_then_proc(char c, size_t size, void* client_data)
00111 {
00112     register chr_data * d = (chr_data *)client_data;
00113
00114     if (d -> countdown<=0) return(2);
00115     d -> countdown -= size;
00116     if (c > d -> target) return(1);
00117     return(0);
00118 }
00119 int CORD_range_contains_chr_greater_then(CORD x, size_t i, size_t n, int c)
00120 {
00121     chr_data d;
00122
00123     d.countdown = n;
00124     d.target = c;
00125     return(CORD_block_iter(x, i, CORD_range_contains_chr_greater_then_proc, &d) == 1/*alternatives: 0 normally ended, 2=struck 'n'*/);
00126 }
00127
00128 static int CORD_block_count_proc(char /*c*/, size_t /*size*/, void* client_data)
00129 {
00130     int* result=(int*)client_data;
00131     (*result)++;
00132     return(0); // 0=continue
00133 }
00134 size_t CORD_block_count(CORD x)
00135 {
00136     size_t result=0;
00137     CORD_block_iter(x, 0, CORD_block_count_proc, &result);
00138     return result;
00139 }
00140
00141 // helpers
00142
00144
00145 const int MAX_MATCH_GROUPS=100;
00146
00147 class String_match_table_template_columns: public ArrayString {
00148 public:
00149     String_match_table_template_columns() {
00150         *this+=new String("prematch");
00151         *this+=new String("match");
00152         *this+=new String("postmatch");
00153         for(int i=0; i<MAX_MATCH_GROUPS; i++) {
00154             *this+=new String(String::Body::Format(1+i), String::L_CLEAN);
00155         }
00156     }
00157 };
00158
00159 Table string_match_table_template(new String_match_table_template_columns);
00160
00161 // String::Body methods
00162
00163 String::Body String::Body::Format(int value) {
00164     char local[MAX_NUMBER];
00165     size_t length=snprintf(local, MAX_NUMBER, "%d", value);
00166     return String::Body(pa_strdup(local, length), length);
00167 }
00168
00169 String::Body String::Body::trim(String::Trim_kind kind, const char* chars,
00170                                 size_t* out_start, size_t* out_length) const {
00171     size_t our_length=length();
00172     if(!our_length)
00173         return *this;
00174     if(!chars)
00175         chars=" \t\n"; // white space
00176
00177     size_t start=0;
00178     size_t end=our_length;
00179     // from left...
00180     if(kind!=TRIM_END) {
00181         CORD_pos pos; set_pos(pos, 0);
00182         while(true) {
00183             char c=CORD_pos_fetch(pos);
00184             if(strchr(chars, c)) {
00185                 if(++start==our_length)
00186                     return 0; // all chars are empty, just return empty string
00187             } else
00188                 break;
00189
00190             CORD_next(pos);
00191         }
00192     }
00193     // from right..
00194     if(kind!=TRIM_START) {
00195         CORD_pos pos; set_pos(pos, end-1);
00196         while(true) {
00197             char c=CORD_pos_fetch(pos);
00198             if(strchr(chars, c)) {
00199                 if(--end==0) // optimization: NO need to check for 'end>=start', that's(<) impossible
00200                     return 0; // all chars are empty, just return empty string
00201             } else
00202                 break;
00203
00204             CORD_prev(pos);
00205         }
00206     }
00207
00208     if(start==0 && end==our_length) // nobody moved a thing
00209         return *this;
00210
00211     if(out_start)
00212         *out_start=start;
00213     size_t new_length=end-start;
00214     if(out_length)
00215         *out_length=new_length;
00216
00217     return mid(start, new_length);
00218 }
00219
00220 static int CORD_batched_iter_fn_generic_hash_code(char c, void * client_data) {
00221     uint& result=*static_cast<uint*>(client_data);
00222     generic_hash_code(result, c);
00223     return 0;
00224 }
00225 static int CORD_batched_iter_fn_generic_hash_code(const char*  s, void * client_data) {
00226     uint& result=*static_cast<uint*>(client_data);
00227     generic_hash_code(result, s);
00228     return 0;
00229 };
00230 uint String::Body::hash_code() const {
00231     uint result=0;
00232     CORD_iter5(body, 0,
00233         CORD_batched_iter_fn_generic_hash_code,
00234         CORD_batched_iter_fn_generic_hash_code, &result);
00235     return result;
00236 }
00237
00238 // String methods
00239
00240 String::String(const char* cstr, size_t helper_length, bool tainted): body(CORD_EMPTY) {
00241     append_help_length(cstr, helper_length, tainted?L_TAINTED:L_CLEAN);
00242 }
00243 String::String(const String::C cstr, bool tainted): body(CORD_EMPTY) {
00244     append_know_length(cstr.str, cstr.length, tainted?L_TAINTED:L_CLEAN);
00245 }
00246
00247 String& String::append_know_length(const char* str, size_t known_length, Language lang) {
00248     if(!known_length)
00249         return *this;
00250
00251     // first: langs
00252     langs.append(body, lang, known_length);
00253     // next: letters themselves
00254     body.append_know_length(str, known_length);
00255
00256     ASSERT_STRING_INVARIANT(*this);
00257     return *this;
00258 }
00259 String& String::append_help_length(const char* str, size_t helper_length, Language lang) {
00260     if(!str)
00261         return *this;
00262     size_t known_length=helper_length?helper_length:strlen(str);
00263     if(!known_length)
00264         return *this;
00265
00266     return append_know_length(str, known_length, lang);
00267 }
00268 String& String::append_strdup(const char* str, size_t helper_length, Language lang) {
00269     size_t known_length=helper_length?helper_length:strlen(str);
00270     if(!known_length)
00271         return *this;
00272
00273     // first: langs
00274     langs.append(body, lang, known_length);
00275     // next: letters themselves
00276     body.append_strdup_know_length(str, known_length);
00277
00278     ASSERT_STRING_INVARIANT(*this);
00279     return *this;
00280 }
00281
00283 String& String::mid(size_t substr_begin, size_t substr_end) const {
00284     String& result=*new String;
00285
00286     size_t self_length=length();
00287     substr_begin=min(substr_begin, self_length);
00288     substr_end=min(max(substr_end, substr_begin), self_length);
00289     size_t substr_length=substr_end-substr_begin;
00290     if(!substr_length)
00291         return result;
00292
00293     // first: their langs
00294     result.langs.append(result.body, langs, substr_begin, substr_length);
00295     // next: letters themselves
00296     result.body=body.mid(substr_begin, substr_length);
00297
00298     ASSERT_STRING_INVARIANT(result);
00299     return result;
00300 }
00301
00302 size_t String::pos(const String::Body substr, size_t this_offset, Language lang) const {
00303     size_t substr_length=substr.length();
00304     while(true) {
00305         size_t substr_begin=body.pos(substr, this_offset);
00306
00307         if(substr_begin==CORD_NOT_FOUND)
00308             return STRING_NOT_FOUND;
00309
00310         if(langs.check_lang(lang, substr_begin, substr_length))
00311             return substr_begin;
00312
00313         this_offset=substr_begin+substr_length;
00314     }
00315 }
00316
00317 size_t String::pos(const String& substr,
00318                 size_t this_offset, Language lang) const {
00319     return pos(substr.body, this_offset, lang);
00320 }
00321
00322 void String::split(ArrayString& result,
00323            size_t& pos_after,
00324            const char* delim,
00325            Language lang, int limit) const {
00326     size_t self_length=length();
00327     if(size_t delim_length=strlen(delim)) {
00328         size_t pos_before;
00329         // while we have 'delim'...
00330         for(; (pos_before=pos(delim, pos_after, lang))!=STRING_NOT_FOUND && limit; limit--) {
00331             result+=&mid(pos_after, pos_before);
00332             pos_after=pos_before+delim_length;
00333         }
00334         // last piece
00335         if(pos_after<self_length && limit) {
00336             result+=&mid(pos_after, self_length);
00337             pos_after=self_length;
00338         }
00339     } else { // empty delim
00340         result+=this;
00341         pos_after+=self_length;
00342     }
00343 }
00344
00345 void String::split(ArrayString& result,
00346            size_t& pos_after,
00347            const String& delim, Language lang,
00348            int limit) const {
00349     if(!delim.is_empty()) {
00350         size_t pos_before;
00351         // while we have 'delim'...
00352         for(; (pos_before=pos(delim, pos_after, lang))!=STRING_NOT_FOUND && limit; limit--) {
00353             result+=&mid(pos_after, pos_before);
00354             pos_after=pos_before+delim.length();
00355         }
00356         // last piece
00357         if(pos_after<length() && limit) {
00358             result+=&mid(pos_after, length());
00359             pos_after=length();
00360         }
00361     } else { // empty delim
00362         result+=this;
00363         pos_after+=length();
00364     }
00365 }
00366
00367 static void regex_options(const String* options, int *result, bool& need_pre_post_match){
00368     struct Regex_option {
00369         const char* keyL;
00370         const char* keyU;
00371         int clear, set;
00372         int *result;
00373         bool *flag;
00374     } regex_option[]={
00375         {"i", "I", 0, PCRE_CASELESS, result, 0}, // a=A
00376         {"s", "S", 0, PCRE_DOTALL, result, 0}, // \n\n$ [default]
00377         {"x", "U", 0, PCRE_EXTENDED, result, 0}, // whitespace in regex ignored
00378         {"m", "M", PCRE_DOTALL, PCRE_MULTILINE, result, 0}, // ^aaa\n$^bbb\n$
00379         {"g", "G", 0, 1, result+1, 0}, // many rows
00380         {"'", 0, 0, 0, 0, &need_pre_post_match},
00381         {0, 0, 0, 0, 0, 0}
00382     };
00383     result[0]=PCRE_EXTRA | PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
00384     result[1]=0;
00385
00386     if(options && !options->is_empty())
00387         for(Regex_option *o=regex_option; o->keyL; o++)
00388             if(options->pos(o->keyL)!=STRING_NOT_FOUND
00389                 || (o->keyU && options->pos(o->keyU)!=STRING_NOT_FOUND)) {
00390                 if(o->flag)
00391                     *o->flag=true;
00392                 else { // result
00393                     *o->result &= ~o->clear;
00394                     *o->result |= o->set;
00395                 }
00396             }
00397 }
00398
00399 Table* String::match(Charset& source_charset,
00400              const String& regexp,
00401              const String* options,
00402              Row_action row_action, void *info,
00403              bool& just_matched) const {
00404     if(regexp.is_empty())
00405         throw Exception(0,
00406             0,
00407             "regexp is empty");
00408
00409     const char* pattern=regexp.cstr(String::L_UNSPECIFIED); // fix any tainted with L_REGEX
00410     const char* errptr;
00411     int erroffset;
00412     bool need_pre_post_match=false;
00413     int option_bits[2]={0};  regex_options(options, option_bits, need_pre_post_match);
00414     bool global=option_bits[1]!=0;
00415     pcre *code=pcre_compile(pattern, option_bits[0],
00416         &errptr, &erroffset,
00417         source_charset.pcre_tables);
00418
00419     if(!code)
00420         throw Exception(0,
00421             &regexp.mid(erroffset, regexp.length()),
00422             "regular expression syntax error - %s", errptr);
00423
00424     int subpatterns=pcre_info(code, 0, 0);
00425     if(subpatterns<0) {
00426         pcre_free(code);
00427         throw Exception(0,
00428             &regexp,
00429             "pcre_info error (%d)",
00430                 subpatterns);
00431     }
00432
00433     const char* subject=cstr();
00434     size_t subject_length=strlen(subject);
00435     const int oveclength=(1/*match*/+MAX_MATCH_GROUPS)*3;
00436     int ovector[oveclength];
00437
00438     // create table
00439     Table::Action_options table_options;
00440     Table& table=*new Table(string_match_table_template, table_options);
00441
00442     int exec_option_bits=0;
00443     int prestart=0;
00444     int poststart=0;
00445     int postfinish=length();
00446     while(true) {
00447         int exec_substrings=pcre_exec(code, 0,
00448             subject, subject_length, prestart,
00449             exec_option_bits, ovector, oveclength);
00450
00451         if(exec_substrings==PCRE_ERROR_NOMATCH) {
00452             pcre_free(code);
00453             row_action(table, 0/*last time, no raw*/, 0, 0, poststart, postfinish, info);
00454             if(global || subpatterns)
00455                 return &table; // global or with subpatterns=true+result
00456             else {
00457                 just_matched=false; return 0; // not global=no result
00458             }
00459         }
00460
00461         if(exec_substrings<0) {
00462             pcre_free(code);
00463             throw Exception(0,
00464                 &regexp,
00465                 "regular expression execute error (%d)",
00466                     exec_substrings);
00467         }
00468
00469         int prefinish=ovector[0];
00470         poststart=ovector[1];
00471         ArrayString* row=new ArrayString;
00472         if(need_pre_post_match) {
00473             *row+=&mid(0, prefinish); // .prematch column value
00474             *row+=&mid(prefinish, poststart); // .match
00475             *row+=&mid(poststart, postfinish); // .postmatch
00476         } else {
00477             *row+=&Empty; // .prematch column value
00478             *row+=&Empty; // .match
00479             *row+=&Empty; // .postmatch
00480         }
00481
00482         for(int i=1; i<exec_substrings; i++) {
00483             // -1:-1 case handled peacefully by mid() itself
00484             *row+=&mid(ovector[i*2+0], ovector[i*2+1]); // .i column value
00485         }
00486
00487         row_action(table, row, prestart, prefinish, poststart, postfinish, info);
00488
00489         if(!global || prestart==poststart) { // not global | going to hang
00490             pcre_free(code);
00491             row_action(table, 0/*last time, no row*/, 0, 0, poststart, postfinish, info);
00492             return &table;
00493         }
00494         prestart=poststart;
00495
00496 /*
00497         if(option_bits[0] & PCRE_MULTILINE)
00498             exec_option_bits|=PCRE_NOTBOL; // start of subject+startoffset not BOL
00499 */
00500     }
00501 }
00502
00503 String& String::change_case(Charset& source_charset, Change_case_kind kind) const {
00504     String& result=*new String();
00505     if(is_empty())
00506         return result;
00507
00508     char* new_cstr=cstrm();
00509     size_t new_cstr_len=length();
00510     if(source_charset.isUTF8()) {
00511         switch(kind) {
00512         case CC_UPPER:
00513             change_case_UTF8((const XMLByte*)new_cstr, new_cstr_len, (XMLByte*)new_cstr, new_cstr_len, UTF8CaseToUpper);
00514             break;
00515         case CC_LOWER:
00516             change_case_UTF8((const XMLByte*)new_cstr, new_cstr_len, (XMLByte*)new_cstr, new_cstr_len, UTF8CaseToLower);
00517             break;
00518         default:
00519             assert(!"unknown change case kind");
00520             break; // never
00521         }
00522
00523     } else {
00524         const unsigned char *tables=source_charset.pcre_tables;
00525
00526         const unsigned char *a;
00527         const unsigned char *b;
00528         switch(kind) {
00529         case CC_UPPER:
00530             a=tables+lcc_offset;
00531             b=tables+fcc_offset;
00532             break;
00533         case CC_LOWER:
00534             a=tables+lcc_offset;
00535             b=0;
00536             break;
00537         default:
00538             assert(!"unknown change case kind");
00539             a=b=0; // calm, compiler
00540             break; // never
00541         }
00542
00543         char *dest=new_cstr;
00544         unsigned char index;
00545         for(const char* current=new_cstr; (index=(unsigned char)*current); current++) {
00546             unsigned char c=a[index];
00547             if(b)
00548                 c=b[c];
00549
00550             *dest++=(char)c;
00551         }
00552     }
00553     result.langs=langs;
00554     result.body=new_cstr;
00555
00556     return result;
00557 }
00558
00559 const String& String::replace(const Dictionary& dict) const {
00560     String& result=*new String();
00561     const char* old_cstr=cstr();
00562     const char* prematch_begin=old_cstr;
00563
00564     const char* current=old_cstr;
00565     while(*current) {
00566         if(Dictionary::Subst subst=dict.first_that_begins(current)) {
00567             // prematch
00568             if(size_t prematch_length=current-prematch_begin) {
00569                 result.langs.append(result.body, langs, prematch_begin-old_cstr, prematch_length);
00570                 result.body.append_strdup_know_length(prematch_begin, prematch_length);
00571             }
00572
00573             // match
00574             // skip 'a' in 'current'; move prematch_begin
00575             current+=subst.from_length; prematch_begin=current;
00576
00577             if(const String* b=subst.to) // are there any b?
00578                 result<<*b;
00579         } else // simply advance
00580             current++;
00581     }
00582
00583     // postmatch
00584     if(size_t postmatch_length=current-prematch_begin) {
00585         result.langs.append(result.body, langs, prematch_begin-old_cstr, postmatch_length);
00586         result.body.append_strdup_know_length(prematch_begin, postmatch_length);
00587     }
00588
00589     ASSERT_STRING_INVARIANT(result);
00590     return result;
00591 }
00592
00593 static int serialize_body_char(char c, char** cur) {
00594     *((*cur)++)=c;
00595     return 0; // 0=continue
00596 };
00597 static int serialize_body_piece(const char* s, char** cur) {
00598     size_t length=strlen(s);
00599     memcpy(*cur, s, length);  *cur+=length;
00600     return 0; // 0=continue
00601 };
00602 static int serialize_lang_piece(char alang, size_t asize, char** cur) {
00603     // lang
00604     **cur=alang; (*cur)++;
00605     // length [WARNING: not cast, addresses must be %4=0 on sparc]
00606     memcpy(*cur, &asize, sizeof(asize));  *cur+=sizeof(asize);
00607
00608     return 0; // 0=continue
00609 }
00610 String::Cm String::serialize(size_t prolog_length) const {
00611     size_t fragments_count=langs.count();
00612     size_t body_length=body.length();
00613     size_t buf_length=
00614         prolog_length //1
00615         +sizeof(size_t) //2
00616         +body_length //3
00617         +1 // 4 for zero terminator used in deserialize
00618         +sizeof(size_t) //5
00619         +fragments_count*(sizeof(char)+sizeof(size_t)); //6
00620
00621     String::Cm result(new(PointerFreeGC) char[buf_length], buf_length);
00622
00623     // 1: prolog
00624     char *cur=result.str+prolog_length;
00625     // 2: chars.count [WARNING: not cast, addresses must be %4=0 on sparc]
00626     memcpy(cur, &body_length, sizeof(body_length));  cur+=sizeof(body_length);
00627     // 3: letters
00628     body.for_each(serialize_body_char, serialize_body_piece, &cur);
00629     // 4: zero terminator
00630     *cur++=0;
00631     // 5: langs.count [WARNING: not cast, addresses must be %4=0 on sparc]
00632     memcpy(cur, &fragments_count, sizeof(fragments_count));  cur+=sizeof(fragments_count);
00633     // 6: lang info
00634     langs.for_each(body, serialize_lang_piece, &cur);
00635
00636     return result;
00637 }
00638 bool String::deserialize(size_t prolog_size, void *buf, size_t buf_size) {
00639     size_t in_buf=buf_size;
00640     if(in_buf<=prolog_size)
00641         return false;
00642     in_buf-=prolog_size;
00643
00644     // 1: prolog
00645     const char* cur=(const char* )buf+prolog_size;
00646
00647     // 2: langs.count
00648     size_t body_length;
00649     if(in_buf<sizeof(body_length)) // body.length don't fit?
00650         return false;
00651     // [WARNING: not cast, addresses must be %4=0 on sparc]
00652     memcpy(&body_length, cur, sizeof(body_length));  cur+=sizeof(body_length);
00653     in_buf-=sizeof(body_length);
00654
00655     if(in_buf<body_length+1) // letters+terminator don't fit?
00656         return false;
00657     // 4: zero terminator
00658     if(cur[body_length] != 0) // in place?
00659         return false;
00660     // 3: letters
00661     body=String::Body(cur, body_length);
00662     cur+=body_length+1;
00663     in_buf-=body_length+1;
00664
00665     // 5: langs.count
00666     size_t fragments_count;
00667     if(in_buf<sizeof(fragments_count)) // langs.count don't fit?
00668         return false;
00669     // [WARNING: not cast, addresses must be %4=0 on sparc]
00670     memcpy(&fragments_count, cur, sizeof(fragments_count));  cur+=sizeof(fragments_count);
00671     in_buf-=sizeof(fragments_count);
00672
00673     if(fragments_count) {
00674         // 6: lang info
00675         size_t total_length=0;
00676         for(size_t f=0; f<fragments_count; f++) {
00677             char lang;
00678             size_t fragment_length;
00679             size_t piece_length=sizeof(lang)+sizeof(fragment_length);
00680             if(in_buf<piece_length) // lang+length
00681                 return false;
00682
00683             // lang
00684             lang=*cur++;
00685             // length [WARNING: not cast, addresses must be %4=0 on sparc]
00686             memcpy(&fragment_length, cur, sizeof(fragment_length));  cur+=sizeof(fragment_length);
00687
00688             // uchar needed to prevent propagating 0x80 bit to upper bytes
00689             langs.append(total_length, (String::Language)(uchar)lang, fragment_length);
00690             total_length+=fragment_length;
00691             in_buf-=piece_length;
00692         }
00693
00694         if(total_length!=body_length) // length(all language fragments) vs length(letters)
00695             return false;
00696     }
00697     if(in_buf!=0) // some strange extra bytes
00698         return false;
00699
00700     ASSERT_STRING_INVARIANT(*this);
00701     return true;
00702 }
00703
00704 const char* String::Body::v() const {
00705     return CORD_to_const_char_star(body);
00706 }
00707 void String::Body::dump() const {
00708     CORD_dump(body);
00709 }
00710
00711 const char* String::Languages::v() const {
00712     if(opt.is_not_just_lang)
00713         return CORD_to_const_char_star(langs);
00714     else
00715         return (const char*)&langs;
00716 }
00717 void String::Languages::dump() const {
00718     if(opt.is_not_just_lang)
00719         CORD_dump(langs);
00720     else
00721         puts((const char*)&langs);
00722 }
00723 const char* String::v() const {
00724     const uint LIMIT_VIEW=20;
00725     char* buf=(char*)malloc(MAX_STRING);
00726     const char*body_view=body.v();
00727     const char*langs_view=langs.v();
00728     snprintf(buf, MAX_STRING,
00729         "%d:%.*s%s}   "
00730         "{%d:%s",
00731         langs.count(), LIMIT_VIEW, langs_view, strlen(langs_view)>LIMIT_VIEW?"...":"",
00732         strlen(body_view), body_view
00733     );
00734
00735     return buf;
00736 }
00737 void String::dump() const {
00738     body.dump();
00739     langs.dump();
00740 }
00741 const String& String::trim(String::Trim_kind kind, const char* chars) const {
00742     if(!length())
00743         return *this;
00744
00745     size_t substr_begin, substr_length;
00746     Body new_body=body.trim(kind, chars, &substr_begin, &substr_length);
00747     if(new_body==body) // we received unchanged pointer, do likewise
00748         return *this;
00749     // new_body differs from body, adjust langs along
00750
00751     String& result=*new String;
00752     if(!new_body) // body.trim produced empty result
00753         return result;
00754     // body.trim produced nonempty result
00755
00756     // first: their langs
00757     result.langs.append(result.body, langs, substr_begin, substr_length);
00758     // next: letters themselves
00759     result.body=new_body;
00760
00761     ASSERT_STRING_INVARIANT(result);
00762     return result;
00763 }


pa_string.h File Reference

Parser: string class decl. More...

Include dependency graph for pa_string.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | String
String which knows the lang of all it's langs. More...

union | Languages
class | Body
struct | C
struct | Cm

Defines

#define | CORD_NO_IO
#define | STRING_NOT_FOUND ((size_t)-1)
this is result of pos functions which mean that substr were not found. More...

#define | ASSERT_STRING_INVARIANT(string) assert((string).langs.invariant((string).body.length()))

Typedefs

typedef Array< const String * > | ArrayString

Functions

int | CORD_range_contains_chr_greater_then (CORD x, size_t i, size_t n, int c)
size_t | CORD_block_count (CORD x)
int | pa_atoi (const char *str, const String *problem_source=0)
double | pa_atod (const char *str, const String *problem_source=0)
template<typename T> size_t | get_length (T current)
template<> size_t | get_length< String::Body > (String::Body body)
uint | hash_code (const String::Body self)
simple hash code of string. used by Hash. More...

Variables

const char *const | IDENT_STRING_H = "$Date: 2005/11/22 15:09:10 $"

Detailed Description

Parser: string class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_string.h.

Define Documentation

#define CORD_NO_IO

Definition at line 18 of file pa_string.h.

#define STRING_NOT_FOUND ((size_t)-1)

this is result of pos functions which mean that substr were not found.

Definition at line 46 of file pa_string.h.

Referenced by _exec_cgi(), Request::absolute(), create_dir_for_file(), detect_charset(), Font::index_display(), Font::index_of(), Font::index_width(), lastposafter(), maybe_enclose(), pa_internal_file_read_http(), pass_cgi_header_attribute(), String::Body::pos(), String::pos(), regex_options(), rmdir(), sendmail(), String::split(), split_options(), and SQL_Driver_services_impl::url_without_login().

#define ASSERT_STRING_INVARIANT ( string ) assert((string).langs.invariant((string).body.length()))

Definition at line 381 of file pa_string.h.

Referenced by String::append_know_length(), String::append_strdup(), String::append_to(), String::deserialize(), String::mid(), String::replace(), String::String(), and String::trim().

Typedef Documentation

typedef Array<const String*> ArrayString

Definition at line 38 of file pa_string.h.

Referenced by _flip(), _load(), VForm::AppendFormEntry(), fill_month_days(), fill_week_days(), join_named_row(), pa_internal_file_read_http(), and split_horizontal().

Function Documentation

int CORD_range_contains_chr_greater_then | ( | CORD | x,
 |  | size_t | i,
 |  | size_t | n,
 |  | int | c
 | ) |

Definition at line 119 of file pa_string.C.

References CORD, CORD_block_iter(), CORD_range_contains_chr_greater_then_proc(), and chr_data::target.

Referenced by String::Languages::check_lang().

size_t CORD_block_count ( CORD x )

Definition at line 134 of file pa_string.C.

References CORD, CORD_block_count_proc(), CORD_block_iter(), and result.

Referenced by String::Languages::count().

int pa_atoi | ( | const char * | str,
 |  | const String * | problem_source = 0
 | ) |

Definition at line 20 of file pa_string.C.

References result, and str.

Referenced by String::as_int(), and cstr_to_time_t().

double pa_atod | ( | const char * | str,
 |  | const String * | problem_source = 0
 | ) |

Definition at line 61 of file pa_string.C.

References result, and str.

Referenced by String::as_double().

template<typename T>
size_t get_length ( T current ) [inline]

Definition at line 49 of file pa_string.h.

Referenced by String::Languages::append(), String::Languages::for_each(), and String::Languages::make_langs().

template<>
size_t get_length< String::Body > ( String::Body body ) [inline]

uint hash_code ( const String::Body self ) [inline]

simple hash code of string. used by Hash.

Definition at line 528 of file pa_string.h.

References String::Body::hash_code(), and uint.

Referenced by Hash< const String::Body, void * >::get(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Hash< const String::Body, void * >::put_replaced(), Hash< const String::Body, void * >::remove(), and Hash< const String::Body, void * >::replace_maybe_append().

Variable Documentation

const char* const IDENT_STRING_H = "$Date: 2005/11/22 15:09:10 $" [static]

Definition at line 11 of file pa_string.h.


pa_string.h Source File

pa_string.h

Go to the documentation of this file.
00001
00008 #ifndef PA_STRING_H
00009 #define PA_STRING_H
00010
00011 static const char * const IDENT_STRING_H="$Date: 2005/11/22 15:09:10 $";
00012
00013 // includes
00014 #include "pa_types.h"
00015 #include "pa_array.h"
00016
00017 extern "C" { // cord's author forgot to do that
00018 #define CORD_NO_IO
00019 #include "cord.h"
00020 };
00021
00022 // defines
00023
00024 // cord extension
00025 /* Returns true if x does contain                                       */
00026 /* char not_c at positions i..i+n. Value i,i+n must be < CORD_len(x).   */
00027 int CORD_range_contains_chr_greater_then(CORD x, size_t i, size_t n, int c);
00028 size_t CORD_block_count(CORD x);
00029
00030 // forwards
00031
00032 class Charset;
00033 class Table;
00034 class SQL_Connection;
00035 class Dictionary;
00036 class Request_charsets;
00037 class String;
00038 typedef Array<const String*> ArrayString;
00039
00040 // generally useful
00041
00042 int pa_atoi(const char* str, const String* problem_source=0);
00043 double pa_atod(const char* str, const String* problem_source=0);
00044
00046 #define STRING_NOT_FOUND ((size_t)-1)
00047
00048 template<typename T>
00049 inline size_t get_length(T current) {
00050     return current;
00051 }
00052
00060 class String: public PA_Object {
00061 public:
00062
00077     enum Language {
00078         L_UNSPECIFIED=0,
00079         // these two must go before others, there are checks for >L_AS_IS
00080         L_CLEAN='0',
00081         L_AS_IS='A',
00082
00083         L_PASS_APPENDED='P',
00088         L_TAINTED='T',
00089         // untaint langs. assigned by ^untaint[lang]{...}
00090         L_FILE_SPEC='F',
00091         L_HTTP_HEADER='h',
00092         L_MAIL_HEADER='m',
00093         L_URI='U',
00094         L_SQL='Q',
00095         L_JS='J',
00096         L_XML='X',
00097         L_HTML='H',
00098         L_REGEX='R',
00099         // READ WARNING ABOVE BEFORE ADDING ANYTHING
00100         L_OPTIMIZE_BIT = 0x80
00101     };
00102
00103     enum Trim_kind {
00104         TRIM_BOTH,
00105         TRIM_START,
00106         TRIM_END
00107     };
00108
00109     union Languages {
00110
00111         struct {
00112 #ifdef PA_LITTLE_ENDIAN
00113             Language lang:8;
00114             int is_not_just_lang:sizeof(CORD)*8-8;
00115 #elif defined(PA_BIG_ENDIAN)
00116             int is_not_just_lang:sizeof(CORD)*8-8;
00117             Language lang:8;
00118 #else
00119 #   error word endianness not determined for some obscure reason
00120 #endif
00121         } opt;
00122         CORD langs;
00123
00124         template<typename C>
00125         CORD make_langs(C current) const {
00126             return opt.is_not_just_lang?
00127                 langs
00128                 :CORD_chars((char)opt.lang, get_length(current));
00129         }
00130
00131         CORD make_langs(size_t aoffset, size_t alength)  const {
00132             return opt.is_not_just_lang?
00133                 CORD_substr(langs, aoffset, alength)
00134                 :CORD_chars((char)opt.lang, alength);
00135         }
00136
00138         template<typename C>
00139         void append(C current,
00140             const CORD to_nonempty_target_langs) {
00141             assert(langs);
00142
00143             if(opt.is_not_just_lang)
00144                 langs=CORD_cat(langs, to_nonempty_target_langs);
00145             else { // we were "just lang"
00146                 size_t current_size=get_length(current);
00147                 assert(current_size);
00148                 langs=CORD_cat(
00149                     CORD_chars((char)opt.lang, current_size),  // first piece [making from just 'lang']
00150                     to_nonempty_target_langs); // new piece
00151             }
00152         }
00153
00154     public:
00155
00156         const char* v() const;
00157         void dump() const;
00158
00159         Languages(): langs(0) {}
00160         Languages(Language alang) {
00161             opt.lang=alang;
00162             opt.is_not_just_lang=0;
00163         }
00164
00166         template<typename C>
00167         void append(C current, Language alang, size_t asize) {
00168             assert(alang);
00169             assert(asize);
00170
00171             if(!opt.is_not_just_lang)
00172                 if(opt.lang) {
00173                     if(opt.lang==alang) // same length? ignoring
00174                         return;
00175                 } else {
00176                     opt.lang=alang; // to uninitialized
00177                     return;
00178                 }
00179
00180             append(current, CORD_chars((char)alang, asize));
00181         }
00182
00184         template<typename C>
00185         void append(C current, size_t appending_length,
00186             const Languages src) {
00187             assert(appending_length);
00188
00189             if(!langs)
00190                 langs=src.langs; // to uninitialized
00191             else if(!src.opt.is_not_just_lang)
00192                 append(current, src.opt.lang, appending_length); // simplifying when simple source
00193             else
00194                 append(current, src.make_langs(appending_length));
00195         }
00196
00198         template<typename C>
00199         void append(C current,
00200             const Languages src, size_t aoffset, size_t alength) {
00201             assert(alength);
00202
00203             if(!langs) // to uninitialized?
00204                 if(src.opt.is_not_just_lang)
00205                     langs=CORD_substr(src.langs, aoffset, alength); // to uninitialized complex
00206                 else
00207                     opt.lang=src.opt.lang; // to uninitialized simple
00208             else
00209                 if(!opt.is_not_just_lang && !src.opt.is_not_just_lang && opt.lang==src.opt.lang) // both simple & of same language?
00210                     return; // ignoring
00211                 else
00212                     append(current, src.make_langs(aoffset, alength));
00213         }
00214
00216         bool check_lang(Language alang, size_t aoffset, size_t alength) const {
00217             if(alang==L_UNSPECIFIED) // ignore lang?
00218                 return true;
00219
00220             if(opt.is_not_just_lang)
00221                 return CORD_range_contains_chr_greater_then(langs, aoffset, alength, (unsigned)alang)==0;
00222             else
00223                 return opt.lang<=alang;
00224         }
00225
00228         size_t count() const {
00229             return opt.is_not_just_lang?
00230                 CORD_block_count(langs)
00231                 : opt.lang?
00232                     1
00233                     : 0;
00234         };
00235
00236         template<typename C, typename I>
00237         void for_each(C current,
00238             int callback(char, size_t, I), I info) const {
00239
00240             if(opt.is_not_just_lang)
00241                 CORD_block_iter(langs, 0, (CORD_block_iter_fn)callback, info);
00242             else
00243                 callback(opt.lang, get_length(current), info);
00244         }
00245
00246         bool invariant(size_t current_length) const {
00247             if(!langs)
00248                 return current_length==0;
00249             if(opt.is_not_just_lang)
00250                 return CORD_len(langs)==current_length;
00251             return true; // uncheckable, actually
00252         }
00253     };
00254
00255     class Body {
00256
00257         CORD body;
00258
00259     public:
00260
00261         const char* v() const;
00262         void dump() const;
00263
00264         Body(): body(CORD_EMPTY) {}
00265         Body(CORD abody): body(abody) {
00266             assert(!body // no body
00267                 || *body // ordinary string
00268                 || body[1]==1 // CONCAT_HDR
00269                 || body[1]==4 // FN_HDR
00270                 || body[1]==6 // SUBSTR_HDR
00271                 );
00272         }
00274         Body(const char* str, size_t helper_length): body(CORD_EMPTY) {
00275             append_know_length(str, helper_length?helper_length:strlen(str));
00276         }
00277         static Body Format(int value);
00278
00279         void clear() { body=CORD_EMPTY; }
00280
00281         bool operator! () const { return is_empty(); }
00282
00283         uint hash_code() const;
00284
00285         const char* cstr() const { return CORD_to_const_char_star(body); }
00286         char* cstrm() const { return CORD_to_char_star(body); }
00287
00288         size_t length() const { return CORD_len(body); }
00289
00290         bool is_empty() const { return body==CORD_EMPTY; }
00291
00292         void append_know_length(const char *str, size_t known_length) {
00293             if(known_length)
00294                 body=CORD_cat_char_star(body, str, known_length);
00295         }
00296         void append_strdup_know_length(const char* str, size_t known_length) {
00297             if(known_length)
00298                 append_know_length(pa_strdup(str, known_length), known_length);
00299         }
00300         void append(char c) { body=CORD_cat_char(body, c); }
00301         Body& operator << (const Body src) { body=CORD_cat(body, src.body); return *this; }
00302         Body& operator << (const char* str) { append_know_length(str, strlen(str)); return *this; }
00303
00304         // could not figure out why this operator is needed [should do this chain: string->simple->==]
00305         bool operator < (const Body src) const { return CORD_cmp(body, src.body)<0; }
00306         bool operator > (const Body src) const { return CORD_cmp(body, src.body)>0; }
00307         bool operator <= (const Body src) const { return CORD_cmp(body, src.body)<=0; }
00308         bool operator >= (const Body src) const { return CORD_cmp(body, src.body)>=0; }
00309         bool operator != (const Body src) const { return CORD_cmp(body, src.body)!=0; }
00310         bool operator == (const Body src) const { return CORD_cmp(body, src.body)==0; }
00311
00312         int ncmp(size_t x_begin, const Body y, size_t y_begin, size_t size) const {
00313             return CORD_ncmp(body, x_begin, y.body, y_begin, size);
00314         }
00315
00316         char fetch(size_t index) const { return CORD_fetch(body, index); }
00317         Body mid(size_t index, size_t length) const { return CORD_substr(body, index, length); }
00318         size_t pos(const char* substr, size_t offset=0) const { return CORD_str(body, offset, substr); }
00319         size_t pos(const Body substr, size_t offset=0) const {
00320             if(!substr.length())
00321                 return STRING_NOT_FOUND; // in this case CORD_str returns 0 [parser users got used to -1]
00322
00323             // CORD_str checks for bad offset [CORD_chr does not]
00324             return CORD_str(body, offset, substr.body);
00325         }
00326         size_t pos(char c,
00327             size_t offset=0) const {
00328             if(offset>=length()) // CORD_chr does not check that [and ABORT's in that case]
00329                 return STRING_NOT_FOUND;
00330
00331             return CORD_chr(body, offset, c);
00332         }
00333
00334         template<typename I> int for_each(
00335             int (*f)(char c, I),
00336             I info) const {
00337             return CORD_iter(body, (CORD_iter_fn)f, (void*)info);
00338         }
00339
00340         template<typename I> int for_each(
00341             int (*f1)(char c, I),
00342             int (*f2)(const char* s, I),
00343             I info) const {
00344             return CORD_iter5(body, 0, (CORD_iter_fn)f1, (CORD_batched_iter_fn)f2, info);
00345         }
00346
00347         void set_pos(CORD_pos& pos, size_t index) const { CORD_set_pos(pos, body, index); }
00348
00349         /*Body normalize() const {
00350             return Body(CORD_balance(body));
00351         }*/
00352
00354         Body trim(Trim_kind kind=TRIM_BOTH, const char* chars=0,
00355             size_t* out_start=0, size_t* out_length=0) const;
00356     };
00357
00358     struct C {
00359         const char *str;
00360         size_t length;
00361         operator const char *() { return str; }
00362         C(): str(0), length(0) {}
00363         C(const char *astr, size_t asize): str(astr), length(asize) {}
00364     };
00365
00366     struct Cm {
00367         char *str;
00368         size_t length;
00369         //operator char *() { return str; }
00370         Cm(): str(0), length(0) {}
00371         Cm(char *astr, size_t asize): str(astr), length(asize) {}
00372     };
00373
00374 private:
00375
00376     Body body;
00377     Languages langs;
00378
00379     const char* v() const;
00380     void dump() const;
00381     #define ASSERT_STRING_INVARIANT(string) \
00382         assert((string).langs.invariant((string).body.length()))
00383
00384 public:
00385
00386     static const String Empty;
00387
00388     explicit String(const char* cstr=0, size_t helper_length=0, bool tainted=false);
00389     explicit String(const C cstr, bool tainted=false);
00390     String(Body abody, Language alang): body(abody), langs(alang) {
00391         ASSERT_STRING_INVARIANT(*this);
00392     }
00393     String(const String& src): body(src.body), langs(src.langs) {
00394         ASSERT_STRING_INVARIANT(*this);
00395     }
00396
00398     operator const Body() const { return body; }
00399
00400     bool is_empty() const { return body.is_empty(); }
00401     size_t length() const { return body.length(); }
00402
00404     Body cstr_to_string_body(Language lang=L_AS_IS,
00405         SQL_Connection* connection=0,
00406         const Request_charsets *charsets=0) const;
00407
00409     const char* cstr(Language lang=L_AS_IS,
00410         SQL_Connection* connection=0,
00411         const Request_charsets *charsets=0) const {
00412         return cstr_to_string_body(lang, connection, charsets).cstr();
00413     }
00415     char *cstrm(Language lang=L_AS_IS,
00416         SQL_Connection* connection=0,
00417         const Request_charsets *charsets=0) const {
00418         return cstr_to_string_body(lang, connection, charsets).cstrm();
00419     }
00421     Cm serialize(size_t prolog_size) const;
00423     bool deserialize(size_t prolog_size, void *buf, size_t buf_size);
00425     String& append_know_length(const char* str, size_t known_length, Language lang);
00427     String& append_help_length(const char* str, size_t helper_length, Language lang);
00428     String& append_strdup(const char* str, size_t helper_length, Language lang);
00429
00430     bool operator == (const char* y) const { return body==Body(y); }
00431     bool operator != (const char* y) const { return body!=Body(y); }
00432
00434     bool starts_with(const char* y) const {
00435         return body.ncmp(0/*x_begin*/, Body(y), 0/*y_begin*/, strlen(y))==0;
00436     }
00438     bool this_starts(const char* x) const {
00439         return Body(x).ncmp(0/*x_begin*/, body, 0/*y_begin*/, length())==0;
00440     }
00441
00442     String& append_to(String& dest, Language lang, bool forced) const;
00443     String& append(const String& src, Language lang, bool forced=false) {
00444         return src.append_to(*this, lang, forced);
00445     }
00446     String& operator << (const String& src) { return append(src, L_PASS_APPENDED); }
00447     String& operator << (const char* src) { return append_help_length(src, 0, L_AS_IS); }
00448     String& operator << (const Body src);
00449
00451     char first_char() const {
00452         return is_empty()?0:body.fetch(0);
00453     }
00454
00455     bool operator < (const String& src) const { return body<src.body; }
00456     bool operator > (const String& src) const { return body>src.body; }
00457     bool operator <= (const String& src) const { return body<=src.body; }
00458     bool operator >= (const String& src) const { return body>=src.body; }
00459     bool operator != (const String& src) const { return body!=src.body; }
00460     bool operator == (const String& src) const { return body==src.body; }
00461
00463     String& mid(size_t substr_begin, size_t substr_end) const;
00464
00470     size_t pos(const Body substr,
00471         size_t this_offset=0, Language lang=L_UNSPECIFIED) const;
00473     size_t pos(const String& substr,
00474         size_t this_offset=0, Language lang=L_UNSPECIFIED) const;
00475     size_t pos(char c,
00476         size_t this_offset=0) const {
00477         return body.pos(c, this_offset);
00478     }
00479
00480     void split(ArrayString& result,
00481         size_t& pos_after,
00482         const char* delim,
00483         Language lang=L_UNSPECIFIED, int limit=-1) const;
00484     void split(ArrayString& result,
00485         size_t& pos_after,
00486         const String& delim,
00487         Language lang=L_UNSPECIFIED, int limit=-1) const;
00488
00489     typedef void (*Row_action)(Table& table, ArrayString* row,
00490         int prestart, int prefinish,
00491         int poststart, int postfinish,
00492         void *info);
00500     Table* match(Charset& source_charset,
00501         const String& regexp,
00502         const String* options,
00503         Row_action row_action, void *info,
00504         bool& just_matched) const;
00505     enum Change_case_kind {
00506         CC_UPPER,
00507         CC_LOWER
00508     };
00509     String& change_case(Charset& source_charset,
00510         Change_case_kind kind) const;
00511     const String& replace(const Dictionary& dict) const;
00512     const String& trim(Trim_kind kind=TRIM_BOTH, const char* chars=0) const;
00513     double as_double() const { return pa_atod(cstr(), this); }
00514     int as_int() const { return pa_atoi(cstr(), this); }
00515
00516 private: //disabled
00517
00518     String& operator = (const String&) { return *this; }
00519
00520 };
00521
00522 template<>
00523 inline size_t get_length<String::Body>(String::Body body) {
00524     return body.length();
00525 }
00526
00528 inline uint hash_code(const String::Body self) {
00529     return self.hash_code();
00530 }
00531
00532
00534 inline String& String::operator << (const String::Body src) {
00535     langs.append(body, L_AS_IS, src.length());
00536     body<<src;
00537     return *this;
00538 }
00539
00540
00541 #endif


pa_stylesheet_connection.C File Reference

Parser: Stylesheet connection implementation. More...

Include dependency graph for pa_stylesheet_connection.C:

Include dependency graph

Go to the source code of this file.

Detailed Description

Parser: Stylesheet connection implementation.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_stylesheet_connection.C.


pa_stylesheet_connection.C Source File

pa_stylesheet_connection.C

Go to the documentation of this file.
00001
00008 #include "pa_config_includes.h"
00009 #ifdef XML
00010 static const char * const IDENT_STYLESHEET_CONNECTION_C="$Date: 2005/12/16 10:15:12 $";
00011
00012 #include "pa_stylesheet_connection.h"
00013 #include "pa_xml_exception.h"
00014
00015 void Stylesheet_connection::load(time_t new_disk_time) {
00016     xsltStylesheet *nstylesheet;
00017     {
00018         pa_xmlStartMonitoringDependencies();
00019         {
00020             int saved=xmlDoValidityCheckingDefaultValue;//
00021             xmlDoValidityCheckingDefaultValue=0;//
00022             nstylesheet=xsltParseStylesheetFile(BAD_CAST ffile_spec.cstr());
00023             xmlDoValidityCheckingDefaultValue = saved;//
00024         }
00025         dependencies=pa_xmlGetDependencies();
00026     }
00027     if(xmlHaveGenericErrors())
00028         throw XmlException(new String(ffile_spec, String::L_TAINTED));
00029     if(!nstylesheet)
00030         throw Exception("file.missing",
00031             new String(ffile_spec, String::L_TAINTED),
00032             "stylesheet failed to load");
00033
00034     xsltFreeStylesheet(fstylesheet);
00035     fstylesheet=nstylesheet;
00036     prev_disk_time=new_disk_time;
00037 }
00038
00039 static void update_max_mtime(const String::Body stat_file_spec_cstr, bool /*value*/, time_t* max) {
00040     size_t size;
00041     time_t atime, mtime, ctime;
00042     file_stat(*new String(stat_file_spec_cstr, String::L_AS_IS),
00043         size,
00044         atime, mtime, ctime,
00045         true/*exception on error*/);
00046
00047     if(mtime>*max)
00048         *max=mtime;
00049 }
00050
00051 time_t Stylesheet_connection::get_disk_time() {
00052     assert(dependencies);
00053
00054     time_t result=0;
00055     dependencies->for_each(update_max_mtime, &result);
00056     return result;
00057 }
00058
00059 #endif


pa_stylesheet_connection.h File Reference

Parser: Stylesheet connection decl. More...

Include dependency graph for pa_stylesheet_connection.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Stylesheet_connection
Connection with stylesheet: remembers time and can figure out that it needs recompilation. More...

class | Stylesheet_connection_ptr
Auto-object used to track Stylesheet_connection usage. More...

Variables

const char *const | IDENT_STYLESHEET_CONNECTION_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: Stylesheet connection decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_stylesheet_connection.h.

Variable Documentation

const char* const IDENT_STYLESHEET_CONNECTION_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_stylesheet_connection.h.


pa_stylesheet_connection.h Source File

pa_stylesheet_connection.h

Go to the documentation of this file.
00001
00008 #ifndef PA_STYLESHEET_CONNECTION_H
00009 #define PA_STYLESHEET_CONNECTION_H
00010
00011 static const char * const IDENT_STYLESHEET_CONNECTION_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 #include "libxslt/xslt.h"
00014 #include "libxslt/xsltInternals.h"
00015
00016
00017 #include "pa_xml_exception.h"
00018 #include "pa_common.h"
00019 #include "pa_globals.h"
00020 #include "pa_xml_io.h"
00021
00022 // defines
00023
00027 class Stylesheet_connection: public PA_Object {
00028
00029     friend class Stylesheet_connection_ptr;
00030
00031 private:
00032
00033     String::Body ffile_spec;
00034     xsltStylesheet *fstylesheet;
00035     HashStringBool* dependencies;
00036     time_t time_used;
00037     time_t prev_disk_time;
00038
00039 public:
00040
00041     Stylesheet_connection(String::Body afile_spec):
00042         ffile_spec(afile_spec),
00043         fstylesheet(0),
00044         dependencies(0),
00045         time_used(0),
00046         prev_disk_time(0),
00047         used(0)
00048     {}
00049
00050     String::Body file_spec() { return ffile_spec; }
00051
00052     bool uncachable() {
00053         return !dependencies/*means they were external*/;
00054     }
00055
00056     bool expired(time_t older_dies) {
00057         return uncachable() || !used && time_used<older_dies;
00058     }
00059     time_t get_time_used() { return time_used; }
00060
00061     void disconnect() {
00062         xsltFreeStylesheet(fstylesheet);  fstylesheet=0;
00063     }
00064
00065     bool connected() { return fstylesheet!=0; }
00066
00067     xsltStylesheet *stylesheet() {
00068         time_t new_disk_time=0;
00069         if(uncachable() || (new_disk_time=get_new_disk_time()))
00070             load(new_disk_time);
00071         return fstylesheet;
00072     }
00073
00074 private:
00075
00077     void close();
00078
00079 private:
00080
00081     time_t get_new_disk_time() {
00082         time_t now_disk_time=get_disk_time();
00083         return now_disk_time>prev_disk_time?now_disk_time:0;
00084     }
00085
00086     void load(time_t new_disk_time);
00087     time_t get_disk_time();
00088
00089 private: // connection usage methods
00090
00091     int used;
00092     void use() {
00093         time_used=time(0); // they started to use at this time
00094         used++;
00095     }
00096     void unuse() {
00097         used--;
00098         if(!used)
00099             close();
00100     }
00101
00102 };
00103
00105 class Stylesheet_connection_ptr {
00106     Stylesheet_connection *fconnection;
00107 public:
00108     explicit Stylesheet_connection_ptr(Stylesheet_connection *aconnection) :
00109         fconnection(aconnection) {
00110         fconnection->use();
00111     }
00112     ~Stylesheet_connection_ptr() {
00113         fconnection->unuse();
00114     }
00115     Stylesheet_connection* operator->() {
00116         return fconnection;
00117     }
00118 /*  Stylesheet_connection& operator*() {
00119         return *fconnection;
00120     }*/
00121
00122     // copying
00123     Stylesheet_connection_ptr(const Stylesheet_connection_ptr& src) : fconnection(src.fconnection) {
00124         fconnection->use();
00125     }
00126     Stylesheet_connection_ptr& operator =(const Stylesheet_connection_ptr& src) {
00127         // may do without this=src check
00128         fconnection->unuse();
00129         fconnection=src.fconnection;
00130         fconnection->use();
00131
00132         return *this;
00133     }
00134 };
00135
00136 #endif


pa_stylesheet_manager.C File Reference

Parser: sql driver manager implementation. More...

Include dependency graph for pa_stylesheet_manager.C:

Include dependency graph

Go to the source code of this file.

Detailed Description

Parser: sql driver manager implementation.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_stylesheet_manager.C.


pa_stylesheet_manager.C Source File

pa_stylesheet_manager.C

Go to the documentation of this file.
00001
00007 #include "pa_config_includes.h"
00008 #ifdef XML
00009
00010 static const char * const IDENT_STYLESHEET_MANAGER_C="$Date: 2005/08/09 08:14:52 $";
00011
00012 #include "pa_stylesheet_manager.h"
00013 #include "pa_exception.h"
00014 #include "pa_common.h"
00015 #include "pa_threads.h"
00016 #include "pa_stack.h"
00017 #include "pa_vhash.h"
00018 #include "pa_vtable.h"
00019
00020 // globals
00021
00022 Stylesheet_manager* stylesheet_manager=0;
00023
00024 // consts
00025
00026 const time_t EXPIRE_UNUSED_CONNECTION_SECONDS=5*60;
00027 const time_t CHECK_EXPIRED_CONNECTION_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2;
00028
00029 // helpers
00030
00031 static void expire_connection(Stylesheet_connection& connection, time_t older_dies) {
00032     if(connection.connected() && connection.expired(older_dies))
00033         connection.disconnect();
00034 }
00035 static void expire_connections(
00036                    Stylesheet_manager::connection_cache_type::key_type /*key*/,
00037                    Stylesheet_manager::connection_cache_type::value_type stack,
00038                    time_t older_dies) {
00039     for(size_t i=0; i<stack->top_index(); i++)
00040         expire_connection(*stack->get(i), older_dies);
00041 }
00042
00043 // Stylesheet_connection methods
00044
00045 void Stylesheet_connection::close() {
00046     stylesheet_manager->close_connection(ffile_spec, *this);
00047 }
00048
00049 // Stylesheet_manager methods
00050
00051 Stylesheet_manager::Stylesheet_manager(): prev_expiration_pass_time(0) {
00052 }
00053
00054 Stylesheet_manager::~Stylesheet_manager() {
00055     connection_cache.for_each(expire_connections, time(0)+(time_t)10/*=in future=expire all*/);
00056 }
00057
00058 Stylesheet_connection_ptr Stylesheet_manager::get_connection(String::Body file_spec) {
00059     Stylesheet_connection* result=get_connection_from_cache(file_spec);
00060     if(!result)
00061         result=new Stylesheet_connection(file_spec);
00062     return Stylesheet_connection_ptr(result);
00063 }
00064
00065 void Stylesheet_manager::close_connection(String::Body file_spec, Stylesheet_connection& connection) {
00066     put_connection_to_cache(file_spec, connection);
00067 }
00068
00069 // stylesheet cache
00071 Stylesheet_connection* Stylesheet_manager::get_connection_from_cache(String::Body file_spec) {
00072     SYNCHRONIZED;
00073
00074     if(connection_cache_type::value_type connections=connection_cache.get(file_spec))
00075         while(!connections->is_empty()) { // there are cached stylesheets to that 'file_spec'
00076             Stylesheet_connection* result=connections->pop();
00077             if(result->connected()) // not expired?
00078                 return result;
00079         }
00080
00081     return 0;
00082 }
00083
00084 void Stylesheet_manager::put_connection_to_cache(String::Body file_spec,
00085                          Stylesheet_connection& connection) {
00086     SYNCHRONIZED;
00087
00088     connection_cache_type::value_type connections=connection_cache.get(file_spec);
00089     if(!connections) { // there are no cached stylesheets to that 'file_spec' yet?
00090         connections=new connection_cache_value_type;
00091         connection_cache.put(file_spec, connections);
00092     }
00093     connections->push(&connection);
00094 }
00095
00096 void Stylesheet_manager::maybe_expire_cache() {
00097     time_t now=time(0);
00098
00099     if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTION_SECONDS) {
00100         connection_cache.for_each(expire_connections, now-EXPIRE_UNUSED_CONNECTION_SECONDS);
00101
00102         prev_expiration_pass_time=now;
00103     }
00104 }
00105
00106 static void add_connection_to_status_cache_table(Stylesheet_connection& connection, Table* table) {
00107     if(connection.connected()) {
00108         ArrayString& row=*new ArrayString;
00109
00110         // file
00111         row+=new String(connection.file_spec(), String::L_AS_IS);
00112         // time
00113         time_t time_used=connection.get_time_used();
00114         row+=new String(pa_strdup(ctime(&time_used)));
00115
00116         *table+=&row;
00117     }
00118 }
00119 static void add_connections_to_status_cache_table(
00120     Stylesheet_manager::connection_cache_type::key_type /*key*/,
00121     Stylesheet_manager::connection_cache_type::value_type stack, Table* table)
00122 {
00123     for(Array_iterator<Stylesheet_connection*> i(*stack); i.has_next(); )
00124         add_connection_to_status_cache_table(*i.next(), table);
00125 }
00126
00127 Value* Stylesheet_manager::get_status() {
00128     VHash* result=new VHash;
00129     // cache
00130     {
00131         ArrayString& columns=*new ArrayString;
00132         columns+=new String("file");
00133         columns+=new String("time");
00134         Table& table=*new Table(&columns, connection_cache.count());
00135
00136         connection_cache.for_each(add_connections_to_status_cache_table, &table);
00137
00138         result->get_hash()->put(*new String("cache"), new VTable(&table));
00139     }
00140     return result;
00141 }
00142
00143 #endif


pa_stylesheet_manager.h File Reference

Parser: Stylesheet manager decl. More...

Include dependency graph for pa_stylesheet_manager.h:

Include dependency graph

Go to the source code of this file.

Compounds

class | Stylesheet_manager
XSLT stylesheet driver manager maintains stylesheet cache expiring unused stylesheets. More...

Variables

const char *const | IDENT_STYLESHEET_MANAGER_H = "$Date: 2005/08/09 08:14:50 $"
Stylesheet_manager * stylesheet_manager
global. More...

Detailed Description

Parser: Stylesheet manager decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

global sql driver manager, must be thread-safe

Definition in file pa_stylesheet_manager.h.

Variable Documentation

const char* const IDENT_STYLESHEET_MANAGER_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 13 of file pa_stylesheet_manager.h.

Stylesheet_manager* stylesheet_manager

global.

Definition at line 64 of file pa_stylesheet_manager.h.

Referenced by Cache_managers::Cache_managers().


pa_stylesheet_manager.h Source File

pa_stylesheet_manager.h

Go to the documentation of this file.
00001
00010 #ifndef PA_STYLESHEET_MANAGER_H
00011 #define PA_STYLESHEET_MANAGER_H
00012
00013 static const char * const IDENT_STYLESHEET_MANAGER_H="$Date: 2005/08/09 08:14:50 $";
00014
00015
00016 #include "pa_hash.h"
00017 #include "pa_table.h"
00018 #include "pa_cache_managers.h"
00019 #include "pa_stack.h"
00020 #include "pa_stylesheet_connection.h"
00021
00026 class Stylesheet_manager: public Cache_manager {
00027     friend class Stylesheet_connection;
00028 public:
00029
00030     Stylesheet_manager();
00031     override ~Stylesheet_manager();
00036     Stylesheet_connection_ptr get_connection(String::Body file_spec);
00037
00038 private: // cache
00039
00040     Stylesheet_connection* get_connection_from_cache(String::Body file_spec);
00041     void put_connection_to_cache(String::Body file_spec, Stylesheet_connection& connection);
00042 private:
00043     time_t prev_expiration_pass_time;
00044
00045 private: // for stylesheet
00046
00048     void close_connection(String::Body file_spec, Stylesheet_connection& connection);
00049
00050 public:
00051     typedef Stack<Stylesheet_connection*> connection_cache_value_type;
00052     typedef Hash<const String::Body, connection_cache_value_type*> connection_cache_type;
00053 private:
00054     connection_cache_type connection_cache;
00055
00056 public: // Cache_manager
00057
00058     override Value* get_status();
00059     override void maybe_expire_cache();
00060
00061 };
00062
00064 extern Stylesheet_manager* stylesheet_manager;
00065
00066 #endif


pa_table.C File Reference

Parser: table class. More...

Include dependency graph for pa_table.C:

Include dependency graph

Go to the source code of this file.

Functions

bool | locate_int_string (Table &self, Locate_int_string_info *info)

Variables

const char *const | IDENT_TABLE_C = "$Date: 2005/08/09 08:14:52 $"

Detailed Description

Parser: table class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_table.C.

Function Documentation

bool locate_int_string | ( | Table & | self,
 |  | Locate_int_string_info * | info
 | ) |

Definition at line 67 of file pa_table.C.

References Table::item().

Referenced by Table::locate().

Variable Documentation

const char* const IDENT_TABLE_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 8 of file pa_table.C.


pa_table.C Source File

pa_table.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_TABLE_C="$Date: 2005/08/09 08:14:52 $";
00009
00010 #include "pa_table.h"
00011
00012 #include "pa_exception.h"
00013
00014 Table::Table(columns_type acolumns, size_t initial_rows):
00015     Array<element_type>(initial_rows),
00016
00017     fcurrent(0),
00018     fcolumns(acolumns),
00019     name2number(new name2number_hash_class) {
00020
00021     if(fcolumns) {
00022         size_t number=1;
00023         for(Array_iterator<const String*> i(*fcolumns); i.has_next(); ) {
00024             const String& name=*i.next();
00025             name2number->put(name, number++);
00026         }
00027     }
00028 }
00029
00030 Table::Table(const Table& src, Action_options& options) :
00031     Array<element_type>(options.limit==ARRAY_OPTION_LIMIT_ALL?0:options.limit/*may be more than needed, no harm done*/),
00032
00033     fcurrent(0),
00034     fcolumns(src.fcolumns),
00035     name2number(src.name2number) {
00036
00037     append(src, options.offset, options.limit, options.reverse);
00038 }
00039
00040 int Table::column_name2index(const String& column_name, bool bark) const {
00041     if(fcolumns) {// named
00042         int result=name2number->get(column_name)-1; // -1 = column not found
00043         if(bark && result<0)
00044             throw Exception("parser.runtime",
00045                 &column_name,
00046                 "column not found");
00047         return result;
00048     } else // nameless
00049         return column_name.as_int();
00050 }
00051
00052 const String* Table::item(size_t column) {
00053     if(valid(fcurrent)) {
00054         element_type row=get(fcurrent);
00055         if(column<row->count()) // proper index?
00056             return row->get(column);
00057     }
00058     return 0; // it's OK we don't have row|column, just return nothing
00059 }
00060
00061 #ifndef DOXYGEN
00062 struct Locate_int_string_info {
00063     int column;
00064     const String* value;
00065 };
00066 #endif
00067 bool locate_int_string(Table& self, Locate_int_string_info* info) {
00068     const String *item_value=self.item(info->column);
00069     return item_value && *item_value==*info->value;
00070 }
00071
00072 bool Table::locate(int column, const String& value,
00073            Table::Action_options& options) {
00074     Locate_int_string_info info={column, &value};
00075     return table_first_that(locate_int_string, &info, options);
00076 }
00077
00078 bool Table::locate(const String& column, const String& value,
00079            Table::Action_options& options) {
00080     return locate(column_name2index(column, true), value, options);
00081 }
00082
00083 void Table::offset(bool absolute, int offset) {
00084     if(size_t lcount=count())
00085         fcurrent=((absolute?0:fcurrent)+offset+lcount)%lcount;
00086 }


pa_table.h File Reference

Parser: table class decl. More...

Include dependency graph for pa_table.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Table
VTable backend. More...

Variables

const char *const | IDENT_TABLE_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: table class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_table.h.

Variable Documentation

const char* const IDENT_TABLE_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_table.h.


pa_table.h Source File

pa_table.h

Go to the documentation of this file.
00001
00008 #ifndef PA_TABLE_H
00009 #define PA_TABLE_H
00010
00011 static const char * const IDENT_TABLE_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 #include "pa_types.h"
00014 #include "pa_hash.h"
00015 #include "pa_string.h"
00016
00031 class Table: public Array<ArrayString*> {
00032 public:
00033     typedef ArrayString* columns_type;
00034
00035     Table(
00036         columns_type acolumns,
00037         size_t initial_rows=3);
00038     Table(const Table& src, Action_options& options);
00039
00041     columns_type columns() { return fcolumns; }
00042
00044     void set_current(size_t acurrent) {
00045         assert(acurrent==0 || acurrent<count());
00046
00047         fcurrent=acurrent;
00048     }
00050     size_t current() const { return fcurrent; }
00051     void offset(bool absolute, int offset);
00052
00056     int column_name2index(const String& column, bool bark) const;
00057
00059     const String* item(size_t column);
00060
00062     const String* item(const String& column) {
00063         int index=column_name2index(column, false);
00064         return index>=0?item(index):0;
00065     }
00066
00068     void save(bool nameless_save, const String& file_spec);
00069
00070     template<typename I>
00071     void table_for_each(void (*func)(Table& self, I* info), I* info, Action_options& o) {
00072         if(!o.adjust(count()))
00073             return;
00074
00075         size_t saved_current=current();
00076         size_t row=o.offset;
00077         if(o.reverse) { // reverse
00078             for(size_t to=row-o.limit; row>=to; --row) {
00079                 set_current(row);
00080                 func(*this, info);
00081             }
00082         } else { // forward
00083             for(size_t to=row+o.limit; row<to; row++) {
00084                 set_current(row);
00085                 func(*this, info);
00086             }
00087         }
00088         set_current(saved_current);
00089     }
00090
00091     template<typename I>
00092     bool table_first_that(bool (*func)(Table& self, I info), I info, Action_options& o) {
00093         if(!o.adjust(count()))
00094             return false;
00095
00096         size_t saved_current=current();
00097         size_t row=o.offset;
00098         if(o.reverse) { // reverse
00099             for(size_t to=row-o.limit; row>=to; --row) {
00100                 set_current(row);
00101
00102                 if(func(*this, info))
00103                     return true;
00104             }
00105         } else { // forward
00106             for(size_t to=row+o.limit; row<to; row++) {
00107                 set_current(row);
00108
00109                 if(func(*this, info))
00110                     return true;
00111             }
00112         }
00113         set_current(saved_current);
00114
00115         return false;
00116     }
00117
00118
00119     bool locate(int column, const String& value, Action_options& options);
00120     bool locate(const String& column, const String& value, Action_options& options);
00121
00122 private:
00123
00125     size_t fcurrent;
00126
00128     columns_type fcolumns;
00129
00131     typedef Hash<const String::Body, int> name2number_hash_class;
00132     name2number_hash_class* name2number;
00133
00135     bool valid(size_t index) const { return index<count(); }
00136
00137 };
00138
00139 #endif


apache13core/pa_threads.C File Reference

pa_threads.C File Reference

Parser: Mutex realization class. More...

Include dependency graph for apache13core/pa_threads.C:

Include dependency graph

Go to the source code of this file.

Functions

pa_thread_t pa_get_thread_id ()

Variables

const char *const | IDENT_THREADS_C = "$Date: 2005/08/09 08:14:53 $"
Mutex global_mutex
const bool | parser_multithreaded = true

Detailed Description

Parser: Mutex realization class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file apache13core/pa_threads.C.

Function Documentation

pa_thread_t pa_get_thread_id ( )

Definition at line 20 of file apache13core/pa_threads.C.

References pa_thread_t.

Variable Documentation

const char* const IDENT_THREADS_C = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 8 of file apache13core/pa_threads.C.

Mutex global_mutex

Definition at line 12 of file apache13core/pa_threads.C.

const bool parser_multithreaded = true

Definition at line 18 of file apache13core/pa_threads.C.


pa_threads.C Source File

pa_threads.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_THREADS_C="$Date: 2005/08/09 08:14:53 $";
00009
00010 #include "pa_threads.h"
00011
00012 Mutex global_mutex;
00013
00014 #ifdef WIN32
00015
00016 #include <windows.h>
00017
00018 const bool parser_multithreaded=true;
00019
00020 pa_thread_t pa_get_thread_id() {
00021     return GetCurrentThreadId();
00022 }
00023
00024 Mutex::Mutex() :
00025     handle(reinterpret_cast<uint>(CreateMutex(NULL, FALSE, 0))) {
00026 }
00027
00028 Mutex::~Mutex() {
00029     CloseHandle(reinterpret_cast<HANDLE>(handle));
00030 }
00031
00032 void Mutex::acquire() {
00033     WaitForSingleObject(reinterpret_cast<HANDLE>(handle), INFINITE);
00034 }
00035
00036 void Mutex::release() {
00037     ReleaseMutex(reinterpret_cast<HANDLE>(handle));
00038 }
00039
00040 #else
00041
00042 const bool parser_multithreaded=false;
00043
00044 pa_thread_t pa_get_thread_id() { return 1; }
00045
00046 Mutex::Mutex() {}
00047 Mutex::~Mutex() {}
00048 void Mutex::acquire() {}
00049 void Mutex::release() {}
00050
00051 #endif


cgi/pa_threads.C File Reference

pa_threads.C File Reference

Parser: zero Mutex realization class. More...

Include dependency graph for cgi/pa_threads.C:

Include dependency graph

Go to the source code of this file.

Functions

pa_thread_t pa_get_thread_id ()

Variables

const char *const | IDENT_THREADS_C = "$Date: 2005/08/09 08:14:53 $"
const bool | parser_multithreaded = false
Mutex global_mutex

Detailed Description

Parser: zero Mutex realization class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file cgi/pa_threads.C.

Function Documentation

pa_thread_t pa_get_thread_id ( )

Definition at line 14 of file cgi/pa_threads.C.

References pa_thread_t.

Variable Documentation

const char* const IDENT_THREADS_C = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 8 of file cgi/pa_threads.C.

const bool parser_multithreaded = false

Definition at line 12 of file cgi/pa_threads.C.

Mutex global_mutex

Definition at line 16 of file cgi/pa_threads.C.


pa_threads.C Source File

pa_threads.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_THREADS_C="$Date: 2005/08/09 08:14:53 $";
00009
00010 #include "pa_threads.h"
00011
00012 const bool parser_multithreaded=false;
00013
00014 pa_thread_t pa_get_thread_id() { return 1; }
00015
00016 Mutex global_mutex;
00017
00018 Mutex::Mutex() {
00019 }
00020
00021 Mutex::~Mutex() {
00022 }
00023
00024 void Mutex::acquire() {
00025 }
00026
00027 void Mutex::release() {
00028 }


isapi/pa_threads.C File Reference

pa_threads.C File Reference

Parser: zero Mutex realization class. More...

Include dependency graph for isapi/pa_threads.C:

Include dependency graph

Go to the source code of this file.

Functions

pa_thread_t pa_get_thread_id ()
get caller thread ID. More...

Variables

const char *const | IDENT_THREADS_C = "$Date: 2005/08/09 08:14:53 $"
const bool | parser_multithreaded = true
Mutex global_mutex

Detailed Description

Parser: zero Mutex realization class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file isapi/pa_threads.C.

Function Documentation

pa_thread_t pa_get_thread_id ( )

get caller thread ID.

Definition at line 16 of file isapi/pa_threads.C.

References pa_thread_t.

Referenced by VStatus::get_element(), pa_register_thread_request(), and pa_thread_request().

Variable Documentation

const char* const IDENT_THREADS_C = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 8 of file isapi/pa_threads.C.

const bool parser_multithreaded = true

Definition at line 14 of file isapi/pa_threads.C.

Mutex global_mutex

Definition at line 20 of file isapi/pa_threads.C.


pa_threads.C Source File

pa_threads.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_THREADS_C="$Date: 2005/08/09 08:14:53 $";
00009
00010 #include "pa_threads.h"
00011
00012 #include <windows.h>
00013
00014 const bool parser_multithreaded=true;
00015
00016 pa_thread_t pa_get_thread_id() {
00017     return GetCurrentThreadId();
00018 }
00019
00020 Mutex global_mutex;
00021
00022 Mutex::Mutex() :
00023     handle(reinterpret_cast<uint>(CreateMutex(NULL, FALSE, 0))) {
00024 }
00025
00026 Mutex::~Mutex() {
00027     CloseHandle(reinterpret_cast<HANDLE>(handle));
00028 }
00029
00030 void Mutex::acquire() {
00031     WaitForSingleObject(reinterpret_cast<HANDLE>(handle), INFINITE);
00032 }
00033
00034 void Mutex::release() {
00035     ReleaseMutex(reinterpret_cast<HANDLE>(handle));
00036 }


pa_threads.h File Reference

Parser: mutex & helpers decls. More...

Include dependency graph for pa_threads.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Mutex
simple semaphore object. More...

class | AutoSYNCHRONIZED
Helper to ensure paired Mutex::acquire() and Mutex::release(). More...

Defines

#define | SYNCHRONIZED AutoSYNCHRONIZED autoSYNCHRONIZED
put it to first line of a function to ensure thread safety. More...

Typedefs

typedef unsigned int | pa_thread_t
thread ID type. More...

Functions

pa_thread_t pa_get_thread_id ()
get caller thread ID. More...

Variables

const char *const | IDENT_THREADS_H = "$Date: 2005/08/09 08:14:50 $"
const bool | parser_multithreaded
Mutex global_mutex

Detailed Description

Parser: mutex & helpers decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_threads.h.

Define Documentation

#define SYNCHRONIZED AutoSYNCHRONIZED autoSYNCHRONIZED

put it to first line of a function to ensure thread safety.

        void someclass::somefunc(...) { SYNCHRONIZED;
            ...
        }

WARNING: don't use THROW or PTHROW with such thread safety mechanizm - longjmp would leave global_mutex acquired, which is wrong!

Definition at line 62 of file pa_threads.h.

Referenced by Random_provider::acquire(), SQL_Driver_manager::get_connection_from_cache(), SQL_Driver_manager::get_driver_from_cache(), SQL_Driver_manager::put_connection_to_cache(), and SQL_Driver_manager::put_driver_to_cache().

Typedef Documentation

typedef unsigned int pa_thread_t

thread ID type.

Definition at line 17 of file pa_threads.h.

Referenced by pa_get_thread_id().

Function Documentation

pa_thread_t pa_get_thread_id ( )

get caller thread ID.

Definition at line 20 of file apache13core/pa_threads.C.

References pa_thread_t.

Referenced by VStatus::get_element(), pa_register_thread_request(), and pa_thread_request().

Variable Documentation

const char* const IDENT_THREADS_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_threads.h.

const bool parser_multithreaded

Definition at line 37 of file pa_threads.h.

Mutex global_mutex

Definition at line 38 of file pa_threads.h.


pa_threads.h Source File

pa_threads.h

Go to the documentation of this file.
00001
00008 #ifndef PA_THREADS_H
00009 #define PA_THREADS_H
00010
00011 static const char * const IDENT_THREADS_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 #include "pa_config_includes.h"
00014 #include "pa_types.h"
00015
00017 typedef unsigned int pa_thread_t;
00018
00020 pa_thread_t pa_get_thread_id();
00021
00022 class AutoSYNCHRONIZED;
00023
00025 class Mutex {
00026     friend class AutoSYNCHRONIZED;
00027 private:
00028     uint handle;
00029 public:
00030     Mutex();
00031     ~Mutex();
00032 private: // for AutoSYNCHRONIZED
00033     void acquire();
00034     void release();
00035 };
00036
00037 extern const bool parser_multithreaded;
00038 extern Mutex global_mutex;
00039
00045 class AutoSYNCHRONIZED {
00046 public:
00047     AutoSYNCHRONIZED() { global_mutex.acquire(); }
00048     ~AutoSYNCHRONIZED() { global_mutex.release(); }
00049 };
00050
00062 #define SYNCHRONIZED AutoSYNCHRONIZED autoSYNCHRONIZED
00063
00064 #endif


pa_types.h File Reference

Parser: generally used types & constants decls. More...

Include dependency graph for pa_types.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | MAX_STRING 0x400
for rare cases of undefined length using this-sized strings. More...

#define | MAX_NUMBER 40
for snprintf(buf, MAX_NUMBER, "%.2f"). More...

#define | max_integral(type) ((1<<sizeof(type)*8)-1)
max value of integral type. More...

Typedefs

typedef unsigned char | uchar
typedef unsigned short | ushort
typedef unsigned int | uint
typedef unsigned long | ulong

Variables

const char *const | IDENT_TYPES_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: generally used types & constants decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_types.h.

Define Documentation

#define MAX_STRING 0x400

for rare cases of undefined length using this-sized strings.

Definition at line 16 of file pa_types.h.

Referenced by _crypt(), atoi(), buildCommand(), CreateHiddenConsoleProcess(), date_attribute(), die_or_abort(), Exception::Exception(), full_file_spec(), VConsole::get_element(), Request::get_exception_cstr(), VDate::get_localtime(), HttpExtensionProc(), log(), SAPI::log(), main(), pa_exec(), pa_internal_file_read_http(), pa_parser_handler(), pa_socks_strerr(), pa_uuencode(), read_pipe(), real_parser_handler(), and String::v().

#define MAX_NUMBER 40

for snprintf(buf, MAX_NUMBER, "%.2f").

Definition at line 18 of file pa_types.h.

Referenced by _exec_cgi(), _save(), die_or_abort(), String::Body::Format(), format(), VInt::get_string(), VDouble::get_string(), main(), VMail::message_hash_to_string(), output_sole_piece(), and pa_parser_handler().

#define max_integral ( type ) ((1<<sizeof(type)*8)-1)

max value of integral type.

Definition at line 35 of file pa_types.h.

Typedef Documentation

typedef unsigned char uchar

Definition at line 22 of file pa_types.h.

Referenced by cstr_to_string_body_block(), String::deserialize(), endian_to_uint(), endian_to_ushort(), measure_jpeg(), parse_IFD_entry_formatted_one_value(), parse_IFD_entry_formatted_value(), parse_IFD_entry_value(), unescape_chars(), x_endian_to_uint(), and x_endian_to_ushort().

typedef unsigned short ushort

Definition at line 25 of file pa_types.h.

Referenced by _measure(), endian_to_ushort(), measure(), measure_gif(), measure_jpeg(), measure_png(), parse_IFD(), parse_IFD_entry(), parse_IFD_entry_formatted_one_value(), parse_IFD_entry_formatted_value(), parse_IFD_entry_value(), and x_endian_to_ushort().

typedef unsigned int uint

Definition at line 28 of file pa_types.h.

Referenced by _exec_cgi(), _process(), _random(), _sql(), Request::compile(), CORD_batched_iter_fn_generic_hash_code(), Operation::Origin::create(), endian_to_uint(), Hash< const String::Body, void * >::expand(), format(), generic_hash_code(), Hash< const String::Body, void * >::get(), String::Body::hash_code(), hash_code(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), measure_jpeg(), Mutex::Mutex(), Operation::Operation(), Hash< K, V >::Pair::Pair(), Parse_control::Parse_control(), parse_exif(), parse_IFD_entry_formatted_one_value(), parse_IFD_entry_formatted_value(), parse_IFD_entry_value(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Hash< const String::Body, void * >::put_replaced(), SAPI::read_post(), Request::register_file(), Hash< const String::Body, void * >::remove(), Hash< const String::Body, void * >::replace_maybe_append(), sql_result_string(), to_wchar_code(), unescape_chars(), Request::use_buf(), String::v(), VL(), x_endian_to_uint(), and xlatOneTo().

typedef unsigned long ulong

Definition at line 31 of file pa_types.h.

Referenced by _sql(), set_addr(), and sql_result_string().

Variable Documentation

const char* const IDENT_TYPES_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_types.h.


pa_types.h Source File

pa_types.h

Go to the documentation of this file.
00001
00008 #ifndef PA_TYPES_H
00009 #define PA_TYPES_H
00010
00011 static const char * const IDENT_TYPES_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 #include "pa_config_includes.h"
00014
00016 #define MAX_STRING 0x400
00017
00018 #define MAX_NUMBER 40
00019
00020 //{@ handy types
00021 #undef uchar
00022 typedef unsigned char uchar;
00023
00024 #undef ushort
00025 typedef unsigned short ushort;
00026
00027 #undef uint
00028 typedef unsigned int uint;
00029
00030 #undef ulong
00031 typedef unsigned long ulong;
00032 //}@
00033
00035 #define max_integral(type) ((1<<sizeof(type)*8)-1)
00036
00037 #endif


pa_uue.C File Reference

Parser: uuencoding impl. More...

Include dependency graph for pa_uue.C:

Include dependency graph

Go to the source code of this file.

Functions

void | pa_uuencode (String &result, const String &file_name, const VFile &vfile)

Variables

const char *const | IDENT_UUE_C = "$Date: 2005/08/09 08:14:52 $"
unsigned char | uue_table [64]

Detailed Description

Parser: uuencoding impl.

Copyright(c) 2000,2001-2005 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Todo:
setrlimit

Definition in file pa_uue.C.

Function Documentation

void pa_uuencode | ( | String & | result,
 |  | const String & | file_name,
 |  | const VFile & | vfile
 | ) |

Definition at line 26 of file pa_uue.C.

References MAX_STRING, result, uue_table, VFile::value_ptr(), and VFile::value_size().

Referenced by file_value_to_string().

Variable Documentation

const char* const IDENT_UUE_C = "$Date: 2005/08/09 08:14:52 $" [static]

Definition at line 10 of file pa_uue.C.

unsigned char uue_table[64] [static]

Initial value:

 {
  '`', '!', '"', '#', '$', '%', '&', '\'',
  '(', ')', '*', '+', ',', '-', '.', '/',
  '0', '1', '2', '3', '4', '5', '6', '7',
  '8', '9', ':', ';', '<', '=', '>', '?',
  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  'X', 'Y', 'Z', '[', '\\',']', '^', '_'
}

Definition at line 16 of file pa_uue.C.

Referenced by pa_uuencode().


pa_uue.C Source File

pa_uue.C

Go to the documentation of this file.
00001
00010 static const char * const IDENT_UUE_C="$Date: 2005/08/09 08:14:52 $";
00011
00012 #include "pa_config_includes.h"
00013
00014 #include "pa_uue.h"
00015
00016 static unsigned char uue_table[64] = {
00017   '`', '!', '"', '#', '$', '%', '&', '\'',
00018   '(', ')', '*', '+', ',', '-', '.', '/',
00019   '0', '1', '2', '3', '4', '5', '6', '7',
00020   '8', '9', ':', ';', '<', '=', '>', '?',
00021   '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
00022   'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
00023   'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
00024   'X', 'Y', 'Z', '[', '\\',']', '^', '_'
00025 };
00026 void pa_uuencode(String& result, const String& file_name, const VFile& vfile) {
00027     //header
00028     result << "content-transfer-encoding: x-uuencode\n" << "\n";
00029     result << "begin 644 " << file_name << "\n";
00030
00031     //body
00032     const unsigned char *in=(const unsigned char *)vfile.value_ptr();
00033     size_t in_length=vfile.value_size();
00034
00035     int count=45;
00036     for(const unsigned char *itemp=in; itemp<(in+in_length); itemp+=count) {
00037         int index;
00038
00039         if((itemp+count)>(in+in_length))
00040             count=in_length-(itemp-in);
00041
00042         char *buf=new(PointerFreeGC) char[MAX_STRING];
00043         char *optr=buf;
00044
00045         /*
00046         * for UU and XX, encode the number of bytes as first character
00047         */
00048         *optr++ = uue_table[count];
00049
00050         for (index=0; index<=count-3; index+=3) {
00051             *optr++ = uue_table[itemp[index] >> 2];
00052             *optr++ = uue_table[((itemp[index  ] & 0x03) << 4) | (itemp[index+1] >> 4)];
00053             *optr++ = uue_table[((itemp[index+1] & 0x0f) << 2) | (itemp[index+2] >> 6)];
00054             *optr++ = uue_table[  itemp[index+2] & 0x3f];
00055         }
00056
00057         /*
00058         * Special handlitempg for itempcomplete litempes
00059         */
00060         if (index != count) {
00061             if (count - index == 2) {
00062                 *optr++ = uue_table[itemp[index] >> 2];
00063                 *optr++ = uue_table[((itemp[index  ] & 0x03) << 4) |
00064                     ( itemp[index+1] >> 4)];
00065                 *optr++ = uue_table[((itemp[index+1] & 0x0f) << 2)];
00066                 *optr++ = uue_table[0];
00067             }
00068             else if (count - index == 1) {
00069                 *optr++ = uue_table[ itemp[index] >> 2];
00070                 *optr++ = uue_table[(itemp[index] & 0x03) << 4];
00071                 *optr++ = uue_table[0];
00072                 *optr++ = uue_table[0];
00073             }
00074         }
00075         /*
00076         * end of line
00077         */
00078         *optr++ = '\n';
00079         *optr = 0;
00080         result << buf;
00081     }
00082
00083     //footer
00084     result<< "`\n"
00085         "end\n";
00086 }


pa_uue.h File Reference

Parser: uue encoding module. More...

Include dependency graph for pa_uue.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

void | pa_uuencode (String &result, const String &file_name, const VFile &vfile)

Variables

const char *const | IDENT_UUE_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: uue encoding module.

Copyright (c) 2000,2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_uue.h.

Function Documentation

void pa_uuencode | ( | String & | result,
 |  | const String & | file_name,
 |  | const VFile & | vfile
 | ) |

Definition at line 26 of file pa_uue.C.

References MAX_STRING, result, uue_table, VFile::value_ptr(), and VFile::value_size().

Referenced by file_value_to_string().

Variable Documentation

const char* const IDENT_UUE_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 11 of file pa_uue.h.


pa_uue.h Source File

pa_uue.h

Go to the documentation of this file.
00001
00008 #ifndef PA_UUE_H
00009 #define PA_UUE_H
00010
00011 static const char * const IDENT_UUE_H="$Date: 2005/08/09 08:14:50 $";
00012
00013 #include "pa_string.h"
00014 #include "pa_vfile.h"
00015
00016 void pa_uuencode(String& result, const String& file_name, const VFile& vfile);
00017
00018 #endif


pa_value.C File Reference

Parser: Value class. More...

Include dependency graph for pa_value.C:

Include dependency graph

Go to the source code of this file.

Functions

const String | name_name (NAME_NAME)
const String | value_name (VALUE_NAME)
const String | expires_name (EXPIRES_NAME)
const String | content_type_name (CONTENT_TYPE_NAME)
String::C | date_attribute (const VDate &vdate)
void | append_attribute_meaning (String &result, Value &value, String::Language lang, bool forced)
void | append_attribute_subattribute (HashStringValue::key_type akey, HashStringValue::value_type avalue, Attributed_meaning_info *info)
const String & | attributed_meaning_to_string (Value &meaning, String::Language lang, bool forced)
$content-type[text/html] -> content-type: text/html $content-type[$value[text/html] charset[windows-1251]] -> content-type: text/html; charset=windows-1251. More...

Variables

const char *const | IDENT_VALUE_C = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: Value class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_value.C.

Function Documentation

const String name_name ( NAME_NAME )

const String value_name ( VALUE_NAME )

const String expires_name ( EXPIRES_NAME )

const String content_type_name ( CONTENT_TYPE_NAME )

String::C date_attribute ( const VDate & vdate ) [static]

Definition at line 86 of file pa_value.C.

References VDate::get_time(), MAX_STRING, and snprintf.

Referenced by append_attribute_meaning().

void append_attribute_meaning | ( | String & | result,
 |  | Value & | value,
 |  | String::Language | lang,
 |  | bool | forced
 | ) | [static]

Definition at line 107 of file pa_value.C.

References String::append(), String::append_help_length(), Value::as(), date_attribute(), Value::get_string(), String::L_CLEAN, String::Language, String::C::length, result, String::C::str, Value::type(), value, and VDATE_TYPE.

Referenced by append_attribute_subattribute(), and attributed_meaning_to_string().

void append_attribute_subattribute | ( | HashStringValue::key_type | akey,
 |  | HashStringValue::value_type | avalue,
 |  | Attributed_meaning_info * | info
 | ) | [static]

Definition at line 129 of file pa_value.C.

References append_attribute_meaning(), String::L_TAINTED, and VALUE_NAME.

Referenced by attributed_meaning_to_string().

const String& attributed_meaning_to_string | ( | Value & | meaning,
 |  | String::Language | lang,
 |  | bool | forced = false
 | ) |

$content-type[text/html] -> content-type: text/html $content-type[$value[text/html] charset[windows-1251]] -> content-type: text/html; charset=windows-1251.

Definition at line 141 of file pa_value.C.

References append_attribute_meaning(), append_attribute_subattribute(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), String::Language, result, and value.

Referenced by http_pass_header(), output_pieces(), output_set_cookie_header(), and store_message_element().

Variable Documentation

const char* const IDENT_VALUE_C = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 8 of file pa_value.C.


pa_value.C Source File

pa_value.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VALUE_C="$Date: 2005/08/09 08:14:53 $";
00009
00010 #include "pa_value.h"
00011 #include "pa_vstateless_class.h"
00012 #include "pa_vmethod_frame.h"
00013 #include "pa_vdate.h"
00014 #include "pa_vobject.h"
00015
00016 // globals
00017
00018 const String name_name(NAME_NAME);
00019
00020 const String value_name(VALUE_NAME);
00021 const String expires_name(EXPIRES_NAME);
00022 const String content_type_name(CONTENT_TYPE_NAME);
00023
00024 // methods
00025
00026 VObject* Value::set_derived(VObject* /*aderived*/) { return 0; }
00027
00028 Junction* Value::get_junction() { return 0; }
00029
00030 Value* Value::base_object() { return bark("is '%s', it has no base object"); }
00031
00032 Value* Value::get_element(const String& /*aname*/, Value& /*aself*/, bool /*looking_up*/) {
00033     return bark("is '%s', it has no elements");
00034 }
00035
00036
00037 VFile* Value::as_vfile(String::Language /*lang*/, const Request_charsets* /*charsets*/) {
00038     bark("is '%s', it does not have file value"); return 0;
00039 }
00040
00042 void Method::check_actual_numbered_params(Value& self,
00043                       MethodParams* actual_numbered_params) const {
00044
00045     int actual_count=actual_numbered_params?actual_numbered_params->count():0;
00046     if(actual_count<min_numbered_params_count) // not proper count? bark
00047         throw Exception("parser.runtime",
00048             0,
00049             "native method of %s (%s) accepts minimum %d parameter(s) (%d present)",
00050                 self.get_class()->name_cstr(),
00051                 self.type(),
00052                 min_numbered_params_count,
00053                 actual_count);
00054
00055 }
00056
00057 Junction::Junction(Value& aself,
00058     const Method* amethod,
00059     VMethodFrame* amethod_frame,
00060     Value* arcontext,
00061     WContext* awcontext,
00062     ArrayOperation* acode): self(aself),
00063     method(amethod),
00064     method_frame(amethod_frame),
00065     rcontext(arcontext),
00066     wcontext(awcontext),
00067     code(acode) {
00068     if(wcontext)
00069         wcontext->attach_junction(this);
00070 }
00071
00072 void Junction::reattach(WContext *new_wcontext) {
00073     if(new_wcontext) {
00074         assert(wcontext!=new_wcontext);
00075         wcontext=new_wcontext;
00076         wcontext->attach_junction(this);
00077     } else {
00078         method_frame=0;
00079         rcontext=0;
00080         wcontext=0;
00081     }
00082 }
00083
00084 // attributed meaning
00085
00086 static String::C date_attribute(const VDate& vdate) {
00088     const char month_names[12][4]={
00089         "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
00090     const char days[7][4]={
00091         "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
00092
00093     time_t when=vdate.get_time();
00094     struct tm *tms=gmtime(&when);
00095     if(!tms)
00096         throw Exception(0,
00097             0,
00098             "bad time in attribute value (seconds from epoch=%u)", when);
00099
00100     char *buf=new(PointerFreeGC) char[MAX_STRING];
00101     return String::C(buf,
00102         snprintf(buf, MAX_STRING, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
00103         days[tms->tm_wday],
00104         tms->tm_mday,month_names[tms->tm_mon],tms->tm_year+1900,
00105         tms->tm_hour,tms->tm_min,tms->tm_sec));
00106 }
00107 static void append_attribute_meaning(String& result,
00108                      Value& value, String::Language lang, bool forced) {
00109     if(const String* string=value.get_string())
00110         result.append(*string, lang, forced);
00111     else
00112         if(Value* vdate=value.as(VDATE_TYPE, false)) {
00113             String::C attribute=date_attribute(static_cast<VDate&>(*vdate));
00114
00115             result.append_help_length(attribute.str, attribute.length, String::L_CLEAN);
00116         } else
00117             throw Exception("parser.runtime",
00118                 &result,
00119                 "trying to append here neither string nor date (%s)",
00120                     value.type());
00121 }
00122 #ifndef DOXYGEN
00123 struct Attributed_meaning_info {
00124     String* header; // header line being constructed
00125     String::Language lang; // language in which to append to that line
00126     bool forced; // do they force that lang?
00127 };
00128 #endif
00129 static void append_attribute_subattribute(HashStringValue::key_type akey,
00130                       HashStringValue::value_type avalue,
00131                       Attributed_meaning_info *info) {
00132     if(akey==VALUE_NAME)
00133         return;
00134
00135     // ...; charset=windows1251
00136     *info->header << "; ";
00137     info->header->append(String(akey, String::L_TAINTED), info->lang, info->forced);
00138     *info->header << "=";
00139     append_attribute_meaning(*info->header, *avalue, info->lang, info->forced);
00140 }
00141 const String& attributed_meaning_to_string(Value& meaning,
00142                        String::Language lang, bool forced) {
00143     String& result=*new String;
00144     if(HashStringValue *hash=meaning.get_hash()) {
00145         // $value(value) $subattribute(subattribute value)
00146         if(Value* value=hash->get(value_name))
00147             append_attribute_meaning(result, *value, lang, forced);
00148
00149         Attributed_meaning_info attributed_meaning_info={&result, lang, false};
00150         hash->for_each(append_attribute_subattribute, &attributed_meaning_info);
00151     } else // result value
00152         append_attribute_meaning(result, meaning, lang, forced);
00153
00154     return result;
00155 }


pa_value.h File Reference

Parser: Value, Method, Junction . More...

Include dependency graph for pa_value.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Value
grandfather of all values in Parser. More...

Defines

#define | PUT_ELEMENT_REPLACED_ELEMENT reinterpret_cast<const VJunction*>(1)
indicator value meaning that put_element overwritten something. More...

Typedefs

typedef Hash< const String::Body,
Value * > 		HashStringValue
typedef Hash< const String::Body,
PA_Object * > 		HashStringObject
typedef Array< Value * > | ArrayValue

Functions

const String & | attributed_meaning_to_string (Value &meaning, String::Language lang, bool forced=false)
$content-type[text/html] -> content-type: text/html $content-type[$value[text/html] charset[windows-1251]] -> content-type: text/html; charset=windows-1251. More...

Variables

const char *const | IDENT_VALUE_H = "$Date: 2005/11/21 10:13:43 $"

Detailed Description

Parser: Value, Method, Junction .

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_value.h.

Define Documentation

#define PUT_ELEMENT_REPLACED_ELEMENT reinterpret_cast<const VJunction*>(1)

indicator value meaning that put_element overwritten something.

Definition at line 115 of file pa_value.h.

Referenced by Request::execute(), VResponse::put_element(), VRequest::put_element(), VMethodFrame::put_element(), VImage::put_element(), VHash::put_element(), VCookie::put_element(), VConsole::put_element(), and Request::put_element().

#define CHARSET_NAME "charset"

common field names.

Definition at line 179 of file pa_value.h.

#define VALUE_NAME "value"

common field names.

Definition at line 180 of file pa_value.h.

Referenced by append_attribute_subattribute(), VMail::fill_received(), VHashfile::put_field(), store_message_element(), and text_value_to_string().

#define EXPIRES_NAME "expires"

common field names.

Definition at line 181 of file pa_value.h.

#define CONTENT_TYPE_NAME "content-type"

common field names.

Definition at line 182 of file pa_value.h.

Referenced by _sql(), and store_message_element().

#define NAME_NAME "name"

common field names.

Definition at line 183 of file pa_value.h.

Typedef Documentation

typedef Hash<const String::Body, Value*> HashStringValue

Definition at line 28 of file pa_value.h.

Referenced by _load(), Request::execute(), and VHashfile::get_hash().

typedef Hash<const String::Body, PA_Object*> HashStringObject

Definition at line 29 of file pa_value.h.

typedef Array<Value*> ArrayValue

Definition at line 30 of file pa_value.h.

Referenced by VMail::message_hash_to_string().

Function Documentation

const String& attributed_meaning_to_string | ( | Value & | meaning,
 |  | String::Language | lang,
 |  | bool | forced = false
 | ) |

$content-type[text/html] -> content-type: text/html $content-type[$value[text/html] charset[windows-1251]] -> content-type: text/html; charset=windows-1251.

Definition at line 141 of file pa_value.C.

References append_attribute_meaning(), append_attribute_subattribute(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), String::Language, result, and value.

Referenced by http_pass_header(), output_pieces(), output_set_cookie_header(), and store_message_element().

Variable Documentation

const char* const IDENT_VALUE_H = "$Date: 2005/11/21 10:13:43 $" [static]

Definition at line 11 of file pa_value.h.

const String value_name

common field names.

Definition at line 187 of file pa_value.h.

const String expires_name

common field names.

Definition at line 188 of file pa_value.h.

const String content_type_name

common field names.

Definition at line 189 of file pa_value.h.

const String name_name

common field names.

Definition at line 190 of file pa_value.h.


pa_value.h Source File

pa_value.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VALUE_H
00009 #define PA_VALUE_H
00010
00011 static const char * const IDENT_VALUE_H="$Date: 2005/11/21 10:13:43 $";
00012
00013 #include "pa_string.h"
00014 #include "pa_array.h"
00015 #include "pa_exception.h"
00016 #include "pa_property.h"
00017
00018 // forwards
00019
00020 class VStateless_class;
00021 class WContext;
00022 class Request; class Request_charsets;
00023 class Junction;
00024 class VJunction;
00025 class Method;
00026 template<typename K, typename V> class Hash;
00027 class Value;
00028 typedef Hash<const String::Body, Value*> HashStringValue;
00029 typedef Hash<const String::Body, PA_Object*> HashStringObject;
00030 typedef Array<Value*> ArrayValue;
00031 class MethodParams;
00032 class VObject;
00033 class VMethodFrame;
00034 class VFile;
00035 class Table;
00036
00038 class Value: public PA_Object {
00039 public: // Value
00040
00042     virtual const char* type() const =0;
00043
00047     virtual VObject* set_derived(VObject* /*aderived*/);
00048
00053     virtual Value* as(const char* atype, bool /*looking_up*/) {
00054         return atype && strcmp(type(), atype)==0?this:0;
00055     }
00057     bool is(const char* atype) { return as(atype, false)!=0; }
00058
00060     virtual bool is_defined() const { return true; }
00061
00063     virtual bool is_string() const { return false; }
00064
00066     virtual bool is_void() const { return false; }
00067
00069     virtual bool is_evaluated_expr() const { return false; }
00070
00072     virtual Value& as_expr_result(bool /*return_string_as_is*/=false) {
00073         return *bark("is '%s', can not be used in expression");
00074     }
00075
00076
00077
00081     virtual HashStringValue* get_hash() { return 0; }
00082
00084     virtual const String* get_string() { return 0; }
00085
00087     virtual double as_double() const { bark("is '%s', it does not have numerical (double) value"); return 0; }
00088
00090     virtual int as_int () const { bark("is '%s', it does not have numerical (int) value"); return 0; }
00091
00093     virtual bool as_bool() const { bark("is '%s', it does not have logical value"); return 0; }
00094
00096     virtual VFile* as_vfile(String::Language lang=String::L_UNSPECIFIED,
00097         const Request_charsets* charsets=0);
00098
00100     virtual Junction* get_junction();
00101
00103     virtual Property* get_property() { return 0; }
00104
00109     virtual Value* base_object();
00110
00112     virtual Value* get_element(const String& /*aname*/, Value& /*aself*/, bool /*looking_up*/);
00113
00115     #define PUT_ELEMENT_REPLACED_ELEMENT reinterpret_cast<const VJunction*>(1)
00119     virtual const VJunction* put_element(Value& /*aself*/, const String& aname, Value* /*avalue*/, bool /*areplace*/) {
00120         // to prevent modification of system classes,
00121         // created at system startup, and not having exception
00122         // handler installed, we neet to bark using request.pool
00123         bark("element can not be stored to %s", &aname);
00124         return 0;
00125     }
00126
00128     virtual VStateless_class *get_class()=0;
00129
00131     virtual VStateless_class *get_last_derived_class() {
00132         return get_class();
00133     };
00135     virtual Value* base() { return 0; }
00136
00138     virtual Table* get_table() { return 0; }
00139
00140 public: // usage
00141
00143     const String& as_string() {
00144         const String* result=get_string();
00145         if(!result)
00146             bark("is '%s', it has no string representation");
00147
00148         return *result;
00149     }
00150
00151 protected:
00152
00154     Value* bark(const char *reason, const String *problem_source=0) const {
00155         if(this) // removing warnings on unreachable code
00156             throw Exception("parser.runtime",
00157                 problem_source,
00158                 reason, type());
00159
00160         return 0;
00161     }
00162
00163 };
00164
00165
00172 const String& attributed_meaning_to_string(Value& meaning,
00173                        String::Language lang,
00174                        bool forced=false);
00175
00176 // defines
00177
00179 #define CHARSET_NAME "charset"
00180 #define VALUE_NAME "value"
00181 #define EXPIRES_NAME "expires"
00182 #define CONTENT_TYPE_NAME "content-type"
00183 #define NAME_NAME "name"
00184
00185
00187 extern const String value_name;
00188 extern const String expires_name;
00189 extern const String content_type_name;
00190 extern const String name_name;
00192
00193 #endif


pa_vbool.h File Reference

Parser: bool class decls. More...

Include dependency graph for pa_vbool.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VBool
VBool. More...

Defines

#define | MAX_BOOL_AS_STRING 20

Variables

const char *const | IDENT_VBOOL_H = "$Date: 2005/11/21 10:13:43 $"

Detailed Description

Parser: bool class decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vbool.h.

Define Documentation

#define MAX_BOOL_AS_STRING 20

Definition at line 18 of file pa_vbool.h.

Variable Documentation

const char* const IDENT_VBOOL_H = "$Date: 2005/11/21 10:13:43 $" [static]

Definition at line 11 of file pa_vbool.h.


pa_vbool.h Source File

pa_vbool.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VBOOL_H
00009 #define PA_VBOOL_H
00010
00011 static const char * const IDENT_VBOOL_H="$Date: 2005/11/21 10:13:43 $";
00012
00013 // include
00014
00015 #include "pa_common.h"
00016 #include "pa_value.h"
00017
00018 #define MAX_BOOL_AS_STRING 20
00019
00021 class VBool: public Value {
00022 public: // Value
00023
00024     override const char* type() const { return "bool"; }
00026     override VStateless_class *get_class() { return 0; }
00028     override bool is_evaluated_expr() const { return true; }
00030     override Value& as_expr_result(bool) { return *new VBool(fbool); }
00032     virtual bool is_defined() const { return as_bool(); }
00034     override bool as_bool() const { return fbool; }
00036     override double as_double() const { return fbool; }
00038     override int as_int() const { return fbool; }
00039
00040 public: // usage
00041
00042     VBool(bool abool): fbool(abool) {}
00043
00044 private:
00045
00046     bool fbool;
00047
00048 };
00049
00050 #endif


pa_vclass.C File Reference

Parser: class parser class impl. More...

Include dependency graph for pa_vclass.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | PROPERTY_BUT_NO_SETTER_IN_SELF reinterpret_cast<const VJunction*>(2)

Variables

const char *const | IDENT_VCLASS_C = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: class parser class impl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vclass.C.

Define Documentation

#define PROPERTY_BUT_NO_SETTER_IN_SELF reinterpret_cast<const VJunction*>(2)

Definition at line 80 of file pa_vclass.C.

Referenced by VClass::prevent_overwrite_property(), and VClass::put_element().

Variable Documentation

const char* const IDENT_VCLASS_C = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 8 of file pa_vclass.C.


pa_vclass.C Source File

pa_vclass.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VCLASS_C="$Date: 2005/08/09 08:14:53 $";
00009
00010 #include "pa_vclass.h"
00011
00012 Property& VClass::add_property(const String& aname) {
00013     String prop_name=aname.mid(4, aname.length());
00014
00015     Property* result;
00016     if(Value* value=ffields.get(prop_name)) {
00017         result=value->get_property();
00018         if(!result) // can occur in ^process
00019             throw Exception("parser.compile",
00020                 &prop_name,
00021                 "property can not be created, already exists field (%s) with that name", value->get_class()->name_cstr());
00022     } else {
00023         VProperty* vproperty=new VProperty();
00024         ffields.put(prop_name, vproperty);
00025         result=&vproperty->get();
00026     }
00027     return *result;
00028 }
00029
00031 void VClass::add_method(const String& aname, Method& amethod)
00032 {
00033     if(aname.starts_with("GET_"))
00034         add_property(aname).getter=&amethod;
00035     else if(aname.starts_with("SET_") )
00036         add_property(aname).setter=&amethod;
00037
00038     // NOT under 'else' for backward compatiblilty:
00039     // if someone used get_xxx names to name regular methods
00040     // still register method:
00041     VStateless_class::add_method(aname, amethod);
00042 }
00043
00044 Value* VClass::as(const char* atype, bool looking_up) {
00045     if(Value* result=Value::as(atype, looking_up))
00046         return result;
00047     else
00048         return fbase?fbase->as(atype, looking_up):0;
00049 }
00050
00052 Value* VClass::get_element(const String& aname, Value& aself, bool alooking_up) {
00053     bool property_but_no_getter_in_self=false;
00054
00055     // simple things first: $field=static field/property
00056     if(Value* result=ffields.get(aname)) {
00057         if(Property* prop=result->get_property()) { // it is property?
00058             if(Method* method=prop->getter)
00059                 return new VJunction(aself, method, true /*is_getter*/);
00060
00061             property_but_no_getter_in_self=true;
00062             goto try_to_find_getter_up_the_tree;
00063         }
00064         return result;
00065     }
00066
00067 try_to_find_getter_up_the_tree:
00068     // $CLASS, $method, or other base element
00069     if(Value* result=VStateless_class::get_element(aname, aself, alooking_up))
00070         return result; // TODO: this can be SIGNIFICANTLY sped up by caching in ffields! [THOUGH decide about different aself] // what REALLY would speed up things is to join storage of properties/methods/fields of all vobject parents into last descenant [sort of vmt + all fields as in other langs]
00071
00072     if(property_but_no_getter_in_self)
00073         throw Exception("parser.runtime",
00074             0,
00075             "this property has no getter method (@GET_%s[])", aname.cstr());
00076
00077     return 0;
00078 }
00079
00080 #define PROPERTY_BUT_NO_SETTER_IN_SELF reinterpret_cast<const VJunction*>(2)
00081 const VJunction* VClass::prevent_overwrite_property(Value* value, Prevent_info* info) {
00082     if(Property* property=value->get_property()) {
00083         if(Method* setter=property->setter)
00084             return new VJunction(*info->self, setter);
00085
00086         return PROPERTY_BUT_NO_SETTER_IN_SELF;
00087     }
00088
00089     return 0;
00090 }
00091 const VJunction* VClass::prevent_append_if_exists_in_base(Value* value, Prevent_info* info)  {
00092     if(VStateless_class* cbase=info->_this->fbase) {
00093         if(Value* obase=info->self->base()) // MXdoc has fbase but does not have object_base[ base() ]
00094             if(const VJunction* result=cbase->put_element(*obase, *info->name, value, true/*try to replace! NEVER overwrite*/))
00095                 return result; // replaced in base
00096     }
00097
00098     return 0;
00099 }
00101 const VJunction* VClass::put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
00102     Prevent_info info={this, &aself, &aname};
00103     if(areplace) {
00104         bool property_but_no_setter_in_self=false;
00105         // trying to replace it in fields/properties
00106         if(const VJunction* result=ffields.maybe_replace_never_append<const VJunction*>(aname, avalue,
00107             prevent_overwrite_property,
00108             &info))
00109             if(result==PROPERTY_BUT_NO_SETTER_IN_SELF)
00110                 property_but_no_setter_in_self=true; // continue to find setter up the tree
00111             else
00112                 return result; // replaced locally
00113
00114         // if not found locally, going up the tree
00115         if(fbase)
00116             if(Value* obase=aself.base()) // MXdoc has fbase but does not have object_base[ base() ]
00117                 if(const VJunction* result=fbase->put_element(*obase, aname, avalue, true/*try to replace! NEVER overwrite*/))
00118                     return result; // replaced in base
00119
00120         if(property_but_no_setter_in_self)
00121             throw Exception("parser.runtime",
00122                 0,
00123                 "this property has no setter method (@SET_%s[value])", aname.cstr());
00124
00125         return 0;
00126     } else // append if not existed neither in fields nor in base classes
00127         return ffields.maybe_replace_maybe_append<const VJunction*>(aname, avalue,
00128             prevent_overwrite_property,
00129             prevent_append_if_exists_in_base,
00130             &info);
00131 }
00132
00134 Value* VClass::create_new_value(Pool& apool, HashStringValue& afields) {
00135     return new VObject(apool, *this, afields);
00136 }


pa_vclass.h File Reference

Parser: class parser class decl. More...

Include dependency graph for pa_vclass.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VClass
stores - static fields: VClass::ffields. More...

struct | Prevent_info

Variables

const char *const | IDENT_VCLASS_H = "$Date: 2005/08/09 08:14:53 $"

Detailed Description

Parser: class parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vclass.h.

Variable Documentation

const char* const IDENT_VCLASS_H = "$Date: 2005/08/09 08:14:53 $" [static]

Definition at line 11 of file pa_vclass.h.


pa_vclass.h Source File

pa_vclass.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VCLASS_H
00009 #define PA_VCLASS_H
00010
00011 static const char * const IDENT_VCLASS_H="$Date: 2005/08/09 08:14:53 $";
00012
00013 // includes
00014
00015 #include "pa_vstateless_class.h"
00016 #include "pa_vjunction.h"
00017 #include "pa_vobject.h"
00018
00022 class VClass: public VStateless_class {
00023 public: // Value
00024
00025     const char* type() const { return name_cstr(); }
00026
00027     override Value* as(const char* atype, bool looking_up);
00028
00030     override Value& as_expr_result(bool) { return *new VBool(as_bool()); }
00032     override bool as_bool() const { return true; }
00033
00034     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00035     override const VJunction* put_element(Value& self, const String& name, Value* value, bool replace);
00036     override Value* create_new_value(Pool& apool, HashStringValue& afields);
00037
00038 public: // VStateless_class
00039
00041     override void add_method(const String& name, Method& method);
00042
00043 private:
00044
00045     Property& add_property(const String& aname);
00046
00047 private:
00048
00049     struct Prevent_info {
00050         VClass* _this;
00051         Value* self;
00052         const String* name;
00053     };
00054     static const VJunction* prevent_overwrite_property(Value* value, Prevent_info* info);
00055     static const VJunction* prevent_append_if_exists_in_base(Value* value, Prevent_info* info);
00056
00057 private: // self
00058
00059     HashStringValue ffields;
00060
00061 };
00062
00063 #endif


pa_vcode_frame.h File Reference

Parser: code_frame write wrapper write context. More...

Include dependency graph for pa_vcode_frame.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VCodeFrame
specialized write wrapper, completely transparent, but intercepting string writes. More...

Variables

const char *const | IDENT_VCODE_FRAME_H = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: code_frame write wrapper write context.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vcode_frame.h.

Variable Documentation

const char* const IDENT_VCODE_FRAME_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vcode_frame.h.


pa_vcode_frame.h Source File

pa_vcode_frame.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VCODE_FRAME_H
00009 #define PA_VCODE_FRAME_H
00010
00011 static const char * const IDENT_VCODE_FRAME_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 #include "pa_wcontext.h"
00014 #include "pa_vvoid.h"
00015
00017 class VCodeFrame: public WContext {
00018 public: // Value
00019
00020     override const char* type() const { return "code_frame"; }
00022     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00023         return wcontext.get_element(aname, aself, looking_up);
00024     }
00026     override const VJunction* put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
00027         // $hash[^if(1){$.field[]}]
00028         // put goes to $hash
00029         return wcontext.put_element(aself, aname, avalue, areplace);
00030     }
00031
00032 public: // WContext
00033
00035     override void write(const String& string, String::Language lang) {
00036         fstring.append(string, lang);
00037     }
00038
00046     override void write(Value& avalue) {
00047         if(const String* lstring=avalue.get_string())
00048             write(*lstring, String::L_PASS_APPENDED);
00049         else
00050             wcontext.write(avalue);
00051     }
00052
00053
00054 public: // usage
00055
00056     VCodeFrame(WContext& awcontext, WContext *parent):
00057         WContext(&awcontext, parent),
00058         wcontext(awcontext) {}
00059
00060 private:
00061
00062     WContext& wcontext;
00063
00064 };
00065
00066 #endif


pa_vconsole.h File Reference

Parser: console class decl. More...

Include dependency graph for pa_vconsole.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VConsole
console class. More...

Defines

#define | CONSOLE_CLASS_NAME "console"
#define | CONSOLE_LINE_NAME "line"

Variables

const char *const | IDENT_VCONSOLE_H = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: console class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vconsole.h.

Define Documentation

#define CONSOLE_CLASS_NAME "console"

Definition at line 22 of file pa_vconsole.h.

Referenced by Request::Request().

#define CONSOLE_LINE_NAME "line"

Definition at line 24 of file pa_vconsole.h.

Referenced by VConsole::get_element(), and VConsole::put_element().

Variable Documentation

const char* const IDENT_VCONSOLE_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vconsole.h.


pa_vconsole.h Source File

pa_vconsole.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VCONSOLE_H
00009 #define PA_VCONSOLE_H
00010
00011 static const char * const IDENT_VCONSOLE_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 // includes
00014
00015 #include "pa_sapi.h"
00016 #include "pa_common.h"
00017 #include "pa_value.h"
00018 #include "pa_string.h"
00019
00020 // defines
00021
00022 #define CONSOLE_CLASS_NAME "console"
00023
00024 #define CONSOLE_LINE_NAME "line"
00025
00027 class VConsole: public Value {
00028 public: // Value
00029
00030     const char* type() const { return "console"; }
00032     VStateless_class *get_class() { return 0; }
00033
00034     // VConsole: $line
00035     Value* get_element(const String& aname, Value& /*aself*/, bool /*looking_up*/) {
00036         // $line
00037         if(aname==CONSOLE_LINE_NAME) {
00038             char local_value[MAX_STRING];
00039             if(fgets(local_value, sizeof(local_value), stdin)) {
00040                 return new VString(*new String(strdup(local_value), true));
00041             }
00042
00043             return 0; // EOF
00044         }
00045
00046         throw Exception("parser.runtime",
00047             &aname,
00048             "reading of invalid field");
00049     }
00050
00052     override const VJunction* put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*areplace*/) {
00053         // $line
00054         if(aname==CONSOLE_LINE_NAME) {
00055             const char* cstr=avalue->as_string().cstr();
00056             puts(cstr);
00057             fflush(stdout);
00058
00059             return PUT_ELEMENT_REPLACED_ELEMENT;
00060         }
00061
00062         throw Exception("parser.runtime",
00063             &aname,
00064             "writing to invalid field");
00065     }
00066
00067 public: // usage
00068
00069     VConsole() {}
00070
00071 };
00072
00073 #endif


pa_vcookie.C File Reference

Parser: cookie class. More...

Include dependency graph for pa_vcookie.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | PATH_NAME "path"
#define | PATH_VALUE_DEFAULT "/"
#define | SESSION_NAME "session"
#define | DEFAULT_EXPIRES_DAYS 90

Functions

const String | path_name (PATH_NAME)
const String | path_value_default (PATH_VALUE_DEFAULT)
char * | search_stop (char *&current, char cstop_at)
Value & | expires_vdate (double days_till_expire)
void | output_set_cookie_header (HashStringValue::key_type aattribute, HashStringValue::value_type ameaning, bool adelete, SAPI_Info &sapi_info)
void | output_after (HashStringValue::key_type aattribute, HashStringValue::value_type ameaning, SAPI_Info *sapi_info)
void | output_deleted (HashStringValue::key_type aattribute, HashStringValue::value_type ameaning, SAPI_Info *sapi_info)

Variables

const char *const | IDENT_VCOOKIE_C = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: cookie class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vcookie.C.

Define Documentation

#define PATH_NAME "path"

Definition at line 19 of file pa_vcookie.C.

#define PATH_VALUE_DEFAULT "/"

Definition at line 20 of file pa_vcookie.C.

#define SESSION_NAME "session"

Definition at line 22 of file pa_vcookie.C.

Referenced by output_set_cookie_header().

#define DEFAULT_EXPIRES_DAYS 90

Definition at line 23 of file pa_vcookie.C.

Referenced by output_set_cookie_header().

Function Documentation

const String path_name ( PATH_NAME ) [static]

const String path_value_default ( PATH_VALUE_DEFAULT ) [static]

char* search_stop | ( | char *& | current,
 |  | char | cstop_at
 | ) | [static]

Definition at line 76 of file pa_vcookie.C.

References result.

Referenced by VCookie::fill_fields().

Value& expires_vdate ( double days_till_expire ) [static]

Definition at line 122 of file pa_vcookie.C.

Referenced by output_set_cookie_header().

void output_set_cookie_header | ( | HashStringValue::key_type | aattribute,
 |  | HashStringValue::value_type | ameaning,
 |  | bool | adelete,
 |  | SAPI_Info & | sapi_info
 | ) | [static]

Definition at line 152 of file pa_vcookie.C.

References SAPI::add_header_attribute(), String::append(), Value::as(), Value::as_double(), attributed_meaning_to_string(), String::cstr(), DEFAULT_EXPIRES_DAYS, expires_vdate(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_string(), Value::is_string(), String::L_HTTP_HEADER, String::L_TAINTED, String::L_UNSPECIFIED, Hash< const String::Body, Value * >::put(), Hash< const String::Body, Value * >::remove(), SESSION_NAME, and VDATE_TYPE.

Referenced by output_after(), and output_deleted().

void output_after | ( | HashStringValue::key_type | aattribute,
 |  | HashStringValue::value_type | ameaning,
 |  | SAPI_Info * | sapi_info
 | ) | [static]

Definition at line 218 of file pa_vcookie.C.

References output_set_cookie_header().

Referenced by VCookie::output_result().

void output_deleted | ( | HashStringValue::key_type | aattribute,
 |  | HashStringValue::value_type | ameaning,
 |  | SAPI_Info * | sapi_info
 | ) | [static]

Definition at line 224 of file pa_vcookie.C.

References output_set_cookie_header().

Referenced by VCookie::output_result().

Variable Documentation

const char* const IDENT_VCOOKIE_C = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 8 of file pa_vcookie.C.


pa_vcookie.C Source File

pa_vcookie.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VCOOKIE_C="$Date: 2005/08/09 08:14:54 $";
00009
00010 #include "pa_sapi.h"
00011 #include "pa_common.h"
00012 #include "pa_vcookie.h"
00013 #include "pa_vstring.h"
00014 #include "pa_vdate.h"
00015 #include "pa_vhash.h"
00016
00017 // defines
00018
00019 #define PATH_NAME "path"
00020 #define PATH_VALUE_DEFAULT "/"
00021
00022 #define SESSION_NAME "session"
00023 #define DEFAULT_EXPIRES_DAYS 90
00024
00025 // statics
00026
00027 static const String path_name(PATH_NAME);
00028 static const String path_value_default(PATH_VALUE_DEFAULT);
00029
00030 // VCookie
00031
00032 Value* VCookie::get_element(const String& aname, Value& /*aself*/, bool /*looking_up*/) {
00033     // $CLASS
00034     if(aname==CLASS_NAME)
00035         return this;
00036
00037     // $cookie
00038     if(deleted.get(aname)) // deleted?
00039         return 0;
00040
00041     if(Value* after_meaning=after.get(aname)) // assigned 'after'?
00042         if(HashStringValue *hash=after_meaning->get_hash())
00043             return hash->get(value_name);
00044         else
00045             return after_meaning;
00046
00047     // neither deleted nor assigned
00048     // return any value it had 'before'
00049     return before.get(aname);
00050 }
00051
00052 const VJunction* VCookie::put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*replace*/) {
00053     // $cookie
00054     bool remove;
00055     Value* lvalue;
00056     if(HashStringValue *hash=avalue->get_hash())
00057         lvalue=hash->get(value_name);
00058     else
00059         lvalue=avalue;
00060
00061     if(lvalue && lvalue->is_string()) {
00062         // taint string being assigned
00063         String& tainted=*new String;
00064         tainted.append(*lvalue->get_string(), String::L_TAINTED, true /*forced*/);
00065         lvalue=new VString(tainted);
00066     }
00067
00068     remove=!lvalue || lvalue->as_string().is_empty();
00069
00070     (remove?deleted:after).put(aname, avalue);
00071     (remove?after:deleted).put(aname, 0);
00072
00073     return PUT_ELEMENT_REPLACED_ELEMENT;
00074 }
00075
00076 static char *search_stop(char*& current, char cstop_at) {
00077     // sanity check
00078     if(!current)
00079         return 0;
00080
00081     // skip leading WS
00082     while(*current==' ' || *current=='\t')
00083         current++;
00084     if(!*current)
00085         return current=0;
00086
00087     char *result=current;
00088     if(char *pstop_at=strchr(current, cstop_at)) {
00089         *pstop_at=0;
00090         current=pstop_at+1;
00091     } else
00092         current=0;
00093     return result;
00094 }
00095
00096
00097 //#include <stdio.h>
00098 void VCookie::fill_fields(Request_info& request_info) {
00099     //request_info.cookie="test-session=value%3D5; test-default1=value%3D1; test-default2=value%3D2; test-tomorrow=value%3D3";
00100     //request_info.cookie="enabled=yes; auth.uid=196325308053599810; enabled=yes; msnames; msuri"; // mdm
00101     if(!request_info.cookie)
00102         return;
00103 /*
00104     FILE *f=fopen("c:\\temp\\a", "wt");
00105     fprintf(f, "cookie=%s", request_info.cookie);
00106     fclose(f);*/
00107     char *cookies=strdup(request_info.cookie);
00108     char *current=cookies;
00109     //_asm int 3;
00110     do {
00111         if(char *attribute=search_stop(current, '='))
00112             if(char *meaning=search_stop(current, ';')) {
00113                 const String& sattribute=
00114                     *new String(unescape_chars(attribute, strlen(attribute)), 0, true);
00115                 const String& smeaning=
00116                     *new String(unescape_chars(meaning, strlen(meaning)), 0, true);
00117                 before.put(sattribute, new VString(smeaning));
00118             }
00119     } while(current);
00120 }
00121
00122 static Value& expires_vdate(double days_till_expire) {
00123     time_t when=time(NULL)+(time_t)(60*60*24*days_till_expire);
00124     struct tm *tms=gmtime(&when);
00125     if(!tms)
00126         throw Exception(0,
00127             0,
00128             "bad expires time (seconds from epoch=%u)", when);
00129
00130     return *new VDate(when);
00131 }
00132
00133 /*
00134     @todo
00135     http://www.netscape.com/newsref/std/cookie_spec.html
00136     When sending cookies to a server,
00137     all cookies with a more specific path mapping should be sent before cookies
00138     with less specific path mappings.
00139     For example, a cookie "name1=foo" with a path mapping of "/" should be sent after
00140     a cookie "name1=foo2" with a path mapping of "/bar" if they are both to be sent.
00141
00142   There are limitations on the number of cookies that a client can store at any one time.
00143   This is a specification of the minimum number of cookies that a client should be prepared
00144   to receive and store.
00145     300 total cookies
00146     4 kilobytes per cookie, where the name and the OPAQUE_STRING combine
00147         to form the 4 kilobyte limit.
00148     20 cookies per server or domain. (note that completely specified hosts
00149         and domains are treated as separate entities and have a 20 cookie limitation
00150         for each, not combined)
00151 */
00152 static void output_set_cookie_header(
00153                   HashStringValue::key_type aattribute,
00154                   HashStringValue::value_type ameaning,
00155                   bool adelete,
00156                   SAPI_Info& sapi_info) {
00157     String string;
00158     // attribute
00159     string.append(String(aattribute, String::L_TAINTED), String::L_HTTP_HEADER, true);
00160     // attribute=
00161     string << "=";
00162     Value* lmeaning;
00163     // figure out 'meaning'
00164     // Set-Cookie: (attribute)=(value); path=/
00165     HashStringValue *hash;
00166     double default_expires_days=adelete?-DEFAULT_EXPIRES_DAYS:+DEFAULT_EXPIRES_DAYS;
00167     if((hash=ameaning->get_hash())) { // ...[hash value]
00168         // clone to safely change it
00169         lmeaning=new VHash(*hash);  hash=lmeaning->get_hash();
00170         // $expires
00171         if(Value* expires=hash->get(expires_name)) {
00172             const String* string;
00173             if(expires->is_string() && (string=expires->get_string()) && (*string==SESSION_NAME))  {
00174                 // $expires[session]
00175                 hash->remove(expires_name);
00176             } else {
00177                 if(Value* vdate=expires->as(VDATE_TYPE, false))
00178                     hash->put(expires_name, vdate); // $expires[DATE]
00179                 else if(double days_till_expire=expires->as_double())
00180                     hash->put(expires_name, &expires_vdate(days_till_expire)); // $expires(days)
00181                 else
00182                     hash->remove(expires_name); // $expires(0)
00183             }
00184         } else // $expires not assigned, defaulting
00185             hash->put(expires_name, &expires_vdate(default_expires_days));
00186     } else { // ...[string value]
00187         Value* wrap_meaning=new VHash;
00188         hash=wrap_meaning->get_hash();
00189         // wrapping lmeaning into hash
00190         hash->put(value_name, ameaning);
00191         // string = $expires not assigned, defaulting
00192         hash->put(expires_name, &expires_vdate(default_expires_days));
00193         // replacing lmeaning with hash-wrapped one
00194         lmeaning=wrap_meaning;
00195     }
00196
00197     if(adelete) {// removing value
00198         /*
00199             http://www.netscape.com/newsref/std/cookie_spec.html
00200             to delete a cookie, it can do so by returning a cookie with the same name,
00201             and an expires time which is in the past
00202         */
00203
00204         // Set-Cookie: (attribute)=; path=/
00205         lmeaning->get_hash()->remove(value_name);
00206     }
00207     // defaulting path
00208     if(!lmeaning->get_hash()->get(path_name))
00209         lmeaning->get_hash()->put(path_name,
00210             new VString(path_value_default));
00211
00212     // append lmeaning
00213     string << attributed_meaning_to_string(*lmeaning, String::L_HTTP_HEADER, true);
00214
00215     // output
00216     SAPI::add_header_attribute(sapi_info, "set-cookie", string.cstr(String::L_UNSPECIFIED));
00217 }
00218 static void output_after(
00219                          HashStringValue::key_type aattribute,
00220                          HashStringValue::value_type ameaning,
00221                          SAPI_Info* sapi_info) {
00222     output_set_cookie_header(aattribute, ameaning, false, *sapi_info);
00223 }
00224 static void output_deleted(
00225                            HashStringValue::key_type aattribute,
00226                            HashStringValue::value_type ameaning,
00227                            SAPI_Info* sapi_info) {
00228     if(ameaning)
00229         output_set_cookie_header(aattribute, ameaning, true, *sapi_info);
00230 }
00231 void VCookie::output_result(SAPI_Info& sapi_info) {
00232     after.for_each(output_after, &sapi_info);
00233     deleted.for_each(output_deleted, &sapi_info);
00234 }


pa_vcookie.h File Reference

Parser: cookie class decls. More...

Include dependency graph for pa_vcookie.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VCookie
cookie class. More...

Defines

#define | COOKIE_CLASS_NAME "cookie"

Variables

const char *const | IDENT_VCOOKIE_H = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: cookie class decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vcookie.h.

Define Documentation

#define COOKIE_CLASS_NAME "cookie"

Definition at line 19 of file pa_vcookie.h.

Referenced by Request::Request().

Variable Documentation

const char* const IDENT_VCOOKIE_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vcookie.h.


pa_vcookie.h Source File

pa_vcookie.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VCOOKIE_H
00009 #define PA_VCOOKIE_H
00010
00011 static const char * const IDENT_VCOOKIE_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 #include "pa_hash.h"
00014 #include "pa_common.h"
00015 #include "pa_value.h"
00016 #include "pa_request_info.h"
00017 #include "pa_sapi.h"
00018
00019 #define COOKIE_CLASS_NAME "cookie"
00020
00022 class VCookie: public Value {
00023
00024     HashStringValue before, after, deleted;
00025
00026 public: // Value
00027
00028     override const char* type() const { return "cookie"; }
00030     override VStateless_class *get_class() { return 0; }
00031
00032     // cookie: CLASS,method,field
00033     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00034     // cookie: field
00035     override const VJunction* put_element(Value& self, const String& name, Value* value, bool replace);
00036
00037 public: // usage
00038
00039     void fill_fields(Request_info& request_info);
00040     void output_result(SAPI_Info& sapi_info);
00041
00042 };
00043
00044 #endif


pa_vdate.h File Reference

Parser: date parser class decl. More...

Include dependency graph for pa_vdate.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VDate
value of type 'date'. implemented with time_t. More...

Defines

#define | VDATE_TYPE "date"

Functions

void | set_tz (const char *tz, char *buf, size_t buf_size)

Variables

const char *const | IDENT_VDATE_H = "$Date: 2005/11/30 15:47:46 $"
Methoded * date_class

Detailed Description

Parser: date parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vdate.h.

Define Documentation

#define VDATE_TYPE "date"

Definition at line 20 of file pa_vdate.h.

Referenced by append_attribute_meaning(), as_expires(), Request::output_result(), output_set_cookie_header(), VHashfile::put_field(), and VDate::type().

Function Documentation

void set_tz | ( | const char * | tz,
 |  | char * | buf,
 |  | size_t | buf_size
 | ) | [inline]

Definition at line 26 of file pa_vdate.h.

References snprintf.

Variable Documentation

const char* const IDENT_VDATE_H = "$Date: 2005/11/30 15:47:46 $" [static]

Definition at line 11 of file pa_vdate.h.

Methoded* date_class

Definition at line 24 of file pa_vdate.h.


pa_vdate.h Source File

pa_vdate.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VDATE_H
00009 #define PA_VDATE_H
00010
00011 static const char * const IDENT_VDATE_H="$Date: 2005/11/30 15:47:46 $";
00012
00013 #include "classes.h"
00014 #include "pa_common.h"
00015 #include "pa_vstateless_object.h"
00016 #include "pa_vint.h"
00017
00018 // defines
00019
00020 #define VDATE_TYPE "date"
00021
00022 // externs
00023
00024 extern Methoded* date_class;
00025
00026 inline void set_tz(const char* tz, char* buf, size_t buf_size) {
00027 #ifndef WIN32
00028     if(tz && *tz){
00029 #endif
00030         snprintf(buf, buf_size, "TZ=%s", tz);
00031         putenv(buf);
00032 #ifndef WIN32
00033     } else
00034         putenv("TZ");
00035 #endif
00036     tzset();
00037 }
00038
00040 class VDate: public VStateless_object {
00041 public: // Value
00042
00043     override const char* type() const { return VDATE_TYPE; }
00044     override VStateless_class *get_class() { return date_class; }
00045
00047     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VDouble(as_double()); }
00048
00050     override double as_double() const { return ((double)ftime)/ SECS_PER_DAY; }
00052     override bool as_bool() const { return ftime!=0; }
00053
00055     tm& get_localtime()
00056     {
00057         char saved_tz[MAX_STRING];
00058         static char saved_tz_pair[MAX_STRING]; //TODO: this is NOT thread safe!
00059         static char temp_tz_pair[MAX_STRING];
00060         if(ftz_cstr) {
00061             if(const char* ltz=getenv("TZ")) {
00062                 strncpy(saved_tz, ltz, sizeof(saved_tz)-1);
00063                 saved_tz[sizeof(saved_tz)-1]=0;
00064             } else
00065                 saved_tz[0]=0;
00066
00067             ::set_tz(ftz_cstr, temp_tz_pair, sizeof(temp_tz_pair));
00068         }
00069         tm *result=::localtime(&ftime);
00070         if(ftz_cstr) {
00071             ::set_tz(saved_tz, saved_tz_pair, sizeof(saved_tz_pair));
00072         }
00073         if(!result)
00074             throw Exception(0,
00075                 0,
00076                 "invalid datetime (after changing TZ)");
00077
00078         return *result;
00079     }
00080
00081
00083     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00084         // $method
00085         if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00086             return result;
00087
00088         // $TZ
00089         if(aname=="TZ")
00090             return ftz? new VString(*ftz): new VString();
00091
00092         // $year month day  hour minute second  weekday
00093         tm& tms=get_localtime();
00094
00095         int result;
00096         if(aname=="year") result=1900+tms.tm_year;
00097         else if(aname=="month") result=1+tms.tm_mon;
00098         else if(aname=="day") result=tms.tm_mday;
00099         else if(aname=="hour") result=tms.tm_hour;
00100         else if(aname=="minute") result=tms.tm_min;
00101         else if(aname=="second") result=tms.tm_sec;
00102         else if(aname=="weekday") result=tms.tm_wday;
00103         else if(aname=="yearday") result=tms.tm_yday;
00104         else if(aname=="daylightsaving") result=tms.tm_isdst;
00105         else if(aname=="week") result=week_no(tms);
00106         else { return bark("%s field not found", &aname); }
00107         return new VInt(result);
00108     }
00109
00110 public: // usage
00111
00112     VDate(time_t adate) :
00113         ftz(0),
00114         ftz_cstr(0) {
00115         set_time(adate);
00116     }
00117
00118     VDate(tm tmIn) :
00119         ftime(0),
00120         ftz(0),
00121         ftz_cstr(0) {
00122         set_time(tmIn);
00123     }
00124
00125     time_t get_time() const { return ftime; }
00126     void set_time(time_t atime) {
00127         if(atime<0)
00128             throw Exception(0,
00129                 0,
00130                 "invalid datetime");
00131         ftime=atime;
00132     }
00133     void set_time(tm tmIn) {
00134         time_t t=mktime(&tmIn);
00135         if(t<0) {
00136             // on some platforms mktime does not fix spring daylightsaving time hole
00137             // in russia -- last sunday of march, 2am->3am hole
00138             // trying to recover:
00139             tmIn.tm_hour--;
00140             t=mktime(&tmIn);
00141         }
00142         set_time(t);
00143     }
00144     void set_tz(const String* atz) {
00145         if((ftz=atz))
00146             ftz_cstr=ftz->cstr();
00147     }
00148
00149     static int week_no(tm& tms) {
00150         // http://www.merlyn.demon.co.uk/weekinfo.htm
00151         int weekyear=tms.tm_year+1900;
00152         const int FirstThurs[] = {7,5,4,3,2,7,6,5,4,2,1,7,6,4,3,2,1,6,5,4,3,1,7,6,5,3,2,1};
00153         return 1 + (tms.tm_yday-(FirstThurs[weekyear % 28]-3))/7;
00154     }
00155
00156 private:
00157
00158     time_t ftime;
00159     const String* ftz;
00160     const char* ftz_cstr;
00161
00162 };
00163
00164 #endif


pa_vdouble.h File Reference

Parser: double parser class decl. More...

Include dependency graph for pa_vdouble.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VDouble
value of type 'double'. implemented with double. More...

Variables

const char *const | IDENT_VDOUBLE_H = "$Date: 2005/11/21 10:13:43 $"
Methoded * double_class

Detailed Description

Parser: double parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vdouble.h.

Variable Documentation

const char* const IDENT_VDOUBLE_H = "$Date: 2005/11/21 10:13:43 $" [static]

Definition at line 11 of file pa_vdouble.h.

Methoded* double_class

Definition at line 21 of file pa_vdouble.h.


pa_vdouble.h Source File

pa_vdouble.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VDOUBLE_H
00009 #define PA_VDOUBLE_H
00010
00011 static const char * const IDENT_VDOUBLE_H="$Date: 2005/11/21 10:13:43 $";
00012
00013 // includes
00014
00015 #include "classes.h"
00016 #include "pa_common.h"
00017 #include "pa_vstateless_object.h"
00018
00019 // externs
00020
00021 extern Methoded* double_class;
00022
00024 class VDouble: public VStateless_object {
00025 public: // Value
00026
00027     override const char* type() const { return "double"; }
00028     override VStateless_class *get_class() { return double_class; }
00029
00031     override bool is_evaluated_expr() const { return true; }
00033     override Value& as_expr_result(bool ) { return *new VDouble(fdouble); }
00034
00037     override const String* get_string() {
00038         char local_buf[MAX_NUMBER];
00039         size_t length=snprintf(local_buf, MAX_NUMBER, has_frac()? "%g": "%.0f", fdouble);
00040         return new String(strdup(local_buf, length), length);
00041     }
00043     override double as_double() const { return fdouble; }
00045     override int as_int() const { return get_int(); }
00047     override bool as_bool() const { return fdouble!=0; }
00048
00049 public: // usage
00050
00051     VDouble(double adouble): fdouble(adouble) {}
00052
00053     int get_int() const { return (int)trunc(fdouble); }
00054     double get_double() const { return fdouble; }
00055
00056     void inc(double increment) { fdouble+=increment; }
00057     void mul(double k) { fdouble*=k; }
00058     void div(double d) { fdouble/=d; }
00059     void mod(int d) { fdouble=((int)fdouble)%d; }
00060
00061 private:
00062
00063     bool has_frac() {
00064         return fdouble-trunc(fdouble)>1e-100;
00065     }
00066
00067 private:
00068
00069     double fdouble;
00070
00071 };
00072
00073 #endif


pa_venv.C File Reference

Parser: env class. More...

Include dependency graph for pa_venv.C:

Include dependency graph

Go to the source code of this file.

Functions

const String | parser_version (PARSER_VERSION)

Variables

const char *const | IDENT = "$Date: 2005/11/22 16:09:26 $"

Detailed Description

Parser: env class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_venv.C.

Function Documentation

const String parser_version ( PARSER_VERSION ) [static]

Variable Documentation

const char* const IDENT = "$Date: 2005/11/22 16:09:26 $" [static]

Definition at line 8 of file pa_venv.C.


pa_venv.C Source File

pa_venv.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT="$Date: 2005/11/22 16:09:26 $";
00009
00010 #include "pa_venv.h"
00011 #include "pa_vstring.h"
00012 #include "pa_version.h"
00013
00014 static const String parser_version(PARSER_VERSION);
00015
00016 Value* VEnv::get_element(const String& aname, Value& /*aself*/, bool /*looking_up*/) {
00017     // $env:PARSER_VERSION
00018     if(aname=="PARSER_VERSION")
00019         return new VString(parser_version);
00020
00021     // getenv
00022     String& result=*new String;
00023     if(const char* local_value=SAPI::get_env(finfo, aname.cstr()))
00024         result.append_help_length(strdup(local_value), 0, String::L_TAINTED);
00025     return new VString(result);
00026 }


pa_venv.h File Reference

Parser: env class decl. More...

Include dependency graph for pa_venv.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VEnv
env class. More...

Defines

#define | ENV_CLASS_NAME "env"

Variables

const char *const | IDENT_VENV_H = "$Date: 2005/11/21 09:24:45 $"

Detailed Description

Parser: env class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_venv.h.

Define Documentation

#define ENV_CLASS_NAME "env"

Definition at line 21 of file pa_venv.h.

Referenced by Request::Request().

Variable Documentation

const char* const IDENT_VENV_H = "$Date: 2005/11/21 09:24:45 $" [static]

Definition at line 11 of file pa_venv.h.


pa_venv.h Source File

pa_venv.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VENV_H
00009 #define PA_VENV_H
00010
00011 static const char * const IDENT_VENV_H="$Date: 2005/11/21 09:24:45 $";
00012
00013 // includes
00014
00015 #include "pa_sapi.h"
00016 #include "pa_value.h"
00017 #include "pa_string.h"
00018
00019 // defines
00020
00021 #define ENV_CLASS_NAME "env"
00022
00024 class VEnv: public Value {
00025     SAPI_Info& finfo;
00026 public: // Value
00027
00028     const char* type() const { return "env"; }
00030     VStateless_class *get_class() { return 0; }
00031
00032     // VEnv: field
00033     Value* get_element(const String& aname, Value& /*aself*/, bool /*looking_up*/);
00034
00035 public: // usage
00036
00037     VEnv(SAPI_Info& ainfo):
00038
00039         finfo(ainfo) {}
00040
00041 };
00042
00043 #endif


pa_version.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define PARSER_VERSION "3.2.1 (compiled on i386-pc-win32)"

Define Documentation

#define PARSER_VERSION "3.2.1 (compiled on i386-pc-win32)"

Definition at line 2 of file pa_version.h.

Referenced by GetExtensionVersion(), pa_version(), real_parser_handler(), and usage().


pa_version.h Source File

pa_version.h

Go to the documentation of this file.
00001 // specified manually [would be overwritten on unix]
00002 #define PARSER_VERSION "3.2.1 (compiled on i386-pc-win32)"


pa_vfile.C File Reference

Parser: file parser type. More...

Include dependency graph for pa_vfile.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | SIZE_NAME "size"
#define | TEXT_NAME "text"

Functions

const String | size_name (SIZE_NAME)
const String | text_name (TEXT_NAME)

Variables

const char *const | IDENT_VFILE_C = "$Date: 2005/08/09 08:14:54 $"
Methoded * file_class

Detailed Description

Parser: file parser type.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vfile.C.

Define Documentation

#define SIZE_NAME "size"

Definition at line 22 of file pa_vfile.C.

#define TEXT_NAME "text"

Definition at line 23 of file pa_vfile.C.

Function Documentation

const String size_name ( SIZE_NAME ) [static]

const String text_name ( TEXT_NAME ) [static]

Variable Documentation

const char* const IDENT_VFILE_C = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 9 of file pa_vfile.C.

Methoded* file_class

Definition at line 18 of file pa_vfile.C.


pa_vfile.C Source File

pa_vfile.C

Go to the documentation of this file.
00001
00009 static const char * const IDENT_VFILE_C="$Date: 2005/08/09 08:14:54 $";
00010
00011 #include "classes.h"
00012 #include "pa_vfile.h"
00013 #include "pa_vstring.h"
00014 #include "pa_vint.h"
00015
00016 // externs
00017
00018 extern Methoded* file_class;
00019
00020 // defines for statics
00021
00022 #define SIZE_NAME "size"
00023 #define TEXT_NAME "text"
00024
00025 // statics
00026
00027 static const String size_name(SIZE_NAME);
00028 static const String text_name(TEXT_NAME);
00029
00030 // methods
00031
00032 VStateless_class *VFile::get_class() { return file_class; }
00033
00034 void VFile::set(
00035         bool tainted,
00036         const char* avalue_ptr, size_t avalue_size,
00037         const char* afile_name_cstr,
00038         Value* acontent_type) {
00039     fvalue_ptr=avalue_ptr;
00040     fvalue_size=avalue_size;
00041
00042     ffields.clear();
00043     // $name
00044     char *lfile_name;
00045     if(afile_name_cstr) {
00046         lfile_name=strdup(afile_name_cstr);
00047         if(char *after_slash=rsplit(lfile_name, '\\'))
00048             lfile_name=after_slash;
00049         if(char *after_slash=rsplit(lfile_name, '/'))
00050             lfile_name=after_slash;
00051     } else
00052         lfile_name=NONAME_DAT;
00053     String& sfile_name=*new String;
00054     sfile_name.append_help_length(lfile_name, 0, String::L_FILE_SPEC);
00055     ffields.put(name_name, new VString(sfile_name));
00056     // $size
00057     ffields.put(size_name, new VInt(fvalue_size));
00058     // $text
00059     if(fvalue_ptr && fvalue_size) { // assigned files don't have ptr, and we really have some bytes
00060         String& text=*new String;
00061         char *premature_zero_pos=(char *)memchr(fvalue_ptr, 0, fvalue_size);
00062         if(premature_zero_pos!=fvalue_ptr) {
00063             size_t copy_size=premature_zero_pos?premature_zero_pos-fvalue_ptr:fvalue_size;
00064             char *copy_ptr=strdup(fvalue_ptr, copy_size);
00065             fix_line_breaks(copy_ptr, copy_size);
00066             text.append_know_length(copy_ptr, copy_size, tainted? String::L_TAINTED : String::L_AS_IS);
00067         }
00068         ffields.put(text_name, new VString(text));
00069     }
00070     // $mime-type
00071     if(acontent_type)
00072         ffields.put(content_type_name, acontent_type);
00073 }
00074
00075 Value* VFile::get_element(const String& aname, Value& aself, bool looking_up) {
00076     // $method
00077     if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00078         return result;
00079
00080     // $field
00081     return ffields.get(aname);
00082 }


pa_vfile.h File Reference

Parser: file parser type decl. More...

Include dependency graph for pa_vfile.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VFile
holds received from user or read from disk file. More...

Defines

#define | NONAME_DAT "noname.dat"

Variables

const char *const | IDENT_VFILE_H = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: file parser type decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vfile.h.

Define Documentation

#define NONAME_DAT "noname.dat"

Definition at line 22 of file pa_vfile.h.

Referenced by Request::output_result(), and VFile::set().

Variable Documentation

const char* const IDENT_VFILE_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vfile.h.


pa_vfile.h Source File

pa_vfile.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VFILE_H
00009 #define PA_VFILE_H
00010
00011 static const char * const IDENT_VFILE_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 // include
00014
00015 #include "pa_common.h"
00016 #include "pa_globals.h"
00017 #include "pa_vstateless_object.h"
00018 #include "pa_vbool.h"
00019
00020 // defines
00021
00022 #define NONAME_DAT "noname.dat"
00023
00024 // forwards
00025
00026 class Methoded;
00027
00032 class VFile: public VStateless_object {
00033
00034     const char* ffile_name_cstr;
00035     const char* fvalue_ptr;
00036     size_t fvalue_size;
00037     HashStringValue ffields;
00038
00039 public: // Value
00040
00041     override const char* type() const { return "file"; }
00042     override VStateless_class *get_class();
00043
00045     override bool as_bool() const { return true; }
00046
00048     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VBool(as_bool()); }
00049
00051     override VFile* as_vfile(String::Language /*lang*/,
00052         const Request_charsets* /*charsets*/) { return this; }
00053
00055     override Value* get_element(const String& aname, Value& aself, bool looking_up);
00056
00057 public: // usage
00058
00059     VFile::VFile(): fvalue_ptr(0), fvalue_size(0) {}
00060
00061     VFile::VFile(HashStringValue& afields): ffields(afields) {}
00062
00064     void set(
00065         bool tainted,
00066         const char* avalue_ptr, size_t avalue_size,
00067         const char* afile_name_cstr=0,
00068         Value* acontent_type=0);
00069
00070     void save(const String& file_spec, bool is_text) {
00071         if(fvalue_ptr)
00072             file_write(file_spec, fvalue_ptr, fvalue_size, is_text);
00073         else
00074             throw Exception("parser.runtime",
00075                 &file_spec,
00076                 "saving stat-ed file");
00077     }
00078
00079     const char* value_ptr() const {
00080         if(!fvalue_ptr)
00081             throw Exception("parser.runtime",
00082                 0,
00083                 "getting value of stat-ed file");
00084
00085         return fvalue_ptr;
00086     }
00087     size_t value_size() const { return fvalue_size; }
00088     HashStringValue& fields() { return ffields; }
00089
00090 private:
00091
00092     Value* fields_element();
00093
00094 };
00095
00096 #endif


pa_vform.C File Reference

Parser: form class. More...

Include dependency graph for pa_vform.C:

Include dependency graph

Go to the source code of this file.

Functions

size_t | getHeader (const char *data, size_t len)
const char * | searchAttribute (const char *data, const char *attr, size_t len)
int | atoi (const char *data, size_t alength)
char * | pa_tolower (char *s)

Variables

const char *const | IDENT_VFORM_C = "$Date: 2005/08/09 08:14:54 $"
Methoded * form_base_class

Detailed Description

Parser: form class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

based on The CGI_C library, by Thomas Boutell.

Definition in file pa_vform.C.

Function Documentation

size_t getHeader | ( | const char * | data,
 |  | size_t | len
 | ) | [static]

Definition at line 28 of file pa_vform.C.

References data.

Referenced by VForm::ParseMimeInput().

const char* searchAttribute | ( | const char * | data,
 |  | const char * | attr,
 |  | size_t | len
 | ) | [static]

Definition at line 40 of file pa_vform.C.

References data.

Referenced by VForm::getAttributeValue(), and VForm::ParseMimeInput().

int atoi | ( | const char * | data,
 |  | size_t | alength
 | ) | [static]

Definition at line 105 of file pa_vform.C.

References data, and MAX_STRING.

Referenced by SAPI::add_header_attribute(), VForm::ParseFormInput(), and real_parser_handler().

char* pa_tolower ( char * s ) [static]

Definition at line 166 of file pa_vform.C.

References p.

Referenced by VForm::ParseMimeInput().

Variable Documentation

const char* const IDENT_VFORM_C = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 10 of file pa_vform.C.

Methoded* form_base_class

Definition at line 61 of file pa_vform.C.


pa_vform.C Source File

pa_vform.C

Go to the documentation of this file.
00001
00010 static const char * const IDENT_VFORM_C="$Date: 2005/08/09 08:14:54 $";
00011
00012 #include "pa_sapi.h"
00013 #include "pa_vform.h"
00014 #include "pa_vstring.h"
00015 #include "pa_globals.h"
00016 #include "pa_request.h"
00017 #include "pa_vfile.h"
00018 #include "pa_common.h"
00019 #include "pa_vtable.h"
00020 #include "pa_charset.h"
00021
00022 // defines
00023
00024 //#define DEBUG_POST
00025
00026 // parse helper funcs
00027
00028 static size_t getHeader(const char* data, size_t len){
00029     size_t i;
00030     int enter=-1;
00031     if (data)
00032         for (i=0;i<len;i++)
00033             if (data[i]=='\n'){
00034                 if (enter>=0) enter++;
00035                 if (enter>1) return i;
00036             } else if (data[i]!='\r') enter=0;
00037         return 0;
00038 }
00039
00040 static const char* searchAttribute(const char* data,
00041                              const char* attr,  //< expected to be lowercased
00042                              size_t len){
00043     size_t i;
00044     if (data)
00045         for (i=0;i<len;i++)
00046             if (tolower((unsigned char)data[i])==*attr){
00047                 size_t j;
00048                 for (j=i+1;j<=len;j++)
00049                     if (!attr[j-i]) return &data[j];
00050                     else {
00051                         if (j==len) break;
00052                         if (attr[j-i]!=tolower((unsigned char)data[j])) break;
00053                     }
00054             }
00055
00056     return NULL;
00057 }
00058
00059 // VForm
00060
00061 extern Methoded* form_base_class;
00062
00063 VForm::VForm(Request_charsets& acharsets, Request_info& arequest_info): VStateless_class(0, form_base_class),
00064     fcharsets(acharsets),
00065     frequest_info(arequest_info),
00066     filled_source(0),
00067     filled_client(0) {
00068 }
00069
00070 char *VForm::strpart(const char* str, size_t len) {
00071     char *result=new(PointerFreeGC) char[len+1];
00072     memcpy(result, str, len);
00073     result[len]=0;
00074     return result;
00075 }
00076
00077 char *VForm::getAttributeValue(const char* data, char *attr, size_t len) {
00078     const char* value=searchAttribute(data, attr, len);
00079     if (value){
00080         size_t i;
00081         if (!(len-=value-data)) return NULL;
00082         if (*value=='"') {
00083             for (i=1;i<len;i++) if (value[i]=='"') break;
00084             return strpart(&value[1], i-1);
00085         } else {
00086             for (i=0;i<len;i++) if (strchr(" ;\"\n\r", value[i])) break;
00087             return strpart(value, i);
00088         }
00089     }
00090     return NULL;
00091 }
00092
00093 String::C VForm::transcode(const char* client, size_t client_size) {
00094     return Charset::transcode(
00095         String::C(strdup(client, client_size), client_size),
00096         fcharsets.client(),
00097         fcharsets.source());
00098 }
00099
00100 void VForm::ParseGetFormInput(const char* query_string, size_t length) {
00101     ParseFormInput(query_string, length);
00102 }
00103
00104
00105 static int atoi(const char* data, size_t alength) {
00106     char buf[MAX_STRING];
00107     size_t length=min(alength, sizeof(buf)-1);
00108     memcpy(buf, data, length); buf[length]=0;
00109     return atoi(buf);
00110 }
00111 void VForm::ParseFormInput(const char* data, size_t length) {
00112     // cut out ?image_map_tail
00113     {
00114         for(size_t pos=0; pos<length; pos++) {
00115             if(data[pos]=='?') {
00116                 size_t start=pos+1;
00117                 size_t aftercomma=start;
00118                 size_t lookingcomma=start;
00119                 for(; lookingcomma<length; lookingcomma++) {
00120                     if(data[lookingcomma]==',') {
00121                         aftercomma=++lookingcomma;
00122                         break;
00123                     }
00124                 }
00125
00126                 if(aftercomma>start) { // ?x,y
00127                     int x=atoi(data+start, aftercomma-1-start);
00128                     int y=atoi(data+aftercomma, length-aftercomma);
00129                     imap.put(String("x"), new VInt(x));
00130                     imap.put(String("y"), new VInt(y));
00131                 } else { // ?qtail
00132                     AppendFormEntry("qtail", data+start, length-start);
00133                 }
00134                 // cut tail
00135                 length=pos;
00136                 break;
00137             }
00138         }
00139     }
00140     // Scan for pairs, unescaping and storing them as they are found
00141     for(size_t pos=0; pos<length; ) {
00142         size_t start=pos;
00143         size_t finish=length;
00144         for(; pos<length; pos++) {
00145             if(data[pos]=='&') {
00146                 finish=pos++;
00147                 break;
00148             }
00149         }
00150
00151         size_t aftereq=start;
00152         size_t lookingeq=start;
00153         for(; lookingeq<finish; lookingeq++) {
00154             if(data[lookingeq]=='=') {
00155                 aftereq=++lookingeq;
00156                 break;
00157             }
00158         }
00159
00160         const char* attr=aftereq>start?unescape_chars(data+start, aftereq-1-start):"nameless";
00161         char *value=unescape_chars(data+aftereq, finish-aftereq);
00162         AppendFormEntry(attr, value, strlen(value));
00163     }
00164 }
00165
00166 static char *pa_tolower(char *s) {
00167     for(char *p=s; *p; p++)
00168         *p=(char)tolower((unsigned char)*p);
00169     return s;
00170 }
00171 void VForm::ParseMimeInput(
00172                            char *content_type,
00173                            const char* data, size_t length) {
00174 /* Scan for mime-presented pairs, storing them as they are found. */
00175     const char
00176         *boundary=pa_tolower(getAttributeValue(content_type, "boundary=", strlen(content_type))),
00177         *lastData=&data[length];
00178     if(!boundary)
00179         throw Exception(0,
00180             0,
00181             "VForm::ParseMimeInput no boundary attribute of Content-Type");
00182
00183     while(true) {
00184         const char
00185             *dataStart=searchAttribute(data, boundary, lastData-data),
00186             *dataEnd=searchAttribute(dataStart, boundary, lastData-dataStart);
00187         size_t headerSize=getHeader(dataStart, lastData-dataStart);
00188
00189         if(!dataStart|!dataEnd|!headerSize) break;
00190         if(searchAttribute(dataStart, "content-disposition: form-data", headerSize)) {
00191             size_t valueSize=(dataEnd-dataStart)-headerSize-5-strlen(boundary);
00192             char *attr=getAttributeValue(dataStart, " name=", headerSize),
00193                  *fName=getAttributeValue(dataStart, " filename=", headerSize);
00194
00195             if(attr) {
00196                 /* OK, we have a new pair, add it to the list. */
00197                 // fName checks are because MSIE passes unassigned <input type=file> as filename="" and empty body
00198                 AppendFormEntry(attr,
00199                         valueSize? &dataStart[headerSize+1]: "",
00200                         valueSize,
00201                         fName && (strlen(fName) || valueSize)? fName: 0);
00202             }
00203         }
00204         data=(dataEnd-strlen(boundary));
00205     }
00206 }
00207
00208 void VForm::AppendFormEntry(const char* cname_cstr,
00209                 const char* raw_cvalue_ptr, const size_t raw_cvalue_size,
00210                 const char* copy_me_file_name_cstr) {
00211     const String& sname=*new String(transcode(cname_cstr, strlen(cname_cstr)));
00212
00213     Value* value;
00214     if(copy_me_file_name_cstr) {
00215         VFile* vfile=new VFile;
00216         // maybe transcode text/* files?
00217         const String& sfile_name=*new String(strdup(copy_me_file_name_cstr));
00218         vfile->set(true/*tainted*/, raw_cvalue_ptr, raw_cvalue_size, sfile_name.cstr());
00219         value=vfile;
00220     } else {
00221         const char* premature_zero_pos=(const char* )memchr(raw_cvalue_ptr, 0, raw_cvalue_size);
00222         size_t cvalue_size=premature_zero_pos?premature_zero_pos-(const char* )raw_cvalue_ptr
00223             :raw_cvalue_size;
00224         char *cvalue_ptr=strdup(raw_cvalue_ptr, cvalue_size);
00225         fix_line_breaks(cvalue_ptr, cvalue_size);
00226         String& string=*new String(transcode(cvalue_ptr, cvalue_size), true);
00227
00228         // tables
00229         {
00230             Value* vtable=tables.get(sname);
00231             if(!vtable) {
00232                 // first appearence
00233                 Table::columns_type columns(new ArrayString(1));
00234                 *columns+=new String("field");
00235
00236                 vtable=new VTable(new Table(columns));
00237                 tables.put(sname, vtable);
00238             }
00239             Table& table=*vtable->get_table();
00240
00241             // this string becomes next row
00242             Table::element_type row(new ArrayString(1));
00243             *row+=&string;
00244             table+=row;
00245         }
00246         value=new VString(string);
00247     }
00248
00249     fields.put_dont_replace(sname, value);
00250 }
00251
00252 void VForm::refill_fields_and_tables() {
00253     fields.clear();
00254     tables.clear();
00255     imap.clear();
00256
00257     //frequest_info.query_string="a=123";
00258     // parsing QS [GET and ?name=value from uri rewrite)]
00259     if(frequest_info.query_string) {
00260         size_t length=strlen(frequest_info.query_string);
00261         char *buf=strdup(frequest_info.query_string, length);
00262         ParseGetFormInput(buf, length);
00263     }
00264
00265 #ifdef DEBUG_POST
00266     frequest_info.method="POST";
00267     void *data;
00268     file_read(*new String("test.stdin"),
00269                data, request.post_size,
00270                false/*as_text*/);
00271     request.post_data=(char*)data;
00272     frequest_info.content_type="multipart/form-data; boundary=----------mcqY2UDNcdEAoN1mLmne2i";
00273
00274 #endif
00275
00276     // parsing POST data
00277     if(frequest_info.method) {
00278         if(const char* content_type=frequest_info.content_type)
00279             if(StrEqNc(frequest_info.method, "post", true)) {
00280                 if(StrEqNc(content_type, "application/x-www-form-urlencoded", true))
00281                     ParseFormInput(frequest_info.post_data, frequest_info.post_size);
00282                 else if(StrEqNc(content_type, "multipart/form-data", 0))
00283                     ParseMimeInput(strdup(content_type),
00284                         frequest_info.post_data, frequest_info.post_size);
00285             }
00286     }
00287
00288     filled_source=&fcharsets.source();
00289     filled_client=&fcharsets.client();
00290 }
00291
00292 bool VForm::should_refill_fields_and_tables() {
00293     return &fcharsets.source()!=filled_source
00294         || &fcharsets.client()!=filled_client;
00295 }
00296
00297 Value* VForm::get_element(const String& aname, Value& aself, bool looking_up) {
00298     if(should_refill_fields_and_tables())
00299         refill_fields_and_tables();
00300
00301     // $fields
00302     if(aname==FORM_FIELDS_ELEMENT_NAME)
00303         return new VHash(fields);
00304
00305     // $tables
00306     if(aname==FORM_TABLES_ELEMENT_NAME)
00307         return new VHash(tables);
00308
00309     // $imap
00310     if(aname==FORM_IMAP_ELEMENT_NAME)
00311         return new VHash(imap);
00312
00313     // $method
00314     if(Value* result=VStateless_class::get_element(aname, aself, looking_up))
00315         return result;
00316
00317     // $element
00318     return fields.get(aname);
00319 }


pa_vform.h File Reference

Parser: form class decls. More...

Include dependency graph for pa_vform.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VForm
derivates from VStateless_class so that :CLASS element referred to this. More...

Defines

#define | FORM_FIELDS_ELEMENT_NAME "fields"
#define | FORM_TABLES_ELEMENT_NAME "tables"
#define | FORM_IMAP_ELEMENT_NAME "imap"

Variables

const char *const | IDENT_VFORM_H = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: form class decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vform.h.

Define Documentation

#define FORM_FIELDS_ELEMENT_NAME "fields"

Definition at line 21 of file pa_vform.h.

Referenced by VForm::get_element().

#define FORM_TABLES_ELEMENT_NAME "tables"

Definition at line 22 of file pa_vform.h.

Referenced by VForm::get_element().

#define FORM_IMAP_ELEMENT_NAME "imap"

Definition at line 23 of file pa_vform.h.

Referenced by VForm::get_element().

Variable Documentation

const char* const IDENT_VFORM_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vform.h.


pa_vform.h Source File

pa_vform.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VFORM_H
00009 #define PA_VFORM_H
00010
00011 static const char * const IDENT_VFORM_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 // includes
00014
00015 #include "classes.h"
00016 #include "pa_common.h"
00017 #include "pa_value.h"
00018
00019 // defines
00020
00021 #define FORM_FIELDS_ELEMENT_NAME "fields"
00022 #define FORM_TABLES_ELEMENT_NAME "tables"
00023 #define FORM_IMAP_ELEMENT_NAME "imap"
00024
00025 // forwards
00026
00027 class Request_info;
00028 class Request_charsets;
00029
00045 class VForm: public VStateless_class {
00046 public: // Value
00047
00048     const char* type() const { return "form"; }
00049
00050     // form: CLASS,method,field,tables field
00051     Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00052
00053 public: // usage
00054
00055     VForm(Request_charsets& acharsets, Request_info& arequest_info);
00056
00057 private:
00058
00059     Request_charsets& fcharsets;
00060     Request_info& frequest_info;
00061
00062     char *strpart(const char* str, size_t len);
00063     char *getAttributeValue(const char* data,char *attr,size_t len);
00064     void UnescapeChars(char **sp, const char* cp, size_t len);
00065     void ParseGetFormInput(const char* query_string, size_t length);
00066     void ParseFormInput(const char* data, size_t length);
00067     void ParseMimeInput(char *content_type, const char* data, size_t length);
00068     void AppendFormEntry(
00069         const char* cname_cstr,
00070         const char* raw_cvalue_ptr, const size_t raw_cvalue_size,
00071         const char* copy_me_file_name_cstr=0);
00072
00073     bool should_refill_fields_and_tables();
00074     void refill_fields_and_tables();
00075
00076 private:
00077
00078     Charset* filled_source;
00079     Charset* filled_client;
00080     HashStringValue fields;
00081     HashStringValue tables;
00082     HashStringValue imap;
00083
00084 private:
00085
00086     String::C transcode(const char* client, size_t client_size);
00087
00088 };
00089
00090 #endif


pa_vhash.C File Reference

Parser: hash class. More...

Include dependency graph for pa_vhash.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: hash class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vhash.C.

Variable Documentation

const char* const IDENT = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 8 of file pa_vhash.C.


pa_vhash.C Source File

pa_vhash.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT="$Date: 2005/08/09 08:14:54 $";
00009
00010 #include "pa_vhash.h"
00011 #include "pa_vfile.h"
00012
00013 VFile* VHash::as_vfile(String::Language /*lang*/,
00014     const Request_charsets * /*charsets*/)
00015 {
00016     return new VFile(fhash);
00017 }
00018
00019 void VHash::extract_default()
00020 {
00021     if( (_default=fhash.get(HASH_DEFAULT_ELEMENT_NAME) ) )
00022         fhash.remove(HASH_DEFAULT_ELEMENT_NAME);
00023 }


pa_vhash.h File Reference

Parser: hash parser type decl. More...

Include dependency graph for pa_vhash.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VHash
value of type 'hash', implemented with Hash. More...

class | VHash_lock

Defines

#define | VHASH_TYPE "hash"
#define | HASH_FIELDS_NAME "fields"
#define | HASH_DEFAULT_ELEMENT_NAME "_default"

Variables

const char *const | IDENT_VHASH_H = "$Date: 2005/08/09 08:14:54 $"
Methoded * hash_class

Detailed Description

Parser: hash parser type decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vhash.h.

Define Documentation

#define VHASH_TYPE "hash"

Definition at line 21 of file pa_vhash.h.

Referenced by _create_or_add(), VObject::get_hash(), and VHash::type().

#define HASH_FIELDS_NAME "fields"

Definition at line 22 of file pa_vhash.h.

Referenced by VHash::get_element().

#define HASH_DEFAULT_ELEMENT_NAME "_default"

Definition at line 24 of file pa_vhash.h.

Referenced by VHash::extract_default(), and VHash::put_element().

Variable Documentation

const char* const IDENT_VHASH_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vhash.h.

Methoded* hash_class

Definition at line 28 of file pa_vhash.h.


pa_vhash.h Source File

pa_vhash.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VHASH_H
00009 #define PA_VHASH_H
00010
00011 static const char * const IDENT_VHASH_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 #include "classes.h"
00014 #include "pa_value.h"
00015 #include "pa_hash.h"
00016 #include "pa_vint.h"
00017 #include "pa_globals.h"
00018
00019 // defines
00020
00021 #define VHASH_TYPE "hash"
00022 #define HASH_FIELDS_NAME "fields"
00023
00024 #define HASH_DEFAULT_ELEMENT_NAME "_default"
00025
00026 // externs
00027
00028 extern Methoded* hash_class;
00029
00030 // forwards
00031
00032 class VHash_lock;
00033
00035 class VHash: public VStateless_object {
00036     friend class VHash_lock;
00037 public: // value
00038
00039     override const char* type() const { return VHASH_TYPE; }
00040     override VStateless_class *get_class() { return hash_class; }
00041
00043     override int as_int() const { return fhash.count(); }
00045     override double as_double() const { return as_int(); }
00047     override bool is_defined() const { return as_bool(); }
00049     override bool as_bool() const { return as_int()!=0; }
00051     override Value& as_expr_result(bool ) { return *new VInt(as_int()); }
00052
00054     override HashStringValue *get_hash() { return &hash(); }
00055
00057     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00058         // $element
00059         if(Value* result=fhash.get(aname))
00060             return result;
00061
00062         // $fields -- pseudo field to make 'hash' more like 'table'
00063         if(aname == HASH_FIELDS_NAME)
00064             return this;
00065
00066         // $method
00067         if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00068             return result;
00069
00070         // default value
00071         return get_default();
00072     }
00073
00075     override const VJunction* put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*replace*/) {
00076         if(aname==HASH_DEFAULT_ELEMENT_NAME)
00077             set_default(avalue);
00078         else
00079             if(flocked) {
00080                 if(!fhash.put_replaced(aname, avalue))
00081                     throw Exception("parser.runtime",
00082                         &aname,
00083                         "can not insert new hash key (hash flocked)");
00084             } else
00085                     fhash.put(aname, avalue);
00086
00087         return PUT_ELEMENT_REPLACED_ELEMENT;
00088     }
00089
00090     override VFile* as_vfile(String::Language lang=String::L_UNSPECIFIED,
00091         const Request_charsets *charsets=0);
00092
00093 public: // usage
00094
00095     VHash(): flocked(false), _default(0) {}
00096
00097     VHash(const HashStringValue& source): fhash(source), flocked(false), _default(0) {}
00098
00099     HashStringValue& hash() {
00100         check_lock();
00101         return fhash;
00102     }
00103
00104     void set_default(Value* adefault) {
00105         _default=adefault;
00106     }
00107     Value* get_default() {
00108         return _default;
00109     }
00110
00111     void extract_default();
00112
00113     void check_lock() {
00114         if(flocked)
00115             throw Exception("parser.runtime",
00116                 0,
00117                 "can not modify hash (flocked)");
00118     }
00119
00120 private:
00121
00122     HashStringValue fhash;
00123     bool flocked;
00124     Value* _default;
00125
00126 };
00127
00128 class VHash_lock {
00129     VHash& fhash;
00130     bool saved;
00131 public:
00132     VHash_lock(VHash& ahash): fhash(ahash) {
00133         saved=fhash.flocked;
00134         fhash.flocked=true;
00135     }
00136     ~VHash_lock() {
00137         fhash.flocked=saved;
00138     }
00139
00140 };
00141
00142 #endif


pa_vhashfile.C File Reference

Parser: table class. More...

Include dependency graph for pa_vhashfile.C:

Include dependency graph

Go to the source code of this file.

Compounds

struct | Hashfile_value_serialized_prolog

Functions

void | check (const char *step, apr_status_t status)
void | for_each_string_callback (apr_sdbm_datum_t apkey, void *ainfo)
void | clear_delete_key (apr_sdbm_datum_t key, void *adb)
void | get_hash__put (const String::Body key, const String &value, void *aresult)
void | delete_file (const char *base_name, const char *ext)

Variables

const char *const | IDENT = "$Date: 2004/12/23 15:01:03 $"
const uint | HASHFILE_VALUE_SERIALIZED_VERSION = 0x0001

Detailed Description

Parser: table class.

Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vhashfile.C.

Function Documentation

void check | ( | const char * | step,
 |  | apr_status_t | status
 | ) |

Definition at line 24 of file pa_vhashfile.C.

References apr_status_t, APR_SUCCESS, and str.

Referenced by clear_delete_key(), VHashfile::close(), VHashfile::for_each(), for_each_string_callback(), VHashfile::get_db_for_writing(), VHashfile::get_field(), VHashfile::open(), VHashfile::put_field(), VHashfile::remove(), and string_contains_char_which().

void for_each_string_callback | ( | apr_sdbm_datum_t | apkey,
 |  | void * | ainfo
 | ) | [static]

Definition at line 234 of file pa_vhashfile.C.

References check(), apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, and pa_strdup().

Referenced by VHashfile::for_each().

void clear_delete_key | ( | apr_sdbm_datum_t | key,
 |  | void * | adb
 | ) | [static]

Definition at line 257 of file pa_vhashfile.C.

References check().

Referenced by VHashfile::clear().

void get_hash__put | ( | const String::Body | key,
 |  | const String & | value,
 |  | void * | aresult
 | ) | [static]

Definition at line 267 of file pa_vhashfile.C.

References value.

Referenced by VHashfile::get_hash().

void delete_file | ( | const char * | base_name,
 |  | const char * | ext
 | ) | [static]

Definition at line 277 of file pa_vhashfile.C.

References base_name, and file_delete().

Referenced by VHashfile::delete_files().

Variable Documentation

const char* const IDENT = "$Date: 2004/12/23 15:01:03 $" [static]

Definition at line 8 of file pa_vhashfile.C.

const uint HASHFILE_VALUE_SERIALIZED_VERSION = 0x0001

Definition at line 20 of file pa_vhashfile.C.

Referenced by VHashfile::deserialize_value(), and VHashfile::serialize_value().


pa_vhashfile.C Source File

pa_vhashfile.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT="$Date: 2004/12/23 15:01:03 $";
00009
00010 #include "pa_globals.h"
00011 #include "pa_common.h"
00012 #include "pa_threads.h"
00013 #include "pa_vtable.h"
00014 #include "pa_vstring.h"
00015 #include "pa_vhashfile.h"
00016 #include "pa_vdate.h"
00017
00018 // consts
00019
00020 const uint HASHFILE_VALUE_SERIALIZED_VERSION=0x0001;
00021
00022 // methods
00023
00024 void check(const char *step, apr_status_t status) {
00025     if(status==APR_SUCCESS)
00026         return;
00027
00028     const char* str=strerror(status);
00029     throw Exception("file.access",
00030         0,
00031         "%s error: %s (%d)",
00032             step, str?str:"<unknown>", status);
00033 }
00034
00035 void VHashfile::open(const String& afile_name) {
00036     file_name=afile_name.cstr(String::L_FILE_SPEC);
00037
00038     if(!entry_exists(file_name))
00039         create_dir_for_file(afile_name);
00040
00041     check("apr_sdbm_open(shared)", apr_sdbm_open(&m_db, file_name,
00042                                         APR_CREATE|APR_READ|APR_SHARELOCK,
00043                                         0664, 0));
00044 }
00045
00046 void VHashfile::close() {
00047     check_db();
00048
00049     check("apr_sdbm_close", apr_sdbm_close(m_db));  m_db=0;
00050 }
00051
00052 void VHashfile::check_db() const {
00053     if(!m_db)
00054         throw Exception(0,
00055             0,
00056             "%s is closed", type());
00057 }
00058
00059 apr_sdbm_t *VHashfile::get_db_for_reading() const {
00060     check_db();
00061
00062     return m_db;
00063 }
00064
00065 apr_sdbm_t *VHashfile::get_db_for_writing() {
00066     check_db();
00067
00068     if(apr_sdbm_rdonly(m_db)) {
00069         // reopen in write mode & exclusive lock
00070         close();
00071         check("apr_sdbm_open(exclusive)", apr_sdbm_open(&m_db, file_name,
00072                                             APR_WRITE,
00073                                             0664, 0));
00074     }
00075
00076     return m_db;
00077 }
00078
00079 VHashfile::~VHashfile() {
00080     if(m_db)
00081         close();
00082 }
00083
00084 struct Hashfile_value_serialized_prolog {
00085     uint version;
00086     time_t time_to_die;
00087 };
00088
00089 apr_sdbm_datum_t VHashfile::serialize_value(const String& string, time_t time_to_die) const {
00090     apr_sdbm_datum_t result;
00091
00092     size_t length=string.length();
00093     result.dsize=sizeof(Hashfile_value_serialized_prolog)+length;
00094     result.dptr=new(PointerFreeGC) char[result.dsize];
00095
00096     Hashfile_value_serialized_prolog& prolog=*reinterpret_cast<Hashfile_value_serialized_prolog*>(result.dptr);
00097     char *output_cstr=result.dptr+sizeof(Hashfile_value_serialized_prolog);
00098
00099     prolog.version=HASHFILE_VALUE_SERIALIZED_VERSION;
00100     prolog.time_to_die=time_to_die;
00101     if(length) // reported errors on storing empty values to hashfiles, but without details. maybe here [win32, intel:solaris, freebsd were OK...]
00102         memcpy(output_cstr, string.cstr(), length);
00103
00104     return result;
00105 }
00106
00107 const String* VHashfile::deserialize_value(apr_sdbm_datum_t key, const apr_sdbm_datum_t value) {
00108     // key not found || it's surely not in our format
00109     if(!value.dptr || (size_t)value.dsize<sizeof(Hashfile_value_serialized_prolog))
00110         return 0;
00111
00112     // [WARNING: not cast, addresses must be %4=0 on sparc]
00113     Hashfile_value_serialized_prolog prolog;
00114     memcpy(&prolog, value.dptr, sizeof(prolog));
00115
00116     if(prolog.version!=HASHFILE_VALUE_SERIALIZED_VERSION
00117         || (prolog.time_to_die/*specified*/
00118             && (prolog.time_to_die <= time(0)/*expired*/))) {
00119         // old format || exipred value
00120         remove(key);
00121         return 0;
00122     }
00123
00124     char *input_cstr=value.dptr+sizeof(Hashfile_value_serialized_prolog);
00125     size_t input_length=value.dsize-sizeof(Hashfile_value_serialized_prolog);
00126
00127     return new String(input_length? pa_strdup(input_cstr, input_length): 0, input_length, true);
00128 }
00129
00130 void VHashfile::put_field(const String& aname, Value *avalue) {
00131     apr_sdbm_t *db=get_db_for_writing();
00132
00133     time_t time_to_die=0;
00134     const String *value_string;
00135
00136     if(HashStringValue *hash=avalue->get_hash()) {
00137         if(Value *value_value=hash->get(value_name)) {
00138             if(value_value->get_junction())
00139                 throw Exception(0,
00140                     0,
00141                     VALUE_NAME" must not be code");
00142
00143             value_string=&value_value->as_string();
00144
00145             if(Value *expires=hash->get(expires_name)) {
00146                 if(Value* vdate=expires->as(VDATE_TYPE, false))
00147                     time_to_die=static_cast<VDate*>(vdate)->get_time(); // $expires[DATE]
00148                 else if(double days_till_expire=expires->as_double())
00149                     time_to_die=time(NULL)+(time_t)(60*60*24*days_till_expire); // $expires(days)
00150             }
00151         } else
00152             throw Exception(0,
00153                 &aname,
00154                 "put hash value must contain ."VALUE_NAME);
00155     } else
00156         value_string=&avalue->as_string();
00157
00158     if(aname.is_empty())
00159         throw Exception("parser.runtime",
00160             0,
00161             "hashfile key must not be empty");
00162
00163     apr_sdbm_datum_t key;
00164     key.dptr=const_cast<char*>(aname.cstr());
00165     key.dsize=aname.length();
00166
00167     apr_sdbm_datum_t value=serialize_value(*value_string, time_to_die);
00168
00169     check("apr_sdbm_store", apr_sdbm_store(db, key, value, APR_SDBM_REPLACE));
00170 }
00171
00172 Value *VHashfile::get_field(const String& aname) {
00173     apr_sdbm_t *db=get_db_for_reading();
00174
00175     apr_sdbm_datum_t key;
00176     key.dptr=const_cast<char*>(aname.cstr());
00177     key.dsize=aname.length();
00178
00179     apr_sdbm_datum_t value;
00180
00181     check("apr_sdbm_fetch", apr_sdbm_fetch(db, &value, key));
00182
00183     const String *sresult=deserialize_value(key, value);
00184     return sresult? new VString(*sresult): 0;
00185 }
00186
00187 void VHashfile::remove(const apr_sdbm_datum_t key) {
00188     apr_sdbm_t *db=get_db_for_writing();
00189
00190     check("apr_sdbm_delete", apr_sdbm_delete(db, key));
00191 }
00192
00193 void VHashfile::remove(const String& aname) {
00194     apr_sdbm_datum_t key;
00195     key.dptr=const_cast<char*>(aname.cstr());
00196     key.dsize=aname.length();
00197
00198     remove(key);
00199 }
00200
00201 void VHashfile::for_each(void callback(apr_sdbm_datum_t, void*), void* info) const {
00202     apr_sdbm_t *db=get_db_for_reading();
00203
00204     Array<apr_sdbm_datum_t> keys;
00205
00206     // collect keys
00207     check("apr_sdbm_lock", apr_sdbm_lock(db, APR_FLOCK_SHARED));
00208     try {
00209         apr_sdbm_datum_t key;
00210         if(apr_sdbm_firstkey(db, &key)==APR_SUCCESS)
00211             do {
00212                  // must clone because it points to page which may go away
00213                 // [if they modify hashfile inside foreach]
00214                 key.dptr = pa_strdup(key.dptr, key.dsize);
00215                 keys+=key;
00216             } while(apr_sdbm_nextkey(db, &key)==APR_SUCCESS);
00217     } catch(...) {
00218             check("apr_sdbm_unlock", apr_sdbm_unlock(db));
00219             rethrow;
00220     }
00221     check("apr_sdbm_unlock", apr_sdbm_unlock(db));
00222
00223     // iterate them
00224     keys.for_each(callback, info);
00225 }
00226
00227 #ifndef DOXYGEN
00228 struct For_each_string_callback_info {
00229     VHashfile* self;
00230     void* nested_info;
00231     void (*nested_callback)(const String::Body, const String&, void*);
00232 };
00233 #endif
00234 static void for_each_string_callback(apr_sdbm_datum_t apkey, void* ainfo) {
00235     For_each_string_callback_info& info=*static_cast<For_each_string_callback_info *>(ainfo);
00236     apr_sdbm_t *db=info.self->get_db_for_reading();
00237
00238     apr_sdbm_datum_t apvalue;
00239     check("apr_sdbm_fetch", apr_sdbm_fetch(db, &apvalue, apkey));
00240
00241     if(const String* svalue=info.self->deserialize_value(apkey, apvalue)) {
00242         const char *clkey=pa_strdup(apkey.dptr, apkey.dsize);
00243
00244         info.nested_callback(clkey, *svalue, info.nested_info);
00245     }
00246 }
00247 void VHashfile::for_each(void callback(const String::Body, const String&, void*), void* ainfo) {
00248     For_each_string_callback_info info;
00249
00250     info.self=this;
00251     info.nested_info=ainfo;
00252     info.nested_callback=callback;
00253
00254     for_each(for_each_string_callback, &info);
00255 }
00256
00257 static void clear_delete_key(apr_sdbm_datum_t key, void* adb) {
00258     check("apr_sdbm_delete", apr_sdbm_delete(static_cast<apr_sdbm_t*>(adb), key));
00259 }
00260 void VHashfile::clear() {
00261     apr_sdbm_t *db=get_db_for_writing();
00262
00263     for_each(clear_delete_key, db);
00264 }
00265
00266
00267 static void get_hash__put(const String::Body key, const String& value, void* aresult) {
00268     static_cast<HashStringValue*>(aresult)->put(key, new VString(value));
00269 }
00270 HashStringValue *VHashfile::get_hash() {
00271     HashStringValue& result=*new HashStringValue();
00272
00273     for_each(get_hash__put, &result);
00274     return &result;
00275 }
00276
00277 static void delete_file(const char* base_name, const char* ext) {
00278     String sfile_name(base_name, false/*already removed tainting at ::open*/);
00279     sfile_name<<ext;
00280     file_delete(sfile_name);
00281 }
00282
00283 void VHashfile::delete_files() {
00284     close();
00285     delete_file(file_name, APR_SDBM_DIRFEXT);
00286     delete_file(file_name, APR_SDBM_PAGFEXT);
00287 }


pa_vhashfile.h File Reference

Parser: hashfile parser type decl. More...

Include dependency graph for pa_vhashfile.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VHashfile
value of type 'hashfile', implemented with SDBM library bundled in ../libs/sdbm. More...

Defines

#define | VHASHFILE_TYPE "hashfile"

Variables

const char *const | IDENT_VHASHFILE_H = "$Date: 2005/08/09 08:14:54 $"
Methoded * hashfile_class

Detailed Description

Parser: hashfile parser type decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vhashfile.h.

Define Documentation

#define VHASHFILE_TYPE "hashfile"

Definition at line 23 of file pa_vhashfile.h.

Referenced by VHashfile::type().

Variable Documentation

const char* const IDENT_VHASHFILE_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vhashfile.h.

Methoded* hashfile_class

Definition at line 27 of file pa_vhashfile.h.


pa_vhashfile.h Source File

pa_vhashfile.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VHASHFILE_H
00009 #define PA_VHASHFILE_H
00010
00011 static const char * const IDENT_VHASHFILE_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 #include "classes.h"
00014 #include "pa_pool.h"
00015 #include "pa_value.h"
00016 #include "pa_hash.h"
00017 #include "pa_vint.h"
00018
00019 #include "apr_sdbm.h"
00020
00021 // defines
00022
00023 #define VHASHFILE_TYPE "hashfile"
00024
00025 // externs
00026
00027 extern Methoded *hashfile_class;
00028
00030 class VHashfile : public VStateless_object, Pooled {
00031 public: // value
00032
00033     override const char *type() const { return VHASHFILE_TYPE; }
00034     override VStateless_class *get_class() { return hashfile_class; }
00035
00037     override HashStringValue *get_hash();
00038
00040     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00041         // $CLASS,$method
00042         if(Value *result=VStateless_object::get_element(aname, aself, looking_up))
00043             return result;
00044
00045         // $element
00046         return get_field(aname);
00047     }
00048
00050     override const VJunction* put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*replace*/) {
00051         put_field(aname, avalue);
00052         return false; // nobody is supposed to derive from hashfile, so does not matter
00053     }
00054
00055 public: // usage
00056
00057     VHashfile(Pool& apool): Pooled(apool), m_db(0) {}
00058     override ~VHashfile();
00059
00060     void open(const String& afile_name);
00061     void close();
00062     void check_db() const;
00063     apr_sdbm_t *get_db_for_reading() const;
00064     apr_sdbm_t *get_db_for_writing();
00065     void clear();
00066     void delete_files();
00067     void remove(const String& aname);
00068
00069     void for_each(void callback(apr_sdbm_datum_t, void*), void* info) const;
00070     void for_each(void callback(const String::Body, const String&, void*), void* info);
00071
00072 public:
00073
00074     void remove(const apr_sdbm_datum_t key);
00075
00076     apr_sdbm_datum_t serialize_value(const String& string, time_t time_to_die) const;
00077     const String* deserialize_value(const apr_sdbm_datum_t key, const apr_sdbm_datum_t value);
00078
00079 private:
00080
00081     Value *get_field(const String& aname);
00082     void put_field(const String& aname, Value *avalue);
00083
00084 private:
00085
00086     const char* file_name;
00087     apr_sdbm_t *m_db;
00088
00089 };
00090
00091 #endif


pa_vimage.C File Reference

Parser: image parser type. More...

Include dependency graph for pa_vimage.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_VIMAGE_C = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: image parser type.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vimage.C.

Variable Documentation

const char* const IDENT_VIMAGE_C = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 8 of file pa_vimage.C.


pa_vimage.C Source File

pa_vimage.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VIMAGE_C="$Date: 2005/08/09 08:14:54 $";
00009
00010 #include "pa_vimage.h"
00011 #include "pa_vint.h"
00012 #include "pa_vstring.h"
00013 #include "gif.h"
00014
00015 void VImage::set(const String* src, int width, int height,
00016                  gdImage* aimage,
00017                  Value* aexif) {
00018     fimage=aimage;
00019     fexif=aexif;
00020
00021     // $src
00022     if(src)
00023         ffields.put(String::Body("src"), new VString(*src));
00024     // $width
00025     if(width)
00026         ffields.put(String::Body("width"), new VInt(width));
00027     // $height
00028     if(height)
00029         ffields.put(String::Body("height"), new VInt(height));
00030     // defaults
00031     // $border(0)
00032     ffields.put(String::Body("border"), new VInt(0));
00033
00034     // internals, take a look at image.C append_attrib_pair before update
00035     // $line-width(1)
00036     ffields.put(String::Body("line-width"), new VInt(1));
00037 }
00038
00039
00040 Value* VImage::get_element(const String& aname, Value& aself, bool looking_up) {
00041     // $method
00042     if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00043         return result;
00044
00045     // $exif
00046     if(aname==EXIF_ELEMENT_NAME)
00047         return fexif;
00048
00049     // $src, $size
00050     return ffields.get(aname);
00051 }
00052
00053 const VJunction* VImage::put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*replace*/) {
00054     ffields.put(aname, avalue);
00055
00056     if(fimage) {
00057         if(aname=="line-width") {
00058             fimage->SetLineWidth(min(max(avalue->as_int(), 1), 10));
00059         } else if(aname=="line-style") {
00060             const String& sline_style=avalue->as_string();
00061             fimage->SetLineStyle(sline_style.length()?sline_style.cstr(String::L_AS_IS):0);
00062         }
00063     }
00064
00065     return PUT_ELEMENT_REPLACED_ELEMENT;
00066 }


pa_vimage.h File Reference

Parser: image parser type decl. More...

Include dependency graph for pa_vimage.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | Font
simple gdImage-based font storage & text output. More...

class | VImage
holds img attributes and [image itself]. More...

Defines

#define | VIMAGE_TYPE "image"
#define | EXIF_ELEMENT_NAME "exif"

Variables

const char *const | IDENT_VIMAGE_H = "$Date: 2005/08/09 08:14:54 $"
Methoded * image_class

Detailed Description

Parser: image parser type decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vimage.h.

Define Documentation

#define VIMAGE_TYPE "image"

Definition at line 19 of file pa_vimage.h.

Referenced by as_image(), and VImage::type().

#define EXIF_ELEMENT_NAME "exif"

Definition at line 20 of file pa_vimage.h.

Referenced by VImage::get_element().

Variable Documentation

const char* const IDENT_VIMAGE_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vimage.h.

Methoded* image_class

Definition at line 56 of file pa_vimage.h.


pa_vimage.h Source File

pa_vimage.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VIMAGE_H
00009 #define PA_VIMAGE_H
00010
00011 static const char * const IDENT_VIMAGE_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 #include "classes.h"
00014 #include "pa_common.h"
00015 #include "pa_vstateless_object.h"
00016
00017 // defines
00018
00019 #define VIMAGE_TYPE "image"
00020 #define EXIF_ELEMENT_NAME "exif"
00021
00022 // forwards
00023
00024 class gdImage;
00025
00027 class Font: public PA_Object {
00028 public:
00029
00030     static const int letter_spacing;
00031     int height;
00032     int monospace;
00033     int spacebarspace;
00034     gdImage* ifont;
00035     const String& alphabet;
00036
00037     Font(
00038         const String& aalphabet,
00039         gdImage* aifont, int aheight, int amonospace, int aspacebarspace);
00040
00042     size_t index_of(char ch);
00043     int index_width(size_t index);
00044     void index_display(gdImage& image, int x, int y, size_t index);
00046
00047     int step_width(int index);
00049
00050     int string_width(const String& s);
00051     void string_display(gdImage& image, int x, int y, const String& s);
00052 };
00053
00054 // externs
00055
00056 extern Methoded* image_class;
00057
00061 class VImage: public VStateless_object {
00062 public: // Value
00063
00064     override const char* type() const { return VIMAGE_TYPE; }
00065     override VStateless_class *get_class() { return image_class; }
00066
00068     override bool as_bool() const { return true; }
00069
00071     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VBool(as_bool()); }
00072
00074     override Value* get_element(const String& aname, Value& aself, bool looking_up);
00075
00077     override const VJunction* put_element(Value& self, const String& name, Value* value, bool replace);
00078
00079 public: // usage
00080
00081     void set(const String* src, int width, int height,
00082         gdImage* aimage,
00083         Value* aexif=0);
00084
00085     HashStringValue& fields() { return ffields; }
00086
00087 public:
00088
00089     gdImage& image() {
00090         if(!fimage)
00091             throw Exception("parser.runtime",
00092                 0,
00093                 "using unitialized image object");
00094
00095         return *fimage;
00096     }
00097
00098     void set_font(Font* afont) { ffont=afont; }
00099     Font& font() {
00100         if(!ffont)
00101             throw Exception("parser.runtime",
00102                 0,
00103                 "set the font first");
00104         return *ffont;
00105     }
00106
00107 private:
00108
00109     gdImage* fimage;
00110     Font* ffont;
00111     HashStringValue ffields;
00112     Value* fexif;
00113
00114 };
00115
00116 #endif


pa_vint.h File Reference

Parser: int parser class decl. More...

Include dependency graph for pa_vint.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VInt
value of type 'int'. implemented with int. More...

Variables

const char *const | IDENT_VINT_H = "$Date: 2005/11/21 10:13:43 $"
Methoded * int_class

Detailed Description

Parser: int parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vint.h.

Variable Documentation

const char* const IDENT_VINT_H = "$Date: 2005/11/21 10:13:43 $" [static]

Definition at line 11 of file pa_vint.h.

Methoded* int_class

Definition at line 17 of file pa_vint.h.


pa_vint.h Source File

pa_vint.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VINT_H
00009 #define PA_VINT_H
00010
00011 static const char * const IDENT_VINT_H="$Date: 2005/11/21 10:13:43 $";
00012
00013 #include "classes.h"
00014 #include "pa_common.h"
00015 #include "pa_vstateless_object.h"
00016
00017 extern Methoded* int_class;
00018
00020 class VInt: public VStateless_object {
00021 public: // Value
00022
00023     override const char* type() const { return "int"; }
00024     override VStateless_class *get_class() { return int_class; }
00025
00027     override bool is_evaluated_expr() const { return true; }
00029     override Value& as_expr_result(bool) { return *new VInt(finteger); }
00030
00032     override const String* get_string() {
00033         char local_buf[MAX_NUMBER];
00034         size_t length=snprintf(local_buf, MAX_NUMBER, "%d", finteger);
00035         return new String(strdup(local_buf, length), length);
00036     }
00038     override double as_double() const { return as_int(); }
00040     override int as_int() const { return finteger; }
00042     override bool as_bool() const { return finteger!=0; }
00043
00044 public: // usage
00045
00046     VInt(int ainteger): finteger(ainteger) {}
00047
00048     int get_int() { return finteger; }
00049     void set_int(int ainteger) { finteger=ainteger; }
00050
00051     void inc(int increment) { finteger+=increment; }
00052     void mul(double k) { finteger=(int)(finteger*k); }
00053     void div(double d) { finteger=(int)(finteger/d); }
00054     void mod(int d) { finteger%=d; }
00055
00056 private:
00057
00058     int finteger;
00059
00060 };
00061
00062 #endif


pa_vjunction.h File Reference

Parser: junction class decl. More...

Include dependency graph for pa_vjunction.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VJunction
junction is method+self+context, implemented with Junction. More...

Variables

const char *const | IDENT_VJUNCTION_H = "$Date: 2005/08/09 08:14:54 $"

Detailed Description

Parser: junction class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vjunction.h.

Variable Documentation

const char* const IDENT_VJUNCTION_H = "$Date: 2005/08/09 08:14:54 $" [static]

Definition at line 11 of file pa_vjunction.h.


pa_vjunction.h Source File

pa_vjunction.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VJUNCTION_H
00009 #define PA_VJUNCTION_H
00010
00011 static const char * const IDENT_VJUNCTION_H="$Date: 2005/08/09 08:14:54 $";
00012
00013 // include
00014
00015 #include "pa_value.h"
00016 #include "pa_vbool.h"
00017 #include "pa_junction.h"
00018
00020 class VJunction: public Value {
00021 public: // VJunction
00022
00023     override const char* type() const { return "junction"; }
00024
00026     override VStateless_class *get_class() { return 0; }
00027
00029     override bool is_defined() const { return false; }
00030
00032     override bool as_bool() const { return is_defined(); }
00033
00035     override Value& as_expr_result(bool) { return *new VBool(as_bool()); }
00036
00038     override Junction* get_junction() { return &fjunction; }
00039
00040 public: // usage
00041
00043     VJunction(Value& aself,
00044         const Method* amethod,
00045         VMethodFrame* amethod_frame,
00046         Value* arcontext,
00047         WContext* awcontext,
00048         ArrayOperation* acode): fjunction(aself, amethod, amethod_frame, arcontext, awcontext, acode) {}
00049
00051     VJunction(Value& aself,
00052         const Method* amethod,
00053         bool ais_getter=false): fjunction(aself, amethod, ais_getter) {}
00054
00055     const Junction& junction() const { return fjunction; }
00056
00057 private:
00058
00059     Junction fjunction;
00060 };
00061
00062
00063 #endif


pa_vmail.C File Reference

Parser: mail class. More...

Include dependency graph for pa_vmail.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | RAW_NAME "raw"
#define | FORMAT_NAME "format"
#define | CHARSET_NAME "charset"

Typedefs

typedef int(* | string_contains_char_which_check )(int)

Enumerations

enum PartType {
P_TEXT, P_HTML, P_FILE, P_MESSAGE,
P_TYPES_COUNT
}

Functions

const String | format_name (FORMAT_NAME)
const String | charset_name (CHARSET_NAME)
bool | string_contains_char_which (const char *string, string_contains_char_which_check check)
char * | trimBoth (char *s)
void | extractEmail (String &result, char *email)
const String & | extractEmails (const String &string)
void | store_message_element (HashStringValue::key_type raw_element_name, HashStringValue::value_type element_value, Store_message_element_info *info)
const String & | file_value_to_string (Request &r, Value *send_value)
const String & | text_value_to_string (Request &r, PartType pt, Value *send_value, Store_message_element_info &info)

Variables

const char *const | IDENT_VMAIL_C = "$Date: 2005/12/09 07:18:08 $"
const char *const | part_name_begins [P_TYPES_COUNT] = {"text", "html", "file", "message"}
const int | MAX_CHARS_IN_HEADER_LINE = 500
Methoded * mail_base_class

Detailed Description

Parser: mail class.

relies on gmime library, by Jeffrey Stedfast <fejj@helixcode.com>

Copyright(c) 2001-2005 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru>(http://paf.design.ru)

Definition in file pa_vmail.C.

Define Documentation

#define RAW_NAME "raw"

Definition at line 32 of file pa_vmail.C.

Referenced by store_message_element().

#define FORMAT_NAME "format"

Definition at line 49 of file pa_vmail.C.

Referenced by store_message_element().

#define CHARSET_NAME "charset"

Definition at line 50 of file pa_vmail.C.

Referenced by store_message_element().

Typedef Documentation

typedef int(* string_contains_char_which_check)(int)

Definition at line 369 of file pa_vmail.C.

Referenced by extractEmail(), and string_contains_char_which().

Enumeration Type Documentation

enum PartType

Enumeration values:
P_TEXT
P_HTML
P_FILE
P_MESSAGE
P_TYPES_COUNT

Definition at line 36 of file pa_vmail.C.

Referenced by VMail::message_hash_to_string(), and text_value_to_string().

Function Documentation

const String format_name ( FORMAT_NAME ) [static]

const String charset_name ( CHARSET_NAME ) [static]

bool string_contains_char_which | ( | const char * | string,
 |  | string_contains_char_which_check | check
 | ) | [static]

Definition at line 370 of file pa_vmail.C.

References check(), and string_contains_char_which_check.

Referenced by extractEmail().

char* trimBoth ( char * s ) [static]

Definition at line 377 of file pa_vmail.C.

Referenced by extractEmail().

void extractEmail | ( | String & | result,
 |  | char * | email
 | ) | [static]

Definition at line 397 of file pa_vmail.C.

References String::append_help_length(), String::is_empty(), String::L_TAINTED, result, string_contains_char_which(), string_contains_char_which_check, and trimBoth().

Referenced by extractEmails().

const String& extractEmails ( const String & string ) [static]

Definition at line 442 of file pa_vmail.C.

References String::cstrm(), extractEmail(), String::is_empty(), lsplit(), result, and rsplit().

Referenced by store_message_element().

void store_message_element | ( | HashStringValue::key_type | raw_element_name,
 |  | HashStringValue::value_type | element_value,
 |  | Store_message_element_info * | info
 | ) | [static]

Definition at line 490 of file pa_vmail.C.

References String::append_strdup(), attributed_meaning_to_string(), String::CC_LOWER, CHARSET_NAME, CONTENT_DISPOSITION_NAME, CONTENT_TYPE_NAME, String::cstr(), extractEmails(), FORMAT_NAME, String::is_empty(), String::L_MAIL_HEADER, String::L_PASS_APPENDED, String::L_TAINTED, String::L_UNSPECIFIED, String::C::length, String::length(), MAIL_OPTIONS_NAME, MAX_CHARS_IN_HEADER_LINE, String::mid(), P_TYPES_COUNT, part_name_begins, RAW_NAME, String::starts_with(), String::C::str, Charset::transcode(), and VALUE_NAME.

Referenced by file_value_to_string(), VMail::message_hash_to_string(), and text_value_to_string().

const String& file_value_to_string | ( | Request & | r,
 |  | Value * | send_value
 | ) | [static]

Definition at line 593 of file pa_vmail.C.

References Value::as_string(), Value::as_vfile(), Request::charsets, CONTENT_DISPOSITION_FILENAME_NAME, CONTENT_DISPOSITION_NAME, CONTENT_DISPOSITION_VALUE, String::cstr(), VFile::fields(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), String::L_AS_IS, String::L_UNSPECIFIED, Request::mime_type_of(), pa_uuencode(), result, and store_message_element().

Referenced by VMail::message_hash_to_string().

const String& text_value_to_string | ( | Request & | r,
 |  | PartType | pt,
 |  | Value * | send_value,
 |  | Store_message_element_info & | info
 | ) | [static]

Definition at line 650 of file pa_vmail.C.

References String::append_know_length(), Value::as_string(), Request::charsets, charsets, String::cstr(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_junction(), String::L_CLEAN, String::L_HTML, String::L_OPTIMIZE_BIT, String::L_UNSPECIFIED, String::Language, String::C::length, Request_charsets::mail(), P_HTML, P_TEXT, part_name_begins, PartType, Request::process_to_string(), result, Request_charsets::source(), store_message_element(), String::C::str, strdup, Charset::transcode(), and VALUE_NAME.

Referenced by VMail::message_hash_to_string().

Variable Documentation

const char* const IDENT_VMAIL_C = "$Date: 2005/12/09 07:18:08 $" [static]

Definition at line 9 of file pa_vmail.C.

const char* const part_name_begins[P_TYPES_COUNT] = {"text", "html", "file", "message"} [static]

Definition at line 45 of file pa_vmail.C.

Referenced by store_message_element(), and text_value_to_string().

const int MAX_CHARS_IN_HEADER_LINE = 500

Definition at line 59 of file pa_vmail.C.

Referenced by store_message_element().

Methoded* mail_base_class

Definition at line 63 of file pa_vmail.C.

Referenced by _send().


pa_vmail.C Source File

pa_vmail.C

Go to the documentation of this file.
00001
00009 static const char * const IDENT_VMAIL_C="$Date: 2005/12/09 07:18:08 $";
00010
00011 #include "pa_sapi.h"
00012 #include "pa_vmail.h"
00013 #include "pa_vstring.h"
00014 #include "pa_request.h"
00015 #include "pa_common.h"
00016 #include "pa_charset.h"
00017 #include "pa_charsets.h"
00018 #include "pa_vdate.h"
00019 #include "pa_vfile.h"
00020 #include "pa_uue.h"
00021
00022 #ifdef WITH_MAILRECEIVE
00023 extern "C" {
00024 #include "gmime.h"
00025 }
00026
00027 #include "pa_charsets.h"
00028 #endif
00029
00030 // defines
00031
00032 #define RAW_NAME "raw"
00033
00034 // internals
00035
00036 enum PartType {
00037     P_TEXT,
00038     P_HTML,
00039     P_FILE,
00040     P_MESSAGE,
00041
00042     P_TYPES_COUNT
00043 };
00044
00045 static const char* const part_name_begins[P_TYPES_COUNT]={"text", "html", "file", "message"};
00046
00047 // defines for statics
00048
00049 #define FORMAT_NAME "format"
00050 #define CHARSET_NAME "charset"
00051
00052 // statics
00053
00054 static const String format_name(FORMAT_NAME);
00055 static const String charset_name(CHARSET_NAME);
00056
00057 // consts
00058
00059 const int MAX_CHARS_IN_HEADER_LINE=500;
00060
00061 // VMail
00062
00063 extern Methoded* mail_base_class;
00064
00065 VMail::VMail(): VStateless_class(0, mail_base_class) {}
00066
00067 #ifdef WITH_MAILRECEIVE
00068
00069 #define EXCEPTION_VALUE "x-exception"
00070
00071 static const String& maybeUpperCase(Charset& source_charset,
00072                     const String& src, bool toUpperCase) {
00073     return toUpperCase?src.change_case(source_charset, String::CC_UPPER):src;
00074 }
00075
00076 static void putReceived(Charset& source_charset,
00077             HashStringValue& received,
00078             const char* must_clone_name, Value* value,
00079             bool nameToUpperCase=false) {
00080
00081     if(must_clone_name && value) {
00082         received.put(
00083             maybeUpperCase(source_charset,
00084                 *new String(pa_strdup(must_clone_name)), nameToUpperCase),
00085             value);
00086     }
00087 }
00088
00089 static void putReceived(Charset& source_charset,
00090             HashStringValue& received,
00091             const char* must_clone_name, const char* must_clone_value,
00092             bool nameToUpperCase=false) {
00093     if(must_clone_name && must_clone_value) {
00094
00095         String::C must_clone_value_cstr(must_clone_value, strlen(must_clone_value));
00096         //must_clone_value_cstr=Charset::transcode(must_clone_value_cstr, UTF8_charset, source_charset);
00097
00098         putReceived(source_charset,
00099             received,
00100             pa_strdup(must_clone_name),
00101             new VString(*new String(pa_strdup(must_clone_value_cstr.str))),
00102             nameToUpperCase
00103         );
00104     }
00105 }
00106
00107 static void putReceived(HashStringValue& received, const char* must_clone_name, time_t value) {
00108     if(must_clone_name)
00109         received.put(
00110             String::Body(pa_strdup(must_clone_name)),
00111             new VDate(value)
00112         );
00113 }
00114
00115 #ifndef DOXYGEN
00116 struct MimeHeaderField2received_info {
00117     Charset* source_charset;
00118     HashStringValue* received;
00119 };
00120 #endif
00121 static void MimeHeaderField2received(const char* must_clone_name, const char* must_clone_value, gpointer data) {
00122     MimeHeaderField2received_info& info=*static_cast<MimeHeaderField2received_info *>(data);
00123
00124     putReceived(*info.source_charset,
00125         *info.received,
00126         must_clone_name, must_clone_value, true/*nameInUpperCase*/);
00127 }
00128
00129 static void parse(Request& r, GMimeStream *stream, HashStringValue& received);
00130
00131 #ifndef DOXYGEN
00132 struct MimePart2body_info {
00133     Request* r;
00134     HashStringValue* body;
00135     int partCounts[P_TYPES_COUNT];
00136 };
00137 #endif
00138 static void MimePart2body(GMimePart *part, gpointer data) {
00139     MimePart2body_info& info=*static_cast<MimePart2body_info *>(data);
00140     Charset& source_charset=info.r->charsets.source();
00141
00142     if(const GMimeContentType *type=g_mime_part_get_content_type(part)) {
00143         if(g_mime_content_type_is_type(type, "multipart", "*"))
00144             return; // skipping frames
00145
00146         PartType partType;
00147         if(part->disposition) // inline/attachment
00148             partType=P_FILE;
00149         else if(g_mime_content_type_is_type(type, "text", "plain"))
00150             partType=P_TEXT;
00151         else if(g_mime_content_type_is_type(type, "text", "html"))
00152             partType=P_HTML;
00153         else if(g_mime_content_type_is_type(type, "message", "*"))
00154             partType=P_MESSAGE;
00155         else
00156             partType=P_FILE;
00157
00158         // partName
00159         const char* partNameNumbered;
00160         char partNameBuf[MAX_STRING];
00161         const char* partNameStart=part_name_begins[partType];
00162         int partNo=++info.partCounts[partType];
00163         snprintf(partNameBuf, MAX_STRING, "%s%d", partNameStart, partNo);
00164         partNameNumbered=partNameBuf;
00165
00166         // $.partX[
00167         VHash* vpartX(new VHash);
00168         putReceived(source_charset, *info.body, partNameNumbered, vpartX);
00169         if(partNo==1)
00170             putReceived(source_charset, *info.body, partNameStart, vpartX);
00171
00172         HashStringValue& partX=vpartX->hash();
00173         {
00174             // $.raw[
00175             VHash* vraw(new VHash);  putReceived(source_charset, partX, RAW_NAME, vraw);
00176             MimeHeaderField2received_info hfr_info={&source_charset, &vraw->hash()};
00177             g_mime_header_foreach(part->headers, MimeHeaderField2received, &hfr_info);
00178         }
00179         const char* content_filename=0;
00180         {
00181             // $.content-type[
00182             VHash* vcontent_type(new VHash);  putReceived(source_charset, partX, "content-type", vcontent_type);
00183             HashStringValue& content_type=vcontent_type->hash();
00184             {
00185                 // $.value[text/plain]
00186                 char value[MAX_STRING];
00187                 snprintf(value, MAX_STRING, "%s/%s",
00188                     type->type?type->type:"x-unknown",
00189                     type->subtype?type->subtype:"x-unknown");
00190                 putReceived(source_charset, content_type, VALUE_NAME, value);
00191             }
00192             GMimeParam *param=type->params;
00193             while(param) {
00194                 // $.charset[windows-1251]  && co
00195                 putReceived(source_charset, content_type, param->name, param->value, true);
00196                 if(strcasecmp(param->name, "name")==0)
00197                     content_filename=param->value;
00198                 param=param->next;
00199             }
00200         }
00201         // $.description
00202         putReceived(source_charset, partX, "description", part->description);
00203         // $.content-id
00204         putReceived(source_charset, partX, "content-id", part->content_id);
00205         // $.content-md5
00206         putReceived(source_charset, partX, "content-md5", part->content_md5);
00207         // $.content-location
00208         putReceived(source_charset, partX, "content-location", part->content_location);
00209
00210         // todo GMimePart:
00211         //   GMimePartEncodingType encoding;
00212         //   GMimeDisposition *disposition;
00213         if(part->disposition) {
00214             GMimeParam *param=part->disposition->params;
00215             while(param) {
00216                 // $.charset[windows-1251]  && co
00217                 if(strcasecmp(param->name, "filename")==0)
00218                     content_filename=param->value;
00219                 param=param->next;
00220             }
00221         }
00222
00223         // MESSAGE
00224         if(partType==P_MESSAGE) {
00225             if(part->content)
00226                 if(GMimeStream *stream=part->content->stream)
00227                     parse(*info.r, stream, partX);
00228         } else {
00229             // $.value[string|file]
00230             size_t buf_len;
00231             const char* local_buf=(const char*)g_mime_part_get_content(part, &buf_len);
00232             if(partType==P_FILE) {
00233                 VFile* vfile(new VFile);
00234                 char *pooled_buf=pa_strdup(local_buf, buf_len);
00235                 VString* vcontent_type=content_filename?
00236                     new VString(info.r->mime_type_of(content_filename)):0;
00237                 vfile->set(true/*tainted*/, pooled_buf, buf_len, content_filename, vcontent_type);
00238                 putReceived(source_charset, partX, VALUE_NAME, vfile);
00239             } else {
00240                 // P_TEXT, P_HTML
00241                 putReceived(source_charset, partX, VALUE_NAME,(const char*)local_buf);
00242             }
00243         }
00244     }
00245 }
00246
00247 int gmt_offset() {
00248 #if defined(HAVE_TIMEZONE) && defined(HAVE_DAYLIGHT)
00249     return timezone+(daylight?60*60*(timezone<0?-1:timezone>0?+1:0):0);
00250 #else
00251     time_t t=time(0);
00252     tm *tm=localtime(&t);
00253 #if defined(HAVE_TM_GMTOFF)
00254     return tm->tm_gmtoff;
00255 #elif defined(HAVE_TM_TZADJ)
00256     return tm->tm_tzadj;
00257 #else
00258 #error neither HAVE_TIMEZONE&HAVE_DAYIGHT nor HAVE_TM_GMTOFF nor HAVE_TM_TZADJ defined
00259 #endif
00260 #endif
00261 }
00262
00263 static void parse(Request& r, GMimeStream *stream, HashStringValue& received) {
00264     Charset& source_charset=r.charsets.source();
00265
00266     GMimeMessage *message=g_mime_parser_construct_message(stream);
00267     try {
00268         const GMimeMessageHeader *messageHeader=message->header;
00269         if(!messageHeader)
00270             return;
00271
00272         // firstly user-defined strings go
00273         //  user headers
00274         {
00275             // $.raw[
00276             VHash* vraw(new VHash);  putReceived(source_charset, received, RAW_NAME, vraw);
00277             MimeHeaderField2received_info hfr_info={&source_charset, &vraw->hash()};
00278             g_mime_header_foreach(messageHeader->headers, MimeHeaderField2received, &hfr_info);
00279         }
00280
00281         // maybe-todo-recipients
00282         // x(messageHeader->recipients)
00283
00284         //  secondly standard headers&body go
00285         //  standard header
00286         // .from
00287         putReceived(source_charset, received, "from", messageHeader->from);
00288         // .reply-to
00289         putReceived(source_charset, received, "reply-to", messageHeader->reply_to);
00290         // .to
00291         // todo: messageHeader->recipients
00292         // .subject
00293         putReceived(source_charset, received, "subject", messageHeader->subject);
00294         // .date(date+gmt_offset)
00295         int tt_offset =
00296             ((messageHeader->gmt_offset / 100) *(60 * 60))
00297             +(messageHeader->gmt_offset % 100) * 60;
00298
00299         putReceived(received, "date",
00300             messageHeader->date // local sender
00301             -tt_offset // move local sender to GMT sender
00302             -gmt_offset() // move GMT sender to our local time
00303         );
00304         // .message-id
00305         putReceived(source_charset, received, "message-id", messageHeader->message_id);
00306
00307         // .body[part/parts
00308         GMimePart *part=message->mime_part;
00309         MimePart2body_info info={&r, &received, {0}};
00310         g_mime_part_foreach(part, MimePart2body, &info);
00311
00312         // normal unref
00313         g_mime_object_unref(GMIME_OBJECT(message));
00314     } catch(const Exception& e) {
00315         // abnormal unref
00316         g_mime_object_unref(GMIME_OBJECT(message));
00317         putReceived(source_charset, received, VALUE_NAME, "<exception occured while parsing message>");
00318         putReceived(source_charset, received, EXCEPTION_VALUE, e.comment());
00319     } catch(...) {
00320         // abnormal unref
00321         g_mime_object_unref(GMIME_OBJECT(message));
00322         putReceived(source_charset, received, VALUE_NAME, "<exception occured while parsing message>");
00323     }
00324 }
00325 #endif
00326
00327
00328
00329 void VMail::fill_received(Request&
00330 #ifdef WITH_MAILRECEIVE
00331                           r
00332 #endif
00333                           ) {
00334     // store letter to received
00335 #ifdef WITH_MAILRECEIVE
00336     if(r.request_info.mail_received) {
00337         // init
00338         g_mime_init(0);
00339         //  g_mime_init(GMIME_INIT_FLAG_UTF8);
00340
00341         // create stream with CRLF filter
00342         GMimeStream *stream = g_mime_stream_fs_new(fileno(stdin));
00343         GMimeStream *istream = g_mime_stream_filter_new_with_stream(stream);
00344         GMimeFilter *filter = g_mime_filter_crlf_new(GMIME_FILTER_CRLF_DECODE, GMIME_FILTER_CRLF_MODE_CRLF_ONLY);
00345         g_mime_stream_filter_add(GMIME_STREAM_FILTER(istream), filter);
00346         g_mime_stream_unref(stream);
00347         stream = istream;
00348         try {
00349             // parse incoming stream
00350             parse(r, stream, vreceived.hash());
00351             // normal stream free
00352             g_mime_stream_unref(stream);
00353         } catch(const Exception& e) {
00354             // abnormal stream free
00355             g_mime_stream_unref(stream);
00356             Charset& source_charset=r.charsets.source();
00357             HashStringValue& received=vreceived.hash();
00358             putReceived(source_charset, received, VALUE_NAME, "<exception occured while parsing messages>");
00359             putReceived(source_charset, received, EXCEPTION_VALUE, e.comment());
00360         } catch(...) {
00361             // abnormal stream free
00362             g_mime_stream_unref(stream);
00363             rethrow;
00364         }
00365     }
00366 #endif
00367 }
00368
00369 typedef int (*string_contains_char_which_check)(int);
00370 static bool string_contains_char_which(const char* string, string_contains_char_which_check check) {
00371     while(char c=*string++) {
00372         if(check((unsigned char)c))
00373             return true;
00374     }
00375     return false;
00376 }
00377 static char *trimBoth(char *s) {
00378     // sanity check
00379     if(!s)
00380         return 0;
00381
00382     // trim head whitespace
00383     while(*s && isspace((unsigned char)*s))
00384         s++;
00385     // trim tail whitespace
00386     char *tail=s+strlen(s);
00387     if(tail>s) {
00388         do {
00389             --tail;
00390             if(isspace((unsigned char)*tail))
00391                 *tail=0;
00392         } while(tail>s);
00393     }
00394     // return it
00395     return s;
00396 }
00397 static void extractEmail(String& result, char *email) {
00398     email=trimBoth(email);
00399     result.append_help_length(email, 0, String::L_TAINTED);
00400
00401     /*
00402         http://www.faqs.org/rfcs/rfc822.html
00403
00404         addr-spec   =  local-part "@" domain        ; global address
00405
00406         local-part  =  word *("." word)             ; uninterpreted case-preserved
00407         word        =  atom / quoted-string
00408
00409         domain      =  sub-domain *("." sub-domain)
00410         sub-domain  =  domain-ref / domain-literal
00411         domain-ref  =  atom                         ; symbolic reference
00412
00413         domain-literal << ignoring for now
00414         quoted-string in word << ignoring for now
00415
00416         atom        =  1*<any CHAR except specials, SPACE and CTLs>  << the ONLY to check
00417
00418         specials    =  "(" / ")" / "<" / ">" / "@"  ; Must be in quoted-
00419                  /  "," / ";" / ":" / "\" / <">  ;  string, to use
00420                  /  "." / "[" / "]"              ;  within a word.
00421
00422     */
00423     const char* exception_type="email.format";
00424     if(strpbrk(email, "()<>,;:\\\"[]"/*specials minus @ and . */))
00425         throw Exception(exception_type,
00426             &result,
00427             "email contains bad characters (specials)");
00428     if(string_contains_char_which(email, (string_contains_char_which_check)isspace))
00429         throw Exception(exception_type,
00430             &result,
00431             "email contains bad characters (whitespace)");
00432     if(string_contains_char_which(email, (string_contains_char_which_check)iscntrl))
00433         throw Exception(exception_type,
00434             &result,
00435             "email contains bad characters (control)");
00436     if(result.is_empty())
00437         throw Exception(exception_type,
00438             0,
00439             "email is empty");
00440 }
00441
00442 static const String& extractEmails(const String& string) {
00443     char *emails=string.cstrm();
00444     String& result=*new String;
00445     while(char *email=lsplit(&emails, ',')) {
00446         rsplit(email, '>');
00447         if(char *in_brackets=lsplit(email, '<'))
00448             email=in_brackets;
00449         if(!result.is_empty())
00450             result<<",";
00451         extractEmail(result, email);
00452     }
00453
00454     return result;
00455 }
00456
00457 #ifndef DOXYGEN
00458 struct Store_message_element_info {
00459     Request_charsets& charsets;
00460     String& header;
00461     const String* & from;
00462     bool extract_to; String* & to;
00463     const String* errors_to;
00464     bool mime_version_specified;
00465     ArrayValue* parts[P_TYPES_COUNT];
00466     int parts_count;
00467     bool backward_compatibility;
00468     Value* content_type;
00469     bool had_content_disposition;
00470
00471     Store_message_element_info(
00472         Request_charsets& acharsets,
00473         String& aheader,
00474         const String* & afrom,
00475         bool aextract_to, String* & ato
00476         ):
00477
00478         charsets(acharsets),
00479         header(aheader),
00480         from(afrom),
00481         extract_to(aextract_to), to(ato),
00482         errors_to(0),
00483         mime_version_specified(false),
00484         parts_count(0),
00485         backward_compatibility(false), content_type(0),
00486         had_content_disposition(false){
00487     }
00488 };
00489 #endif
00490 static void store_message_element(HashStringValue::key_type raw_element_name,
00491                   HashStringValue::value_type element_value,
00492                   Store_message_element_info *info) {
00493     const String& low_element_name=String(raw_element_name, String::L_TAINTED).change_case(
00494         info->charsets.source(), String::CC_LOWER);
00495
00496     // exclude internals
00497     if(low_element_name==MAIL_OPTIONS_NAME
00498         || low_element_name==CHARSET_NAME
00499         || low_element_name==VALUE_NAME
00500         || low_element_name==RAW_NAME
00501         || low_element_name==FORMAT_NAME
00502         || low_element_name==NAME_NAME)
00503         return;
00504
00505     // grep parts
00506     for(int pt=0; pt<P_TYPES_COUNT; pt++) {
00507         if(low_element_name.starts_with(part_name_begins[pt])) {
00508             // check that $.message# '#' is digit
00509             size_t start_len=strlen(part_name_begins[pt]);
00510             if(low_element_name.length()>start_len) {
00511                 const char* at_num=low_element_name.mid(start_len, start_len+1).cstr();
00512                 if(!isdigit((unsigned char)*at_num))
00513                     continue;
00514             }
00515             *info->parts[pt]+=element_value;
00516             info->parts_count++;
00517             return;
00518         }
00519     }
00520
00521     // fetch some special headers
00522     if(low_element_name=="from")
00523         info->from=&extractEmails(element_value->as_string());
00524     if(low_element_name==CONTENT_DISPOSITION_NAME)
00525         info->had_content_disposition=true;
00526     if(info->extract_to) { // defined only when SMTP used, see mail.C [collecting info for RCPT to-s]
00527         bool is_to=low_element_name=="to" ;
00528         bool is_cc=low_element_name=="cc" ;
00529         bool is_bcc=low_element_name=="bcc" ;
00530         if(is_to||is_cc||is_bcc) {
00531             if(!info->to)
00532                 info->to=new String;
00533             else
00534                 *info->to << ",";
00535             *info->to << extractEmails(element_value->as_string());
00536         }
00537
00538         if(is_bcc) // blinding it
00539             return;
00540     }
00541     if(low_element_name=="errors-to")
00542         info->errors_to=&extractEmails(element_value->as_string());
00543     if(low_element_name=="mime-version")
00544         info->mime_version_specified=true;
00545
00546     // has content type?
00547     if(low_element_name==CONTENT_TYPE_NAME) {
00548         info->content_type=element_value;
00549         if(info->backward_compatibility)
00550             return;
00551     }
00552
00553     // preparing header line
00554     const String& source_line=attributed_meaning_to_string(*element_value,
00555         String::L_PASS_APPENDED/*does not matter, would cstr(AS_IS) right away*/);
00556     if(source_line.is_empty())
00557         return; // we don't need empty headers here [used in clearing content-disposition]
00558
00559     const char* source_line_cstr=source_line.cstr();
00560     String::C mail=Charset::transcode(
00561         String::C(source_line_cstr, source_line.length()),
00562         info->charsets.source(),
00563         info->charsets.mail());
00564     String& mail_line=*new String;
00565     if(low_element_name=="to"
00566         || low_element_name=="cc"
00567         || low_element_name=="bcc")
00568     {
00569         // never wrap address lines, mailer can not handle wrapped properly
00570         mail_line.append_strdup(mail.str, mail.length, String::L_MAIL_HEADER);
00571     } else {
00572         while(mail.length) {
00573             bool too_long=mail.length>MAX_CHARS_IN_HEADER_LINE;
00574             size_t length=too_long
00575                 ? MAX_CHARS_IN_HEADER_LINE
00576                 : mail.length;
00577
00578             mail_line.append_strdup(mail.str, length, String::L_MAIL_HEADER);
00579             mail.length-=length;
00580
00581             if(too_long)
00582                 mail_line << "\n "; // break header and continue it on next line
00583         }
00584     }
00585
00586     // append header line
00587     info->header
00588         << raw_element_name
00589         << ":" << mail_line.cstr(String::L_UNSPECIFIED, 0, &info->charsets)
00590         << "\n";
00591 }
00592
00593 static const String& file_value_to_string(Request& r, Value* send_value) {
00594     String& result=*new String;
00595
00596     VFile* vfile;
00597     const String* file_name=0;
00598     Value* vformat=0;
00599     const String* dummy_from;
00600     String* dummy_to;
00601     Store_message_element_info info(r.charsets,
00602         result, dummy_from, false, dummy_to);
00603     if(HashStringValue *send_hash=send_value->get_hash()) { // hash
00604         send_hash->for_each(store_message_element, &info);
00605
00606         // $.value
00607         if(Value* value=send_hash->get(value_name))
00608             vfile=value->as_vfile(String::L_UNSPECIFIED);
00609         else
00610             throw Exception("parser.runtime",
00611                 0,
00612                 "file part has no $value");
00613
00614         // $.format
00615         vformat=send_hash->get(format_name);
00616
00617         // $.name
00618         if(Value* vfile_name=send_hash->get(name_name)) // $name specified
00619             file_name=&vfile_name->as_string();
00620     } else  // must be VFile then
00621         vfile=send_value->as_vfile(String::L_AS_IS);
00622
00623     if(!file_name)
00624         file_name=&vfile->fields().get(name_name)->as_string();
00625
00626     const char* file_name_cstr=file_name->cstr();
00627
00628     // content-type: application/octet-stream
00629     result << "content-type: " << r.mime_type_of(file_name_cstr)
00630         << "; name=\"" << file_name_cstr << "\"\n";
00631
00632     if(!info.had_content_disposition) {
00633         // content-disposition: attachment; filename="user_file_name"
00634         result <<
00635             CONTENT_DISPOSITION_NAME ": "CONTENT_DISPOSITION_VALUE"; "
00636             CONTENT_DISPOSITION_FILENAME_NAME"=\"" << file_name_cstr << "\"\n";
00637     }
00638
00639     const String* type=vformat?&vformat->as_string():0;
00640     if(!type/*default = uue*/ || *type=="uue") {
00641         pa_uuencode(result, *file_name, *vfile);
00642     } else // for now
00643         throw Exception("parser.runtime",
00644             type,
00645             "unknown attachment encode format");
00646
00647     return result;
00648 }
00649
00650 static const String& text_value_to_string(Request& r,
00651                       PartType pt, Value* send_value,
00652                       Store_message_element_info& info) {
00653     String& result=*new String;
00654
00655     Value* text_value;
00656     if(HashStringValue* send_hash=send_value->get_hash()) {
00657         // $.USER-HEADERS
00658         info.content_type=0; info.backward_compatibility=false; // reset
00659         send_hash->for_each(store_message_element, &info);
00660         // $.value
00661         text_value=send_hash->get(value_name);
00662         if(!text_value)
00663             throw Exception("parser.runtime",
00664                 0,
00665                 "%s part has no $" VALUE_NAME, part_name_begins[pt]);
00666     } else
00667         text_value=send_value;
00668
00669     if(!info.content_type) {
00670         result
00671             << "content-type: text/" << (pt==P_TEXT?"plain":"html")
00672             << "; charset=" << info.charsets.mail().NAME()
00673             << "\n";
00674     }
00675
00676     // header|body separator
00677     result << "\n";
00678
00679     // body
00680     const String* body;
00681     switch(pt) {
00682     case P_TEXT:
00683         body=&text_value->as_string();
00684         break;
00685     case P_HTML:
00686         {
00687             Temp_lang temp_lang(r, String::Language(String::L_HTML | String::L_OPTIMIZE_BIT));
00688             if(text_value->get_junction())
00689                 body=&r.process_to_string(*text_value);
00690             else {
00691                 throw Exception("parser.runtime",
00692                     0,
00693                     "html part value must be code");
00694             }
00695
00696             break;
00697         }
00698     default:
00699         throw Exception(0,
00700             0,
00701             "unhandled part type #%d", pt);
00702     }
00703     if(body) {
00704         Request_charsets charsets(r.charsets.source(), r.charsets.mail()/*uri!*/, r.charsets.mail());
00705         const char* body_cstr=strdup(body->cstr(String::L_UNSPECIFIED, 0, &charsets));  // body
00706         String::C mail=Charset::transcode(
00707             String::C(body_cstr, strlen(body_cstr)),
00708             r.charsets.source(),
00709             r.charsets.mail()/*always set - either mail.charset or $request:charset*/);
00711         result.append_know_length(mail.str, mail.length, String::L_CLEAN);
00712     }
00713
00714     return result;
00715 };
00716
00718 const String& VMail::message_hash_to_string(Request& r,
00719                         HashStringValue* message_hash, int level,
00720                         const String* & from, bool extract_to, String* & to) {
00721
00722     if(!message_hash)
00723         throw Exception("parser.runtime",
00724             0,
00725             "message must be hash");
00726
00727     String& result=*new String;
00728
00729     if(Value* vrecodecharset_name=message_hash->get(charset_name))
00730         r.charsets.set_mail(charsets.get(vrecodecharset_name->as_string()
00731             .change_case(r.charsets.source(), String::CC_UPPER)));
00732     else
00733         r.charsets.set_mail(r.charsets.source());
00734     // no big deal that we leave it set. they wont miss this point which would reset it
00735
00736     Store_message_element_info info(r.charsets,
00737         result, from, extract_to, to);
00738     {
00739         // for backward compatibilyty $.body+$.content-type ->
00740         // $.text[$.value[] $.content-type[]]
00741
00742         for(int pt=0; pt<P_TYPES_COUNT; pt++)
00743             info.parts[pt]=new ArrayValue(1);
00744
00745         Value* body=message_hash->get("body");
00746         if(body) {
00747             message_hash->remove("body");
00748             info.backward_compatibility=true;
00749         }
00750         message_hash->for_each(store_message_element, &info);
00751
00752         if(body) {
00753             VHash& text_part=*new VHash();
00754             HashStringValue& hash=text_part.hash();
00755             hash.put(value_name, body);
00756             if(info.content_type)
00757                 hash.put(content_type_name, info.content_type);
00758
00759             *info.parts[P_TEXT]+=&text_part;
00760             info.parts_count++;
00761         }
00762
00763         if(!info.errors_to)
00764             result << "errors-to: postmaster\n"; // errors-to: default
00765         if(!info.mime_version_specified)
00766             result << "MIME-Version: 1.0\n"; // MIME-Version: default
00767     }
00768
00769     int textCount=info.parts[P_TEXT]->count();
00770     if(textCount>1)
00771         throw Exception("parser.runtime",
00772             0,
00773             "multiple text parts not supported, use file part");
00774     int htmlCount=info.parts[P_HTML]->count();
00775     if(htmlCount>1)
00776         throw Exception("parser.runtime",
00777             0,
00778             "multiple html parts not supported, use file part");
00779
00780
00781     bool multipart=info.parts_count>1;
00782     bool alternative=textCount && htmlCount;
00783     // header
00784     char *boundary=0;
00785     if(multipart) {
00786         boundary=new(PointerFreeGC) char[MAX_NUMBER];
00787         snprintf(boundary, MAX_NUMBER-5/*lEvEl*/, "lEvEl%d", level);
00788         // multi-part
00789         result
00790             << "content-type: multipart/related; boundary=\""
00791             << boundary << "\"\n"
00792                 "\n"
00793                 "This is a multi-part message in MIME format.";
00794     }
00795
00796     // alternative or not
00797     {
00798         if(alternative) {
00799             result << "\n\n--" << boundary << "\n" // intermediate boundary
00800                 "content-type: multipart/alternative; boundary=\"ALT" << boundary << "\"\n";
00801         }
00802         for(int i=0; i<2; i++) {
00803             PartType pt=i==0?P_TEXT:P_HTML;
00804             if(info.parts[pt]->count()) {
00805                 if(alternative)
00806                     result << "\n\n--ALT" << boundary << "\n"; // intermediate boundary
00807                 else if(boundary)
00808                     result << "\n\n--" << boundary << "\n";  // intermediate boundary
00809                 result << text_value_to_string(r, pt, info.parts[pt]->get(0), info);
00810             }
00811         }
00812         if(alternative)
00813             result << "\n\n--ALT" << boundary << "--\n";
00814     }
00815
00816     // files
00817     {
00818         ArrayValue& files=*info.parts[P_FILE];
00819         for(size_t i=0; i<files.count(); i++) {
00820             if(boundary)
00821                 result << "\n\n--" << boundary << "\n";  // intermediate boundary
00822             result << file_value_to_string(r, files.get(i));
00823         }
00824     }
00825
00826     // messages
00827     {
00828         ArrayValue& messages=*info.parts[P_MESSAGE];
00829         for(size_t i=0; i<messages.count(); i++) {
00830             if(boundary)
00831                 result << "\n\n--" << boundary << "\n";  // intermediate boundary
00832
00833             const String* dummy_from;
00834             String* dummy_to;
00835             result << message_hash_to_string(r, messages.get(i)->get_hash(), level+1,
00836                 dummy_from, false, dummy_to);
00837         }
00838     }
00839
00840     // tailer
00841     if(boundary)
00842         result << "\n\n--" << boundary << "--\n"; // finish boundary
00843
00844     // return
00845     return result;
00846 }
00847
00848
00849 Value* VMail::get_element(const String& aname, Value& aself, bool looking_up) {
00850     // $fields
00851 #ifdef WITH_MAILRECEIVE
00852     if(aname==MAIL_RECEIVED_ELEMENT_NAME)
00853         return &vreceived;
00854 #endif
00855
00856     // $CLASS,$method
00857     if(Value* result=VStateless_class::get_element(aname, aself, looking_up))
00858         return result;
00859
00860     return 0;
00861 }
00862
00863 #if defined(WITH_MAILRECEIVE) && defined(_MSC_VER)
00864 #   define GNOME_LIBS "../../../../win32/gnome"
00865 #   pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")
00866 #   ifdef _DEBUG
00867 #       pragma comment(lib, GNOME_LIBS "/gmime-x.x.x/Debug/libgmime.lib")
00868 #   else
00869 #       pragma comment(lib, GNOME_LIBS "/gmime-x.x.x/Release/libgmime.lib")
00870 #   endif
00871 #endif


pa_vmail.h File Reference

Parser: mail class decls. More...

Include dependency graph for pa_vmail.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VMail
$mail:received letter. More...

Defines

#define | MAIL_RECEIVED_ELEMENT_NAME "received"
#define | MAIL_OPTIONS_NAME "options"

Variables

const char *const | IDENT_VMAIL_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: mail class decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vmail.h.

Define Documentation

#define MAIL_RECEIVED_ELEMENT_NAME "received"

Definition at line 19 of file pa_vmail.h.

Referenced by VMail::get_element().

#define MAIL_OPTIONS_NAME "options"

Definition at line 20 of file pa_vmail.h.

Referenced by _send(), and store_message_element().

Variable Documentation

const char* const IDENT_VMAIL_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vmail.h.


pa_vmail.h Source File

pa_vmail.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VMAIL_H
00009 #define PA_VMAIL_H
00010
00011 static const char * const IDENT_VMAIL_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 #include "classes.h"
00014 #include "pa_common.h"
00015 #include "pa_vhash.h"
00016
00017 // defines
00018
00019 #define MAIL_RECEIVED_ELEMENT_NAME "received"
00020 #define MAIL_OPTIONS_NAME "options"
00021
00022 // forwards
00023
00024 class Request_info;
00025
00029 class VMail: public VStateless_class {
00030
00031     VHash vreceived;
00032
00033 public: // Value
00034
00035     override const char* type() const { return "mail"; }
00036
00037     // mail: CLASS,methods,received field
00038     Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00039
00040 public: // usage
00041
00042     VMail();
00043
00044     void fill_received(Request& r);
00045     const String& message_hash_to_string(Request& r,
00046         HashStringValue* message_hash, int level,
00047         const String* & from, bool extract_to, String* & to);
00048
00049 };
00050
00051 #endif


pa_vmath.C File Reference

Parser: math class. More...

Include dependency graph for pa_vmath.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_VMATH_C = "$Date: 2005/08/09 08:14:55 $"
Methoded * math_base_class

Detailed Description

Parser: math class.

Copyright(c) 2001-2005 ArtLebedev Group(http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru>(http://paf.design.ru)

Definition in file pa_vmath.C.

Variable Documentation

const char* const IDENT_VMATH_C = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 8 of file pa_vmath.C.

Methoded* math_base_class

Definition at line 15 of file pa_vmath.C.


pa_vmath.C Source File

pa_vmath.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VMATH_C="$Date: 2005/08/09 08:14:55 $";
00009
00010 #include "pa_vmath.h"
00011 #include "pa_vdouble.h"
00012
00013 // externs
00014
00015 extern Methoded* math_base_class;
00016
00017 // methods
00018
00019 VMath::VMath(): VStateless_class(0, math_base_class) {
00020     fconsts.put(String::Body("PI"), new VDouble(PI));
00021 }


pa_vmath.h File Reference

Parser: math class decls. More...

Include dependency graph for pa_vmath.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VMath

Defines

#define | PI 3.1415926535

Variables

const char *const | IDENT_VMATH_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: math class decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vmath.h.

Define Documentation

#define PI 3.1415926535

Definition at line 20 of file pa_vmath.h.

Referenced by degrees(), radians(), and VMath::VMath().

Variable Documentation

const char* const IDENT_VMATH_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vmath.h.


pa_vmath.h Source File

pa_vmath.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VMATH_H
00009 #define PA_VMATH_H
00010
00011 static const char * const IDENT_VMATH_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 // includes
00014
00015 #include "classes.h"
00016 #include "pa_common.h"
00017
00018 // defines
00019
00020 #define PI 3.1415926535
00021
00024 class VMath: public VStateless_class {
00025 public: // Value
00026
00027     const char* type() const { return "math"; }
00028
00029     // math: CLASS,method,field
00030     Value* get_element(const String& aname, Value& aself, bool looking_up) {
00031         // $CLASS,$method
00032         if(Value* result=VStateless_class::get_element(aname, aself, looking_up))
00033             return result;
00034
00035         // $const
00036         return fconsts.get(aname);
00037     }
00038
00039 public: // usage
00040
00041     VMath();
00042
00043 private:
00044
00045     HashStringValue fconsts;
00046
00047 };
00048
00049 #endif


pa_vmemory.h File Reference

Parser: memory parser class. More...

Include dependency graph for pa_vmemory.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VMemory

Variables

const char *const | IDENT_VMEMORY_H = "$Date: 2005/08/09 08:14:55 $"
Methoded * memory_base_class

Detailed Description

Parser: memory parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vmemory.h.

Variable Documentation

const char* const IDENT_VMEMORY_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vmemory.h.

Methoded* memory_base_class

Definition at line 17 of file pa_vmemory.h.


pa_vmemory.h Source File

pa_vmemory.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VMEMORY_H
00009 #define PA_VMEMORY_H
00010
00011 static const char * const IDENT_VMEMORY_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 #include "classes.h"
00014 #include "pa_vstateless_object.h"
00015 #include "pa_globals.h"
00016
00017 extern Methoded* memory_base_class;
00018
00020 class VMemory: public VStateless_class {
00021 public: // Value
00022
00023     const char* type() const { return "memory"; }
00024
00026     Value* get_element(const String& aname, Value& aself, bool looking_up) {
00027         // $CLASS,$method
00028         if(Value* result=VStateless_class::get_element(aname, aself, looking_up))
00029             return result;
00030
00031         return 0;
00032     }
00033
00034     VMemory(): VStateless_class(0, memory_base_class) {}
00035
00036 };
00037
00038 #endif


pa_vmethod_frame.C File Reference

Parser: method frame class. More...

Include dependency graph for pa_vmethod_frame.C:

Include dependency graph

Go to the source code of this file.

Functions

const String | result_var_name (RESULT_VAR_NAME)

Variables

const char *const | IDENT_VSTATELESS_CLASS_C = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: method frame class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)\

Definition in file pa_vmethod_frame.C.

Function Documentation

const String result_var_name ( RESULT_VAR_NAME )

Variable Documentation

const char* const IDENT_VSTATELESS_CLASS_C = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 8 of file pa_vmethod_frame.C.


pa_vmethod_frame.C Source File

pa_vmethod_frame.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VSTATELESS_CLASS_C="$Date: 2005/08/09 08:14:55 $";
00009
00010 #include "pa_vmethod_frame.h"
00011 #include "pa_request.h"
00012
00013 // globals
00014
00015 const String result_var_name(RESULT_VAR_NAME);
00016
00017 // MethodParams: methods
00018
00019 Value& MethodParams::get_processed(Value* value, const char* msg, int index, Request& r) {
00020         return r.process_to_value(as_junction(value, msg, index), false /*do not intercept string*/);
00021 }
00022
00023 // VMethodFrame: methods
00024
00025 VMethodFrame::VMethodFrame(
00026     const Junction& ajunction/*info: always method-junction*/,
00027     VMethodFrame *acaller) :
00028     WContext(0/*empty*/, 0 /* no parent, junctions can be reattached only up to VMethodFrame */),
00029
00030     fcaller(acaller),
00031
00032     store_param_index(0),
00033     my(0), fnumbered_params(0),
00034     fself(0),
00035
00036     fresult_initial_void(0),
00037
00038     junction(ajunction) {
00039
00040     if(junction.method->max_numbered_params_count) // this method uses numbered params?
00041         fnumbered_params=new MethodParams;
00042     else {
00043         my=new HashStringValue;
00044
00045         const Method &method=*junction.method;
00046         if(method.locals_names) { // are there any local var names?
00047             // remember them
00048             // those are flags that fname is local == to be looked up in 'my'
00049             for(Array_iterator<const String*> i(*method.locals_names); i.has_next(); ) {
00050                 // speedup: not checking for clash with "result" fname
00051                 const String& fname=*i.next();
00052                 set_my_variable(fname, *new VVoid);
00053             }
00054         }
00055         { // always there is one local: $result
00056             fresult_initial_void=new VVoid;
00057             set_my_variable(result_var_name, *fresult_initial_void);
00058         }
00059     }
00060 }
00061
00062 Value* VMethodFrame::get_result_variable() {
00063     Value* result=my?my->get(result_var_name):0;
00064     return result!=fresult_initial_void ? result : 0;
00065 }


pa_vmethod_frame.h File Reference

Parser: method_frame write context. More...

Include dependency graph for pa_vmethod_frame.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | MethodParams
method parameters passed in this array. More...

class | VMethodFrame
Method frame write context accepts values written by method code also handles method parameters and local variables. More...

class | Temp_method_frame_self
Auto-object used for temporary changing VMethod_frame::fself. More...

Defines

#define | CALLER_ELEMENT_NAME "caller"
#define | SELF_ELEMENT_NAME "self"
#define | RESULT_VAR_NAME "result"

Variables

const char *const | IDENT_VMETHOD_FRAME_H = "$Date: 2005/11/21 10:13:43 $"

Detailed Description

Parser: method_frame write context.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vmethod_frame.h.

Define Documentation

#define CALLER_ELEMENT_NAME "caller"

Definition at line 19 of file pa_vmethod_frame.h.

Referenced by VMethodFrame::get_element().

#define SELF_ELEMENT_NAME "self"

Definition at line 20 of file pa_vmethod_frame.h.

Referenced by VMethodFrame::get_element().

#define RESULT_VAR_NAME "result"

Definition at line 21 of file pa_vmethod_frame.h.

Variable Documentation

const char* const IDENT_VMETHOD_FRAME_H = "$Date: 2005/11/21 10:13:43 $" [static]

Definition at line 11 of file pa_vmethod_frame.h.


pa_vmethod_frame.h Source File

pa_vmethod_frame.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VMETHOD_FRAME_H
00009 #define PA_VMETHOD_FRAME_H
00010
00011 static const char * const IDENT_VMETHOD_FRAME_H="$Date: 2005/11/21 10:13:43 $";
00012
00013 #include "pa_wcontext.h"
00014 #include "pa_vvoid.h"
00015 #include "pa_vjunction.h"
00016
00017 // defines
00018
00019 #define CALLER_ELEMENT_NAME "caller"
00020 #define SELF_ELEMENT_NAME "self"
00021 #define RESULT_VAR_NAME "result"
00022
00023 // forwards
00024
00025 class Request;
00026
00032 class MethodParams: public Array<Value*> {
00033 public:
00034     Value& operator[] (size_t index) { return *get(index); }
00035
00036     Value& last() { return *get(count()-1); }
00037
00039     Value& as_junction(int index, const char* msg) {
00040         Value* value=get(index);
00041         return as_junction(value, msg, index);
00042     }
00044     Value& as_junction(Value* value, const char* msg, int index) {
00045         return get_as(value, true, msg, index);
00046     }
00048     Value& as_no_junction(int index, const char* msg) {
00049         Value* value=get(index);
00050         return as_no_junction(value, msg, index);
00051     }
00053     Value& as_no_junction(Value* value, const char* msg, int index) {
00054         return get_as(value, false, msg, index);
00055     }
00057     double as_double(int index, const char* msg, Request& r) {
00058         Value* value=get(index);
00059         if(!value->is_evaluated_expr())
00060             value=&get_processed(value, msg, index, r);
00061         return value->as_double();
00062     }
00064     int as_int(int index, const char* msg, Request& r) {
00065         Value* value=get(index);
00066         if(!value->is_evaluated_expr())
00067             value=&get_processed(value, msg, index, r);
00068         return value->as_int();
00069     }
00071     bool as_bool(int index, const char* msg, Request& r) {
00072         Value* value=get(index);
00073         if(!value->is_evaluated_expr())
00074             value=&get_processed(value, msg, index, r);
00075         return value->as_bool();
00076     }
00078     const String& as_string(int index, const char* msg) {
00079         return as_no_junction(index, msg).as_string();
00080     }
00081
00082 private:
00083
00085     Value& get_as(Value* value, bool as_junction, const char* msg, int index) {
00086         if((value->get_junction()!=0) ^ as_junction)
00087             throw Exception("parser.runtime",
00088                 0,
00089                 "%s (parameter #%d)", msg, 1+index);
00090
00091         return *value;
00092     }
00093
00094     Value& get_processed(Value* value, const char* msg, int index, Request& r);
00095
00096 };
00097
00102 class VMethodFrame: public WContext {
00103     VMethodFrame *fcaller;
00104
00105     size_t store_param_index;
00106     HashStringValue* my;/*OR*/MethodParams* fnumbered_params;
00107     Value* fself;
00108
00109     Value* fresult_initial_void;
00110
00111 public: // Value
00112
00113     override const char* type() const { return "method_frame"; }
00114
00116     override const String* get_string() {
00117         // check the $result value
00118         Value* result=get_result_variable();
00119         // if we have one, return it's string value, else return as usual: accumulated fstring or fvalue
00120         return result ? result->get_string() : WContext::get_string();
00121     }
00122
00124     override Value* get_element(const String& aname, Value& /*aself*/, bool looking_up) {
00125         if(my) {
00126             if(Value* result=my->get(aname))
00127                 return result;
00128         }
00129         if(Value* result=self().get_element(aname, self(), looking_up))
00130             return result;
00131
00132         if(aname==CALLER_ELEMENT_NAME)
00133             return caller();
00134
00135         if(aname==SELF_ELEMENT_NAME)
00136             return &self();
00137
00138         return 0;
00139     }
00141     override const VJunction* put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*areplace*/) {
00142         if(my && my->put_replaced(aname, avalue))
00143             return PUT_ELEMENT_REPLACED_ELEMENT;
00144
00145         return self().put_element(self(), aname, avalue, false/*=always, areplace*/);
00146     }
00147
00149     override VStateless_class* get_class() { return self().get_class(); }
00150
00152     override Value* base() { return self().base(); }
00153
00154 public: // WContext
00155
00156     override StringOrValue result() {
00157         // check the $result value
00158         Value* result_value=get_result_variable();
00159         // if we have one, return it, else return as usual: accumulated fstring or fvalue
00160         return result_value ? StringOrValue(*result_value) : WContext::result();
00161     }
00162
00163     void write(Value& avalue, String::Language alang) {
00164         WContext::write(avalue, alang);
00165     }
00166
00167 public: // usage
00168
00169     VMethodFrame(
00170         const Junction& ajunction/*info: always method-junction*/,
00171         VMethodFrame *acaller);
00172
00173     VMethodFrame *caller() { return fcaller; }
00174
00175     void set_self(Value& aself) { fself=&aself; }
00177     Value& self() { return *fself; }
00178
00179     bool can_store_param() {
00180         const Method& method=*junction.method;
00181         return method.params_names && store_param_index<method.params_names->count();
00182     }
00183     void store_param(Value& value) {
00184         const Method& method=*junction.method;
00185         size_t max_params=
00186             method.max_numbered_params_count?method.max_numbered_params_count:
00187             method.params_names?method.params_names->count():
00188             0;
00189         if(store_param_index==max_params)
00190             throw Exception("parser.runtime",
00191                 0, //&name(),
00192                 "method of %s (%s) accepts maximum %d parameter(s)",
00193                     junction.self.get_class()->name_cstr(),
00194                     junction.self.type(),
00195                     max_params);
00196
00197         if(fnumbered_params) { // are this method params numbered?
00198             *fnumbered_params+=&value;
00199         } else { // named param
00200             // speedup: not checking for clash with "result" fname
00201             const String& fname=*(*method.params_names)[store_param_index];
00202             set_my_variable(fname, value);
00203         }
00204         store_param_index++;
00205     }
00206     void fill_unspecified_params() {
00207         const Method &method=*junction.method;
00208         if(method.params_names) { // there are any named parameters might need filling?
00209             size_t param_count=method.params_names->count();
00210             for(; store_param_index<param_count; store_param_index++) {
00211                 const String& fname=*(*method.params_names)[store_param_index];
00212                 my->put(fname, new VVoid);
00213             }
00214         }
00215     }
00216
00217     MethodParams* numbered_params() { return fnumbered_params; }
00218
00219 private:
00220
00221     void set_my_variable(const String& fname, Value& value) {
00222         my->put(fname, &value); // remember param
00223     }
00224
00225     Value* get_result_variable();
00226
00227 public:
00228
00229     const Junction& junction;
00230
00231 };
00232
00234 class Temp_method_frame_self {
00235     VMethodFrame& fmethod_frame;
00236     Value* saved_self;
00237 public:
00238     Temp_method_frame_self(VMethodFrame& amethod_frame, Value& aself) :
00239         fmethod_frame(amethod_frame),
00240         saved_self(&amethod_frame.self()) {
00241         fmethod_frame.set_self(aself);
00242     }
00243     ~Temp_method_frame_self() {
00244         fmethod_frame.set_self(*saved_self);
00245     }
00246 };
00247
00248 #endif


pa_vobject.C File Reference

Parser: object class impl. More...

Include dependency graph for pa_vobject.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_VOBJECT_C = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: object class impl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vobject.C.

Variable Documentation

const char* const IDENT_VOBJECT_C = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 12 of file pa_vobject.C.


pa_vobject.C Source File

pa_vobject.C

Go to the documentation of this file.
00001
00008 #include "pa_vobject.h"
00009 #include "pa_vhash.h"
00010 #include "pa_vtable.h"
00011
00012 static const char * const IDENT_VOBJECT_C="$Date: 2005/08/09 08:14:55 $";
00013
00014 Value* VObject::as(const char* atype, bool looking_up) {
00015     if(!looking_up)
00016         return get_last_derived().as(atype, true/*the only user*/); // figure out from last_derivate upwards
00017
00018     // is it me?
00019     if(Value *result=Value::as(atype, false))
00020         return result;
00021
00022     // is it my base?
00023     if(fbase) {
00024         if(Value *result=fbase->as(atype, true))
00025             return result;
00026     }
00027
00028     // neither
00029     return 0;
00030 }
00031
00033 bool VObject::is_defined() const {
00034     return fbase?fbase->is_defined():Value::is_defined();
00035 }
00037 Value& VObject::as_expr_result(bool) {
00038     return fbase?fbase->as_expr_result():Value::as_expr_result();
00039 }
00041 int VObject::as_int() const {
00042     return fbase?fbase->as_int():Value::as_int();
00043 }
00045 double VObject::as_double() {
00046     return fbase?fbase->as_double():Value::as_double();
00047 }
00049 bool VObject::as_bool() const {
00050     return fbase?fbase->as_bool():Value::as_bool();
00051 }
00053 VFile* VObject::as_vfile(String::Language lang, const Request_charsets *charsets) {
00054     return fbase?fbase->as_vfile(lang, charsets):
00055         Value::as_vfile(lang, charsets);
00056 }
00057
00059 HashStringValue* VObject::get_hash() {
00060     if(Value* vhash=get_last_derived().as(VHASH_TYPE, false))
00061         return vhash->get_hash();
00062
00063     return 0;
00064 }
00066 Table *VObject::get_table() {
00067     if(Value *vtable=get_last_derived().as(VTABLE_TYPE, false))
00068         return vtable->get_table();
00069
00070     return 0;
00071 }
00072
00074 Value* VObject::get_element(const String& aname, Value&, bool looking_up) {
00075     // simple things first: $field=ffields.field
00076     if(Value* result=ffields.get(aname))
00077         return result;
00078
00079     // gets element from last_derivate upwards
00080     if(!looking_up) {
00081         // $CLASS
00082         if(aname==CLASS_NAME)
00083             return get_class();
00084
00085         // $virtual_method $virtual_property
00086         VObject& last_derived=get_last_derived();
00087         if(Value* result=last_derived.stateless_object__get_element(aname, last_derived))
00088             return result;
00089     }
00090
00091     return 0;
00092 }
00093
00094 const VJunction* VObject::prevent_append_if_exists_in_static_or_base(Value* value, Prevent_append_if_exists_in_static_or_base_info* info)  {
00095     // $virtual_property, any this/bases $static_property
00096     VObject& last_derived=info->_this->get_last_derived();
00097     if(const VJunction* result=last_derived.stateless_object__put_element(last_derived, *info->name, value))
00098         return result; // replaced in any(derivate or base) statics fields/properties
00099
00100     return 0;
00101 }
00102
00104 const VJunction* VObject::put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*areplace*/) {
00105     Prevent_append_if_exists_in_static_or_base_info info={this, &aname};
00106     return ffields.replace_maybe_append<const VJunction*>(aname, avalue,
00107         prevent_append_if_exists_in_static_or_base,
00108         &info);
00109 }


pa_vobject.h File Reference

Parser: object class decl. More...

Include dependency graph for pa_vobject.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VObject
parser class instance, stores - class VObject::fclass; - fields VObject::ffields (dynamic, not static, which are stored in class). More...

struct | Prevent_append_if_exists_in_static_or_base_info
class | Temp_derived

Defines

#define | BASE_NAME "BASE"

Variables

const char *const | IDENT_VOBJECT_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: object class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vobject.h.

Define Documentation

#define BASE_NAME "BASE"

Definition at line 22 of file pa_vobject.h.

Variable Documentation

const char* const IDENT_VOBJECT_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vobject.h.


pa_vobject.h Source File

pa_vobject.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VOBJECT_H
00009 #define PA_VOBJECT_H
00010
00011 static const char * const IDENT_VOBJECT_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 // includes
00014
00015 #include "pa_vjunction.h"
00016 #include "pa_vclass.h"
00017 #include "pa_vstateless_object.h"
00018 #include "pa_vfile.h"
00019
00020 // defines
00021
00022 #define BASE_NAME "BASE"
00023
00029 class VObject: public VStateless_object {
00030
00031     VStateless_class& fclass;
00032     HashStringValue& ffields;
00033     VObject* fderived;
00034     Value* fbase;
00035
00036 public: // Value
00037
00038     const char* type() const { return fclass.name_cstr(); }
00039     override Value* as(const char* atype, bool looking_up);
00040
00042     override VStateless_class *get_class() { return &fclass; }
00043     override VStateless_class *get_last_derived_class() { return get_last_derived().get_class(); }
00044     override Value* base() { return fbase; }
00045
00046     override bool is_defined() const;
00047     override Value& as_expr_result(bool);
00048     override int as_int() const;
00049     override double as_double();
00050     override bool as_bool() const;
00051     override VFile* as_vfile(String::Language lang=String::L_UNSPECIFIED,
00052         const Request_charsets *charsets=0);
00053
00054     override HashStringValue* get_hash();
00055     override Table *get_table();
00056
00057     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00058     override const VJunction* put_element(Value& self, const String& name, Value* value, bool replace);
00059
00061     override VObject* set_derived(VObject* aderived) {
00062         VObject* result=fderived;
00063         fderived=aderived;
00064         return result;
00065     }
00066
00067 public: // creation
00068
00069     VObject(Pool& apool, VStateless_class& aclass, HashStringValue& afields): fclass(aclass), ffields(afields), fderived(0) {
00070         if(VStateless_class* base_class=fclass.base_class())
00071             (fbase=base_class->create_new_value(apool, afields))->set_derived(this);
00072     }
00073
00074 private:
00075
00076     VObject& get_last_derived() {
00077         return fderived?fderived->get_last_derived():*this;
00078     }
00079
00080     Value* stateless_object__get_element(const String& aname, Value& aself) {
00081         return VStateless_object::get_element(aname, aself, false);
00082     }
00083
00084     const VJunction* stateless_object__put_element(Value& aself, const String& aname, Value* avalue) {
00085         return VStateless_object::put_element(aself, aname, avalue, true/*try to replace! NEVER overwrite*/);
00086     }
00087
00088     struct Prevent_append_if_exists_in_static_or_base_info {
00089         VObject* _this;
00090         const String* name;
00091     };
00092     static const VJunction* prevent_append_if_exists_in_static_or_base(Value* value,
00093         Prevent_append_if_exists_in_static_or_base_info* info);
00094
00095 };
00096
00097 class Temp_derived {
00098     Value& fvalue;
00099     VObject* fsaved_derived;
00100 public:
00101     Temp_derived(Value& avalue, VObject* aderived) :
00102         fvalue(avalue),
00103         fsaved_derived(avalue.set_derived(aderived)) {}
00104     ~Temp_derived() { fvalue.set_derived(fsaved_derived); }
00105 };
00106
00107 #endif


pa_vproperty.h File Reference

Parser: property class decl. More...

Include dependency graph for pa_vproperty.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VProperty
property two methods. More...

Variables

const char *const | IDENT_VPROPERTY_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: property class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vproperty.h.

Variable Documentation

const char* const IDENT_VPROPERTY_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vproperty.h.


pa_vproperty.h Source File

pa_vproperty.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VPROPERTY_H
00009 #define PA_VPROPERTY_H
00010
00011 static const char * const IDENT_VPROPERTY_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 // include
00014
00015 #include "pa_value.h"
00016 #include "pa_vbool.h"
00017 #include "pa_property.h"
00018
00020 class VProperty: public Value {
00021 public: // VProperty
00022
00023     override const char* type() const { return "property"; }
00024
00026     override VStateless_class *get_class() { bark("is '%s', it has no class"); return 0; }
00027
00029     override bool is_defined() const { bark("is '%s', it has no 'defined'"); return false; }
00030
00032     override bool as_bool() const { return is_defined(); }
00033
00035     override Value& as_expr_result(bool) { return *new VBool(as_bool()); }
00036
00038     override Property* get_property() { return &fproperty; }
00039
00040 public: // usage
00041
00042     Property& get() { return fproperty; }
00043
00044 private:
00045
00046     Property fproperty;
00047 };
00048
00049
00050 #endif


pa_vrequest.C File Reference

Parser: request class. More...

Include dependency graph for pa_vrequest.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | DOCUMENT_ROOT_NAME "document-root"

Variables

const char *const | IDENT_VREQUEST_C = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: request class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vrequest.C.

Define Documentation

#define DOCUMENT_ROOT_NAME "document-root"

Definition at line 18 of file pa_vrequest.C.

Referenced by VRequest::get_element(), and VRequest::put_element().

Variable Documentation

const char* const IDENT_VREQUEST_C = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 8 of file pa_vrequest.C.


pa_vrequest.C Source File

pa_vrequest.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VREQUEST_C="$Date: 2005/08/09 08:14:55 $";
00009
00010 #include "pa_vrequest.h"
00011 #include "pa_request_info.h"
00012 #include "pa_request_charsets.h"
00013 #include "pa_charsets.h"
00014 #include "pa_vstring.h"
00015
00016 // defines
00017
00018 #define DOCUMENT_ROOT_NAME "document-root"
00019
00020
00021 // request: CLASS,method,field
00022 Value* VRequest::get_element(const String& aname, Value&  /*aself*/, bool /*looking_up*/) {
00023     // $charset
00024     if(aname==CHARSET_NAME)
00025         return new VString(*new String(fcharsets.source().NAME(), String::L_TAINTED));
00026
00027     // $query $uri $document-root $body
00028     const char* buf;
00029     size_t size=0;
00030     if(aname=="query")
00031         buf=finfo.query_string;
00032     else if(aname=="uri")
00033         buf=finfo.uri;
00034     else if(aname==DOCUMENT_ROOT_NAME)
00035         buf=finfo.document_root;
00036     else if(aname=="body") {
00037         buf=finfo.post_data;
00038         size=finfo.post_size;
00039     } else
00040         return bark("%s field not found", &aname);
00041
00042     return new VString(*new String(buf?buf:"", size, true));
00043 }
00044
00045 const VJunction* VRequest::put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
00046     // $charset
00047     if(aname==CHARSET_NAME) {
00048         fcharsets.set_source(charsets.get(avalue->as_string().
00049             change_case(UTF8_charset, String::CC_UPPER)));
00050         return PUT_ELEMENT_REPLACED_ELEMENT;
00051     }
00052
00053     // $document-root
00054     if(aname==DOCUMENT_ROOT_NAME) {
00055         finfo.document_root=avalue->as_string().cstr(String::L_FILE_SPEC);
00056         return PUT_ELEMENT_REPLACED_ELEMENT;
00057     }
00058
00059     return Value::put_element(aself, aname, avalue, areplace);
00060 }


pa_vrequest.h File Reference

Parser: request class decl. More...

Include dependency graph for pa_vrequest.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VRequest
request class. More...

Defines

#define | REQUEST_CLASS_NAME "request"

Variables

const char *const | IDENT_VREQUEST_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: request class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vrequest.h.

Define Documentation

#define REQUEST_CLASS_NAME "request"

Definition at line 20 of file pa_vrequest.h.

Referenced by Request::Request().

Variable Documentation

const char* const IDENT_VREQUEST_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vrequest.h.


pa_vrequest.h Source File

pa_vrequest.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VREQUEST_H
00009 #define PA_VREQUEST_H
00010
00011 static const char * const IDENT_VREQUEST_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 // includes
00014
00015 //#include "pa_common.h"
00016 #include "pa_value.h"
00017
00018 // defines
00019
00020 #define REQUEST_CLASS_NAME "request"
00021
00022 // forwards
00023
00024 class Request_info;
00025
00027 class VRequest: public Value {
00028
00029     Request_info& finfo;
00030     Request_charsets& fcharsets;
00031
00032 public: // Value
00033
00034     override const char* type() const { return "request"; }
00036     override VStateless_class *get_class() { return 0; }
00037
00039     override Value* get_element(const String& name, Value& aself, bool /*looking_up*/);
00040
00042     override const VJunction* put_element(Value& self, const String& name, Value* value, bool replace);
00043
00044 public: // usage
00045
00046     VRequest(Request_info& ainfo, Request_charsets& acharsets):
00047         finfo(ainfo), fcharsets(acharsets) {}
00048
00049 };
00050
00051 #endif


pa_vresponse.C File Reference

Parser: response class. More...

Include dependency graph for pa_vresponse.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | REQUEST_HEADERS_ELEMENT_NAME "headers"

Variables

const char *const | IDENT_VRESPONSE_C = "$Date: 2005/11/22 13:57:11 $"

Detailed Description

Parser: response class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vresponse.C.

Define Documentation

#define REQUEST_HEADERS_ELEMENT_NAME "headers"

Definition at line 20 of file pa_vresponse.C.

Referenced by VResponse::get_element().

Variable Documentation

const char* const IDENT_VRESPONSE_C = "$Date: 2005/11/22 13:57:11 $" [static]

Definition at line 8 of file pa_vresponse.C.


pa_vresponse.C Source File

pa_vresponse.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VRESPONSE_C="$Date: 2005/11/22 13:57:11 $";
00009
00010 #include "pa_vresponse.h"
00011 #include "pa_request_charsets.h"
00012 #include "pa_charsets.h"
00013 #include "pa_charset.h"
00014 #include "pa_vstring.h"
00015 #include "pa_vdate.h"
00016 #include "pa_vhash.h"
00017
00018 // defines
00019
00020 #define REQUEST_HEADERS_ELEMENT_NAME "headers"
00021
00022 Value* VResponse::get_element(const String& aname, Value& aself, bool looking_up) {
00023     // $charset
00024     if(aname==CHARSET_NAME)
00025         return new VString(*new String(fcharsets.client().NAME(), String::L_TAINTED));
00026
00027     // $method
00028     if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00029         return result;
00030
00031     // $fields
00032     if(aname==REQUEST_HEADERS_ELEMENT_NAME)
00033         return new VHash(ffields);
00034
00035     // $field
00036     return ffields.get(aname.change_case(fcharsets.source(), String::CC_LOWER));
00037 }
00038
00039 const VJunction* VResponse::put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*areplace*/) {
00040     // guard charset change
00041     if(aname==CHARSET_NAME)
00042         fcharsets.set_client(charsets.get(avalue->as_string().
00043             change_case(UTF8_charset, String::CC_UPPER)));
00044     else
00045         ffields.put(
00046             aname.change_case(fcharsets.source(), String::CC_LOWER),
00047             avalue);
00048
00049     return PUT_ELEMENT_REPLACED_ELEMENT;
00050 }


pa_vresponse.h File Reference

Parser: response class. More...

Include dependency graph for pa_vresponse.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VResponse
value of type 'response'. More...

Variables

const char *const | IDENT_VRESPONSE_H = "$Date: 2005/08/09 08:14:55 $"
Methoded * response_class

Detailed Description

Parser: response class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vresponse.h.

Variable Documentation

const char* const IDENT_VRESPONSE_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vresponse.h.

Methoded* response_class

Definition at line 25 of file pa_vresponse.h.


pa_vresponse.h Source File

pa_vresponse.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VRESPONSE_H
00009 #define PA_VRESPONSE_H
00010
00011 static const char * const IDENT_VRESPONSE_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 #include "pa_vstateless_object.h"
00014 #include "pa_string.h"
00015 #include "classes.h"
00016
00017 // forwards
00018
00019 class Response;
00020 class Request_info;
00021 class Request_charsets;
00022
00023 // externals
00024
00025 extern Methoded* response_class;
00026
00028 class VResponse: public VStateless_object {
00029
00030     Request_info& finfo;
00031     Request_charsets& fcharsets;
00032
00033     HashStringValue ffields;
00034
00035 public: // Value
00036
00037     override const char* type() const { return "response"; }
00038     override VStateless_class *get_class() { return response_class; }
00039
00041     override HashStringValue* get_hash() { return &ffields; }
00042
00044     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00045
00047     override const VJunction* put_element(Value& self, const String& name, Value* value, bool replace);
00048
00049 public: // usage
00050
00051     VResponse(Request_info& ainfo, Request_charsets& acharsets):
00052         finfo(ainfo), fcharsets(acharsets) {}
00053
00055     HashStringValue& fields() { return ffields; }
00056
00057 };
00058
00059
00060 #endif


pa_vstateless_class.C File Reference

Parser: stateless class. More...

Include dependency graph for pa_vstateless_class.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_VSTATELESS_CLASS_C = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: stateless class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)\

Definition in file pa_vstateless_class.C.

Variable Documentation

const char* const IDENT_VSTATELESS_CLASS_C = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 8 of file pa_vstateless_class.C.


pa_vstateless_class.C Source File

pa_vstateless_class.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VSTATELESS_CLASS_C="$Date: 2005/08/09 08:14:55 $";
00009
00010 #include "pa_vstateless_class.h"
00011 #include "pa_vproperty.h"
00012
00014 void VStateless_class::add_method(const String& name, Method& method) {
00015     if(flocked)
00016         throw Exception("parser.runtime",
00017             &name,
00018             "can not add method to system class (maybe you have forgotten .CLASS in ^process[$caller.CLASS]{...}?)");
00019
00020     put_method(name, &method);
00021 }
00022
00023 void VStateless_class::add_native_method(
00024     const char* cstr_name,
00025     Method::Call_type call_type,
00026     NativeCodePtr native_code,
00027     int min_numbered_params_count, int max_numbered_params_count) {
00028
00029     const String& name=*new String(cstr_name);
00030
00031     Method& method=*new Method(
00032         call_type,
00033         min_numbered_params_count, max_numbered_params_count,
00034         0/*params_names*/, 0/*locals_names*/,
00035         0/*parser_code*/, native_code
00036         );
00037     add_method(name, method);
00038 }
00039
00041 Value* VStateless_class::get_element(const String& aname, Value& aself, bool looking_up) {
00042     // $CLASS
00043     if(aname==CLASS_NAME)
00044         return this;
00045     // $method=junction(self+class+method)
00046     if(Method* method=get_method(aname))
00047         return new VJunction(aself, method);
00048
00049     // base monkey
00050     if(fbase) {
00051         if(Value* obase=aself.base()) // MXdoc has fbase but does not have object_base[ base() ]
00052             return fbase->get_element(aname, *obase, looking_up);
00053     }
00054
00055     return 0;
00056 }
00057
00058 void VStateless_class::put_method(const String& aname, Method* amethod) {
00059     fmethods.put(aname, amethod);
00060 }


pa_vstateless_class.h File Reference

Parser: stateless class decls. More...

Include dependency graph for pa_vstateless_class.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VStateless_class
object' class. More...

class | Temp_method
Auto-object used for temporarily substituting/removing class method. More...

Defines

#define | CLASS_NAME "CLASS"

Variables

const char *const | IDENT_VSTATELESS_CLASS_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: stateless class decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vstateless_class.h.

Define Documentation

#define CLASS_NAME "CLASS"

Definition at line 23 of file pa_vstateless_class.h.

Referenced by VStateless_class::get_element(), VObject::get_element(), and VCookie::get_element().

Variable Documentation

const char* const IDENT_VSTATELESS_CLASS_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vstateless_class.h.


pa_vstateless_class.h Source File

pa_vstateless_class.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VSTATELESS_CLASS_H
00009 #define PA_VSTATELESS_CLASS_H
00010
00011 static const char * const IDENT_VSTATELESS_CLASS_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 // include
00014
00015 #include "pa_pool.h"
00016 #include "pa_hash.h"
00017 #include "pa_vjunction.h"
00018 #include "pa_method.h"
00019 #include "pa_vproperty.h"
00020
00021 // defines
00022
00023 #define CLASS_NAME "CLASS"
00024
00025 // forwards
00026
00027 class VStateless_class;
00028
00029 class Temp_method;
00030
00038 class VStateless_class: public Value {
00039     friend class Temp_method;
00040
00041     const String* fname;
00042     mutable const char* fname_cstr;
00043     Hash<const String::Body, Method*> fmethods;
00044
00045     bool flocked;
00046
00047 protected:
00048
00049     VStateless_class* fbase;
00050
00051 public: // Value
00052
00053     const char* type() const { return "stateless_class"; }
00054
00056     override VStateless_class *get_class() { return this; }
00058     override Value* base() { return fbase; }
00059     override Value* get_element(const String& aname, Value& aself, bool looking_up);
00060
00061 public: // usage
00062
00063     VStateless_class(
00064         const String* aname=0,
00065         VStateless_class* abase=0):
00066         fname(aname),
00067         flocked(false),
00068         fbase(abase) {
00069     }
00070
00071     void lock() { flocked=true; }
00072
00073     const String& name() const {
00074         if(!fname) {
00075             if(fbase)
00076                 return fbase->name();
00077
00078             throw Exception("parser.runtime",
00079                 0,
00080                 "getting name of nameless class");
00081         }
00082
00083         return *fname;
00084     }
00085     const char* name_cstr() const{
00086         if(this) {
00087             if(!fname_cstr) // remembering last calculated, and can't reassign 'fname_cstr'!
00088                 fname_cstr=name().cstr();
00089             return fname_cstr;
00090         } else
00091             return "<unknown>";
00092     }
00093     void set_name(const String& aname) {
00094         fname=&aname;
00095     }
00096
00097     Method* get_method(const String& aname) const {
00098         return fmethods.get(aname);
00099     }
00100
00102     virtual void add_method(const String& name, Method& method);
00103
00104     void add_native_method(
00105         const char* cstr_name,
00106         Method::Call_type call_type,
00107         NativeCodePtr native_code,
00108         int min_numbered_params_count, int max_numbered_params_count);
00109
00110     void set_base(VStateless_class* abase) {
00111         // remember the guy
00112         fbase=abase;
00113     }
00114     VStateless_class* base_class() { return fbase; }
00115
00116     bool derived_from(VStateless_class& vclass) {
00117         return
00118             fbase==&vclass ||
00119             fbase && fbase->derived_from(vclass);
00120     }
00121
00123
00124     virtual Value* get_field(const String&) { return 0; }
00125     virtual bool replace_field(const String&, Value*) { return false; }
00127
00129     virtual Value* create_new_value(Pool&, HashStringValue& /*afields*/) { return 0; }
00130
00131 protected:
00132
00133     void fill_properties(HashStringValue& acache);
00134
00135 private:
00136
00137     void put_method(const String& aname, Method* amethod);
00138 };
00139
00141 class Temp_method {
00142     VStateless_class& fclass;
00143     const String& fname;
00144     Method* saved_method;
00145 public:
00146     Temp_method(VStateless_class& aclass, const String& aname, Method* amethod) :
00147         fclass(aclass),
00148         fname(aname),
00149         saved_method(aclass.get_method(aname)) {
00150         fclass.put_method(aname, amethod);
00151     }
00152     ~Temp_method() {
00153         fclass.put_method(fname, saved_method);
00154     }
00155 };
00156
00157 #endif


pa_vstateless_object.h File Reference

Parser: stateless_object class decl. More...

Include dependency graph for pa_vstateless_object.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VStateless_object
the object of some class. More...

Variables

const char *const | IDENT_VSTATELESS_OBJECT_H = "$Date: 2005/08/09 08:14:55 $"

Detailed Description

Parser: stateless_object class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vstateless_object.h.

Variable Documentation

const char* const IDENT_VSTATELESS_OBJECT_H = "$Date: 2005/08/09 08:14:55 $" [static]

Definition at line 11 of file pa_vstateless_object.h.


pa_vstateless_object.h Source File

pa_vstateless_object.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VSTATELESS_OBJECT_H
00009 #define PA_VSTATELESS_OBJECT_H
00010
00011 static const char * const IDENT_VSTATELESS_OBJECT_H="$Date: 2005/08/09 08:14:55 $";
00012
00013 // include
00014
00015 #include "pa_vjunction.h"
00016 #include "pa_vstateless_class.h"
00017
00022 class VStateless_object: public Value {
00023 public: // Value
00024
00026     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00027         return get_class()->get_element(aname, aself, looking_up);
00028     }
00029
00031     override const VJunction* put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
00032         return get_class()->put_element(aself, aname, avalue, areplace);
00033     }
00034
00035 };
00036
00037 #endif


pa_vstatus.C File Reference

Parser: status class impl. More...

Include dependency graph for pa_vstatus.C:

Include dependency graph

Go to the source code of this file.

Compounds

struct | _IO_COUNTERS_
union | FT

Defines

#define | EPOCH_BIAS 116444736000000000i64

Typedefs

typedef _IO_COUNTERS_ | IO_COUNTERS_
typedef IO_COUNTERS_ * | PIO_COUNTERS_
typedef unsigned __int64 | ui64
typedef BOOL(WINAPI * | PGETPROCESSTIMES )(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME)
typedef BOOL(WINAPI * | GETPROCESSIOCOUNTERS )(HANDLE, PIO_COUNTERS_)
typedef BOOL(WINAPI * | PGETPROCESSMEMORYINFO )(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD)

Functions

Value & rusage_element ()
Value & memory_element ()

Variables

const char *const | IDENT_VSTATUS_C = "$Date: 2005/08/09 08:14:56 $"

Detailed Description

Parser: status class impl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Win32 rusage author: Victor Fedoseev <vvf_ru@mail.ru>

Definition in file pa_vstatus.C.

Define Documentation

#define EPOCH_BIAS 116444736000000000i64

Definition at line 50 of file pa_vstatus.C.

Referenced by rusage_element().

Typedef Documentation

typedef struct _IO_COUNTERS_ IO_COUNTERS_

typedef IO_COUNTERS_* PIO_COUNTERS_

Definition at line 36 of file pa_vstatus.C.

typedef unsigned __int64 ui64

Definition at line 38 of file pa_vstatus.C.

Referenced by rusage_element().

typedef BOOL(WINAPI * PGETPROCESSTIMES)(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME)

Definition at line 40 of file pa_vstatus.C.

Referenced by rusage_element().

typedef BOOL(WINAPI * GETPROCESSIOCOUNTERS)(HANDLE,PIO_COUNTERS_)

Definition at line 42 of file pa_vstatus.C.

Referenced by rusage_element().

typedef BOOL(WINAPI * PGETPROCESSMEMORYINFO)(HANDLE,PPROCESS_MEMORY_COUNTERS,DWORD)

Definition at line 44 of file pa_vstatus.C.

Referenced by rusage_element().

Function Documentation

Value& rusage_element ( )

Definition at line 62 of file pa_vstatus.C.

References EPOCH_BIAS, FT::ft_scalar, FT::ft_struct, GETPROCESSIOCOUNTERS, VHash::hash(), _IO_COUNTERS_::OtherOperationCount, _IO_COUNTERS_::OtherTransferCount, PGETPROCESSMEMORYINFO, PGETPROCESSTIMES, Hash< const String::Body, Value * >::put(), _IO_COUNTERS_::ReadOperationCount, _IO_COUNTERS_::ReadTransferCount, ui64, _IO_COUNTERS_::WriteOperationCount, and _IO_COUNTERS_::WriteTransferCount.

Referenced by VStatus::get_element().

Value& memory_element ( )

Definition at line 198 of file pa_vstatus.C.

References VHash::hash(), and Hash< const String::Body, Value * >::put().

Referenced by VStatus::get_element().

Variable Documentation

const char* const IDENT_VSTATUS_C = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 10 of file pa_vstatus.C.


pa_vstatus.C Source File

pa_vstatus.C

Go to the documentation of this file.
00001
00010 static const char * const IDENT_VSTATUS_C="$Date: 2005/08/09 08:14:56 $";
00011
00012 #include "pa_vstatus.h"
00013 #include "pa_cache_managers.h"
00014 #include "pa_vhash.h"
00015 #include "pa_vdouble.h"
00016 #include "pa_threads.h"
00017
00018 #ifdef HAVE_SYS_RESOURCE_H
00019 // rusage
00020 #include <sys/resource.h>
00021 #endif
00022
00023 #ifdef WIN32
00024 #include <windows.h>
00025 #include "psapi.h"
00026
00027 // should be in windows.h, but were't
00028 typedef struct _IO_COUNTERS_ {
00029     ULONGLONG  ReadOperationCount;
00030     ULONGLONG  WriteOperationCount;
00031     ULONGLONG  OtherOperationCount;
00032     ULONGLONG ReadTransferCount;
00033     ULONGLONG WriteTransferCount;
00034     ULONGLONG OtherTransferCount;
00035 } IO_COUNTERS_;
00036 typedef IO_COUNTERS_ *PIO_COUNTERS_;
00037
00038 typedef unsigned __int64 ui64;
00039 // kernel32.dll (NT/2K/XP)
00040 typedef BOOL (WINAPI *PGETPROCESSTIMES)(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME);
00041 //typedef BOOL (WINAPI *PGETPROCESSHEAPS)(DWORD,PHANDLE);
00042 typedef BOOL (WINAPI *GETPROCESSIOCOUNTERS)(HANDLE,PIO_COUNTERS_);
00043 // psapi.dll (2K/XP)
00044 typedef BOOL (WINAPI *PGETPROCESSMEMORYINFO)(HANDLE,PPROCESS_MEMORY_COUNTERS,DWORD);
00045
00046 // from CRT time.c
00047 /*
00048  * Number of 100 nanosecond units from 1/1/1601 to 1/1/1970
00049  */
00050 #define EPOCH_BIAS  116444736000000000i64
00051
00052 /*
00053  * Union to facilitate converting from FILETIME to unsigned __int64
00054  */
00055 typedef union {
00056         unsigned __int64 ft_scalar;
00057         FILETIME ft_struct;
00058         } FT;
00059
00060 #endif
00061
00062 Value& rusage_element() {
00063     VHash& rusage=*new VHash;
00064     HashStringValue& hash=rusage.hash();
00065
00066 #ifdef WIN32
00067     double d1;
00068     HANDLE hProc = GetCurrentProcess();
00069
00070     HMODULE hMod = LoadLibrary("kernel32.dll");
00071     if(hMod){
00072         // NT/2K/XP
00073         PGETPROCESSTIMES pGetProcessTimes = (PGETPROCESSTIMES)GetProcAddress(hMod, "GetProcessTimes");
00074         if(pGetProcessTimes){
00075             FILETIME CreationTime, ExitTime;
00076             FT KernelTime, UserTime;
00077             if(pGetProcessTimes(hProc, &CreationTime, &ExitTime, &KernelTime.ft_struct, &UserTime.ft_struct)){
00078                 // dwHighDateTime & dwLowDateTime - 1/10 000 000 seconds in 64 bit
00079                 /* the amount of time that the process has executed in user mode */
00080                 d1 = double((LONGLONG)UserTime.ft_scalar)/10000000.0;
00081                 hash.put(String::Body("utime"),  new VDouble(d1));
00082 //                  hash.put(String::Body("UserTime"),  new VDouble(d1));
00083
00084                 /* the amount of time that the process has executed in kernel mode */
00085                 d1 = double((LONGLONG)KernelTime.ft_scalar)/10000000.0;
00086                 hash.put(String::Body("stime"),  new VDouble(d1));
00087 //                  hash.put(String::Body("KernelTime"),  new VDouble( d1));
00088             }
00089         }
00090
00091         // NT/2K/XP
00092         GETPROCESSIOCOUNTERS pGetProcessIoCounters = (GETPROCESSIOCOUNTERS)GetProcAddress(hMod, "GetProcessIoCounters");
00093         if(pGetProcessIoCounters){
00094             IO_COUNTERS_ ioc;
00095             if(pGetProcessIoCounters(hProc, &ioc)){
00096                 /* Specifies the number of I/O operations performed, other than read and write operations */
00097                 hash.put(String::Body(     "OtherOperationCount"),
00098                     new VDouble(double((LONGLONG)ioc.OtherOperationCount)));
00099                 /* Specifies the number of bytes transferred during operations other than read and write operations */
00100                 hash.put(String::Body(     "OtherTransferCount"),
00101                     new VDouble(double((LONGLONG)ioc.OtherTransferCount)/1024.0));
00102                 /* Specifies the number of read operations performed */
00103                 hash.put(String::Body(     "ReadOperationCount"),
00104                     new VDouble(double((LONGLONG)ioc.ReadOperationCount)));
00105                 /* Specifies the number of bytes read */
00106                 hash.put(String::Body(     "ReadTransferCount"),
00107                     new VDouble(double((LONGLONG)ioc.ReadTransferCount)/1024.0));
00108                 /* Specifies the number of write operations performed */
00109                 hash.put(String::Body(     "WriteOperationCount"),
00110                     new VDouble(double((LONGLONG)ioc.WriteOperationCount)));
00111                 /* Specifies the number of bytes written */
00112                 hash.put(String::Body(     "WriteTransferCount"),
00113                     new VDouble(double((LONGLONG)ioc.WriteTransferCount)/1024.0));
00114             }
00115         }
00116         FreeLibrary(hMod);
00117         /*
00118         PGETPROCESSHEAPS pGetProcessHeaps = (PGETPROCESSHEAPS)GetProcAddress(hMod, "GetProcessHeaps");
00119         if(pGetProcessHeaps){
00120         }
00121         */
00122     }
00123
00124     // 2K/XP
00125     hMod = LoadLibrary("psapi.dll");
00126     if(hMod){
00127         PGETPROCESSMEMORYINFO pGetProcessMemoryInfo = (PGETPROCESSMEMORYINFO)GetProcAddress(hMod, "GetProcessMemoryInfo");
00128         if(pGetProcessMemoryInfo){
00129             PROCESS_MEMORY_COUNTERS pmc;
00130             pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
00131             if(pGetProcessMemoryInfo(hProc, &pmc, sizeof(PROCESS_MEMORY_COUNTERS))){
00132                 /* The peak working set size */
00133                 d1 = double(pmc.PeakWorkingSetSize)/1024.0;
00134                 hash.put(String::Body("maxrss"), new VDouble(d1));
00135 //                  hash.put(String::Body("PeakWorkingSetSize")),  new VDouble( d1)));
00136                 /* The peak nonpaged pool usage */
00137                 d1 = double(pmc.QuotaPeakNonPagedPoolUsage)/1024.0;
00138 //                  hash.put(String::Body("ixrss"), new VDouble(d1));
00139                 hash.put(String::Body("QuotaPeakNonPagedPoolUsage"),  new VDouble( d1));
00140                 /* The peak paged pool usage */
00141                 d1 = double(pmc.QuotaPeakPagedPoolUsage)/1024.0;
00142 //                  hash.put(String::Body("idrss"),  new VDouble( d1));
00143                 hash.put(String::Body("QuotaPeakPagedPoolUsage"),  new VDouble( d1));
00144                 /* The peak pagefile usage */
00145                 d1 = double(pmc.PeakPagefileUsage)/1024.0;
00146 //                  hash.put(String::Body("isrss"),  new VDouble( d1));
00147                 hash.put(String::Body("PeakPagefileUsage"),  new VDouble( d1));
00148             }
00149         }
00150         FreeLibrary(hMod);
00151     }
00152
00153     // all windows.
00154     FT ft;
00155 GetSystemTimeAsFileTime( &(ft.ft_struct) );
00156     ft.ft_scalar -= EPOCH_BIAS;
00157     ui64 tv_sec = ft.ft_scalar/10000000i64;
00158     ui64 tv_usec = (ft.ft_scalar-tv_sec*10000000i64)/10i64;
00159     hash.put(String::Body("tv_sec"), new VDouble(double((LONGLONG)tv_sec)));
00160     hash.put(String::Body("tv_usec"), new VDouble(double((LONGLONG)tv_usec)));
00161
00162 #else
00163
00164 #ifdef HAVE_GETRUSAGE
00165     struct rusage u;
00166     if(getrusage(RUSAGE_SELF,&u)<0)
00167         throw Exception(0,
00168             0,
00169             "getrusage failed (#%d)", errno);
00170
00171     hash.put(String::Body("utime"), new VDouble(
00172         u.ru_utime.tv_sec+u.ru_utime.tv_usec/1000000.0));
00173     hash.put(String::Body("stime"), new VDouble(
00174         u.ru_stime.tv_sec+u.ru_stime.tv_usec/1000000.0));
00175     hash.put(String::Body("maxrss"), new VDouble(u.ru_maxrss));
00176     hash.put(String::Body("ixrss"), new VDouble(u.ru_ixrss));
00177     hash.put(String::Body("idrss"), new VDouble(u.ru_idrss));
00178     hash.put(String::Body("isrss"), new VDouble(u.ru_isrss));
00179 #endif
00180
00181 #ifdef HAVE_GETTIMEOFDAY
00182     struct timeval tp;
00183     if(gettimeofday(&tp, NULL)<0)
00184         throw Exception(0,
00185             0,
00186             "gettimeofday failed (#%d)", errno);
00187
00188     hash.put(String::Body("tv_sec"), new VDouble(tp.tv_sec));
00189     hash.put(String::Body("tv_usec"), new VDouble(tp.tv_usec));
00190 #endif
00191
00192 #endif
00193
00194     return rusage;
00195 }
00196
00197 #ifndef PA_DEBUG_DISABLE_GC
00198 Value& memory_element() {
00199     VHash& memory=*new VHash;
00200     HashStringValue& hash=memory.hash();
00201     size_t heap_size=GC_get_heap_size();
00202     size_t free_bytes=GC_get_free_bytes();
00203     size_t bytes_since_gc=GC_get_bytes_since_gc();
00204     size_t total_bytes=GC_get_total_bytes();
00205
00206     hash.put(String::Body("used"), new VDouble((heap_size-free_bytes)/1024.0));
00207     hash.put(String::Body("free"), new VDouble(free_bytes/1024.0));
00208     hash.put(String::Body("ever_allocated_since_compact"), new VDouble(bytes_since_gc/1024.0));
00209     hash.put(String::Body("ever_allocated_since_start"), new VDouble(total_bytes/1024.0));
00210
00211     return memory;
00212 }
00213 #endif
00214
00215 Value* VStatus::get_element(const String& aname, Value& /*aself*/, bool /*looking_up*/) {
00216     // getstatus
00217     if(Cache_manager* manager=cache_managers->get(aname))
00218         return manager->get_status();
00219
00220     // $pid
00221     if(aname=="pid")
00222         return new VInt(getpid());
00223
00224     // $tid
00225     if(aname=="tid")
00226         return new VInt(pa_get_thread_id());
00227
00228     // $rusage
00229     if(aname=="rusage")
00230         return &rusage_element();
00231
00232 #ifndef PA_DEBUG_DISABLE_GC
00233     // $memory
00234     if(aname=="memory")
00235         return &memory_element();
00236 #endif
00237
00238     return 0;
00239 }


pa_vstatus.h File Reference

Parser: status class decl. More...

Include dependency graph for pa_vstatus.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VStatus
status class. More...

Defines

#define | STATUS_CLASS_NAME "status"

Variables

const char *const | IDENT_VSTATUS_H = "$Date: 2005/08/09 08:14:56 $"

Detailed Description

Parser: status class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vstatus.h.

Define Documentation

#define STATUS_CLASS_NAME "status"

Definition at line 19 of file pa_vstatus.h.

Referenced by Request::Request().

Variable Documentation

const char* const IDENT_VSTATUS_H = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 11 of file pa_vstatus.h.


pa_vstatus.h Source File

pa_vstatus.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VSTATUS_H
00009 #define PA_VSTATUS_H
00010
00011 static const char * const IDENT_VSTATUS_H="$Date: 2005/08/09 08:14:56 $";
00012
00013 // includes
00014
00015 #include "pa_value.h"
00016
00017 // define
00018
00019 #define STATUS_CLASS_NAME "status"
00020
00022 class VStatus: public Value {
00023
00024 public: // Value
00025
00026     const char* type() const { return "status"; }
00027     VStateless_class *get_class() { return 0; }
00028
00029     // VStatus: field
00030     Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00031
00032 public: //  usage
00033
00034 };
00035
00036 #endif


pa_vstring.C File Reference

Parser: string class. More...

Include dependency graph for pa_vstring.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_VSTRING_C = "$Date: 2005/08/09 08:14:56 $"

Detailed Description

Parser: string class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vstring.C.

Variable Documentation

const char* const IDENT_VSTRING_C = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 8 of file pa_vstring.C.


pa_vstring.C Source File

pa_vstring.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VSTRING_C="$Date: 2005/08/09 08:14:56 $";
00009
00010 #include "pa_vstring.h"
00011 #include "pa_vfile.h"
00012
00013 VFile* VString::as_vfile(String::Language lang, const Request_charsets* charsets) {
00014     VFile& result=*new VFile;
00015     const char* cstr=fstring->cstr(lang, 0, charsets);
00016     result.set(false/*not tainted*/, cstr, strlen(cstr));
00017     return &result;
00018 }


pa_vstring.h File Reference

Parser: string parser class decl. More...

Include dependency graph for pa_vstring.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VString
value of type 'string'. implemented with String. More...

Variables

const char *const | IDENT_VSTRING_H = "$Date: 2005/08/09 08:14:56 $"
Methoded * string_class

Detailed Description

Parser: string parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vstring.h.

Variable Documentation

const char* const IDENT_VSTRING_H = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 11 of file pa_vstring.h.

Methoded* string_class

Definition at line 20 of file pa_vstring.h.


pa_vstring.h Source File

pa_vstring.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VSTRING_H
00009 #define PA_VSTRING_H
00010
00011 static const char * const IDENT_VSTRING_H="$Date: 2005/08/09 08:14:56 $";
00012
00013 // includes
00014
00015 #include "pa_vstateless_object.h"
00016 #include "pa_vdouble.h"
00017
00018 // externs
00019
00020 extern Methoded* string_class;
00021
00023 class VString: public VStateless_object {
00024 public: // Value
00025
00026     override const char* type() const { return "string"; }
00027     override VStateless_class *get_class() { return string_class; }
00029     override bool is_defined() const { return !fstring->is_empty(); }
00031     override bool as_bool() const { return as_double()!=0; }
00033     override bool is_string() const { return true; }
00035     override Value& as_expr_result(bool return_string_as_is=false) {
00036         if(return_string_as_is)
00037             return *this;
00038         else
00039             return *new VDouble(as_double());
00040     }
00042     override const String* get_string() { return fstring; };
00044     override double as_double() const { return fstring->as_double(); }
00046     override int as_int() const { return fstring->as_int(); }
00047
00049     override VFile* as_vfile(String::Language lang=String::L_UNSPECIFIED,
00050         const Request_charsets *charsets=0);
00051
00053     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00054         // $method
00055         if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00056             return result;
00057
00058         // bad $string.field
00059         return bark("%s method not found", &aname);
00060     }
00061
00062 public: // usage
00063
00064     VString(): fstring(new String) {}
00065     VString(const String& avalue): fstring(&avalue) {}
00066
00067     const String& string() const { return *fstring; }
00068     void set_string(const String& astring) { fstring=&astring; }
00069
00070 private:
00071     const String* fstring;
00072
00073 };
00074
00075 #endif


pa_vtable.C File Reference

Parser: table class. More...

Include dependency graph for pa_vtable.C:

Include dependency graph

Go to the source code of this file.

Functions

void | store_column_item_to_hash (const String *column_name, Record_info *info)

Variables

const char *const | IDENT_VTABLE_C = "$Date: 2005/08/09 08:14:56 $"

Detailed Description

Parser: table class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vtable.C.

Function Documentation

void store_column_item_to_hash | ( | const String * | column_name,
 |  | Record_info * | info
 | ) | [static]

Definition at line 21 of file pa_vtable.C.

References value.

Referenced by VTable::fields_element().

Variable Documentation

const char* const IDENT_VTABLE_C = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 8 of file pa_vtable.C.


pa_vtable.C Source File

pa_vtable.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VTABLE_C="$Date: 2005/08/09 08:14:56 $";
00009
00010 #include "pa_vtable.h"
00011 #include "pa_vstring.h"
00012 #include "pa_vhash.h"
00013 #include "pa_vvoid.h"
00014
00015 #ifndef DOXYGEN
00016 struct Record_info {
00017     Table* table;
00018     HashStringValue* hash;
00019 };
00020 #endif
00021 static void store_column_item_to_hash(const String* column_name,
00022                       Record_info *info) {
00023     Value* value;
00024     if(const String* column_item=info->table->item(*column_name))
00025         value=new VString(*column_item);
00026     else
00027         value=new VVoid;
00028     info->hash->put(*column_name, value);
00029 }
00030 Value* VTable::fields_element() {
00031     Table& ltable=table();
00032     if(Table::columns_type columns=ltable.columns()) {
00033         Value& result=*new VHash;
00034         Record_info record_info={&ltable, result.get_hash()};
00035         columns->for_each(store_column_item_to_hash, &record_info);
00036         return &result;
00037     }
00038     return 0;
00039 }
00040
00041
00042 Value* VTable::get_element(const String& aname, Value& aself, bool looking_up) {
00043     // fields
00044     if(aname==TABLE_FIELDS_ELEMENT_NAME)
00045         return fields_element();
00046
00047     // methods
00048     if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00049         return result;
00050
00051     // columns
00052     if(ftable) {
00053         int index=ftable->column_name2index(aname, false);
00054         if(index>=0) // column aname|number valid
00055             if(const String* string=ftable->item(index)) // there is such column
00056                 return new VString(*string);
00057             else
00058                 return new VVoid;
00059     }
00060
00061     throw Exception("parser.runtime",
00062         &aname,
00063         "column not found");
00064 }


pa_vtable.h File Reference

Parser: table parser class decl. More...

Include dependency graph for pa_vtable.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VTable
value of type 'table'. implemented with Table. More...

Defines

#define | VTABLE_TYPE "table"
#define | TABLE_FIELDS_ELEMENT_NAME "fields"

Variables

const char *const | IDENT_VTABLE_H = "$Date: 2005/08/09 08:14:56 $"
Methoded * table_class

Detailed Description

Parser: table parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vtable.h.

Define Documentation

#define VTABLE_TYPE "table"

Definition at line 20 of file pa_vtable.h.

Referenced by VObject::get_table(), and VTable::type().

#define TABLE_FIELDS_ELEMENT_NAME "fields"

Definition at line 21 of file pa_vtable.h.

Referenced by VTable::get_element().

Variable Documentation

const char* const IDENT_VTABLE_H = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 11 of file pa_vtable.h.

Methoded* table_class

Definition at line 25 of file pa_vtable.h.


pa_vtable.h Source File

pa_vtable.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VTABLE_H
00009 #define PA_VTABLE_H
00010
00011 static const char * const IDENT_VTABLE_H="$Date: 2005/08/09 08:14:56 $";
00012
00013 #include "pa_vstateless_object.h"
00014 #include "pa_table.h"
00015 //#include "pa_vvoid.h"
00016 #include "pa_vint.h"
00017
00018 // defines
00019
00020 #define VTABLE_TYPE "table"
00021 #define TABLE_FIELDS_ELEMENT_NAME "fields"
00022
00023 // externs
00024
00025 extern Methoded* table_class;
00026
00028 class VTable: public VStateless_object {
00029 public: // Value
00030
00031     override const char* type() const { return VTABLE_TYPE; }
00032     override VStateless_class *get_class() { return table_class; }
00034     override int as_int() const { return table().count(); }
00036     override double as_double() const { return as_int(); }
00038     override bool is_defined() const { return as_bool(); }
00040     override bool as_bool() const { return as_int()!=0; }
00042     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VInt(as_int()); }
00044     override Table* get_table() { return ftable; }
00046     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00047
00048 public: // usage
00049
00050     VTable(Table* atable=0): ftable(atable) {}
00051
00052     void set_table(Table& avalue) {
00053         ftable=&avalue;
00054     }
00055     Table& table() const {
00056         if(!ftable)
00057             bark("getting unset vtable value", 0);
00058
00059         return *ftable;
00060     }
00061
00062 private:
00063
00064     Value* fields_element();
00065
00066 private:
00067
00068     Table* ftable;
00069
00070 };
00071
00072 #endif


pa_vvoid.C File Reference

Parser: string class. More...

Include dependency graph for pa_vvoid.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT = "$Date: 2005/08/09 08:14:56 $"

Detailed Description

Parser: string class.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vvoid.C.

Variable Documentation

const char* const IDENT = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 8 of file pa_vvoid.C.


pa_vvoid.C Source File

pa_vvoid.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT="$Date: 2005/08/09 08:14:56 $";
00009
00010 #include "pa_vvoid.h"
00011 #include "pa_vfile.h"
00012
00013 const String VVoid::void_string_value;
00014
00015 VFile* VVoid::as_vfile(String::Language /*lang*/, const Request_charsets* /*charsets*/) {
00016     VFile& result=*new VFile;
00017     result.set(false/*not tainted*/, "", 0);
00018     return &result;
00019 }


pa_vvoid.h File Reference

Parser: void parser class. More...

Include dependency graph for pa_vvoid.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VVoid
value of type 'void'. ex: usually $sjfklsjfksjdfk has this type. More...

Variables

const char *const | IDENT_VVOID_H = "$Date: 2005/08/09 08:14:56 $"
Methoded * void_class

Detailed Description

Parser: void parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vvoid.h.

Variable Documentation

const char* const IDENT_VVOID_H = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 11 of file pa_vvoid.h.

Methoded* void_class

Definition at line 17 of file pa_vvoid.h.

Referenced by marshal_bind().


pa_vvoid.h Source File

pa_vvoid.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VVOID_H
00009 #define PA_VVOID_H
00010
00011 static const char * const IDENT_VVOID_H="$Date: 2005/08/09 08:14:56 $";
00012
00013 #include "classes.h"
00014 #include "pa_vstateless_object.h"
00015 #include "pa_globals.h"
00016
00017 extern Methoded* void_class;
00018
00020 class VVoid: public VStateless_object {
00021 public: // Value
00022
00023     override const char* type() const { return "void"; }
00024     override VStateless_class *get_class() { return void_class; }
00025
00027     override bool is_void() const { return true; }
00029     override const String* get_string() { return &void_string_value; }
00031     override bool as_bool() const { return false; }
00033     override bool is_defined() const { return false; }
00035     override double as_double() const { return 0; }
00037     override int as_int() const { return 0; }
00039     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *this; }
00040
00042     override VFile* as_vfile(String::Language lang=String::L_UNSPECIFIED,
00043         const Request_charsets *charsets=0);
00044
00046     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00047         // methods
00048         if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00049             return result;
00050
00051         return 0;
00052     }
00053
00055     override const VJunction* put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
00056         return Value::put_element(aself, aname, avalue, areplace);
00057     }
00058
00059 private:
00060
00061     static const String void_string_value;
00062
00063 };
00064
00065 #endif


pa_vxdoc.C File Reference

Include dependency graph for pa_vxdoc.C:

Include dependency graph

Go to the source code of this file.


pa_vxdoc.C Source File

pa_vxdoc.C

Go to the documentation of this file.
00001
00007 #include "pa_config_includes.h"
00008 #ifdef XML
00009
00010 static const char * const IDENT_VXDOC="$Date: 2005/12/16 14:48:22 $";
00011
00012 #include "pa_vxdoc.h"
00013
00014 // defines
00015
00016 #define SEARCH_NAMESPACES_NAME "search-namespaces"
00017
00018
00019 VXnode& VXdoc::wrap(xmlNode& anode) {
00020     VXnode* result;
00021     if((result=static_cast<VXnode*>(anode._private))) {
00022         assert(anode.doc==fdocument);
00023         return *result;
00024     }
00025
00026     result=new VXnode(anode);
00027     anode._private=result;
00028     anode.doc=fdocument;
00029
00030     return *result;
00031 }
00032
00033
00034 Value* VXdoc::as(const char* atype, bool looking_up) {
00035     if(Value* result=Value::as(atype, looking_up))
00036         return result;
00037     else
00038         return VXnode::as(atype, looking_up);
00039 }
00040
00042 Value* VXdoc::get_element(const String& aname, Value& aself, bool looking_up) {
00043     if(aname==SEARCH_NAMESPACES_NAME) {
00044         return &search_namespaces;
00045     }
00046
00047     // up
00048     try {
00049         return VXnode::get_element(aname, aself, looking_up);
00050     } catch(Exception) {
00051         // ignore bad node elements, they can be valid here...
00052
00053         // fields
00054         xmlDoc& xmldoc=get_xmldoc();
00055
00056         if(aname=="doctype") {
00057             // readonly attribute DocumentType doctype;
00058             if(xmlNode* node=(xmlNode*)xmldoc.intSubset)
00059                 return &wrap(*node);
00060             else
00061                 return 0;
00062         } else if(aname=="implementation") {
00063             // readonly attribute DOMImplementation implementation;
00064             return 0;
00065         } else if(aname=="documentElement") {
00066             // readonly attribute Element documentElement;
00067             xmlNode* rootElement=xmlDocGetRootElement(&xmldoc);
00068             assert(rootElement);
00069             return &wrap(*rootElement);
00070         }
00071
00072         return bark("%s field not found", &aname);
00073     }
00074 }
00075
00076 #endif


pa_vxdoc.h File Reference

Parser: xdoc parser class decl. More...

Include dependency graph for pa_vxdoc.h:

Include dependency graph

Go to the source code of this file.

Compounds

class | VXdoc
value of type 'xdoc'. implemented with libxml & co. More...

struct | Output_options

Defines

#define | VXDOC_TYPE "xdoc"

Variables

const char *const | IDENT_VXDOC_H = "$Date: 2005/12/16 10:15:12 $"
Methoded * xdoc_class

Detailed Description

Parser: xdoc parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vxdoc.h.

Define Documentation

#define VXDOC_TYPE "xdoc"

Definition at line 21 of file pa_vxdoc.h.

Referenced by VXdoc::type().

Variable Documentation

const char* const IDENT_VXDOC_H = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 11 of file pa_vxdoc.h.

Methoded* xdoc_class

Definition at line 25 of file pa_vxdoc.h.


pa_vxdoc.h Source File

pa_vxdoc.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VXDOC_H
00009 #define PA_VXDOC_H
00010
00011 static const char * const IDENT_VXDOC_H="$Date: 2005/12/16 10:15:12 $";
00012
00013 #include "classes.h"
00014 #include "pa_common.h"
00015 #include "pa_vstateless_object.h"
00016 #include "pa_vxnode.h"
00017 #include "pa_vhash.h"
00018
00019 // defines
00020
00021 #define VXDOC_TYPE "xdoc"
00022
00023 // externals
00024
00025 extern Methoded* xdoc_class;
00026
00028 class VXdoc: public VXnode {
00029 public: // Value
00030
00031     override const char* type() const { return VXDOC_TYPE; }
00032     override Value* as(const char* atype, bool looking_up);
00033
00034     override VStateless_class* get_class() { return xdoc_class; }
00035
00037     override bool as_bool() const { return true; }
00038
00040     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VBool(as_bool()); }
00041
00043     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00044
00045 public: // VXNode
00046
00047     override xmlNode& get_xmlnode() {
00048         return *reinterpret_cast<xmlNode*>(&get_xmldoc());
00049     }
00050
00051     override VXdoc& get_vxdoc() {
00052         return *this;
00053     }
00054
00055 public: // usage
00056
00057     VXdoc() :
00058         VXnode(*this),
00059         fcharsets(0),
00060         fdocument(0) {}
00061
00062     VXdoc(Request_charsets& acharsets, xmlDoc& adocument) : VXnode(*this) {
00063         set_xmldoc(acharsets, adocument);
00064     }
00065
00066 public: // VXdoc
00067
00068     void set_xmldoc(Request_charsets& acharsets, xmlDoc& adocument) {
00069         fcharsets=&acharsets;
00070         fdocument=&adocument;
00071         fdocument->_private=this;
00072     }
00073     xmlDoc& get_xmldoc() {
00074         if(!fdocument)
00075             throw Exception("parser.runtime",
00076                 0,
00077                 "using unitialized xdoc object");
00078         return *fdocument;
00079     }
00080
00081     Request_charsets& charsets() {
00082         if(!fcharsets)
00083             throw Exception("parser.runtime",
00084                 0,
00085                 "using unitialized xdoc object");
00086         return *fcharsets;
00087     }
00088
00089     VXnode& wrap(xmlNode& anode);
00090
00091 public:
00092
00093     VHash search_namespaces;
00094
00095     struct Output_options {
00096         const String* method;            /* the output method */
00097         const String* encoding;          /* encoding string */
00098         const String* mediaType;         /* media-type string */
00099         int indent;                 /* should output being indented */
00100         const String* version;           /* version string */
00101         int standalone;             /* standalone = "yes" | "no" */
00102         int omitXmlDeclaration;     /* omit-xml-declaration = "yes" | "no" */
00103
00104         Output_options() {
00105             memset(this, 0, sizeof(*this));
00106             indent=standalone=omitXmlDeclaration=-1;
00107         };
00108     } output_options;
00109
00110 private:
00111
00112     Request_charsets* fcharsets;
00113     xmlDoc* fdocument;
00114 };
00115
00116 #endif


pa_vxnode.C File Reference

Include dependency graph for pa_vxnode.C:

Include dependency graph

Go to the source code of this file.


pa_vxnode.C Source File

pa_vxnode.C

Go to the documentation of this file.
00001
00007 #include "pa_config_includes.h"
00008 #ifdef XML
00009
00010 static const char * const IDENT_VXNODE_C="$Date: 2005/12/19 12:55:09 $";
00011
00012 #include "pa_vxnode.h"
00013 #include "pa_vxdoc.h"
00014 #include "pa_vstring.h"
00015 #include "pa_vbool.h"
00016 #include "pa_vhash.h"
00017 #include "pa_request_charsets.h"
00018 #include "pa_charset.h"
00019 #include "pa_xml_exception.h"
00020
00021 Request_charsets& VXnode::charsets() {
00022     return get_vxdoc().charsets();
00023 }
00024
00025 Value* VXnode::get_element(const String& aname, Value& aself, bool looking_up) {
00026     // $CLASS,$method
00027     if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
00028         return result;
00029
00030     // fields
00031     xmlNode& selfNode=get_xmlnode();
00032
00033     if(aname=="nodeName") {
00034         return new VString(charsets().source().transcode(selfNode.name));
00035     } else if(aname=="nodeValue") {
00036         switch(selfNode.type) {
00037         case XML_ATTRIBUTE_NODE:
00038         case XML_PI_NODE:
00039         case XML_CDATA_SECTION_NODE:
00040         case XML_COMMENT_NODE:
00041         case XML_TEXT_NODE:
00042             return new VString(charsets().source().transcode(xmlNodeGetContent(&selfNode)));
00043         default:
00044             return 0;
00045         }
00046     } else if(aname=="nodeType") {
00047         return new VInt(selfNode.type);
00048     } else if(aname=="parentNode") {
00049         if(xmlNode* result_node=selfNode.parent)
00050             return &get_vxdoc().wrap(*result_node);
00051         return 0;
00052     } else if(aname=="childNodes") {
00053         if(xmlNode* currentNode=selfNode.children) {
00054             VHash* result=new VHash;
00055             int i=0;
00056             do {
00057                 result->hash().put(
00058                     String::Body::Format(i++),
00059                     &get_vxdoc().wrap(*currentNode));
00060             } while((currentNode=currentNode->next));
00061             return result;
00062         }
00063         return 0;
00064     } else if(aname=="firstChild") {
00065         if(xmlNode* result_node=selfNode.children)
00066             return &get_vxdoc().wrap(*result_node);
00067         return 0;
00068     } else if(aname=="lastChild") {
00069         if(xmlNode* result_node=selfNode.last)
00070             return &get_vxdoc().wrap(*result_node);
00071         return 0;
00072     } else if(aname=="previousSibling") {
00073         if(xmlNode* result_node=selfNode.prev)
00074             return &get_vxdoc().wrap(*result_node);
00075         return 0;
00076     } else if(aname=="nextSibling") {
00077         if(xmlNode* result_node=selfNode.next)
00078             return &get_vxdoc().wrap(*result_node);
00079         return 0;
00080     } else if(aname=="ownerDocument") {
00081         return &get_vxdoc();
00082     } else switch(selfNode.type) {
00083         case XML_ELEMENT_NODE:
00084             if(aname=="attributes") {
00085                 if(xmlNode* currentNode=(xmlNode*)selfNode.properties) {
00086                     VHash* result=new VHash;
00087                     do {
00088                         result->hash().put(
00089                             charsets().source().transcode(currentNode->name),
00090                             &get_vxdoc().wrap(*currentNode));
00091                     } while((currentNode=currentNode->next));
00092                     return result;
00093                 }
00094                 return 0;
00095             } else if(aname=="tagName") {
00096                 return new VString(charsets().source().transcode(selfNode.name));
00097             }
00098             break;
00099         case XML_ATTRIBUTE_NODE:
00100             if(aname=="specified")
00101                 return new VBool(true); // were not working in gdome, leaving out
00102             else if(aname=="name")
00103                 return new VString(charsets().source().transcode(selfNode.name));
00104             else if(aname=="value")
00105                 return new VString(charsets().source().transcode(xmlNodeGetContent(&selfNode)));
00106             break;
00107 /*
00108         case XML_COMMENT_NODE:
00109             substringData(unsigned int offset, unsigned int count)
00110 */
00111         case XML_PI_NODE:
00112             if(aname=="target")
00113                 return new VString(charsets().source().transcode(selfNode.name));
00114             else if(aname=="data")
00115                 return new VString(charsets().source().transcode(xmlNodeGetContent(&selfNode)));
00116             break;
00117         case XML_DTD_NODE:
00118             {
00119                 if(aname=="name") {
00120                     // readonly attribute DOMString aname;
00121                     // The aname of DTD; i.e., the aname immediately following
00122                     // the DOCTYPE keyword in an XML source document.
00123                     return new VString(charsets().source().transcode(selfNode.name));
00124                 }
00125                 /*
00126                 readonly attribute NamedNodeMap entities;
00127                 readonly attribute NamedNodeMap notations;
00128                 virtual const XalanNamedNodeMap* getEntities () const = 0
00129                 This function returns a NamedNodeMap containing the general entities, both external and internal, declared in the DTD. More...
00130                 virtual const XalanNamedNodeMap* getNotations () const = 0
00131                 This function returns a named selfNode map containing an entry for each notation declared in a document's DTD. More...
00132                 */
00133             }
00134             break;
00135             /* someday
00136         case XML_NOTATION_NODE:
00137             {
00138                 GdomeNotation *notation=XML_NOT(selfNode);
00139                 if(aname=="publicId") {
00140                     // readonly attribute DOMString publicId;
00141                     return new VString(charsets().source().transcode(gdome_not_publicId(notation, &exc)));
00142                 } else if(aname=="systemId") {
00143                     // readonly attribute DOMString systemId;
00144                     return new VString(charsets().source().transcode(gdome_not_systemId(notation, &exc)));
00145                 }
00146             }
00147             break;
00148             */
00149         default:
00150             // calm compiler on unhandled cases
00151             break;
00152     }
00153
00154     return bark("%s field not found", &aname);
00155 }
00156
00157 const VJunction* VXnode::put_element(Value& /*aself*/, const String& aname, Value* avalue, bool /*replace*/)
00158 {
00159     xmlNode& selfNode=get_xmlnode();
00160
00161     if(aname=="nodeValue") {
00162         xmlNodeSetContent(&selfNode,
00163             charsets().source().transcode(avalue->as_string()));
00164
00165         return PUT_ELEMENT_REPLACED_ELEMENT;
00166     }
00167
00168     bark("element can not be stored to %s", &aname);
00169     return 0;
00170 }
00171 #endif


pa_vxnode.h File Reference

Parser: xnode parser class decl. More...

Include dependency graph for pa_vxnode.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | VXnode
value of type 'xnode'. implemented with xmlNode. More...

Defines

#define | VXNODE_TYPE "xnode"

Variables

const char *const | IDENT_VXNODE_H = "$Date: 2005/12/16 14:48:22 $"
Methoded * xnode_class

Detailed Description

Parser: xnode parser class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_vxnode.h.

Define Documentation

#define VXNODE_TYPE "xnode"

Definition at line 23 of file pa_vxnode.h.

Referenced by VXnode::type().

Variable Documentation

const char* const IDENT_VXNODE_H = "$Date: 2005/12/16 14:48:22 $" [static]

Definition at line 11 of file pa_vxnode.h.

Methoded* xnode_class

Definition at line 27 of file pa_vxnode.h.


pa_vxnode.h Source File

pa_vxnode.h

Go to the documentation of this file.
00001
00008 #ifndef PA_VXNODE_H
00009 #define PA_VXNODE_H
00010
00011 static const char * const IDENT_VXNODE_H="$Date: 2005/12/16 14:48:22 $";
00012
00013 #include "classes.h"
00014 #include "pa_common.h"
00015 #include "pa_vstateless_object.h"
00016
00017 extern "C" {
00018 #include "libxml/tree.h"
00019 };
00020
00021 // defines
00022
00023 #define VXNODE_TYPE "xnode"
00024
00025 // externals
00026
00027 extern Methoded* xnode_class;
00028
00029 // forwards
00030
00031 class VXdoc;
00032
00034 class VXnode: public VStateless_object {
00035 public: // Value
00036
00037     override const char* type() const { return VXNODE_TYPE; }
00038     override VStateless_class* get_class() { return xnode_class; }
00039
00041     override bool as_bool() const { return true; }
00042
00044     override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VBool(as_bool()); }
00045
00047     override Value* get_element(const String& aname, Value& aself, bool /*looking_up*/);
00048
00050     override const VJunction* put_element(Value& self, const String& aname, Value* avalue, bool replace);
00051
00052 public: // usage
00053
00054     VXnode(xmlNode& anode) :
00055         fnode(anode) {}
00056
00057 public: // VXnode
00058
00059     virtual xmlNode& get_xmlnode() {
00060         return fnode;
00061     }
00062
00063     virtual VXdoc& get_vxdoc() {
00064         assert(fnode.doc);
00065         VXdoc* result=static_cast<VXdoc*>(fnode.doc->_private);
00066         assert(result);
00067         return *result;
00068     }
00069
00070     Request_charsets& charsets();
00071
00072 private:
00073
00074     xmlNode& fnode;
00075 };
00076
00077 #endif


pa_wcontext.C File Reference

Parser: write context class. More...

Include dependency graph for pa_wcontext.C:

Include dependency graph

Go to the source code of this file.

Variables

const char *const IDENT_WCONTEXT_C = "$Date: 2005/12/06 10:27:40 $"

Detailed Description

Parser: write context class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_wcontext.C.

Variable Documentation

const char* const IDENT_WCONTEXT_C = "$Date: 2005/12/06 10:27:40 $" [static]

Definition at line 8 of file pa_wcontext.C.


pa_wcontext.C Source File

pa_wcontext.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_WCONTEXT_C="$Date: 2005/12/06 10:27:40 $";
00009
00010 #include "pa_wcontext.h"
00011
00012 // appends a fstring to result
00013 void WContext::write(Value& avalue) {
00014     if(fvalue) { // already have value?
00015         // must not construct twice
00016         throw Exception("parser.runtime",
00017             fvalue->get_class()?&fvalue->get_class()->name():0,
00018             "%s may not be overwritten with %s, store it to variable instead",
00019                 fvalue->type(),
00020                 avalue.type());
00021     } else
00022         fvalue=&avalue;
00023 }
00024
00025
00026 void WContext::detach_junctions() {
00027     Array_iterator<Junction*> i(junctions);
00028     while(i.has_next())
00029         i.next()->reattach(fparent);
00030     // someday free junctions
00031     // the day has come?
00032     // no, libgc will do that for us!
00033 }


pa_wcontext.h File Reference

Parser: write context class decl. More...

Include dependency graph for pa_wcontext.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | StringOrValue
class | WContext
Write context they do different write()s here, later picking up the result. More...

Variables

const char *const | IDENT_WCONTEXT_H = "$Date: 2005/12/06 10:27:40 $"

Detailed Description

Parser: write context class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_wcontext.h.

Variable Documentation

const char* const IDENT_WCONTEXT_H = "$Date: 2005/12/06 10:27:40 $" [static]

Definition at line 11 of file pa_wcontext.h.


pa_wcontext.h Source File

pa_wcontext.h

Go to the documentation of this file.
00001
00008 #ifndef PA_WCONTEXT_H
00009 #define PA_WCONTEXT_H
00010
00011 static const char * const IDENT_WCONTEXT_H="$Date: 2005/12/06 10:27:40 $";
00012
00013 #include "pa_value.h"
00014 #include "pa_vstring.h"
00015 #include "pa_vhash.h"
00016
00017 class Request;
00018
00019 class StringOrValue {
00020 public:
00021     StringOrValue() : fstring(0), fvalue(0) {}
00023     StringOrValue(const String& astring) : fstring(&astring), fvalue(0) {}
00024     StringOrValue(Value& avalue) : fstring(0), fvalue(&avalue) {}
00025
00026     void set_string(const String& astring) { fstring=&astring; }
00027     void set_value(Value& avalue) { fvalue=&avalue; }
00028     const String* get_string() { return fstring; }
00029     Value* get_value() { return fvalue; }
00030     Value& as_value() const {
00031         Value* result=fvalue?fvalue:new VString(*fstring);
00032         return *result;
00033     }
00034     const String& as_string() const {
00035         return fstring?*fstring:fvalue->as_string();
00036     }
00037 private:
00038     const String* fstring;
00039     Value* fvalue;
00040 };
00041
00046 class WContext: public Value {
00047     friend class Request;
00048
00049 public: // Value
00050
00051     override const char* type() const { return "wcontext"; }
00053     override const String* get_string() { return &fstring; };
00054
00056     override VStateless_class *get_class() { return fvalue?fvalue->get_class():0; }
00057
00058 public: // WContext
00059
00061     virtual void write(const String& astring, String::Language alang) {
00062         fstring.append(astring, alang);
00063     }
00065     virtual void write(Value& avalue);
00066
00071     void write(
00072         Value& avalue, String::Language alang) {
00073         if(const String* fstring=avalue.get_string())
00074             write(*fstring, alang);
00075         else
00076             write(avalue);
00077     }
00078
00084     virtual StringOrValue result() {
00085         return fvalue?StringOrValue(*fvalue):StringOrValue(fstring);
00086     }
00087
00088     void attach_junction(Junction* ajunction) {
00089         junctions+=ajunction;
00090     }
00091
00092 public: // usage
00093
00094     WContext(Value* avalue, WContext *aparent):
00095         fstring(*new String),
00096         fvalue(avalue),
00097         fparent(aparent) {
00098         constructing=in_expression=entered_class=entered_object=were_string_writes=false;
00099     }
00100     virtual ~WContext() {
00101         detach_junctions();
00102     }
00103
00104     void set_constructing(bool aconstructing) { constructing=aconstructing; }
00105     bool get_constructing() { return constructing; }
00106
00107     void set_in_expression(bool ain_expression) { in_expression=ain_expression; }
00108     bool get_in_expression() { return in_expression; }
00109
00110     void set_somebody_entered_some_class() { entered_class=true; }
00111     bool get_somebody_entered_some_class() { return entered_class; }
00112
00113 private:
00114
00115     void detach_junctions();
00116
00117 protected:
00118     String& fstring;
00119     Value* fvalue;
00120
00121 private: // status
00122
00123     bool constructing;
00124     bool in_expression;
00125     bool entered_object;
00126     bool entered_class;
00127     bool were_string_writes;
00128
00129 private:
00130
00131     WContext *fparent;
00132     Array<Junction*>  junctions;
00133
00134 };
00135
00136 #endif


pa_wwrapper.h File Reference

Parser: write_wrapper write context. More...

Include dependency graph for pa_wwrapper.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | WWrapper
specialized write context, adds to WContext VHash autocreation ability. More...

Variables

const char *const | IDENT_WWRAPPER_H = "$Date: 2005/08/09 08:14:56 $"

Detailed Description

Parser: write_wrapper write context.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_wwrapper.h.

Variable Documentation

const char* const IDENT_WWRAPPER_H = "$Date: 2005/08/09 08:14:56 $" [static]

Definition at line 11 of file pa_wwrapper.h.


pa_wwrapper.h Source File

pa_wwrapper.h

Go to the documentation of this file.
00001
00008 #ifndef PA_WWRAPPER_H
00009 #define PA_WWRAPPER_H
00010
00011 static const char * const IDENT_WWRAPPER_H="$Date: 2005/08/09 08:14:56 $";
00012
00013 #include "pa_wcontext.h"
00014 #include "pa_exception.h"
00015
00017 class WWrapper: public WContext {
00018 public: // Value
00019
00020     override const char* type() const { return "wwrapper"; }
00022     override Value* get_element(const String& aname, Value& aself, bool looking_up) {
00023         return as_value().get_element(aname, aself, looking_up);
00024     }
00026     override const VJunction* put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
00027         if(!fvalue) {
00028             fvalue=new VHash;
00029             // not constructing anymore [if were constructing]
00030             // so to allow method calls after real constructor-method call
00031             // sample:
00032             //  $hash[
00033             //      $.key1[$i]
00034             //      ^i.inc[]  ^rem{allow such calls}
00035             //      $.key2[$1]
00036             set_constructing(false);
00037         }
00038
00039         return fvalue->put_element(aself, aname, avalue, areplace);
00040     }
00041
00042 public: // usage
00043
00044     WWrapper(Value* avalue, WContext *aparent) :
00045         WContext(avalue, aparent) {
00046     }
00047
00048 private:
00049     // raises an exception on 0 value
00050     Value& as_value() const {
00051         if(!fvalue)
00052             throw Exception(0,
00053                 0,
00054                 "accessing wrapper without value");
00055
00056         return *fvalue;
00057     }
00058 };
00059
00060 #endif


pa_xml_exception.C File Reference

Parser: exception class. More...

Include dependency graph for pa_xml_exception.C:

Include dependency graph

Go to the source code of this file.

Detailed Description

Parser: exception class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_xml_exception.C.


pa_xml_exception.C Source File

pa_xml_exception.C

Go to the documentation of this file.
00001
00008 #include "pa_config_includes.h"
00009
00010 #ifdef XML
00011
00012 static const char * const IDENT="$Date: 2005/12/16 10:15:12 $";
00013
00014 #include "pa_xml_exception.h"
00015 #include "pa_globals.h"
00016 #include "pa_common.h"
00017
00018 // methods
00019
00020 XmlException::XmlException(const String* aproblem_source) {
00021     ftype="xml";
00022     fproblem_source=aproblem_source;
00023
00024     if(const char* xml_generic_errors=xmlGenericErrors()) {
00025         fcomment=pa_strdup(xml_generic_errors);
00026     } else
00027         fcomment="-UNKNOWN ERROR-";
00028 }
00029 #endif


pa_xml_exception.h File Reference

Parser: xml exception decls. More...

Include dependency graph for pa_xml_exception.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Detailed Description

Parser: xml exception decls.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_xml_exception.h.


pa_xml_exception.h Source File

pa_xml_exception.h

Go to the documentation of this file.
00001
00008 #ifndef PA_XML_EXCEPTION_H
00009 #define PA_XML_EXCEPTION_H
00010
00011 #ifdef XML
00012
00013 static const char * const IDENT_XML_EXCEPTION_H="$Date: 2005/12/16 10:15:12 $";
00014
00015 // includes
00016
00017 #include "pa_exception.h"
00018
00019 // defines
00020
00021 class XmlException: public Exception {
00022 public:
00023
00024     XmlException(
00025         const String* aproblem_source);
00026
00027 };
00028
00029 #endif
00030
00031 #endif


pa_xml_io.C File Reference

Parser: plugins to xml library, controlling i/o; implementation. More...

Include dependency graph for pa_xml_io.C:

Include dependency graph

Go to the source code of this file.

Detailed Description

Parser: plugins to xml library, controlling i/o; implementation.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_xml_io.C.


pa_xml_io.C Source File

pa_xml_io.C

Go to the documentation of this file.
00001
00008 #include "pa_xml_io.h"
00009
00010 #ifdef XML
00011
00012 static const char * const IDENT="$Date: 2005/08/09 08:14:53 $";
00013
00014 #include "libxslt/extensions.h"
00015
00016 #include "pa_threads.h"
00017 #include "pa_globals.h"
00018 #include "pa_request.h"
00019
00020 static Hash<pa_thread_t, HashStringBool*> xml_dependencies;
00021
00022 static void add_dependency(const String::Body url) {
00023     pa_thread_t thread_id=pa_get_thread_id();
00024     HashStringBool* urls;
00025     {
00026         SYNCHRONIZED;
00027
00028         // try to get existing for this thread_id
00029         urls=xml_dependencies.get(thread_id);
00030     }
00031
00032     if(urls) // do we need to monitor now?
00033         urls->put(url, true);
00034 }
00035
00036 void pa_xmlStartMonitoringDependencies() {
00037     pa_thread_t thread_id=pa_get_thread_id();
00038     HashStringBool* urls=new HashStringBool;
00039     {
00040         SYNCHRONIZED;  // find+fill blocked
00041
00042         xml_dependencies.put(thread_id, urls);
00043     }
00044 }
00045
00046 void pa_xmlStopMonitoringDependencies() {
00047     pa_thread_t thread_id=pa_get_thread_id();
00048     {
00049         SYNCHRONIZED;  // find+fill blocked
00050
00051         xml_dependencies.put(thread_id, 0);
00052     }
00053 }
00054
00055 HashStringBool* pa_xmlGetDependencies() {
00056     pa_thread_t thread_id=pa_get_thread_id();
00057     {
00058         SYNCHRONIZED;  // find+remove blocked
00059
00060         HashStringBool* result=xml_dependencies.get(thread_id);
00061         xml_dependencies.remove(thread_id);
00062         return result;
00063     }
00064 }
00065
00066 #ifndef DOXYGEN
00067 struct MemoryStream {
00068     const char* m_buf;
00069     size_t m_size;
00070     size_t m_position;
00071
00072     int read(char* a_buffer, size_t a_size) {
00073         size_t left=m_size-m_position;
00074         if(!left)
00075             return 0;
00076
00077         size_t to_read=min(a_size, left);
00078         memcpy(a_buffer, m_buf+m_position, to_read);
00079         m_position+=to_read;
00080         return to_read;
00081     }
00082
00083 };
00084 #endif
00085
00086 static void *
00087 xmlFileOpen_ReadIntoStream (const char* do_not_store_filename, bool adjust_path_to_root_from_document_root=false) {
00088 #ifdef PA_SAFE_MODE
00089 //copied from libxml/catalog.c
00090 #   define XML_XML_DEFAULT_CATALOG "file:
00091     // disable attempts to consult default catalog [usually, that file belongs to other user/group]
00092     if(strcmp(do_not_store_filename, XML_XML_DEFAULT_CATALOG)==0)
00093         return 0;
00094 #endif
00095
00096     Request& r=pa_thread_request();
00097     char adjust_buf[MAX_STRING];
00098     if(adjust_path_to_root_from_document_root) {
00099         const char* document_root=r.request_info.document_root;
00100         if(!document_root)
00101             document_root=".";
00102
00103         adjust_buf[0]=0;
00104         strcat(adjust_buf, document_root);
00105         strcat(adjust_buf, &do_not_store_filename[16]);
00106         do_not_store_filename=adjust_buf;
00107     } else
00108         if(strstr(do_not_store_filename, "file://"))
00109             do_not_store_filename+=7/*strlen("file://")*/;
00110         else if(*do_not_store_filename && do_not_store_filename[1]!=':' && strstr(do_not_store_filename, "://"))  {
00111             pa_xmlStopMonitoringDependencies();
00112             return 0; // plug out [do not handle other prefixes]
00113         }
00114
00115     const char* can_store_filename=pa_strdup(do_not_store_filename);
00116     add_dependency(can_store_filename);
00117
00118     const char *buf;
00119     try {
00120         buf=file_read_text(r.charsets, *new String(can_store_filename));
00121     } catch(const Exception& e) {
00122         if(strcmp(e.type(), "file.missing")==0)
00123             return 0; // let the library try that and report an error properly
00124
00125         buf=e.comment();
00126     } catch(...) {
00127         buf="xmlFileOpen_ReadIntoStream: unknown error";
00128     }
00129     MemoryStream* stream=new(UseGC) MemoryStream;
00130     stream->m_buf=buf;
00131     stream->m_size=strlen(buf);
00132     return (void *)stream;
00133 }
00134
00135 static int
00136 xmlFileMatchMonitor(const char* /*file_spec_cstr*/) {
00137     return 1; // always intercept, causing xmlFileOpenMonitor to be called
00138 }
00139 static void *
00140 xmlFileOpenMonitor(const char* filename) {
00141     return xmlFileOpen_ReadIntoStream(filename); // handles localfile case, else returns 0
00142 }
00143
00144
00153 static int
00154 xmlFileMatchLocalhost(const char* filename) {
00155     if (!strncmp(filename, "http://localhost", 16))
00156         return(1);
00157     return(0);
00158 }
00159
00168 static void *
00169 xmlFileOpenLocalhost (const char* filename) {
00170     return xmlFileOpen_ReadIntoStream(filename, true/*adjust path to root from document_root*/);
00171 }
00172
00173 static int
00174 xmlFileMatchMethod(const char* filename) {
00175     if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
00176         return(1);
00177     return(0);
00178 }
00179
00181 static void *
00182 xmlFileOpenMethod (const char* afilename) {
00183     const char* buf;
00184     try {
00185         Request& r=pa_thread_request();
00186
00187         char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
00188         const char* method_cstr=lsplit(&s, '/');
00189         const String* method=new String(method_cstr);
00190         String::Body param_body("/");
00191         if(s)
00192             param_body.append_know_length(s, strlen(s));
00193
00194         VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
00195         {
00196             Temp_lang temp_lang(r, String::L_XML); // default language: XML
00197             Request::Execute_nonvirtual_method_result body=
00198                 r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
00199             if(body.string) {
00200                 buf=body.string->cstr(String::L_UNSPECIFIED);
00201             } else
00202                 throw Exception(0,
00203                     new String(afilename),
00204                     "'%s' method not found in %s class",
00205                             method_cstr, MAIN_CLASS_NAME);
00206         }
00207     } catch(const Exception& e) {
00208         buf=e.comment();
00209     } catch(...) {
00210         buf="xmlFileOpenLocalhost: unknown error";
00211     }
00212     MemoryStream* stream=new(UseGC) MemoryStream;
00213     stream->m_buf=buf;
00214     stream->m_size=strlen(buf);
00215     return (void *)stream;
00216 }
00217
00228 static int
00229 pa_xmlFileReadMethod (void * context, //< MemoryStream actually
00230                       char * buffer, int len)
00231 {
00232     MemoryStream& stream=*static_cast<MemoryStream*>(context);
00233
00234     return stream.read(buffer, len);
00235 }
00236
00237 static int
00238 pa_xmlFileCloseMethod (void * /*context*/) {
00239     return 0;
00240 }
00241
00242
00243
00244 void pa_xml_io_init() {
00245     // file open monitorer [for xslt cacher]
00246     // safe mode checker, always fail match, but checks non-"://" there
00247     xmlRegisterInputCallbacks(
00248         xmlFileMatchMonitor, xmlFileOpenMonitor,
00249         pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
00250
00251     // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
00252     xmlRegisterInputCallbacks(
00253         xmlFileMatchLocalhost, xmlFileOpenLocalhost,
00254         pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
00255
00256     // parser://method/param/here -> ^MAIN:method[/params/here]
00257     xmlRegisterInputCallbacks(
00258         xmlFileMatchMethod, xmlFileOpenMethod,
00259         pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
00260 }
00261
00262 #endif


pa_xml_io.h File Reference

Parser: plugins to xml library, controlling i/o. More...

Include dependency graph for pa_xml_io.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Typedefs

typedef Hash< const String::Body,
bool > 		HashStringBool

Functions

void | pa_xml_io_init ()
void | pa_xmlStartMonitoringDependencies ()
HashStringBool * pa_xmlGetDependencies ()

Variables

const char *const | IDENT_XML_IO_H = "$Date: 2005/08/09 08:14:50 $"

Detailed Description

Parser: plugins to xml library, controlling i/o.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file pa_xml_io.h.

Typedef Documentation

typedef Hash<const String::Body, bool> HashStringBool

Definition at line 21 of file pa_xml_io.h.

Referenced by _open().

Function Documentation

void pa_xml_io_init ( )

void pa_xmlStartMonitoringDependencies ( )

HashStringBool* pa_xmlGetDependencies ( )

Variable Documentation

const char* const IDENT_XML_IO_H = "$Date: 2005/08/09 08:14:50 $" [static]

Definition at line 14 of file pa_xml_io.h.


pa_xml_io.h Source File

pa_xml_io.h

Go to the documentation of this file.
00001
00008 #include "pa_config_includes.h"
00009
00010 #ifdef XML
00011 #ifndef PA_XML_IO_H
00012 #define PA_XML_IO_H
00013
00014 static const char * const IDENT_XML_IO_H="$Date: 2005/08/09 08:14:50 $";
00015
00016 #include "pa_string.h"
00017 #include "pa_hash.h"
00018
00019 void pa_xml_io_init();
00020
00021 typedef Hash<const String::Body, bool> HashStringBool;
00022
00023 void pa_xmlStartMonitoringDependencies();
00024 HashStringBool* pa_xmlGetDependencies();
00025
00026 #endif
00027 #endif


parser3.C File Reference

Parser: scripting and CGI main. More...

Include dependency graph for parser3.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | SAPI_Info
SAPI func decl. More...

Defines

#define | REDIRECT_PREFIX "REDIRECT_"
#define | PARSER_CONFIG_ENV_NAME "CGI_PARSER_CONFIG"
#define | PARSER_LOG_ENV_NAME "CGI_PARSER_LOG"

Functions

void | log (const char *fmt, va_list args)
void | die_or_abort (const char *fmt, va_list args, bool write_core)
void | full_file_spec (const char *file_name, char *buf, size_t buf_size)
void | log_signal (const char *signal_name)
const char * | maybe_reconstruct_IIS_status_in_qs (const char *original)
void | real_parser_handler (const char *filespec_to_process, const char *request_method, bool header_only)
main workhorse. More...

void | usage (const char *program)
int | main (int argc, char *argv[])

Variables

const char *const | IDENT_PARSER3_C = "$Date: 2005/12/19 11:56:38 $"
const size_t | READ_POST_CHUNK_SIZE = 0x400*0x400
IIS refuses to read bigger chunks. More...

const char * | argv0
const char * | config_filespec_cstr = 0
bool | fail_on_config_read_problem = true
bool | cgi
we were started as CGI? More...

bool | mail_received = false
we were started with -m option? [asked to parse incoming message to $mail:received]. More...

Request * | request = 0
Request_info * | request_info = 0
bool | execution_canceled = false
SAPI_Info SAPI_info

Detailed Description

Parser: scripting and CGI main.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file parser3.C.

Define Documentation

#define REDIRECT_PREFIX "REDIRECT_"

Definition at line 43 of file parser3.C.

Referenced by log(), and real_parser_handler().

#define PARSER_CONFIG_ENV_NAME "CGI_PARSER_CONFIG"

Definition at line 44 of file parser3.C.

Referenced by real_parser_handler().

#define PARSER_LOG_ENV_NAME "CGI_PARSER_LOG"

Definition at line 45 of file parser3.C.

Referenced by log().

Function Documentation

void log | ( | const char * | fmt,
 |  | va_list | args
 | ) | [static]

Definition at line 66 of file parser3.C.

References config_filespec_cstr, MAX_STRING, PARSER_LOG_ENV_NAME, REDIRECT_PREFIX, remove_crlf(), rsplit(), size, snprintf, and vsnprintf.

Referenced by main(), and real_parser_handler().

void die_or_abort | ( | const char * | fmt,
 |  | va_list | args,
 |  | bool | write_core
 | ) | [static]

Definition at line 145 of file parser3.C.

References abort(), SAPI::add_header_attribute(), MAX_NUMBER, MAX_STRING, SAPI_info, SAPI::send_body(), SAPI::send_header(), snprintf, and vsnprintf.

Referenced by SAPI::abort(), and SAPI::die().

void full_file_spec | ( | const char * | file_name,
 |  | char * | buf,
 |  | size_t | buf_size
 | ) | [static]

Definition at line 253 of file parser3.C.

References back_slashes_to_slashes(), MAX_STRING, and snprintf.

Referenced by main(), and real_parser_handler().

void log_signal ( const char * signal_name ) [static]

Definition at line 272 of file parser3.C.

References Request_info::content_length, SAPI::log(), Request_info::method, SAPI_info, and Request_info::uri.

const char* maybe_reconstruct_IIS_status_in_qs ( const char * original )

Definition at line 301 of file parser3.C.

Referenced by real_parser_handler().

void real_parser_handler | ( | const char * | filespec_to_process,
 |  | const char * | request_method,
 |  | bool | header_only
 | ) | [static]

main workhorse.

Todo:
IIS: remove trailing default-document[index.html] from $request.uri. to do that we need to consult metabase, wich is tested but seems slow.

Definition at line 351 of file parser3.C.

References argv0, atoi(), AUTO_FILE_NAME, cgi, config_filespec_cstr, Request_info::content_length, Request_info::content_type, Request_info::cookie, Request::core(), SAPI::die(), Request_info::document_root, entry_exists(), fail_on_config_read_problem, full_file_spec(), String::L_AS_IS, String::L_HTML, String::L_OPTIMIZE_BIT, String::Language, log(), mail_received, Request_info::mail_received, MAX_STRING, maybe_reconstruct_IIS_status_in_qs(), Request_info::method, pa_globals_done(), pa_globals_init(), pa_socks_done(), pa_socks_init(), PARSER_CONFIG_ENV_NAME, PARSER_VERSION, Request_info::path_translated, Request_info::query_string, REDIRECT_PREFIX, request, rsplit(), SAPI_info, snprintf, and Request_info::uri.

void usage ( const char * program ) [static]

Definition at line 580 of file parser3.C.

References PARSER_VERSION.

Referenced by main().

int main | ( | int | argc,
 |  | char * | argv[]
 | ) |

Definition at line 598 of file parser3.C.

References _O_BINARY, SAPI::add_header_attribute(), argv0, cgi, config_filespec_cstr, SAPI::die(), full_file_spec(), GC_dont_gc, GC_java_finalization, getopt(), SAPI::log(), log(), mail_received, MAX_NUMBER, MAX_STRING, real_parser_handler(), SAPI_info, SAPI::send_body(), SAPI::send_header(), snprintf, and usage().

Variable Documentation

const char* const IDENT_PARSER3_C = "$Date: 2005/12/19 11:56:38 $" [static]

Definition at line 8 of file parser3.C.

const size_t READ_POST_CHUNK_SIZE = 0x400*0x400

IIS refuses to read bigger chunks.

Definition at line 48 of file parser3.C.

const char* argv0 [static]

Definition at line 50 of file parser3.C.

Referenced by main(), and real_parser_handler().

const char* config_filespec_cstr = 0 [static]

Definition at line 51 of file parser3.C.

Referenced by log(), main(), and real_parser_handler().

bool fail_on_config_read_problem = true [static]

Definition at line 52 of file parser3.C.

Referenced by real_parser_handler().

bool cgi [static]

we were started as CGI?

Definition at line 54 of file parser3.C.

Referenced by main(), and real_parser_handler().

bool mail_received = false [static]

we were started with -m option? [asked to parse incoming message to $mail:received].

Definition at line 55 of file parser3.C.

Referenced by main(), and real_parser_handler().

Request* request = 0

Definition at line 58 of file parser3.C.

Referenced by http_request(), real_parser_handler(), and VForm::refill_fields_and_tables().

Request_info* request_info = 0

Definition at line 59 of file parser3.C.

Referenced by VCookie::fill_fields(), real_parser_handler(), and Request::Request().

bool execution_canceled = false

Definition at line 60 of file parser3.C.

class SAPI_Info SAPI_info

Referenced by SAPI::add_header_attribute(), die_or_abort(), SAPI::environment(), SAPI::get_env(), SAPI::log(), log_signal(), main(), SAPI::read_post(), real_parser_handler(), SAPI::send_body(), and SAPI::send_header().


parser3.C Source File

parser3.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_PARSER3_C="$Date: 2005/12/19 11:56:38 $";
00009
00010 #include "pa_config_includes.h"
00011
00012 #if _MSC_VER
00013 #   include <crtdbg.h>
00014 #endif
00015
00016 #include "pa_sapi.h"
00017 #include "classes.h"
00018 #include "pa_common.h"
00019 #include "pa_request.h"
00020 #include "pa_socks.h"
00021 #include "pa_version.h"
00022
00023 #ifdef WIN32
00024 #   include <windows.h>
00025 #   include "getopt.h"
00026 #else
00027 #   include <getopt.h>
00028 #endif
00029
00030 // defines
00031
00032 // comment remove me after debugging
00033 //#define PA_DEBUG_CGI_ENTRY_EXIT   "c:\\parser\\debug-parser3.log"
00034
00035 #if _MSC_VER && !defined(_DEBUG)
00036 #   define PA_SUPPRESS_SYSTEM_EXCEPTION
00037 #endif
00038
00039 //#define DEBUG_MAILRECEIVE "mailreceive.eml"
00040
00041 // consts
00042
00043 #define REDIRECT_PREFIX "REDIRECT_"
00044 #define PARSER_CONFIG_ENV_NAME "CGI_PARSER_CONFIG"
00045 #define PARSER_LOG_ENV_NAME "CGI_PARSER_LOG"
00046
00048 const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M
00049
00050 static const char* argv0;
00051 static const char* config_filespec_cstr=0;
00052 static bool fail_on_config_read_problem=true;
00053
00054 static bool cgi;
00055 static bool mail_received=false;
00056
00057 // for signal handlers
00058 Request *request=0;
00059 Request_info *request_info=0;
00060 bool execution_canceled=false;
00061
00062 // SAPI
00063
00064 class SAPI_Info{} SAPI_info;
00065
00066 static void log(const char* fmt, va_list args) {
00067     bool opened=false;
00068     FILE *f=0;
00069
00070     const char* log_by_env=getenv(PARSER_LOG_ENV_NAME);
00071     if(!log_by_env)
00072         log_by_env=getenv(REDIRECT_PREFIX PARSER_LOG_ENV_NAME);
00073     if(log_by_env) {
00074         f=fopen(log_by_env, "at");
00075         opened=f!=0;
00076     }
00077 #ifdef PA_DEBUG_CGI_ENTRY_EXIT
00078     f=fopen(PA_DEBUG_CGI_ENTRY_EXIT, "at");
00079     opened=f!=0;
00080 #endif
00081
00082     if(!opened && config_filespec_cstr) {
00083         char beside_config_path[MAX_STRING];
00084         strncpy(beside_config_path, config_filespec_cstr, MAX_STRING-1);  beside_config_path[MAX_STRING-1]=0;
00085         if(!(
00086             rsplit(beside_config_path, '/') ||
00087             rsplit(beside_config_path, '\\'))) { // strip filename
00088             // no path, just filename
00089             beside_config_path[0]='.'; beside_config_path[1]=0;
00090         }
00091
00092         char file_spec[MAX_STRING];
00093         snprintf(file_spec, MAX_STRING,
00094             "%s/parser3.log", beside_config_path);
00095         f=fopen(file_spec, "at");
00096         opened=f!=0;
00097     }
00098     // fallback to stderr
00099     if(!opened)
00100         f=stderr;
00101
00102     // use no memory [so that we could log out-of-memory error]
00103     setbuf(f, 0); // stderr stream is unbuffered by default, but still...
00104
00105     // prefix
00106     time_t t=time(0);
00107     if(const char* stamp=ctime(&t)) { // never saw that
00108         if(size_t len=strlen(stamp)) // saw once stamp being =""
00109             fprintf(f, "[%.*s] [%u] ", len-1, stamp,
00110             (unsigned int)getpid()
00111             );
00112     }
00113     // message
00114
00115     char buf[MAX_STRING];
00116     size_t size=vsnprintf(buf, MAX_STRING, fmt, args);
00117     remove_crlf(buf, buf+size);
00118
00119     fwrite(buf, size, 1, f);
00120     // newline
00121     fprintf(f, "\n");
00122
00123     if(opened)
00124         fclose(f);
00125     else
00126         fflush(f);
00127 }
00128 #ifdef PA_DEBUG_CGI_ENTRY_EXIT
00129 static void log(const char* fmt, ...) {
00130     va_list args;
00131     va_start(args,fmt);
00132     log(fmt, args);
00133     va_end(args);
00134 }
00135 #endif
00136
00137 // appends to parser3.log located beside my binary if openable, to stderr otherwize
00138 void SAPI::log(SAPI_Info&, const char* fmt, ...) {
00139     va_list args;
00140     va_start(args,fmt);
00141     ::log(fmt, args);
00142     va_end(args);
00143 }
00144
00145 static void die_or_abort(const char* fmt, va_list args, bool write_core) {
00146     // log
00147
00148     // logging is more important than user
00149     // she can cancel download, we'd get SIGPIPE,
00150     // nothing would be logged then
00151     ::log(fmt, args);
00152
00153     // inform user
00154
00155     char body[MAX_STRING];
00156     int content_length=vsnprintf(body, MAX_STRING, fmt, args);
00157
00158     // prepare header
00159     // let's be honest, that's bad we couldn't produce valid output
00160     SAPI::add_header_attribute(SAPI_info, "status", "500");
00161     SAPI::add_header_attribute(SAPI_info, "content-type", "text/plain");
00162     char content_length_cstr[MAX_NUMBER];
00163     snprintf(content_length_cstr, sizeof(content_length_cstr), "%u", content_length);
00164     SAPI::add_header_attribute(SAPI_info, "content-length", content_length_cstr);
00165
00166     // send header
00167     SAPI::send_header(SAPI_info);
00168
00169     // body
00170     SAPI::send_body(SAPI_info, body, content_length);
00171
00172     // exit & try to produce core dump[unix] or invoke debugger[Win32 Debug version]
00173     if(write_core) {
00174 #if defined(WIN32) && !defined(_DEBUG)
00175         // IIS with abort failes to show STDOUT, it just barks "abnormal program termination"
00176         exit(1);
00177 #else
00178 #if _MSC_VER
00179         _asm int 3;
00180 #endif
00181         abort();
00182 #endif
00183     }
00184     else
00185         exit(1);
00186 }
00187
00188 void SAPI::die(const char* fmt, ...) {
00189     va_list args;
00190     va_start(args, fmt);
00191     die_or_abort(fmt, args, false/*write core?*/);
00192 //unreachable anyway    va_end(args);
00193 }
00194
00195 void SAPI::abort(const char* fmt, ...) {
00196     va_list args;
00197     va_start(args, fmt);
00198     die_or_abort(fmt, args, true/*write core?*/);
00199 //unreachable anyway    va_end(args);
00200 }
00201
00202 char* SAPI::get_env(SAPI_Info& , const char* name) {
00203     if(char *local=getenv(name))
00204         return pa_strdup(local);
00205     else
00206         return 0;
00207 }
00208
00209 const char* const *SAPI::environment(SAPI_Info&) {
00210 #ifdef _MSC_VER
00211     extern char **_environ;
00212     return _environ;
00213 #else
00214     extern char **environ;
00215     return environ;
00216 #endif
00217 }
00218
00219 size_t SAPI::read_post(SAPI_Info& , char *buf, size_t max_bytes) {
00220     size_t read_size=0;
00221     do {
00222         ssize_t chunk_size=read(fileno(stdin),
00223             buf+read_size, min(READ_POST_CHUNK_SIZE, max_bytes-read_size));
00224         if(chunk_size<=0)
00225             break;
00226         read_size+=chunk_size;
00227     } while(read_size<max_bytes);
00228
00229     return read_size;
00230 }
00231
00232 void SAPI::add_header_attribute(SAPI_Info& , const char* dont_store_key, const char* dont_store_value) {
00233     if(cgi)
00234         printf("%s: %s\n", dont_store_key, dont_store_value);
00235 }
00236
00238 void SAPI::send_header(SAPI_Info& ) {
00239     if(cgi) {
00240 //      puts("expires: Fri, 23 Mar 2001 09:32:23 GMT");
00241
00242         // header | body  delimiter
00243         puts("");
00244     }
00245 }
00246
00247 size_t SAPI::send_body(SAPI_Info& , const void *buf, size_t size) {
00248     return stdout_write(buf, size);
00249 }
00250
00251 //
00252
00253 static void full_file_spec(const char* file_name, char *buf, size_t buf_size) {
00254     if(file_name)
00255         if(file_name[0]=='/'
00256 #ifdef WIN32
00257             || file_name[0] && file_name[1]==':'
00258 #endif
00259             )
00260                 strncpy(buf, file_name, buf_size);
00261         else {
00262             char cwd[MAX_STRING];  getcwd(cwd, MAX_STRING);
00263             snprintf(buf, buf_size, "%s/%s", cwd, file_name);
00264         }
00265     else
00266         buf[0]=0;
00267 #ifdef WIN32
00268     back_slashes_to_slashes(buf);
00269 #endif
00270 }
00271
00272 static void log_signal(const char* signal_name) {
00273     if(request_info)
00274         SAPI::log(SAPI_info, "%s received while %s. uri=%s, method=%s, cl=%u",
00275             signal_name,
00276             request?"executing code":"reading data",
00277             request_info->uri,
00278             request_info->method,
00279             request_info->content_length);
00280     else
00281         SAPI::log(SAPI_info, "%s received before or after processing request",
00282             signal_name);
00283 }
00284
00285 #ifdef SIGUSR1
00286 static void SIGUSR1_handler(int /*sig*/){
00287     log_signal("SIGUSR1");
00288 }
00289 #endif
00290
00291 #ifdef SIGPIPE
00292 static void SIGPIPE_handler(int /*sig*/){
00293     log_signal("SIGPIPE");
00294     execution_canceled=true;
00295     if(request)
00296         request->set_interrupted(true);
00297 }
00298 #endif
00299
00300 #ifdef WIN32
00301 const char* maybe_reconstruct_IIS_status_in_qs(const char* original)
00302 {
00303     // 404;http://servername/page[?param=value...]
00304     // ';' should be urlencoded by HTTP standard, so we shouldn't get it from browser
00305     // and can consider that as an indication that this is IIS way to report errors
00306
00307     if(original
00308         && isdigit((unsigned char)original[0])
00309         && isdigit((unsigned char)original[1])
00310         && isdigit((unsigned char)original[2])
00311         && original[3]==';')
00312     {
00313         size_t original_len=strlen(original);
00314         char* reconstructed=new(PointerFreeGC) char[original_len
00315             +12/*IIS-STATUS=&*/
00316             +14/*IIS-DOCUMENT=&*/
00317             +1];
00318         char* cur=reconstructed;
00319         memcpy(cur, "IIS-STATUS=", 11);  cur+=11;
00320         memcpy(cur, original, 3); cur+=3;
00321         *cur++='&';
00322
00323         const char* qmark_at=strchr(original, '?');
00324         memcpy(cur, "IIS-DOCUMENT=", 13);  cur+=13;
00325         {
00326             size_t value_len=(qmark_at? qmark_at-original: original_len)-4;
00327             memcpy(cur, original+4, value_len);  cur+=value_len;
00328         }
00329
00330         if(qmark_at) {
00331             *cur++='&';
00332             strcpy(cur, qmark_at+1/*skip ? itself*/);
00333         } else
00334             *cur=0;
00335
00336         return reconstructed;
00337     }
00338
00339     return original;
00340 }
00341 #endif
00342
00351 static void real_parser_handler(const char* filespec_to_process,
00352                 const char* request_method, bool header_only)
00353 {
00354     // init socks
00355     pa_socks_init();
00356
00357     // init global variables
00358     pa_globals_init();
00359
00360     if(!filespec_to_process || !*filespec_to_process)
00361         SAPI::die("Parser/%s"
00362 #ifdef PA_DEBUG_CGI_ENTRY_EXIT
00363         " with entry/exit tracing"
00364 #endif
00365         , PARSER_VERSION);
00366
00367     // Request info
00368     Request_info request_info;  memset(&request_info, 0, sizeof(request_info));
00369     char document_root_buf[MAX_STRING];
00370     if(cgi) {
00371         if(const char* env_document_root=getenv("DOCUMENT_ROOT"))
00372             request_info.document_root=env_document_root;
00373         else if(const char* path_info=getenv("PATH_INFO")) {
00374             // IIS
00375             size_t len=min(sizeof(document_root_buf)-1, strlen(filespec_to_process)-strlen(path_info));
00376             memcpy(document_root_buf, filespec_to_process, len); document_root_buf[len]=0;
00377             request_info.document_root=document_root_buf;
00378         } else
00379             throw Exception("parser.runtime",
00380                 0,
00381                 "CGI: no PATH_INFO defined(in reinventing DOCUMENT_ROOT)");
00382     } else {
00383         full_file_spec("", document_root_buf, sizeof(document_root_buf));
00384         request_info.document_root=document_root_buf;
00385     }
00386     request_info.path_translated=filespec_to_process;
00387     request_info.method=request_method ? request_method : "GET";
00388     const char* query_string=
00389 #ifdef WIN32
00390         maybe_reconstruct_IIS_status_in_qs
00391 #endif
00392         (getenv("QUERY_STRING"));
00393     request_info.query_string=query_string;
00394     if(cgi) {
00395         // few absolute obligatory
00396         const char* path_info=getenv("PATH_INFO");
00397         if(!path_info)
00398             SAPI::die("CGI: illegal call (missing PATH_INFO)");
00399         const char* script_name=getenv("SCRIPT_NAME");
00400         if(!script_name)
00401                 SAPI::die("CGI: illegal call (missing SCRIPT_NAME)");
00402
00403         const char* env_request_uri=getenv("REQUEST_URI");
00404         if(env_request_uri)
00405             request_info.uri=env_request_uri;
00406         else
00407             if(query_string) {
00408                 char* reconstructed_uri=new(PointerFreeGC) char[
00409                     strlen(path_info)+1/*'?'*/+
00410                     strlen(query_string)+1/*0*/];
00411                 strcpy(reconstructed_uri, path_info);
00412                 strcat(reconstructed_uri, "?");
00413                 strcat(reconstructed_uri, query_string);
00414                 request_info.uri=reconstructed_uri;
00415             } else
00416                 request_info.uri=path_info;
00417
00418         if(env_request_uri) { // apache & others stuck to standards
00419             /*
00420                 http://parser3/env.html?123  =OK
00421                 $request:uri=/env.html?123
00422                 REQUEST_URI='/env.html?123'
00423                 SCRIPT_NAME='/cgi-bin/parser3'
00424                 PATH_INFO='/env.html'
00425
00426                 http://parser3/cgi-bin/parser3/env.html?123 =ERROR
00427                 $request:uri=/cgi-bin/parser3/env.html?123
00428                 REQUEST_URI='/cgi-bin/parser3/env.html?123'
00429                 SCRIPT_NAME='/cgi-bin/parser3'
00430                 PATH_INFO='/env.html'
00431             */
00432             size_t script_name_len=strlen(script_name);
00433             size_t uri_len=strlen(env_request_uri);
00434             if(strncmp(env_request_uri, script_name, script_name_len)==0 &&
00435                 script_name_len != uri_len) // under IIS they are the same
00436                 SAPI::die("CGI: illegal call (1)");
00437         } else { // seen on IIS5
00438             /*
00439                 http://nestle/env.html?123 =OK
00440                 $request:uri=/env.html?123
00441                 REQUEST_URI=''
00442                 SCRIPT_NAME='/env.html'
00443                 PATH_INFO='/env.html'
00444
00445                 http://nestle/cgi-bin/parser3.exe/env.html =ERROR
00446                 $request:uri=/env.html
00447                 REQUEST_URI=''
00448                 SCRIPT_NAME='/cgi-bin/parser3.exe'
00449                 PATH_INFO='/env.html'
00450             */
00451             if(strcmp(script_name, path_info)!=0)
00452                 SAPI::die("CGI: illegal call (2)");
00453         }
00454     } else
00455         request_info.uri="";
00456
00457     request_info.content_type=getenv("CONTENT_TYPE");
00458     const char* content_length=getenv("CONTENT_LENGTH");
00459     request_info.content_length=(content_length?atoi(content_length):0);
00460     request_info.cookie=getenv("HTTP_COOKIE");
00461     request_info.mail_received=mail_received;
00462
00463     // get request_info ptr for signal handlers
00464     ::request_info=&request_info;
00465     if(execution_canceled)
00466         SAPI::die("Execution canceled");
00467
00468 #ifdef PA_DEBUG_CGI_ENTRY_EXIT
00469     log("request_info: method=%s, uri=%s, q=%s, dr=%s, pt=%s, cookies=%s, cl=%u",
00470         request_info.method,
00471         request_info.uri,
00472         request_info.query_string,
00473         request_info.document_root,
00474         request_info.path_translated,
00475         request_info.cookie,
00476         request_info.content_length);
00477 #endif
00478
00479     // prepare to process request
00480     Request request(SAPI_info, request_info,
00481         cgi ? String::Language(String::L_HTML|String::L_OPTIMIZE_BIT) : String::L_AS_IS,
00482         true /* status_allowed */);
00483
00484     // get request ptr for signal handlers
00485     ::request=&request;
00486
00487     char config_filespec_buf[MAX_STRING];
00488     if(!config_filespec_cstr) {
00489         const char* config_by_env=getenv(PARSER_CONFIG_ENV_NAME);
00490         if(!config_by_env)
00491             config_by_env=getenv(REDIRECT_PREFIX PARSER_CONFIG_ENV_NAME);
00492         if(config_by_env)
00493             config_filespec_cstr=config_by_env;
00494         else {
00495             // beside by binary
00496             char beside_binary_path[MAX_STRING];
00497             strncpy(beside_binary_path, argv0, MAX_STRING-1);  beside_binary_path[MAX_STRING-1]=0; // filespec of my binary
00498             if(!(
00499                 rsplit(beside_binary_path, '/') ||
00500                 rsplit(beside_binary_path, '\\'))) { // strip filename
00501                 // no path, just filename
00502                 // @todo full path, not ./!
00503                 beside_binary_path[0]='.'; beside_binary_path[1]=0;
00504             }
00505             snprintf(config_filespec_buf, MAX_STRING,
00506                 "%s/%s",
00507                 beside_binary_path, AUTO_FILE_NAME);
00508             config_filespec_cstr=config_filespec_buf;
00509             fail_on_config_read_problem=entry_exists(config_filespec_cstr);
00510         }
00511     }
00512
00513     // process the request
00514     request.core(
00515         config_filespec_cstr, fail_on_config_read_problem,
00516         header_only);
00517
00518     // no request [prevent signal handlers from accessing invalid memory]
00519     ::request=0;
00520
00521     // finalize global variables
00522     pa_globals_done();
00523
00524     //
00525     pa_socks_done();
00526 }
00527
00528 #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION
00529 static const Exception
00530 call_real_parser_handler__do_PEH_return_it(
00531     const char* filespec_to_process,
00532     const char* request_method, bool header_only)
00533 {
00534     try {
00535         real_parser_handler(
00536             filespec_to_process,
00537             request_method, header_only);
00538     } catch(const Exception& e) {
00539         return e;
00540     }
00541
00542     return Exception();
00543 }
00544 static void call_real_parser_handler__supress_system_exception(
00545     const char* filespec_to_process,
00546     const char* request_method, bool header_only)
00547 {
00548     Exception parser_exception;
00549     LPEXCEPTION_POINTERS system_exception=0;
00550
00551     __try {
00552         parser_exception=call_real_parser_handler__do_PEH_return_it(
00553             filespec_to_process,
00554             request_method, header_only);
00555     } __except (
00556         (system_exception=GetExceptionInformation()),
00557         EXCEPTION_EXECUTE_HANDLER)
00558     {
00559
00560         if(system_exception)
00561             if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord)
00562                 throw Exception("system",
00563                     0,
00564                     "0x%08X at 0x%08X", er->ExceptionCode,  er->ExceptionAddress);
00565             else
00566                 throw Exception("system",
00567                     0,
00568                     "<no exception record>");
00569         else
00570             throw Exception("system",
00571                 0,
00572                 "<no exception information>");
00573     }
00574
00575     if(parser_exception)
00576         throw Exception(parser_exception);
00577 }
00578 #endif
00579
00580 static void usage(const char* program) {
00581     printf(
00582         "Parser/%s\n"
00583         "Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)\n"
00584         "Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)\n"
00585         "\n"
00586         "Usage: %s [options] file\n"
00587         "Options are:\n"
00588 #ifdef WITH_MAILRECEIVE
00589         "    -m              Parse mail, put received letter to $mail:received\n"
00590 #endif
00591         "    -f config_file  Use this config file (/path/to/auto.p)\n"
00592         "    -h              Display usage information (this message)\n"
00593         , PARSER_VERSION,
00594         program);
00595     exit(EINVAL);
00596 }
00597
00598 int main(int argc, char *argv[]) {
00599 #ifdef PA_DEBUG_CGI_ENTRY_EXIT
00600     log("main: entry");
00601 #endif
00602     //_asm int 3;
00603     GC_java_finalization=0;
00604
00605 #ifndef PA_DEBUG_DISABLE_GC
00606     // Dont collect unless explicitly requested
00607     // this is quicker (~30% ), but less memory-efficient(~8%)
00608     // so deciding for speed
00609     GC_dont_gc=1;
00610 #endif
00611 /*
00612
00613     Array<int> test;
00614     test+=3;
00615     test+=4;
00616 //  int a=test.count();
00617     int i=0;
00618     scanf("%d", &i);
00619     int b=test.get(i);
00620 //  int b=test.get(10);
00621     printf("%d", b);//test.count());*/
00622
00623 #ifdef SIGUSR1
00624     if(signal(SIGUSR1, SIGUSR1_handler)==SIG_ERR)
00625         SAPI::die("Can not set handler for SIGUSR1");
00626 #endif
00627 #ifdef SIGPIPE
00628     if(signal(SIGPIPE, SIGPIPE_handler)==SIG_ERR)
00629         SAPI::die("Can not set handler for SIGPIPE");
00630 #endif
00631
00632
00633 #ifdef DEBUG_MAILRECEIVE
00634     if(FILE *fake_in=fopen(DEBUG_MAILRECEIVE, "rt")) {
00635         dup2(fake_in->_file, 0/*STDIN_FILENO*/);
00636     }
00637 #endif
00638
00639 #ifdef _DEBUG
00640     //_crtBreakAlloc=46;
00641 #endif
00642     argv0=argv[0];
00643
00644     umask(2);
00645
00646     // were we started as CGI?
00647     cgi=
00648         getenv("SERVER_SOFTWARE") ||
00649         getenv("SERVER_NAME") ||
00650         getenv("GATEWAY_INTERFACE") ||
00651         getenv("REQUEST_METHOD");
00652
00653     char *raw_filespec_to_process;
00654     if(cgi) {
00655         raw_filespec_to_process=getenv("PATH_TRANSLATED");
00656         if(raw_filespec_to_process && !*raw_filespec_to_process)
00657             raw_filespec_to_process=0;
00658     } else {
00659         optind = 1;
00660         opterr = 0;
00661         int c;
00662         while((c = getopt(argc, argv, "hf:"
00663 #ifdef WITH_MAILRECEIVE
00664             "m"
00665 #endif
00666             )) > 0) {
00667             switch (c) {
00668             case 'h':
00669                 usage(argv[0]);
00670                 break;
00671             case 'f':
00672                 config_filespec_cstr=optarg;
00673                 break;
00674 #ifdef WITH_MAILRECEIVE
00675             case 'm':
00676                 mail_received=true;
00677                 break;
00678 #endif
00679             default:
00680                 fprintf(stderr, "%s: invalid option '%c'\n", argv[0], optopt);
00681                 usage(argv[0]);
00682                 break;
00683             }
00684         }
00685         if (optind != argc - 1) {
00686             fprintf(stderr, "%s: file not specified\n", argv[0]);
00687             usage(argv[0]);
00688         }
00689
00690         raw_filespec_to_process=argv[optind++];
00691     }
00692
00693 #ifdef WIN32
00694     setmode(fileno(stdin), _O_BINARY);
00695     setmode(fileno(stdout), _O_BINARY);
00696     setmode(fileno(stderr), _O_BINARY);
00697 #endif
00698
00699 #if defined(_MSC_VER) && defined(_DEBUG)
00700     // Get current flag
00701     int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
00702
00703     // Turn on leak-checking bit
00704     tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
00705
00706     // Set flag to the new value
00707     _CrtSetDbgFlag( tmpFlag );
00708 //  _CrtSetBreakAlloc(61);
00709
00710     _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
00711     _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
00712 #endif
00713
00714     char filespec_to_process[MAX_STRING];
00715     full_file_spec(raw_filespec_to_process, filespec_to_process, sizeof(filespec_to_process));
00716
00717     const char* request_method=getenv("REQUEST_METHOD");
00718     bool header_only=request_method && strcasecmp(request_method, "HEAD")==0;
00719
00720     try { // global try
00721 #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION
00722         call_real_parser_handler__supress_system_exception(
00723 #else
00724         real_parser_handler(
00725 #endif
00726             filespec_to_process,
00727             request_method, header_only);
00728     } catch(const Exception& e) { // global problem
00729         // don't allocate anything on pool here:
00730         //   possible pool' exception not catch-ed now
00731         //   and there could be out-of-memory exception
00732         char buf[MAX_STRING];
00733         snprintf(buf, MAX_STRING, "Unhandled exception %s",
00734             e.comment());
00735         // log it
00736         SAPI::log(SAPI_info, "%s", buf);
00737
00738         //
00739         int content_length=strlen(buf);
00740
00741         // prepare header
00742         SAPI::add_header_attribute(SAPI_info, "content-type", "text/plain");
00743         char content_length_cstr[MAX_NUMBER];
00744         snprintf(content_length_cstr, MAX_NUMBER, "%u", content_length);
00745         SAPI::add_header_attribute(SAPI_info, "content-length", content_length_cstr);
00746
00747         // send header
00748         SAPI::send_header(SAPI_info);
00749
00750         // send body
00751         if(!header_only)
00752             SAPI::send_body(SAPI_info, buf, content_length);
00753
00754         // unsuccessful finish
00755     }
00756
00757 #ifdef PA_DEBUG_CGI_ENTRY_EXIT
00758     log("main: successful return");
00759 #endif
00760     return 0;
00761 }


parser3isapi.C File Reference

Parser: IIS extension. More...

Include dependency graph for parser3isapi.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | MAX_STATUS_LENGTH sizeof("xxxx LONGEST STATUS DESCRIPTION")

Functions

void | abort (const char *fmt, va_list args)
int | grep_char (const char *s, char c)
const char * | mk_env_pair (const char *key, const char *value)
bool | parser_init ()
void | parser_done ()
BOOL WINAPI | GetExtensionVersion (HSE_VERSION_INFO *pVer)
ISAPI //. More...

BOOL WINAPI | TerminateExtension (DWORD)
void | real_parser_handler (SAPI_Info &SAPI_info, bool header_only)
ISAPI // main workhorse. More...

DWORD WINAPI | HttpExtensionProc (LPEXTENSION_CONTROL_BLOCK lpECB)
BOOL WINAPI | DllMain (HINSTANCE hinstDLL, DWORD, LPVOID)

Variables

const char *const | IDENT_PARSER3ISAPI_C = "$Date: 2005/12/09 07:18:08 $"
const char * | IIS51vars []
const int | IIS51var_count = sizeof(IIS51vars)/sizeof(*IIS51vars)
char | argv0 [MAX_STRING] = ""

Detailed Description

Parser: IIS extension.

Copyright (c) 2000,2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file parser3isapi.C.

Define Documentation

#define MAX_STATUS_LENGTH sizeof("xxxx LONGEST STATUS DESCRIPTION")

Definition at line 34 of file parser3isapi.C.

Function Documentation

void abort | ( | const char * | fmt,
 |  | va_list | args
 | ) | [static]

Todo:
event log

Definition at line 91 of file parser3isapi.C.

Referenced by die_or_abort(), SQL_Driver::operator new(), operator new(), and operator new[]().

int grep_char | ( | const char * | s,
 |  | char | c
 | ) | [static]

Definition at line 138 of file parser3isapi.C.

References result.

const char* mk_env_pair | ( | const char * | key,
 |  | const char * | value
 | ) | [static]

Definition at line 148 of file parser3isapi.C.

References result, and value.

Referenced by SAPI_environment_append().

bool parser_init ( ) [static]

Definition at line 262 of file parser3isapi.C.

References pa_globals_init(), and pa_socks_init().

Referenced by GetExtensionVersion().

void parser_done ( ) [static]

Definition at line 284 of file parser3isapi.C.

References pa_globals_done(), and pa_socks_done().

Referenced by TerminateExtension().

BOOL WINAPI GetExtensionVersion ( HSE_VERSION_INFO * pVer )

ISAPI //.

Definition at line 293 of file parser3isapi.C.

References BOOL, parser_init(), and PARSER_VERSION.

BOOL WINAPI TerminateExtension ( DWORD )

Definition at line 300 of file parser3isapi.C.

References BOOL, and parser_done().

void real_parser_handler | ( | SAPI_Info & | SAPI_info,
 |  | bool | header_only
 | ) |

ISAPI // main workhorse.

Todo:
IIS: remove trailing default-document[index.html] from $request.uri. to do that we need to consult metabase, wich is tested&works but seems slow runtime and not could-be-quickly-implemented if prepared.
Test:
PARSER_VERSION from outside

Definition at line 320 of file parser3isapi.C.

References argv0, AUTO_FILE_NAME, back_slashes_to_slashes(), Request_info::content_length, Request_info::content_type, Request_info::cookie, Request::core(), Request_info::document_root, entry_exists(), GC_dont_gc, SAPI::get_env(), String::L_HTML, String::L_OPTIMIZE_BIT, String::Language, Request_info::mail_received, MAX_STRING, Request_info::method, pa_strdup(), Request_info::path_translated, Request_info::query_string, request, request_info, rsplit(), snprintf, and Request_info::uri.

Referenced by HttpExtensionProc(), main(), and pa_parser_handler().

DWORD WINAPI HttpExtensionProc ( LPEXTENSION_CONTROL_BLOCK lpECB )

Definition at line 447 of file parser3isapi.C.

References SAPI::log(), MAX_STRING, real_parser_handler(), SAPI::send_body(), and snprintf.

BOOL WINAPI DllMain | ( | HINSTANCE | hinstDLL,
 |  | DWORD | ,
 |  | LPVOID |
 | ) |

Definition at line 536 of file parser3isapi.C.

References argv0, and BOOL.

Variable Documentation

const char* const IDENT_PARSER3ISAPI_C = "$Date: 2005/12/09 07:18:08 $" [static]

Definition at line 8 of file parser3isapi.C.

const char* IIS51vars[]

Initial value:

{
    "APPL_MD_PATH", "APPL_PHYSICAL_PATH",
    "AUTH_PASSWORD", "AUTH_TYPE", "AUTH_USER",
    "CERT_COOKIE", "CERT_FLAGS", "CERT_ISSUER", "CERT_KEYSIZE", "CERT_SECRETKEYSIZE",
    "CERT_SERIALNUMBER", "CERT_SERVER_ISSUER", "CERT_SERVER_SUBJECT", "CERT_SUBJECT",
    "CONTENT_LENGTH", "CONTENT_TYPE",
    "LOGON_USER",
    "HTTPS", "HTTPS_KEYSIZE", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_SERVER_SUBJECT",
    "INSTANCE_ID",  "INSTANCE_META_PATH",
    "PATH_INFO",    "PATH_TRANSLATED",
    "QUERY_STRING",
    "REMOTE_ADDR", "REMOTE_HOST", "REMOTE_USER", "REQUEST_METHOD",
    "SCRIPT_NAME",
    "SERVER_NAME", "SERVER_PORT", "SERVER_PORT_SECURE", "SERVER_PROTOCOL", "SERVER_SOFTWARE",
    "URL",
}

Definition at line 38 of file parser3isapi.C.

const int IIS51var_count = sizeof(IIS51vars)/sizeof(*IIS51vars)

Definition at line 54 of file parser3isapi.C.

char argv0[MAX_STRING] = ""

Definition at line 58 of file parser3isapi.C.

Referenced by DllMain(), and real_parser_handler().


parser3isapi.C Source File

parser3isapi.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_PARSER3ISAPI_C="$Date: 2005/12/09 07:18:08 $";
00009
00010 #ifndef _MSC_VER
00011 #   error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)]
00012 #endif
00013
00014 #include "pa_config_includes.h"
00015
00016 #include "pa_sapi.h"
00017 #include "pa_globals.h"
00018 #include "pa_request.h"
00019 #include "pa_version.h"
00020 #include "pa_socks.h"
00021
00022 #include <windows.h>
00023 #include <process.h>
00024
00025 #include <httpext.h>
00026
00027 // defines
00028
00029 #if _MSC_VER && !defined(_DEBUG)
00030 #   define PA_SUPPRESS_SYSTEM_EXCEPTION
00031 #endif
00032
00033
00034 #define MAX_STATUS_LENGTH sizeof("xxxx LONGEST STATUS DESCRIPTION")
00035
00036 // consts
00037
00038 const char* IIS51vars[]={
00039     "APPL_MD_PATH", "APPL_PHYSICAL_PATH",
00040     "AUTH_PASSWORD", "AUTH_TYPE", "AUTH_USER",
00041     "CERT_COOKIE", "CERT_FLAGS", "CERT_ISSUER", "CERT_KEYSIZE", "CERT_SECRETKEYSIZE",
00042     "CERT_SERIALNUMBER", "CERT_SERVER_ISSUER", "CERT_SERVER_SUBJECT", "CERT_SUBJECT",
00043     "CONTENT_LENGTH", "CONTENT_TYPE",
00044     "LOGON_USER",
00045     "HTTPS", "HTTPS_KEYSIZE", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_SERVER_SUBJECT",
00046     "INSTANCE_ID",  "INSTANCE_META_PATH",
00047     "PATH_INFO",    "PATH_TRANSLATED",
00048     "QUERY_STRING",
00049     "REMOTE_ADDR", "REMOTE_HOST", "REMOTE_USER", "REQUEST_METHOD",
00050     "SCRIPT_NAME",
00051     "SERVER_NAME", "SERVER_PORT", "SERVER_PORT_SECURE", "SERVER_PROTOCOL", "SERVER_SOFTWARE",
00052     "URL",
00053 };
00054 const int IIS51var_count=sizeof(IIS51vars)/sizeof(*IIS51vars);
00055
00056 // globals
00057
00058 char argv0[MAX_STRING]="";
00059
00060 // SAPI
00061
00062 #ifndef DOXYGEN
00063 /*
00064     ISAPI SAPI functions receive this context information.
00065     see Pool::set_context
00066 */
00067 class SAPI_Info {
00068 public:
00069     LPEXTENSION_CONTROL_BLOCK lpECB;
00070     String *header;
00071     DWORD http_response_code;
00072 };
00073 #endif
00074
00075 // goes to 'cs-uri-query' log file field. webmaster: switch it ON[default OFF].
00076 void SAPI::log(SAPI_Info& SAPI_info, const char* fmt, ...) {
00077     va_list args;
00078     va_start(args,fmt);
00079     char buf[MAX_STRING];
00080     const char* prefix="PARSER_ERROR:";
00081     strcpy(buf, prefix);
00082     char *start=buf+strlen(prefix);
00083     DWORD size=vsnprintf(start, MAX_STRING-strlen(prefix), fmt, args);
00084     remove_crlf(start, start+size);
00085
00086     SAPI_info.lpECB->ServerSupportFunction(SAPI_info.lpECB->ConnID,
00087         HSE_APPEND_LOG_PARAMETER, buf, &size, 0);
00088 }
00089
00091 static void abort(const char* fmt, va_list args) {
00092     if(FILE *log=fopen("c:\\parser3die.log", "at")) {
00093         vfprintf(log, fmt, args);
00094         fclose(log);
00095     }
00096     // exit & try to produce core dump
00097     abort();
00098 }
00099 void SAPI::die(const char* fmt, ...) {
00100     va_list args;
00101     va_start(args, fmt);
00102     ::abort(fmt, args);
00103 //  va_end(args);
00104 }
00105
00106 void SAPI::abort(const char* fmt, ...) {
00107     va_list args;
00108     va_start(args, fmt);
00109     ::abort(fmt, args);
00110 //  va_end(args);
00111 }
00112
00113 char* SAPI::get_env(SAPI_Info& SAPI_info, const char* name) {
00114     char *variable_buf=new(PointerFreeGC) char[MAX_STRING];
00115     DWORD variable_len = MAX_STRING-1;
00116
00117     if(SAPI_info.lpECB->GetServerVariable(SAPI_info.lpECB->ConnID, const_cast<char *>(name),
00118         variable_buf, &variable_len)) {
00119         if(*variable_buf) { // saw returning len=1 && *buf=0 :(
00120             variable_buf[variable_len]=0;
00121             return variable_buf;
00122         }
00123     } else if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) {
00124         variable_buf=new(PointerFreeGC) char[variable_len+1];
00125
00126         if(SAPI_info.lpECB->GetServerVariable(SAPI_info.lpECB->ConnID, const_cast<char *>(name),
00127             variable_buf, &variable_len)) {
00128             if(*variable_buf) {
00129                 variable_buf[variable_len]=0;
00130                 return variable_buf;
00131             }
00132         }
00133     }
00134
00135     return 0;
00136 }
00137
00138 static int grep_char(const char* s, char c) {
00139     int result=0;
00140     if(s) {
00141         while(s=strchr(s, c)) {
00142             s++; // skip found c
00143             result++;
00144         }
00145     }
00146     return result;
00147 }
00148 static const char* mk_env_pair(const char* key, const char* value) {
00149     char *result=new(PointerFreeGC) char[strlen(key)+1/*=*/+strlen(value)+1/*0*/];
00150     strcpy(result, key); strcat(result, "="); strcat(result, value);
00151     return result;
00152 }
00153 const char* const *SAPI::environment(SAPI_Info& info) {
00154     // we know this buf is writable
00155     char* all_http_vars=SAPI::get_env(info, "ALL_HTTP");
00156     const int http_var_count=grep_char(all_http_vars, '\n')+1/*\n for theoretical(never saw) this \0*/;
00157
00158     const char* *result=new(PointerFreeGC) const char*[IIS51var_count+http_var_count+1/*0*/];
00159     const char* *cur=result;
00160
00161     // IIS5.1 vars
00162     for(int i=0; i<IIS51var_count; i++) {
00163         const char* key=IIS51vars[i];
00164         if(const char* value=SAPI::get_env(info, key))
00165             *cur++=mk_env_pair(key, value);
00166     }
00167
00168     // HTTP_* vars
00169     if(char *s=all_http_vars) {
00170         while(char *key=lsplit(&s, '\n'))
00171             if(char *value=lsplit(key, ':'))
00172                 *cur++=mk_env_pair(key, value);
00173     }
00174
00175     // mark EOE
00176     *cur=0;
00177
00178     return result;
00179 }
00180
00181 size_t SAPI::read_post(SAPI_Info& SAPI_info, char *buf, size_t max_bytes) {
00182     DWORD read_from_buf=0;
00183     DWORD read_from_input=0;
00184     DWORD total_read=0;
00185
00186     read_from_buf=min(SAPI_info.lpECB->cbAvailable, max_bytes);
00187     memcpy(buf, SAPI_info.lpECB->lpbData, read_from_buf);
00188     total_read+=read_from_buf;
00189
00190     if(read_from_buf<max_bytes &&
00191         read_from_buf<SAPI_info.lpECB->cbTotalBytes) {
00192         DWORD cbRead=0, cbSize;
00193
00194         read_from_input=min(max_bytes-read_from_buf,
00195             SAPI_info.lpECB->cbTotalBytes-read_from_buf);
00196         while(cbRead < read_from_input) {
00197             cbSize=read_from_input - cbRead;
00198             if(!SAPI_info.lpECB->ReadClient(SAPI_info.lpECB->ConnID,
00199                 buf+read_from_buf+cbRead, &cbSize) ||
00200                 cbSize==0)
00201                 break;
00202             cbRead+=cbSize;
00203         }
00204         total_read+=cbRead;
00205     }
00206     return total_read;
00207 }
00208
00209 void SAPI::add_header_attribute(SAPI_Info& SAPI_info,
00210                 const char* dont_store_key, const char* dont_store_value) {
00211     if(strcasecmp(dont_store_key, "location")==0)
00212         SAPI_info.http_response_code=302;
00213
00214     if(strcasecmp(dont_store_key, "status")==0)
00215         SAPI_info.http_response_code=atoi(dont_store_value);
00216     else
00217         (*SAPI_info.header) << pa_strdup(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n";
00218 }
00219
00221 void SAPI::send_header(SAPI_Info& SAPI_info) {
00222     HSE_SEND_HEADER_EX_INFO header_info;
00223
00224     char status_buf[MAX_STATUS_LENGTH];
00225     switch(SAPI_info.http_response_code) {
00226         case 200:
00227             header_info.pszStatus="200 OK";
00228             break;
00229         case 302:
00230             header_info.pszStatus="302 Moved Temporarily";
00231             break;
00232         case 401:// useless untill parser auth mech
00233             header_info.pszStatus="401 Authorization Required";
00234             break;
00235         default:
00236             snprintf(status_buf, MAX_STATUS_LENGTH,
00237                 "%d Undescribed", SAPI_info.http_response_code);
00238             header_info.pszStatus=status_buf;
00239             break;
00240     }
00241     header_info.cchStatus=strlen(header_info.pszStatus);
00242     *SAPI_info.header << "\r\n"; // ISAPI v<5 did quite well without it
00243     header_info.pszHeader=SAPI_info.header->cstr();
00244     header_info.cchHeader=SAPI_info.header->length();
00245     header_info.fKeepConn=true;
00246
00247     SAPI_info.lpECB->dwHttpStatusCode=SAPI_info.http_response_code;
00248
00249     SAPI_info.lpECB->ServerSupportFunction(SAPI_info.lpECB->ConnID,
00250         HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
00251 }
00252
00253 size_t SAPI::send_body(SAPI_Info& SAPI_info, const void *buf, size_t size) {
00254     DWORD num_bytes=size;
00255     if(!SAPI_info.lpECB->WriteClient(SAPI_info.lpECB->ConnID,
00256         const_cast<void *>(buf), &num_bytes, HSE_IO_SYNC))
00257         return 0;
00258     return (size_t)num_bytes;
00259 }
00260
00261
00262 static bool parser_init() {
00263     static bool globals_inited=false;
00264     if(globals_inited)
00265         return true;
00266     globals_inited=true;
00267
00268     try {
00269         // init socks
00270         pa_socks_init();
00271         // init global variables
00272         pa_globals_init();
00273
00274         // successful finish
00275         return true;
00276     } catch(.../*const Exception& e*/) { // global problem
00277         //const char* body=e.comment();
00278
00279         // unsuccessful finish
00280         return false;
00281     }
00282 }
00283
00284 static void parser_done() {
00285     // finalize global variables
00286     pa_globals_done();
00287
00288     //
00289     pa_socks_done();
00290 }
00291
00293 BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer) {
00294     pVer->dwExtensionVersion = HSE_VERSION;
00295     strncpy(pVer->lpszExtensionDesc, "Parser "PARSER_VERSION, HSE_MAX_EXT_DLL_NAME_LEN-1);
00296     pVer->lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN-1]=0;
00297     return parser_init();
00298 }
00299 // dwFlags & HSE_TERM_MUST_UNLOAD means we can't return false
00300 BOOL WINAPI TerminateExtension(
00301   DWORD /*dwFlags*/
00302 )
00303 {
00304     parser_done();
00305
00306     return TRUE;
00307 }
00308
00320 void real_parser_handler(SAPI_Info& SAPI_info, bool header_only) {
00321     // collect garbage from prev request
00322 #ifndef PA_DEBUG_DISABLE_GC
00323     {
00324         int saved=GC_dont_gc;
00325         GC_dont_gc=0;
00326         GC_gcollect();
00327         GC_dont_gc=saved;
00328     }
00329 #endif
00330
00331     SAPI_info.header=new String;
00332     LPEXTENSION_CONTROL_BLOCK lpECB=SAPI_info.lpECB;
00333
00334     // Request info
00335     Request_info request_info;  memset(&request_info, 0, sizeof(request_info));
00336
00337     size_t path_translated_buf_size=strlen(lpECB->lpszPathTranslated)+1;
00338     char *filespec_to_process=pa_strdup(lpECB->lpszPathTranslated, path_translated_buf_size);
00339 #ifdef WIN32
00340     back_slashes_to_slashes(filespec_to_process);
00341 #endif
00342
00343     if(const char* path_info=SAPI::get_env(SAPI_info, "PATH_INFO")) {
00344         // IIS
00345         size_t len=strlen(filespec_to_process)-strlen(path_info);
00346         char *buf=new(PointerFreeGC) char[len+1];
00347         strncpy(buf, filespec_to_process, len); buf[len]=0;
00348         request_info.document_root=buf;
00349     } else
00350         throw Exception("parser.runtime",
00351             0,
00352             "ISAPI: no PATH_INFO defined (in reinventing DOCUMENT_ROOT)");
00353
00354     request_info.path_translated=filespec_to_process;
00355     request_info.method=lpECB->lpszMethod;
00356     request_info.query_string=lpECB->lpszQueryString;
00357     if(lpECB->lpszQueryString && *lpECB->lpszQueryString) {
00358         char *reconstructed_uri=new(PointerFreeGC) char[
00359             strlen(lpECB->lpszPathInfo)+1/*'?'*/+
00360             strlen(lpECB->lpszQueryString)+1/*0*/];
00361         strcpy(reconstructed_uri, lpECB->lpszPathInfo);
00362         strcat(reconstructed_uri, "?");
00363         strcat(reconstructed_uri, lpECB->lpszQueryString);
00364         request_info.uri=reconstructed_uri;
00365     } else
00366         request_info.uri=lpECB->lpszPathInfo;
00367
00368     request_info.content_type=lpECB->lpszContentType;
00369     request_info.content_length=lpECB->cbTotalBytes;
00370     request_info.cookie=SAPI::get_env(SAPI_info, "HTTP_COOKIE");
00371     request_info.mail_received=false;
00372
00373     // prepare to process request
00374     Request request(SAPI_info,
00375         request_info,
00376         String::Language(String::L_HTML|String::L_OPTIMIZE_BIT),
00377         true /* status_allowed */);
00378
00379     // beside by binary
00380     static char beside_binary_path[MAX_STRING];
00381     strncpy(beside_binary_path, argv0, MAX_STRING-1);  beside_binary_path[MAX_STRING-1]=0; // filespec of my binary
00382     if(!(
00383         rsplit(beside_binary_path, '/') ||
00384         rsplit(beside_binary_path, '\\'))) { // strip filename
00385         // no path, just filename
00386         beside_binary_path[0]='.'; beside_binary_path[1]=0;
00387     }
00388     char config_filespec[MAX_STRING];
00389     snprintf(config_filespec, MAX_STRING,
00390         "%s/%s",
00391         beside_binary_path, AUTO_FILE_NAME);
00392     bool fail_on_config_read_problem=entry_exists(config_filespec);
00393
00394     // process the request
00395     request.core(
00396         config_filespec, fail_on_config_read_problem, // /path/to/first/auto.p
00397         header_only);
00398 }
00399
00400 #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION
00401 static const Exception
00402 call_real_parser_handler__do_PEH_return_it(
00403     SAPI_Info& SAPI_info, bool header_only)
00404 {
00405     try {
00406         real_parser_handler(SAPI_info, header_only);
00407     } catch(const Exception& e) {
00408         return e;
00409     }
00410
00411     return Exception();
00412 }
00413 static void call_real_parser_handler__supress_system_exception(
00414     SAPI_Info& SAPI_info, bool header_only)
00415 {
00416     Exception parser_exception;
00417     LPEXCEPTION_POINTERS system_exception=0;
00418
00419     __try {
00420         parser_exception=call_real_parser_handler__do_PEH_return_it(
00421             SAPI_info, header_only);
00422     } __except (
00423         (system_exception=GetExceptionInformation()),
00424         EXCEPTION_EXECUTE_HANDLER)
00425     {
00426
00427         if(system_exception)
00428             if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord)
00429                 throw Exception("system",
00430                     0,
00431                     "0x%08X at 0x%08X", er->ExceptionCode,  er->ExceptionAddress);
00432             else
00433                 throw Exception("system",
00434                     0,
00435                     "<no exception record>");
00436         else
00437             throw Exception("system",
00438                 0,
00439                 "<no exception information>");
00440     }
00441
00442     if(parser_exception)
00443         throw Exception(parser_exception);
00444 }
00445 #endif
00446
00447 DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB) {
00448     //_asm int 3;
00449     SAPI_Info SAPI_info={
00450         lpECB,
00451         0, // filling later: so that if there would be error pool would have SAPI_info
00452         200 // default http_response_code [lpECB->dwHttpStatusCode seems to be always 0, even on 404 redirect to /404.html]
00453     };
00454
00455     bool header_only=strcasecmp(lpECB->lpszMethod, "HEAD")==0;
00456     try { // global try
00457 #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION
00458         call_real_parser_handler__supress_system_exception(
00459 #else
00460         real_parser_handler(
00461 #endif
00462             SAPI_info, header_only);
00463         // successful finish
00464     } catch(const Exception& e) { // global problem
00465         // don't allocate anything on pool here:
00466         //   possible pool' exception not catch-ed now
00467             //   and there could be out-of-memory exception
00468         const char* body=e.comment();
00469         // log it
00470         SAPI::log(SAPI_info, "exception in request exception handler: %s", body);
00471
00472         //
00473         int content_length=strlen(body);
00474
00475         // prepare header // not using SAPI func wich allocates on pool
00476         char header_buf[MAX_STRING];
00477         int header_len=snprintf(header_buf, MAX_STRING,
00478             "content-type: text/plain\r\n"
00479             "content-length: %u\r\n"
00480 //          "expires: Fri, 23 Mar 2001 09:32:23 GMT\r\n"
00481             "\r\n",
00482             content_length);
00483
00484         HSE_SEND_HEADER_EX_INFO header_info;
00485         header_info.pszStatus="200 OK";
00486         header_info.cchStatus=strlen(header_info.pszStatus);
00487         header_info.pszHeader=header_buf;
00488         header_info.cchHeader=header_len;
00489         header_info.fKeepConn=true;
00490
00491         // send header
00492         lpECB->dwHttpStatusCode=200;
00493         lpECB->ServerSupportFunction(lpECB->ConnID,
00494             HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
00495
00496         // send body
00497         if(!header_only)
00498             SAPI::send_body(SAPI_info, body, content_length);
00499
00500         // unsuccessful finish
00501     }
00502 /*
00503         const char* body="test";
00504
00505         //
00506         int content_length=strlen(body);
00507
00508         // prepare header // not using SAPI func wich allocates on pool
00509         char header_buf[MAX_STRING];
00510         int header_len=snprintf(header_buf, MAX_STRING,
00511             "content-type: text/plain\r\n"
00512             "content-length: %u\r\n"
00513             "expires: Fri, 23 Mar 2001 09:32:23 GMT\r\n"
00514             "\r\n",
00515             content_length);
00516         HSE_SEND_HEADER_EX_INFO header_info;
00517         header_info.pszStatus="200 OK";
00518         header_info.cchStatus=strlen(header_info.pszStatus);
00519         header_info.pszHeader=header_buf;
00520         header_info.cchHeader=header_len;
00521         header_info.fKeepConn=true;
00522
00523     // send header
00524         lpECB->dwHttpStatusCode=200;
00525         lpECB->ServerSupportFunction(lpECB->ConnID,
00526             HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
00527
00528         // send body
00529     DWORD num_bytes=content_length;
00530     lpECB->WriteClient(lpECB->ConnID,
00531         (void *)body, &num_bytes, HSE_IO_SYNC);
00532 */
00533     return HSE_STATUS_SUCCESS_AND_KEEP_CONN;
00534 }
00535
00536 BOOL WINAPI DllMain(
00537   HINSTANCE hinstDLL,  // handle to the DLL module
00538   DWORD /*fdwReason*/,     // reason for calling function
00539   LPVOID /*lpvReserved*/   // reserved
00540   ) {
00541
00542     GetModuleFileName(
00543       hinstDLL,    // handle to module
00544       argv0,  // file name of module
00545       sizeof(argv0)         // size of buffer
00546     );
00547
00548     return TRUE;
00549 }


pcre.c File Reference

Include dependency graph for pcre.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | DPRINTF(p)
#define | BRASTACK_SIZE 200
#define | STRING(a) # a
#define | XSTRING(s) STRING(s)

Functions

BOOL | compile_regex (int, int, int *, uschar **, const uschar **, const char **, BOOL, int, int *, int *, compile_data *)
const char * | pcre_version (void)
int | pcre_info (const pcre *external_re, int *optptr, int *first_char)
int | check_escape (const uschar **ptrptr, const char **errorptr, int bracount, int options, BOOL isclass, compile_data *cd)
BOOL | is_counted_repeat (const uschar *p, compile_data *cd)
const uschar * | read_repeat_counts (const uschar *p, int *minp, int *maxp, const char **errorptr, compile_data *cd)
int | find_fixedlength (uschar *code)
BOOL | compile_branch (int options, int *brackets, uschar **codeptr, const uschar **ptrptr, const char **errorptr, int *optchanged, int *reqchar, int *countlits, compile_data *cd)
const uschar * | first_significant_code (const uschar *code, int *options, int optbit, BOOL optstop)
BOOL | is_anchored (register const uschar *code, int *options)
BOOL | is_startline (const uschar *code)
int | find_firstchar (const uschar *code, int *options)
pcre * | pcre_compile (const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables)
BOOL | match_ref (int offset, register const uschar *eptr, int length, match_data *md, unsigned long int ims)
BOOL | match (register const uschar *eptr, register const uschar *ecode, int offset_top, match_data *md, unsigned long int ims, BOOL condassert, const uschar *eptrb)
int | pcre_exec (const pcre *external_re, const pcre_extra *external_extra, const char *subject, int length, int start_offset, int options, int *offsets, int offsetcount)

Variables

const char | rep_min [] = { 0, 0, 1, 1, 0, 0 }
const char | rep_max [] = { 0, 0, 0, 0, 1, 1 }
const short int | escapes []
void *(* | pcre_malloc )(size_t)=malloc
void(* | pcre_free )(void *)=free

Define Documentation

#define DPRINTF ( p )

Definition at line 47 of file pcre.c.

Referenced by compile_regex(), match(), pcre_compile(), and pcre_exec().

#define BRASTACK_SIZE 200

Definition at line 66 of file pcre.c.

Referenced by pcre_compile().

#define STRING ( a ) # a

Definition at line 151 of file pcre.c.

#define XSTRING ( s ) STRING(s)

Definition at line 152 of file pcre.c.

Referenced by pcre_version().

Function Documentation

BOOL compile_regex | ( | int | ,
 |  | int | ,
 |  | int * | ,
 |  | uschar ** | ,
 |  | const uschar ** | ,
 |  | const char ** | ,
 |  | BOOL | ,
 |  | int | ,
 |  | int * | ,
 |  | int * | ,
 |  | compile_data * |
 | ) | [static]

Definition at line 1653 of file pcre.c.

References BOOL, compile_branch(), DPRINTF, ERR25, find_fixedlength(), OP_ALT, OP_CREF, OP_END, OP_KET, OP_OPT, OP_REVERSE, PCRE_IMS, PCRE_MAX_POS, and uschar.

Referenced by compile_branch(), and pcre_compile().

const char* pcre_version ( void )

Definition at line 155 of file pcre.c.

References PCRE_DATE, PCRE_MAJOR, PCRE_MINOR, and XSTRING.

int pcre_info | ( | const pcre * | external_re,
 |  | int * | optptr,
 |  | int * | first_char
 | ) |

Definition at line 185 of file pcre.c.

References real_pcre::first_char, real_pcre::magic_number, MAGIC_NUMBER, real_pcre::options, pcre, PCRE_ERROR_BADMAGIC, PCRE_ERROR_NULL, PCRE_FIRSTSET, PCRE_STARTLINE, PUBLIC_OPTIONS, and real_pcre::top_bracket.

Referenced by String::match().

int check_escape | ( | const uschar ** | ptrptr,
 |  | const char ** | errorptr,
 |  | int | bracount,
 |  | int | options,
 |  | BOOL | isclass,
 |  | compile_data * | cd
 | ) | [static]

Definition at line 254 of file pcre.c.

References BOOL, ctype_digit, ctype_xdigit, compile_data::ctypes, ERR1, ERR2, ERR3, ESC_REF, escapes, compile_data::fcc, compile_data::lcc, PCRE_EXTRA, and uschar.

Referenced by compile_branch(), and pcre_compile().

BOOL is_counted_repeat | ( | const uschar * | p,
 |  | compile_data * | cd
 | ) | [static]

Definition at line 395 of file pcre.c.

References ctype_digit, compile_data::ctypes, p, and uschar.

Referenced by compile_branch(), and pcre_compile().

const uschar* read_repeat_counts | ( | const uschar * | p,
 |  | int * | minp,
 |  | int * | maxp,
 |  | const char ** | errorptr,
 |  | compile_data * | cd
 | ) | [static]

Definition at line 432 of file pcre.c.

References ctype_digit, compile_data::ctypes, ERR4, ERR5, p, and uschar.

Referenced by compile_branch(), and pcre_compile().

int find_fixedlength ( uschar * code ) [static]

Definition at line 483 of file pcre.c.

References OP_ALT, OP_ANY, OP_ASSERT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_BRA, OP_CHARS, OP_CIRC, OP_CLASS, OP_COND, OP_CREF, OP_CRMINQUERY, OP_CRMINRANGE, OP_CRMINSTAR, OP_CRQUERY, OP_CRRANGE, OP_CRSTAR, OP_DIGIT, OP_DOLL, OP_END, OP_EOD, OP_EODN, OP_EXACT, OP_KET, OP_KETRMAX, OP_KETRMIN, OP_NOT_DIGIT, OP_NOT_WHITESPACE, OP_NOT_WORD_BOUNDARY, OP_NOT_WORDCHAR, OP_ONCE, OP_OPT, OP_REF, OP_REVERSE, OP_SOD, OP_TYPEEXACT, OP_WHITESPACE, OP_WORD_BOUNDARY, OP_WORDCHAR, and uschar.

Referenced by compile_regex().

BOOL compile_branch | ( | int | options,
 |  | int * | brackets,
 |  | uschar ** | codeptr,
 |  | const uschar ** | ptrptr,
 |  | const char ** | errorptr,
 |  | int * | optchanged,
 |  | int * | reqchar,
 |  | int * | countlits,
 |  | compile_data * | cd
 | ) | [static]

Definition at line 646 of file pcre.c.

References BOOL, cbit_digit, cbit_space, cbit_word, compile_data::cbits, check_escape(), compile_regex(), ctype_digit, ctype_meta, ctype_space, compile_data::ctypes, ERR11, ERR12, ERR13, ERR14, ERR24, ERR27, ERR6, ERR7, ERR8, ERR9, ESC_b, ESC_D, ESC_d, ESC_REF, ESC_S, ESC_s, ESC_W, ESC_w, ESC_Z, EXTRACT_MAX, compile_data::fcc, is_counted_repeat(), offset, OP_ANY, OP_ASSERT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_BRA, OP_BRAZERO, OP_CHARS, OP_CIRC, OP_CLASS, OP_COND, OP_CRPLUS, OP_CRQUERY, OP_CRRANGE, OP_CRSTAR, OP_DOLL, OP_EODN, OP_EXACT, OP_KET, OP_KETRMAX, OP_NOTSTAR, OP_ONCE, OP_OPT, OP_PLUS, OP_QUERY, OP_REF, OP_STAR, OP_TYPESTAR, OP_UPTO, PCRE_CASELESS, PCRE_DOTALL, PCRE_EXTENDED, PCRE_EXTRA, PCRE_IMS, PCRE_INGROUP, PCRE_MULTILINE, PCRE_UNGREEDY, read_repeat_counts(), and uschar.

Referenced by compile_regex().

const uschar* first_significant_code | ( | const uschar * | code,
 |  | int * | options,
 |  | int | optbit,
 |  | BOOL | optstop
 | ) | [static]

Definition at line 1811 of file pcre.c.

References BOOL, OP_ALT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_CREF, OP_NOT_WORD_BOUNDARY, OP_OPT, OP_WORD_BOUNDARY, and uschar.

Referenced by find_firstchar(), is_anchored(), and is_startline().

BOOL is_anchored | ( | register const uschar * | code,
 |  | int * | options
 | ) | [static]

Definition at line 1875 of file pcre.c.

References first_significant_code(), OP_ALT, OP_ANY, OP_ASSERT, OP_BRA, OP_CIRC, OP_COND, OP_ONCE, OP_SOD, OP_TYPEMINSTAR, OP_TYPESTAR, PCRE_DOTALL, PCRE_MULTILINE, and uschar.

Referenced by pcre_compile().

BOOL is_startline ( const uschar * code ) [static]

Definition at line 1911 of file pcre.c.

References first_significant_code(), OP_ALT, OP_ANY, OP_ASSERT, OP_BRA, OP_CIRC, OP_COND, OP_ONCE, OP_TYPEMINSTAR, OP_TYPESTAR, and uschar.

Referenced by pcre_compile().

int find_firstchar | ( | const uschar * | code,
 |  | int * | options
 | ) | [static]

Definition at line 1947 of file pcre.c.

References first_significant_code(), OP_ALT, OP_ASSERT, OP_BRA, OP_CHARS, OP_COND, OP_EXACT, OP_MINPLUS, OP_ONCE, OP_PLUS, PCRE_CASELESS, and uschar.

Referenced by pcre_compile().

pcre* pcre_compile | ( | const char * | pattern,
 |  | int | options,
 |  | const char ** | errorptr,
 |  | int * | erroroffset,
 |  | const unsigned char * | tables
 | ) |

Definition at line 2012 of file pcre.c.

References BRASTACK_SIZE, compile_data::cbits, cbits_offset, check_escape(), real_pcre::code, compile_regex(), ctype_digit, ctype_meta, ctype_space, compile_data::ctypes, ctypes_offset, DPRINTF, ERR12, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, ERR21, ERR22, ERR23, ERR24, ERR26, ERR28, ESC_b, ESC_REF, compile_data::fcc, fcc_offset, find_firstchar(), real_pcre::first_char, is_anchored(), is_counted_repeat(), is_startline(), compile_data::lcc, lcc_offset, real_pcre::magic_number, MAGIC_NUMBER, offsetof, OP_ALT, OP_ASSERT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_BRA, OP_CHARS, OP_CLASS, OP_COND, OP_CREF, OP_CRMINPLUS, OP_CRMINQUERY, OP_CRMINRANGE, OP_CRMINSTAR, OP_CRPLUS, OP_CRQUERY, OP_CRRANGE, OP_CRSTAR, OP_END, OP_EXACT, OP_KET, OP_KETRMAX, OP_KETRMIN, OP_MINPLUS, OP_MINQUERY, OP_MINSTAR, OP_MINUPTO, OP_NOTEXACT, OP_NOTMINPLUS, OP_NOTMINQUERY, OP_NOTMINSTAR, OP_NOTMINUPTO, OP_NOTPLUS, OP_NOTQUERY, OP_NOTSTAR, OP_NOTUPTO, OP_ONCE, OP_OPT, OP_PLUS, OP_QUERY, OP_REF, OP_REVERSE, OP_STAR, OP_TYPEEXACT, OP_TYPEMINPLUS, OP_TYPEMINQUERY, OP_TYPEMINSTAR, OP_TYPEMINUPTO, OP_TYPEPLUS, OP_TYPEQUERY, OP_TYPESTAR, OP_TYPEUPTO, OP_UPTO, real_pcre::options, pcre, PCRE_ANCHORED, PCRE_CASELESS, PCRE_DOLLAR_ENDONLY, PCRE_DOTALL, PCRE_EXTENDED, PCRE_EXTRA, PCRE_FIRSTSET, PCRE_ICHANGED, PCRE_IMS, PCRE_MULTILINE, PCRE_REQCHSET, PCRE_STARTLINE, PCRE_UNGREEDY, PUBLIC_OPTIONS, read_repeat_counts(), real_pcre::req_char, size, real_pcre::tables, real_pcre::top_backref, real_pcre::top_bracket, and uschar.

Referenced by _list(), and String::match().

BOOL match_ref | ( | int | offset,
 |  | register const uschar * | eptr,
 |  | int | length,
 |  | match_data * | md,
 |  | unsigned long int | ims
 | ) | [static]

Definition at line 2902 of file pcre.c.

References match_data::end_subject, match_data::lcc, offset, match_data::offset_vector, p, PCRE_CASELESS, match_data::start_subject, and uschar.

Referenced by match().

BOOL match | ( | register const uschar * | eptr,
 |  | register const uschar * | ecode,
 |  | int | offset_top,
 |  | match_data * | md,
 |  | unsigned long int | ims,
 |  | BOOL | condassert,
 |  | const uschar * | eptrb
 | ) | [static]

Definition at line 2961 of file pcre.c.

References BOOL, ctype_digit, ctype_space, ctype_word, match_data::ctypes, data, DPRINTF, match_data::end_match_ptr, match_data::end_offset_top, match_data::end_subject, match_data::endonly, match_data::errorcode, match_data::lcc, match_ref(), match_data::notbol, match_data::notempty, match_data::noteol, offset, match_data::offset_end, match_data::offset_max, match_data::offset_overflow, match_data::offset_vector, OP_ALT, OP_ANY, OP_ASSERT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_BRA, OP_BRAMINZERO, OP_BRAZERO, OP_CHARS, OP_CIRC, OP_CLASS, OP_COND, OP_CREF, OP_CRMINPLUS, OP_CRMINQUERY, OP_CRMINRANGE, OP_CRMINSTAR, OP_CRPLUS, OP_CRQUERY, OP_CRRANGE, OP_CRSTAR, OP_DIGIT, OP_DOLL, OP_END, OP_EOD, OP_EODN, OP_EXACT, OP_KET, OP_KETRMAX, OP_KETRMIN, OP_MINPLUS, OP_MINQUERY, OP_MINSTAR, OP_MINUPTO, OP_NOT_DIGIT, OP_NOT_WHITESPACE, OP_NOT_WORD_BOUNDARY, OP_NOT_WORDCHAR, OP_NOTEXACT, OP_NOTMINPLUS, OP_NOTMINQUERY, OP_NOTMINSTAR, OP_NOTMINUPTO, OP_NOTPLUS, OP_NOTQUERY, OP_NOTSTAR, OP_NOTUPTO, OP_ONCE, OP_OPT, OP_PLUS, OP_QUERY, OP_REF, OP_REVERSE, OP_SOD, OP_STAR, OP_TYPEEXACT, OP_TYPEMINPLUS, OP_TYPEMINQUERY, OP_TYPEMINSTAR, OP_TYPEMINUPTO, OP_TYPEPLUS, OP_TYPEQUERY, OP_TYPESTAR, OP_TYPEUPTO, OP_UPTO, OP_WHITESPACE, OP_WORD_BOUNDARY, OP_WORDCHAR, PCRE_CASELESS, PCRE_DOTALL, PCRE_ERROR_UNKNOWN_NODE, PCRE_IMS, PCRE_MAX_POS, PCRE_MULTILINE, rep_max, rep_min, match_data::start_match, match_data::start_subject, and uschar.

Referenced by pcre_exec().

int pcre_exec | ( | const pcre * | external_re,
 |  | const pcre_extra * | external_extra,
 |  | const char * | subject,
 |  | int | length,
 |  | int | start_offset,
 |  | int | options,
 |  | int * | offsets,
 |  | int | offsetcount
 | ) |

Definition at line 4193 of file pcre.c.

References BOOL, real_pcre::code, match_data::ctypes, ctypes_offset, DPRINTF, match_data::end_match_ptr, match_data::end_offset_top, match_data::end_subject, match_data::endonly, match_data::errorcode, fcc_offset, real_pcre::first_char, match_data::lcc, lcc_offset, real_pcre::magic_number, MAGIC_NUMBER, match(), match_data::notbol, match_data::notempty, match_data::noteol, match_data::offset_end, match_data::offset_max, match_data::offset_overflow, match_data::offset_vector, real_pcre::options, real_pcre_extra::options, p, pcre, PCRE_ANCHORED, PCRE_CASELESS, PCRE_DOLLAR_ENDONLY, PCRE_DOTALL, PCRE_ERROR_BADMAGIC, PCRE_ERROR_BADOPTION, PCRE_ERROR_NOMATCH, PCRE_ERROR_NOMEMORY, PCRE_ERROR_NULL, pcre_extra, PCRE_FIRSTSET, PCRE_ICHANGED, PCRE_MULTILINE, PCRE_NOTBOL, PCRE_NOTEMPTY, PCRE_NOTEOL, PCRE_REQCHSET, PCRE_STARTLINE, PCRE_STUDY_MAPPED, PUBLIC_EXEC_OPTIONS, real_pcre::req_char, real_pcre_extra::start_bits, match_data::start_match, match_data::start_subject, real_pcre::tables, real_pcre::top_backref, real_pcre::top_bracket, and uschar.

Referenced by _list(), and String::match().

Variable Documentation

const char rep_min[] = { 0, 0, 1, 1, 0, 0 } [static]

Definition at line 71 of file pcre.c.

Referenced by match().

const char rep_max[] = { 0, 0, 0, 0, 1, 1 } [static]

Definition at line 72 of file pcre.c.

Referenced by match().

const short int escapes[] [static]

Initial value:

 {
    0,      0,      0,      0,      0,      0,      0,      0,
    0,      0,    ':',    ';',    '<',    '=',    '>',    '?',
  '@', -ESC_A, -ESC_B,      0, -ESC_D,      0,      0,      0,
    0,      0,      0,      0,      0,      0,      0,      0,
    0,      0,      0, -ESC_S,      0,      0,      0, -ESC_W,
    0,      0, -ESC_Z,    '[',   '\\',    ']',    '^',    '_',
  '`',      7, -ESC_b,      0, -ESC_d,     27,   '\f',      0,
    0,      0,      0,      0,      0,      0,   '\n',      0,
    0,      0,   '\r', -ESC_s,   '\t',      0,      0, -ESC_w,
    0,      0, -ESC_z
}

Definition at line 97 of file pcre.c.

Referenced by check_escape().

void*(* pcre_malloc)(size_t) = malloc

Definition at line 127 of file pcre.c.

void(* pcre_free)(void *) = free

Definition at line 128 of file pcre.c.

Referenced by _list(), and String::match().


pcre.c Source File

pcre.c

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005 /*
00006 This is a library of functions to support regular expressions whose syntax
00007 and semantics are as close as possible to those of the Perl 5 language. See
00008 the file Tech.Notes for some information on the internals.
00009
00010 Written by: Philip Hazel <ph10@cam.ac.uk>
00011
00012            Copyright (c) 1997-1999 University of Cambridge
00013
00014 -----------------------------------------------------------------------------
00015 Permission is granted to anyone to use this software for any purpose on any
00016 computer system, and to redistribute it freely, subject to the following
00017 restrictions:
00018
00019 1. This software is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022
00023 2. The origin of this software must not be misrepresented, either by
00024    explicit claim or by omission.
00025
00026 3. Altered versions must be plainly marked as such, and must not be
00027    misrepresented as being the original software.
00028
00029 4. If PCRE is embedded in any software that is released under the GNU
00030    General Purpose Licence (GPL), then the terms of that licence shall
00031    supersede any condition above with which it is incompatible.
00032 -----------------------------------------------------------------------------
00033 */
00034
00035
00036 /* Define DEBUG to get debugging output on stdout. */
00037
00038 /* #define DEBUG */
00039
00040 /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
00041 inline, and there are *still* stupid compilers about that don't like indented
00042 pre-processor statements. I suppose it's only been 10 years... */
00043
00044 #ifdef DEBUG
00045 #define DPRINTF(p) printf p
00046 #else
00047 #define DPRINTF(p) /*nothing*/
00048 #endif
00049
00050 /* Include the internals header, which itself includes Standard C headers plus
00051 the external pcre header. */
00052
00053 #include "internal.h"
00054
00055
00056 /* Allow compilation as C++ source code, should anybody want to do that. */
00057
00058 #ifdef __cplusplus
00059 #define class pcre_class
00060 #endif
00061
00062
00063 /* Number of items on the nested bracket stacks at compile time. This should
00064 not be set greater than 200. */
00065
00066 #define BRASTACK_SIZE 200
00067
00068
00069 /* Min and max values for the common repeats; for the maxima, 0 => infinity */
00070
00071 static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
00072 static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
00073
00074 /* Text forms of OP_ values and things, for debugging (not all used) */
00075
00076 #ifdef DEBUG
00077 static const char *OP_names[] = {
00078   "End", "\\A", "\\B", "\\b", "\\D", "\\d",
00079   "\\S", "\\s", "\\W", "\\w", "\\Z", "\\z",
00080   "Opt", "^", "$", "Any", "chars", "not",
00081   "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
00082   "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
00083   "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
00084   "*", "*?", "+", "+?", "?", "??", "{", "{",
00085   "class", "Ref",
00086   "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not",
00087   "AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cref",
00088   "Brazero", "Braminzero", "Bra"
00089 };
00090 #endif
00091
00092 /* Table for handling escaped characters in the range '0'-'z'. Positive returns
00093 are simple data values; negative values are for special things like \d and so
00094 on. Zero means further processing is needed (for things like \x), or the escape
00095 is invalid. */
00096
00097 static const short int escapes[] = {
00098     0,      0,      0,      0,      0,      0,      0,      0,   /* 0 - 7 */
00099     0,      0,    ':',    ';',    '<',    '=',    '>',    '?',   /* 8 - ? */
00100   '@', -ESC_A, -ESC_B,      0, -ESC_D,      0,      0,      0,   /* @ - G */
00101     0,      0,      0,      0,      0,      0,      0,      0,   /* H - O */
00102     0,      0,      0, -ESC_S,      0,      0,      0, -ESC_W,   /* P - W */
00103     0,      0, -ESC_Z,    '[',   '\\',    ']',    '^',    '_',   /* X - _ */
00104   '`',      7, -ESC_b,      0, -ESC_d,     27,   '\f',      0,   /* ` - g */
00105     0,      0,      0,      0,      0,      0,   '\n',      0,   /* h - o */
00106     0,      0,   '\r', -ESC_s,   '\t',      0,      0, -ESC_w,   /* p - w */
00107     0,      0, -ESC_z                                            /* x - z */
00108 };
00109
00110 /* Definition to allow mutual recursion */
00111
00112 static BOOL
00113   compile_regex(int, int, int *, uschar **, const uschar **, const char **,
00114     BOOL, int, int *, int *, compile_data *);
00115
00116
00117
00118 /*************************************************
00119 *               Global variables                 *
00120 *************************************************/
00121
00122 /* PCRE is thread-clean and doesn't use any global variables in the normal
00123 sense. However, it calls memory allocation and free functions via the two
00124 indirections below, which are can be changed by the caller, but are shared
00125 between all threads. */
00126
00127 void *(*pcre_malloc)(size_t) = malloc;
00128 void  (*pcre_free)(void *) = free;
00129
00130
00131
00132
00133 /*************************************************
00134 *             Default character tables           *
00135 *************************************************/
00136
00137 /* A default set of character tables is included in the PCRE binary. Its source
00138 is built by the maketables auxiliary program, which uses the default C ctypes
00139 functions, and put in the file chartables.c. These tables are used by PCRE
00140 whenever the caller of pcre_compile() does not provide an alternate set of
00141 tables. */
00142
00143 #include "chartables.c"
00144
00145
00146
00147 /*************************************************
00148 *          Return version string                 *
00149 *************************************************/
00150
00151 #define STRING(a)  # a
00152 #define XSTRING(s) STRING(s)
00153
00154 const char *
00155 pcre_version(void)
00156 {
00157 return XSTRING(PCRE_MAJOR) "." XSTRING(PCRE_MINOR) " " XSTRING(PCRE_DATE);
00158 }
00159
00160
00161
00162
00163 /*************************************************
00164 *       Return info about a compiled pattern     *
00165 *************************************************/
00166
00167 /* This function picks potentially useful data out of the private
00168 structure. The public options are passed back in an int - though the
00169 re->options field has been expanded to a long int, all the public options
00170 at the low end of it, and so even on 16-bit systems this will still be OK.
00171 Therefore, I haven't changed the API for pcre_info().
00172
00173 Arguments:
00174   external_re   points to compiled code
00175   optptr        where to pass back the options
00176   first_char    where to pass back the first character,
00177                 or -1 if multiline and all branches start ^,
00178                 or -2 otherwise
00179
00180 Returns:        number of identifying extraction brackets
00181                 or negative values on error
00182 */
00183
00184 int
00185 pcre_info(const pcre *external_re, int *optptr, int *first_char)
00186 {
00187 const real_pcre *re = (const real_pcre *)external_re;
00188 if (re == NULL) return PCRE_ERROR_NULL;
00189 if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
00190 if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS);
00191 if (first_char != NULL)
00192   *first_char = ((re->options & PCRE_FIRSTSET) != 0)? re->first_char :
00193      ((re->options & PCRE_STARTLINE) != 0)? -1 : -2;
00194 return re->top_bracket;
00195 }
00196
00197
00198
00199
00200 #ifdef DEBUG
00201 /*************************************************
00202 *        Debugging function to print chars       *
00203 *************************************************/
00204
00205 /* Print a sequence of chars in printable format, stopping at the end of the
00206 subject if the requested.
00207
00208 Arguments:
00209   p           points to characters
00210   length      number to print
00211   is_subject  TRUE if printing from within md->start_subject
00212   md          pointer to matching data block, if is_subject is TRUE
00213
00214 Returns:     nothing
00215 */
00216
00217 static void
00218 pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
00219 {
00220 int c;
00221 if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
00222 while (length-- > 0)
00223   if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
00224 }
00225 #endif
00226
00227
00228
00229
00230 /*************************************************
00231 *            Handle escapes                      *
00232 *************************************************/
00233
00234 /* This function is called when a \ has been encountered. It either returns a
00235 positive value for a simple escape such as \n, or a negative value which
00236 encodes one of the more complicated things such as \d. On entry, ptr is
00237 pointing at the \. On exit, it is on the final character of the escape
00238 sequence.
00239
00240 Arguments:
00241   ptrptr     points to the pattern position pointer
00242   errorptr   points to the pointer to the error message
00243   bracount   number of previous extracting brackets
00244   options    the options bits
00245   isclass    TRUE if inside a character class
00246   cd         pointer to char tables block
00247
00248 Returns:     zero or positive => a data character
00249              negative => a special escape sequence
00250              on error, errorptr is set
00251 */
00252
00253 static int
00254 check_escape(const uschar **ptrptr, const char **errorptr, int bracount,
00255   int options, BOOL isclass, compile_data *cd)
00256 {
00257 const uschar *ptr = *ptrptr;
00258 int c = *(++ptr) & 255;   /* Ensure > 0 on signed-char systems */
00259 int i;
00260
00261 if (c == 0) *errorptr = ERR1;
00262
00263 /* Digits or letters may have special meaning; all others are literals. */
00264
00265 else if (c < '0' || c > 'z') {}
00266
00267 /* Do an initial lookup in a table. A non-zero result is something that can be
00268 returned immediately. Otherwise further processing may be required. */
00269
00270 else if ((i = escapes[c - '0']) != 0) c = i;
00271
00272 /* Escapes that need further processing, or are illegal. */
00273
00274 else
00275   {
00276   const uschar *oldptr;
00277   switch (c)
00278     {
00279     /* The handling of escape sequences consisting of a string of digits
00280     starting with one that is not zero is not straightforward. By experiment,
00281     the way Perl works seems to be as follows:
00282
00283     Outside a character class, the digits are read as a decimal number. If the
00284     number is less than 10, or if there are that many previous extracting
00285     left brackets, then it is a back reference. Otherwise, up to three octal
00286     digits are read to form an escaped byte. Thus \123 is likely to be octal
00287     123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
00288     value is greater than 377, the least significant 8 bits are taken. Inside a
00289     character class, \ followed by a digit is always an octal number. */
00290
00291     case '1': case '2': case '3': case '4': case '5':
00292     case '6': case '7': case '8': case '9':
00293
00294     if (!isclass)
00295       {
00296       oldptr = ptr;
00297       c -= '0';
00298       while ((cd->ctypes[ptr[1]] & ctype_digit) != 0)
00299         c = c * 10 + *(++ptr) - '0';
00300       if (c < 10 || c <= bracount)
00301         {
00302         c = -(ESC_REF + c);
00303         break;
00304         }
00305       ptr = oldptr;      /* Put the pointer back and fall through */
00306       }
00307
00308     /* Handle an octal number following \. If the first digit is 8 or 9, Perl
00309     generates a binary zero byte and treats the digit as a following literal.
00310     Thus we have to pull back the pointer by one. */
00311
00312     if ((c = *ptr) >= '8')
00313       {
00314       ptr--;
00315       c = 0;
00316       break;
00317       }
00318
00319     /* \0 always starts an octal number, but we may drop through to here with a
00320     larger first octal digit */
00321
00322     case '0':
00323     c -= '0';
00324     while(i++ < 2 && (cd->ctypes[ptr[1]] & ctype_digit) != 0 &&
00325       ptr[1] != '8' && ptr[1] != '9')
00326         c = c * 8 + *(++ptr) - '0';
00327     break;
00328
00329     /* Special escapes not starting with a digit are straightforward */
00330
00331     case 'x':
00332     c = 0;
00333     while (i++ < 2 && (cd->ctypes[ptr[1]] & ctype_xdigit) != 0)
00334       {
00335       ptr++;
00336       c = c * 16 + cd->lcc[*ptr] -
00337         (((cd->ctypes[*ptr] & ctype_digit) != 0)? '0' : 'W');
00338       }
00339     break;
00340
00341     case 'c':
00342     c = *(++ptr);
00343     if (c == 0)
00344       {
00345       *errorptr = ERR2;
00346       return 0;
00347       }
00348
00349     /* A letter is upper-cased; then the 0x40 bit is flipped */
00350
00351     if (c >= 'a' && c <= 'z') c = cd->fcc[c];
00352     c ^= 0x40;
00353     break;
00354
00355     /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
00356     other alphameric following \ is an error if PCRE_EXTRA was set; otherwise,
00357     for Perl compatibility, it is a literal. This code looks a bit odd, but
00358     there used to be some cases other than the default, and there may be again
00359     in future, so I haven't "optimized" it. */
00360
00361     default:
00362     if ((options & PCRE_EXTRA) != 0) switch(c)
00363       {
00364       default:
00365       *errorptr = ERR3;
00366       break;
00367       }
00368     break;
00369     }
00370   }
00371
00372 *ptrptr = ptr;
00373 return c;
00374 }
00375
00376
00377
00378 /*************************************************
00379 *            Check for counted repeat            *
00380 *************************************************/
00381
00382 /* This function is called when a '{' is encountered in a place where it might
00383 start a quantifier. It looks ahead to see if it really is a quantifier or not.
00384 It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
00385 where the ddds are digits.
00386
00387 Arguments:
00388   p         pointer to the first char after '{'
00389   cd        pointer to char tables block
00390
00391 Returns:    TRUE or FALSE
00392 */
00393
00394 static BOOL
00395 is_counted_repeat(const uschar *p, compile_data *cd)
00396 {
00397 if ((cd->ctypes[*p++] & ctype_digit) == 0) return FALSE;
00398 while ((cd->ctypes[*p] & ctype_digit) != 0) p++;
00399 if (*p == '}') return TRUE;
00400
00401 if (*p++ != ',') return FALSE;
00402 if (*p == '}') return TRUE;
00403
00404 if ((cd->ctypes[*p++] & ctype_digit) == 0) return FALSE;
00405 while ((cd->ctypes[*p] & ctype_digit) != 0) p++;
00406 return (*p == '}');
00407 }
00408
00409
00410
00411 /*************************************************
00412 *         Read repeat counts                     *
00413 *************************************************/
00414
00415 /* Read an item of the form {n,m} and return the values. This is called only
00416 after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
00417 so the syntax is guaranteed to be correct, but we need to check the values.
00418
00419 Arguments:
00420   p          pointer to first char after '{'
00421   minp       pointer to int for min
00422   maxp       pointer to int for max
00423              returned as -1 if no max
00424   errorptr   points to pointer to error message
00425   cd         pointer to character tables clock
00426
00427 Returns:     pointer to '}' on success;
00428              current ptr on error, with errorptr set
00429 */
00430
00431 static const uschar *
00432 read_repeat_counts(const uschar *p, int *minp, int *maxp,
00433   const char **errorptr, compile_data *cd)
00434 {
00435 int min = 0;
00436 int max = -1;
00437
00438 while ((cd->ctypes[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0';
00439
00440 if (*p == '}') max = min; else
00441   {
00442   if (*(++p) != '}')
00443     {
00444     max = 0;
00445     while((cd->ctypes[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0';
00446     if (max < min)
00447       {
00448       *errorptr = ERR4;
00449       return p;
00450       }
00451     }
00452   }
00453
00454 /* Do paranoid checks, then fill in the required variables, and pass back the
00455 pointer to the terminating '}'. */
00456
00457 if (min > 65535 || max > 65535)
00458   *errorptr = ERR5;
00459 else
00460   {
00461   *minp = min;
00462   *maxp = max;
00463   }
00464 return p;
00465 }
00466
00467
00468
00469 /*************************************************
00470 *        Find the fixed length of a pattern      *
00471 *************************************************/
00472
00473 /* Scan a pattern and compute the fixed length of subject that will match it,
00474 if the length is fixed. This is needed for dealing with backward assertions.
00475
00476 Arguments:
00477   code     points to the start of the pattern (the bracket)
00478
00479 Returns:   the fixed length, or -1 if there is no fixed length
00480 */
00481
00482 static int
00483 find_fixedlength(uschar *code)
00484 {
00485 int length = -1;
00486
00487 register int branchlength = 0;
00488 register uschar *cc = code + 3;
00489
00490 /* Scan along the opcodes for this branch. If we get to the end of the
00491 branch, check the length against that of the other branches. */
00492
00493 for (;;)
00494   {
00495   int d;
00496   register int op = *cc;
00497   if (op >= OP_BRA) op = OP_BRA;
00498
00499   switch (op)
00500     {
00501     case OP_BRA:
00502     case OP_ONCE:
00503     case OP_COND:
00504     d = find_fixedlength(cc);
00505     if (d < 0) return -1;
00506     branchlength += d;
00507     do cc += (cc[1] << 8) + cc[2]; while (*cc == OP_ALT);
00508     cc += 3;
00509     break;
00510
00511     /* Reached end of a branch; if it's a ket it is the end of a nested
00512     call. If it's ALT it is an alternation in a nested call. If it is
00513     END it's the end of the outer call. All can be handled by the same code. */
00514
00515     case OP_ALT:
00516     case OP_KET:
00517     case OP_KETRMAX:
00518     case OP_KETRMIN:
00519     case OP_END:
00520     if (length < 0) length = branchlength;
00521       else if (length != branchlength) return -1;
00522     if (*cc != OP_ALT) return length;
00523     cc += 3;
00524     branchlength = 0;
00525     break;
00526
00527     /* Skip over assertive subpatterns */
00528
00529     case OP_ASSERT:
00530     case OP_ASSERT_NOT:
00531     case OP_ASSERTBACK:
00532     case OP_ASSERTBACK_NOT:
00533     do cc += (cc[1] << 8) + cc[2]; while (*cc == OP_ALT);
00534     cc += 3;
00535     break;
00536
00537     /* Skip over things that don't match chars */
00538
00539     case OP_REVERSE:
00540     cc++;
00541     /* Fall through */
00542
00543     case OP_CREF:
00544     case OP_OPT:
00545     cc++;
00546     /* Fall through */
00547
00548     case OP_SOD:
00549     case OP_EOD:
00550     case OP_EODN:
00551     case OP_CIRC:
00552     case OP_DOLL:
00553     case OP_NOT_WORD_BOUNDARY:
00554     case OP_WORD_BOUNDARY:
00555     cc++;
00556     break;
00557
00558     /* Handle char strings */
00559
00560     case OP_CHARS:
00561     branchlength += *(++cc);
00562     cc += *cc + 1;
00563     break;
00564
00565     /* Handle exact repetitions */
00566
00567     case OP_EXACT:
00568     case OP_TYPEEXACT:
00569     branchlength += (cc[1] << 8) + cc[2];
00570     cc += 4;
00571     break;
00572
00573     /* Handle single-char matchers */
00574
00575     case OP_NOT_DIGIT:
00576     case OP_DIGIT:
00577     case OP_NOT_WHITESPACE:
00578     case OP_WHITESPACE:
00579     case OP_NOT_WORDCHAR:
00580     case OP_WORDCHAR:
00581     case OP_ANY:
00582     branchlength++;
00583     cc++;
00584     break;
00585
00586
00587     /* Check a class for variable quantification */
00588
00589     case OP_CLASS:
00590     cc += (*cc == OP_REF)? 2 : 33;
00591
00592     switch (*cc)
00593       {
00594       case OP_CRSTAR:
00595       case OP_CRMINSTAR:
00596       case OP_CRQUERY:
00597       case OP_CRMINQUERY:
00598       return -1;
00599
00600       case OP_CRRANGE:
00601       case OP_CRMINRANGE:
00602       if ((cc[1] << 8) + cc[2] != (cc[3] << 8) + cc[4]) return -1;
00603       branchlength += (cc[1] << 8) + cc[2];
00604       cc += 5;
00605       break;
00606
00607       default:
00608       branchlength++;
00609       }
00610     break;
00611
00612     /* Anything else is variable length */
00613
00614     default:
00615     return -1;
00616     }
00617   }
00618 /* Control never gets here */
00619 }
00620
00621
00622
00623
00624 /*************************************************
00625 *           Compile one branch                   *
00626 *************************************************/
00627
00628 /* Scan the pattern, compiling it into the code vector.
00629
00630 Arguments:
00631   options      the option bits
00632   brackets     points to number of brackets used
00633   code         points to the pointer to the current code point
00634   ptrptr       points to the current pattern pointer
00635   errorptr     points to pointer to error message
00636   optchanged   set to the value of the last OP_OPT item compiled
00637   reqchar      set to the last literal character required, else -1
00638   countlits    set to count of mandatory literal characters
00639   cd           contains pointers to tables
00640
00641 Returns:       TRUE on success
00642                FALSE, with *errorptr set on error
00643 */
00644
00645 static BOOL
00646 compile_branch(int options, int *brackets, uschar **codeptr,
00647   const uschar **ptrptr, const char **errorptr, int *optchanged,
00648   int *reqchar, int *countlits, compile_data *cd)
00649 {
00650 int repeat_type, op_type;
00651 int repeat_min, repeat_max;
00652 int bravalue, length;
00653 int greedy_default, greedy_non_default;
00654 int prevreqchar;
00655 int condcount = 0;
00656 int subcountlits = 0;
00657 register int c;
00658 register uschar *code = *codeptr;
00659 uschar *tempcode;
00660 const uschar *ptr = *ptrptr;
00661 const uschar *tempptr;
00662 uschar *previous = NULL;
00663 uschar class[32];
00664
00665 /* Set up the default and non-default settings for greediness */
00666
00667 greedy_default = ((options & PCRE_UNGREEDY) != 0);
00668 greedy_non_default = greedy_default ^ 1;
00669
00670 /* Initialize no required char, and count of literals */
00671
00672 *reqchar = prevreqchar = -1;
00673 *countlits = 0;
00674
00675 /* Switch on next character until the end of the branch */
00676
00677 for (;; ptr++)
00678   {
00679   BOOL negate_class;
00680   int class_charcount;
00681   int class_lastchar;
00682   int newoptions;
00683   int condref;
00684   int subreqchar;
00685
00686   c = *ptr;
00687   if ((options & PCRE_EXTENDED) != 0)
00688     {
00689     if ((cd->ctypes[c] & ctype_space) != 0) continue;
00690     if (c == '#')
00691       {
00692       while ((c = *(++ptr)) != 0 && c != '\n');
00693       continue;
00694       }
00695     }
00696
00697   switch(c)
00698     {
00699     /* The branch terminates at end of string, |, or ). */
00700
00701     case 0:
00702     case '|':
00703     case ')':
00704     *codeptr = code;
00705     *ptrptr = ptr;
00706     return TRUE;
00707
00708     /* Handle single-character metacharacters */
00709
00710     case '^':
00711     previous = NULL;
00712     *code++ = OP_CIRC;
00713     break;
00714
00715     case '$':
00716     previous = NULL;
00717     *code++ = OP_DOLL;
00718     break;
00719
00720     case '.':
00721     previous = code;
00722     *code++ = OP_ANY;
00723     break;
00724
00725     /* Character classes. These always build a 32-byte bitmap of the permitted
00726     characters, except in the special case where there is only one character.
00727     For negated classes, we build the map as usual, then invert it at the end.
00728     */
00729
00730     case '[':
00731     previous = code;
00732     *code++ = OP_CLASS;
00733
00734     /* If the first character is '^', set the negation flag and skip it. */
00735
00736     if ((c = *(++ptr)) == '^')
00737       {
00738       negate_class = TRUE;
00739       c = *(++ptr);
00740       }
00741     else negate_class = FALSE;
00742
00743     /* Keep a count of chars so that we can optimize the case of just a single
00744     character. */
00745
00746     class_charcount = 0;
00747     class_lastchar = -1;
00748
00749     /* Initialize the 32-char bit map to all zeros. We have to build the
00750     map in a temporary bit of store, in case the class contains only 1
00751     character, because in that case the compiled code doesn't use the
00752     bit map. */
00753
00754     memset(class, 0, 32 * sizeof(uschar));
00755
00756     /* Process characters until ] is reached. By writing this as a "do" it
00757     means that an initial ] is taken as a data character. */
00758
00759     do
00760       {
00761       if (c == 0)
00762         {
00763         *errorptr = ERR6;
00764         goto FAILED;
00765         }
00766
00767       /* Backslash may introduce a single character, or it may introduce one
00768       of the specials, which just set a flag. Escaped items are checked for
00769       validity in the pre-compiling pass. The sequence \b is a special case.
00770       Inside a class (and only there) it is treated as backspace. Elsewhere
00771       it marks a word boundary. Other escapes have preset maps ready to
00772       or into the one we are building. We assume they have more than one
00773       character in them, so set class_count bigger than one. */
00774
00775       if (c == '\\')
00776         {
00777         c = check_escape(&ptr, errorptr, *brackets, options, TRUE, cd);
00778         if (-c == ESC_b) c = '\b';
00779         else if (c < 0)
00780           {
00781           register const uschar *cbits = cd->cbits;
00782           class_charcount = 10;
00783           switch (-c)
00784             {
00785             case ESC_d:
00786             for (c = 0; c < 32; c++) class[c] |= cbits[c+cbit_digit];
00787             continue;
00788
00789             case ESC_D:
00790             for (c = 0; c < 32; c++) class[c] |= ~cbits[c+cbit_digit];
00791             continue;
00792
00793             case ESC_w:
00794             for (c = 0; c < 32; c++)
00795               class[c] |= (cbits[c+cbit_digit] | cbits[c+cbit_word]);
00796             continue;
00797
00798             case ESC_W:
00799             for (c = 0; c < 32; c++)
00800               class[c] |= ~(cbits[c+cbit_digit] | cbits[c+cbit_word]);
00801             continue;
00802
00803             case ESC_s:
00804             for (c = 0; c < 32; c++) class[c] |= cbits[c+cbit_space];
00805             continue;
00806
00807             case ESC_S:
00808             for (c = 0; c < 32; c++) class[c] |= ~cbits[c+cbit_space];
00809             continue;
00810
00811             default:
00812             *errorptr = ERR7;
00813             goto FAILED;
00814             }
00815           }
00816         /* Fall through if single character */
00817         }
00818
00819       /* A single character may be followed by '-' to form a range. However,
00820       Perl does not permit ']' to be the end of the range. A '-' character
00821       here is treated as a literal. */
00822
00823       if (ptr[1] == '-' && ptr[2] != ']')
00824         {
00825         int d;
00826         ptr += 2;
00827         d = *ptr;
00828
00829         if (d == 0)
00830           {
00831           *errorptr = ERR6;
00832           goto FAILED;
00833           }
00834
00835         /* The second part of a range can be a single-character escape, but
00836         not any of the other escapes. */
00837
00838         if (d == '\\')
00839           {
00840           d = check_escape(&ptr, errorptr, *brackets, options, TRUE, cd);
00841           if (d < 0)
00842             {
00843             if (d == -ESC_b) d = '\b'; else
00844               {
00845               *errorptr = ERR7;
00846               goto FAILED;
00847               }
00848             }
00849           }
00850
00851         if (d < c)
00852           {
00853           *errorptr = ERR8;
00854           goto FAILED;
00855           }
00856
00857         for (; c <= d; c++)
00858           {
00859           class[c/8] |= (1 << (c&7));
00860           if ((options & PCRE_CASELESS) != 0)
00861             {
00862             int uc = cd->fcc[c];           /* flip case */
00863             class[uc/8] |= (1 << (uc&7));
00864             }
00865           class_charcount++;                /* in case a one-char range */
00866           class_lastchar = c;
00867           }
00868         continue;   /* Go get the next char in the class */
00869         }
00870
00871       /* Handle a lone single character - we can get here for a normal
00872       non-escape char, or after \ that introduces a single character. */
00873
00874       class [c/8] |= (1 << (c&7));
00875       if ((options & PCRE_CASELESS) != 0)
00876         {
00877         c = cd->fcc[c];   /* flip case */
00878         class[c/8] |= (1 << (c&7));
00879         }
00880       class_charcount++;
00881       class_lastchar = c;
00882       }
00883
00884     /* Loop until ']' reached; the check for end of string happens inside the
00885     loop. This "while" is the end of the "do" above. */
00886
00887     while ((c = *(++ptr)) != ']');
00888
00889     /* If class_charcount is 1 and class_lastchar is not negative, we saw
00890     precisely one character. This doesn't need the whole 32-byte bit map.
00891     We turn it into a 1-character OP_CHAR if it's positive, or OP_NOT if
00892     it's negative. */
00893
00894     if (class_charcount == 1 && class_lastchar >= 0)
00895       {
00896       if (negate_class)
00897         {
00898         code[-1] = OP_NOT;
00899         }
00900       else
00901         {
00902         code[-1] = OP_CHARS;
00903         *code++ = 1;
00904         }
00905       *code++ = class_lastchar;
00906       }
00907
00908     /* Otherwise, negate the 32-byte map if necessary, and copy it into
00909     the code vector. */
00910
00911     else
00912       {
00913       if (negate_class)
00914         for (c = 0; c < 32; c++) code[c] = ~class[c];
00915       else
00916         memcpy(code, class, 32);
00917       code += 32;
00918       }
00919     break;
00920
00921     /* Various kinds of repeat */
00922
00923     case '{':
00924     if (!is_counted_repeat(ptr+1, cd)) goto NORMAL_CHAR;
00925     ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorptr, cd);
00926     if (*errorptr != NULL) goto FAILED;
00927     goto REPEAT;
00928
00929     case '*':
00930     repeat_min = 0;
00931     repeat_max = -1;
00932     goto REPEAT;
00933
00934     case '+':
00935     repeat_min = 1;
00936     repeat_max = -1;
00937     goto REPEAT;
00938
00939     case '?':
00940     repeat_min = 0;
00941     repeat_max = 1;
00942
00943     REPEAT:
00944     if (previous == NULL)
00945       {
00946       *errorptr = ERR9;
00947       goto FAILED;
00948       }
00949
00950     /* If the next character is '?' this is a minimizing repeat, by default,
00951     but if PCRE_UNGREEDY is set, it works the other way round. Advance to the
00952     next character. */
00953
00954     if (ptr[1] == '?')
00955       { repeat_type = greedy_non_default; ptr++; }
00956     else repeat_type = greedy_default;
00957
00958     /* If previous was a string of characters, chop off the last one and use it
00959     as the subject of the repeat. If there was only one character, we can
00960     abolish the previous item altogether. A repeat with a zero minimum wipes
00961     out any reqchar setting, backing up to the previous value. We must also
00962     adjust the countlits value. */
00963
00964     if (*previous == OP_CHARS)
00965       {
00966       int len = previous[1];
00967
00968       if (repeat_min == 0) *reqchar = prevreqchar;
00969       *countlits += repeat_min - 1;
00970
00971       if (len == 1)
00972         {
00973         c = previous[2];
00974         code = previous;
00975         }
00976       else
00977         {
00978         c = previous[len+1];
00979         previous[1]--;
00980         code--;
00981         }
00982       op_type = 0;                 /* Use single-char op codes */
00983       goto OUTPUT_SINGLE_REPEAT;   /* Code shared with single character types */
00984       }
00985
00986     /* If previous was a single negated character ([^a] or similar), we use
00987     one of the special opcodes, replacing it. The code is shared with single-
00988     character repeats by adding a suitable offset into repeat_type. */
00989
00990     else if ((int)*previous == OP_NOT)
00991       {
00992       op_type = OP_NOTSTAR - OP_STAR;  /* Use "not" opcodes */
00993       c = previous[1];
00994       code = previous;
00995       goto OUTPUT_SINGLE_REPEAT;
00996       }
00997
00998     /* If previous was a character type match (\d or similar), abolish it and
00999     create a suitable repeat item. The code is shared with single-character
01000     repeats by adding a suitable offset into repeat_type. */
01001
01002     else if ((int)*previous < OP_EODN || *previous == OP_ANY)
01003       {
01004       op_type = OP_TYPESTAR - OP_STAR;  /* Use type opcodes */
01005       c = *previous;
01006       code = previous;
01007
01008       OUTPUT_SINGLE_REPEAT:
01009
01010       /* If the maximum is zero then the minimum must also be zero; Perl allows
01011       this case, so we do too - by simply omitting the item altogether. */
01012
01013       if (repeat_max == 0) goto END_REPEAT;
01014
01015       /* Combine the op_type with the repeat_type */
01016
01017       repeat_type += op_type;
01018
01019       /* A minimum of zero is handled either as the special case * or ?, or as
01020       an UPTO, with the maximum given. */
01021
01022       if (repeat_min == 0)
01023         {
01024         if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
01025           else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
01026         else
01027           {
01028           *code++ = OP_UPTO + repeat_type;
01029           *code++ = repeat_max >> 8;
01030           *code++ = (repeat_max & 255);
01031           }
01032         }
01033
01034       /* The case {1,} is handled as the special case + */
01035
01036       else if (repeat_min == 1 && repeat_max == -1)
01037         *code++ = OP_PLUS + repeat_type;
01038
01039       /* The case {n,n} is just an EXACT, while the general case {n,m} is
01040       handled as an EXACT followed by an UPTO. An EXACT of 1 is optimized. */
01041
01042       else
01043         {
01044         if (repeat_min != 1)
01045           {
01046           *code++ = OP_EXACT + op_type;  /* NB EXACT doesn't have repeat_type */
01047           *code++ = repeat_min >> 8;
01048           *code++ = (repeat_min & 255);
01049           }
01050
01051         /* If the mininum is 1 and the previous item was a character string,
01052         we either have to put back the item that got cancelled if the string
01053         length was 1, or add the character back onto the end of a longer
01054         string. For a character type nothing need be done; it will just get
01055         put back naturally. Note that the final character is always going to
01056         get added below. */
01057
01058         else if (*previous == OP_CHARS)
01059           {
01060           if (code == previous) code += 2; else previous[1]++;
01061           }
01062
01063         /*  For a single negated character we also have to put back the
01064         item that got cancelled. */
01065
01066         else if (*previous == OP_NOT) code++;
01067
01068         /* If the maximum is unlimited, insert an OP_STAR. */
01069
01070         if (repeat_max < 0)
01071           {
01072           *code++ = c;
01073           *code++ = OP_STAR + repeat_type;
01074           }
01075
01076         /* Else insert an UPTO if the max is greater than the min. */
01077
01078         else if (repeat_max != repeat_min)
01079           {
01080           *code++ = c;
01081           repeat_max -= repeat_min;
01082           *code++ = OP_UPTO + repeat_type;
01083           *code++ = repeat_max >> 8;
01084           *code++ = (repeat_max & 255);
01085           }
01086         }
01087
01088       /* The character or character type itself comes last in all cases. */
01089
01090       *code++ = c;
01091       }
01092
01093     /* If previous was a character class or a back reference, we put the repeat
01094     stuff after it, but just skip the item if the repeat was {0,0}. */
01095
01096     else if (*previous == OP_CLASS || *previous == OP_REF)
01097       {
01098       if (repeat_max == 0)
01099         {
01100         code = previous;
01101         goto END_REPEAT;
01102         }
01103       if (repeat_min == 0 && repeat_max == -1)
01104         *code++ = OP_CRSTAR + repeat_type;
01105       else if (repeat_min == 1 && repeat_max == -1)
01106         *code++ = OP_CRPLUS + repeat_type;
01107       else if (repeat_min == 0 && repeat_max == 1)
01108         *code++ = OP_CRQUERY + repeat_type;
01109       else
01110         {
01111         *code++ = OP_CRRANGE + repeat_type;
01112         *code++ = repeat_min >> 8;
01113         *code++ = repeat_min & 255;
01114         if (repeat_max == -1) repeat_max = 0;  /* 2-byte encoding for max */
01115         *code++ = repeat_max >> 8;
01116         *code++ = repeat_max & 255;
01117         }
01118       }
01119
01120     /* If previous was a bracket group, we may have to replicate it in certain
01121     cases. */
01122
01123     else if ((int)*previous >= OP_BRA || (int)*previous == OP_ONCE ||
01124              (int)*previous == OP_COND)
01125       {
01126       register int i;
01127       int ketoffset = 0;
01128       int len = code - previous;
01129       uschar *bralink = NULL;
01130
01131       /* If the maximum repeat count is unlimited, find the end of the bracket
01132       by scanning through from the start, and compute the offset back to it
01133       from the current code pointer. There may be an OP_OPT setting following
01134       the final KET, so we can't find the end just by going back from the code
01135       pointer. */
01136
01137       if (repeat_max == -1)
01138         {
01139         register uschar *ket = previous;
01140         do ket += (ket[1] << 8) + ket[2]; while (*ket != OP_KET);
01141         ketoffset = code - ket;
01142         }
01143
01144       /* The case of a zero minimum is special because of the need to stick
01145       OP_BRAZERO in front of it, and because the group appears once in the
01146       data, whereas in other cases it appears the minimum number of times. For
01147       this reason, it is simplest to treat this case separately, as otherwise
01148       the code gets far too mess. There are several special subcases when the
01149       minimum is zero. */
01150
01151       if (repeat_min == 0)
01152         {
01153         /* If we set up a required char from the bracket, we must back off
01154         to the previous value and reset the countlits value too. */
01155
01156         if (subcountlits > 0)
01157           {
01158           *reqchar = prevreqchar;
01159           *countlits -= subcountlits;
01160           }
01161
01162         /* If the maximum is also zero, we just omit the group from the output
01163         altogether. */
01164
01165         if (repeat_max == 0)
01166           {
01167           code = previous;
01168           goto END_REPEAT;
01169           }
01170
01171         /* If the maximum is 1 or unlimited, we just have to stick in the
01172         BRAZERO and do no more at this point. */
01173
01174         if (repeat_max <= 1)
01175           {
01176           memmove(previous+1, previous, len);
01177           code++;
01178           *previous++ = OP_BRAZERO + repeat_type;
01179           }
01180
01181         /* If the maximum is greater than 1 and limited, we have to replicate
01182         in a nested fashion, sticking OP_BRAZERO before each set of brackets.
01183         The first one has to be handled carefully because it's the original
01184         copy, which has to be moved up. The remainder can be handled by code
01185         that is common with the non-zero minimum case below. We just have to
01186         adjust the value or repeat_max, since one less copy is required. */
01187
01188         else
01189           {
01190           int offset;
01191           memmove(previous+4, previous, len);
01192           code += 4;
01193           *previous++ = OP_BRAZERO + repeat_type;
01194           *previous++ = OP_BRA;
01195
01196           /* We chain together the bracket offset fields that have to be
01197           filled in later when the ends of the brackets are reached. */
01198
01199           offset = (bralink == NULL)? 0 : previous - bralink;
01200           bralink = previous;
01201           *previous++ = offset >> 8;
01202           *previous++ = offset & 255;
01203           }
01204
01205         repeat_max--;
01206         }
01207
01208       /* If the minimum is greater than zero, replicate the group as many
01209       times as necessary, and adjust the maximum to the number of subsequent
01210       copies that we need. */
01211
01212       else
01213         {
01214         for (i = 1; i < repeat_min; i++)
01215           {
01216           memcpy(code, previous, len);
01217           code += len;
01218           }
01219         if (repeat_max > 0) repeat_max -= repeat_min;
01220         }
01221
01222       /* This code is common to both the zero and non-zero minimum cases. If
01223       the maximum is limited, it replicates the group in a nested fashion,
01224       remembering the bracket starts on a stack. In the case of a zero minimum,
01225       the first one was set up above. In all cases the repeat_max now specifies
01226       the number of additional copies needed. */
01227
01228       if (repeat_max >= 0)
01229         {
01230         for (i = repeat_max - 1; i >= 0; i--)
01231           {
01232           *code++ = OP_BRAZERO + repeat_type;
01233
01234           /* All but the final copy start a new nesting, maintaining the
01235           chain of brackets outstanding. */
01236
01237           if (i != 0)
01238             {
01239             int offset;
01240             *code++ = OP_BRA;
01241             offset = (bralink == NULL)? 0 : code - bralink;
01242             bralink = code;
01243             *code++ = offset >> 8;
01244             *code++ = offset & 255;
01245             }
01246
01247           memcpy(code, previous, len);
01248           code += len;
01249           }
01250
01251         /* Now chain through the pending brackets, and fill in their length
01252         fields (which are holding the chain links pro tem). */
01253
01254         while (bralink != NULL)
01255           {
01256           int oldlinkoffset;
01257           int offset = code - bralink + 1;
01258           uschar *bra = code - offset;
01259           oldlinkoffset = (bra[1] << 8) + bra[2];
01260           bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
01261           *code++ = OP_KET;
01262           *code++ = bra[1] = offset >> 8;
01263           *code++ = bra[2] = (offset & 255);
01264           }
01265         }
01266
01267       /* If the maximum is unlimited, set a repeater in the final copy. We
01268       can't just offset backwards from the current code point, because we
01269       don't know if there's been an options resetting after the ket. The
01270       correct offset was computed above. */
01271
01272       else code[-ketoffset] = OP_KETRMAX + repeat_type;
01273       }
01274
01275     /* Else there's some kind of shambles */
01276
01277     else
01278       {
01279       *errorptr = ERR11;
01280       goto FAILED;
01281       }
01282
01283     /* In all case we no longer have a previous item. */
01284
01285     END_REPEAT:
01286     previous = NULL;
01287     break;
01288
01289
01290     /* Start of nested bracket sub-expression, or comment or lookahead or
01291     lookbehind or option setting or condition. First deal with special things
01292     that can come after a bracket; all are introduced by ?, and the appearance
01293     of any of them means that this is not a referencing group. They were
01294     checked for validity in the first pass over the string, so we don't have to
01295     check for syntax errors here.  */
01296
01297     case '(':
01298     newoptions = options;
01299     condref = -1;
01300
01301     if (*(++ptr) == '?')
01302       {
01303       int set, unset;
01304       int *optset;
01305
01306       switch (*(++ptr))
01307         {
01308         case '#':                 /* Comment; skip to ket */
01309         ptr++;
01310         while (*ptr != ')') ptr++;
01311         continue;
01312
01313         case ':':                 /* Non-extracting bracket */
01314         bravalue = OP_BRA;
01315         ptr++;
01316         break;
01317
01318         case '(':
01319         bravalue = OP_COND;       /* Conditional group */
01320         if ((cd->ctypes[*(++ptr)] & ctype_digit) != 0)
01321           {
01322           condref = *ptr - '0';
01323           while (*(++ptr) != ')') condref = condref*10 + *ptr - '0';
01324           ptr++;
01325           }
01326         else ptr--;
01327         break;
01328
01329         case '=':                 /* Positive lookahead */
01330         bravalue = OP_ASSERT;
01331         ptr++;
01332         break;
01333
01334         case '!':                 /* Negative lookahead */
01335         bravalue = OP_ASSERT_NOT;
01336         ptr++;
01337         break;
01338
01339         case '<':                 /* Lookbehinds */
01340         switch (*(++ptr))
01341           {
01342           case '=':               /* Positive lookbehind */
01343           bravalue = OP_ASSERTBACK;
01344           ptr++;
01345           break;
01346
01347           case '!':               /* Negative lookbehind */
01348           bravalue = OP_ASSERTBACK_NOT;
01349           ptr++;
01350           break;
01351
01352           default:                /* Syntax error */
01353           *errorptr = ERR24;
01354           goto FAILED;
01355           }
01356         break;
01357
01358         case '>':                 /* One-time brackets */
01359         bravalue = OP_ONCE;
01360         ptr++;
01361         break;
01362
01363         default:                  /* Option setting */
01364         set = unset = 0;
01365         optset = &set;
01366
01367         while (*ptr != ')' && *ptr != ':')
01368           {
01369           switch (*ptr++)
01370             {
01371             case '-': optset = &unset; break;
01372
01373             case 'i': *optset |= PCRE_CASELESS; break;
01374             case 'm': *optset |= PCRE_MULTILINE; break;
01375             case 's': *optset |= PCRE_DOTALL; break;
01376             case 'x': *optset |= PCRE_EXTENDED; break;
01377             case 'U': *optset |= PCRE_UNGREEDY; break;
01378             case 'X': *optset |= PCRE_EXTRA; break;
01379
01380             default:
01381             *errorptr = ERR12;
01382             goto FAILED;
01383             }
01384           }
01385
01386         /* Set up the changed option bits, but don't change anything yet. */
01387
01388         newoptions = (options | set) & (~unset);
01389
01390         /* If the options ended with ')' this is not the start of a nested
01391         group with option changes, so the options change at this level. At top
01392         level there is nothing else to be done (the options will in fact have
01393         been set from the start of compiling as a result of the first pass) but
01394         at an inner level we must compile code to change the ims options if
01395         necessary, and pass the new setting back so that it can be put at the
01396         start of any following branches, and when this group ends, a resetting
01397         item can be compiled. */
01398
01399         if (*ptr == ')')
01400           {
01401           if ((options & PCRE_INGROUP) != 0 &&
01402               (options & PCRE_IMS) != (newoptions & PCRE_IMS))
01403             {
01404             *code++ = OP_OPT;
01405             *code++ = *optchanged = newoptions & PCRE_IMS;
01406             }
01407           options = newoptions;  /* Change options at this level */
01408           previous = NULL;       /* This item can't be repeated */
01409           continue;              /* It is complete */
01410           }
01411
01412         /* If the options ended with ':' we are heading into a nested group
01413         with possible change of options. Such groups are non-capturing and are
01414         not assertions of any kind. All we need to do is skip over the ':';
01415         the newoptions value is handled below. */
01416
01417         bravalue = OP_BRA;
01418         ptr++;
01419         }
01420       }
01421
01422     /* Else we have a referencing group; adjust the opcode. */
01423
01424     else
01425       {
01426       if (++(*brackets) > EXTRACT_MAX)
01427         {
01428         *errorptr = ERR13;
01429         goto FAILED;
01430         }
01431       bravalue = OP_BRA + *brackets;
01432       }
01433
01434     /* Process nested bracketed re. Assertions may not be repeated, but other
01435     kinds can be. We copy code into a non-register variable in order to be able
01436     to pass its address because some compilers complain otherwise. Pass in a
01437     new setting for the ims options if they have changed. */
01438
01439     previous = (bravalue >= OP_ONCE)? code : NULL;
01440     *code = bravalue;
01441     tempcode = code;
01442
01443     if (!compile_regex(
01444          options | PCRE_INGROUP,       /* Set for all nested groups */
01445          ((options & PCRE_IMS) != (newoptions & PCRE_IMS))?
01446            newoptions & PCRE_IMS : -1, /* Pass ims options if changed */
01447          brackets,                     /* Bracket level */
01448          &tempcode,                    /* Where to put code (updated) */
01449          &ptr,                         /* Input pointer (updated) */
01450          errorptr,                     /* Where to put an error message */
01451          (bravalue == OP_ASSERTBACK ||
01452           bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
01453          condref,                      /* Condition reference number */
01454          &subreqchar,                  /* For possible last char */
01455          &subcountlits,                /* For literal count */
01456          cd))                          /* Tables block */
01457       goto FAILED;
01458
01459     /* At the end of compiling, code is still pointing to the start of the
01460     group, while tempcode has been updated to point past the end of the group
01461     and any option resetting that may follow it. The pattern pointer (ptr)
01462     is on the bracket. */
01463
01464     /* If this is a conditional bracket, check that there are no more than
01465     two branches in the group. */
01466
01467     if (bravalue == OP_COND)
01468       {
01469       uschar *tc = code;
01470       condcount = 0;
01471
01472       do {
01473          condcount++;
01474          tc += (tc[1] << 8) | tc[2];
01475          }
01476       while (*tc != OP_KET);
01477
01478       if (condcount > 2)
01479         {
01480         *errorptr = ERR27;
01481         goto FAILED;
01482         }
01483       }
01484
01485     /* Handle updating of the required character. If the subpattern didn't
01486     set one, leave it as it was. Otherwise, update it for normal brackets of
01487     all kinds, forward assertions, and conditions with two branches. Don't
01488     update the literal count for forward assertions, however. If the bracket
01489     is followed by a quantifier with zero repeat, we have to back off. Hence
01490     the definition of prevreqchar and subcountlits outside the main loop so
01491     that they can be accessed for the back off. */
01492
01493     if (subreqchar > 0 &&
01494          (bravalue >= OP_BRA || bravalue == OP_ONCE || bravalue == OP_ASSERT ||
01495          (bravalue == OP_COND && condcount == 2)))
01496       {
01497       prevreqchar = *reqchar;
01498       *reqchar = subreqchar;
01499       if (bravalue != OP_ASSERT) *countlits += subcountlits;
01500       }
01501
01502     /* Now update the main code pointer to the end of the group. */
01503
01504     code = tempcode;
01505
01506     /* Error if hit end of pattern */
01507
01508     if (*ptr != ')')
01509       {
01510       *errorptr = ERR14;
01511       goto FAILED;
01512       }
01513     break;
01514
01515     /* Check \ for being a real metacharacter; if not, fall through and handle
01516     it as a data character at the start of a string. Escape items are checked
01517     for validity in the pre-compiling pass. */
01518
01519     case '\\':
01520     tempptr = ptr;
01521     c = check_escape(&ptr, errorptr, *brackets, options, FALSE, cd);
01522
01523     /* Handle metacharacters introduced by \. For ones like \d, the ESC_ values
01524     are arranged to be the negation of the corresponding OP_values. For the
01525     back references, the values are ESC_REF plus the reference number. Only
01526     back references and those types that consume a character may be repeated.
01527     We can test for values between ESC_b and ESC_Z for the latter; this may
01528     have to change if any new ones are ever created. */
01529
01530     if (c < 0)
01531       {
01532       if (-c >= ESC_REF)
01533         {
01534         previous = code;
01535         *code++ = OP_REF;
01536         *code++ = -c - ESC_REF;
01537         }
01538       else
01539         {
01540         previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
01541         *code++ = -c;
01542         }
01543       continue;
01544       }
01545
01546     /* Data character: reset and fall through */
01547
01548     ptr = tempptr;
01549     c = '\\';
01550
01551     /* Handle a run of data characters until a metacharacter is encountered.
01552     The first character is guaranteed not to be whitespace or # when the
01553     extended flag is set. */
01554
01555     NORMAL_CHAR:
01556     default:
01557     previous = code;
01558     *code = OP_CHARS;
01559     code += 2;
01560     length = 0;
01561
01562     do
01563       {
01564       if ((options & PCRE_EXTENDED) != 0)
01565         {
01566         if ((cd->ctypes[c] & ctype_space) != 0) continue;
01567         if (c == '#')
01568           {
01569           while ((c = *(++ptr)) != 0 && c != '\n');
01570           if (c == 0) break;
01571           continue;
01572           }
01573         }
01574
01575       /* Backslash may introduce a data char or a metacharacter. Escaped items
01576       are checked for validity in the pre-compiling pass. Stop the string
01577       before a metaitem. */
01578
01579       if (c == '\\')
01580         {
01581         tempptr = ptr;
01582         c = check_escape(&ptr, errorptr, *brackets, options, FALSE, cd);
01583         if (c < 0) { ptr = tempptr; break; }
01584         }
01585
01586       /* Ordinary character or single-char escape */
01587
01588       *code++ = c;
01589       length++;
01590       }
01591
01592     /* This "while" is the end of the "do" above. */
01593
01594     while (length < 255 && (cd->ctypes[c = *(++ptr)] & ctype_meta) == 0);
01595
01596     /* Update the last character and the count of literals */
01597
01598     prevreqchar = (length > 1)? code[-2] : *reqchar;
01599     *reqchar = code[-1];
01600     *countlits += length;
01601
01602     /* Compute the length and set it in the data vector, and advance to
01603     the next state. */
01604
01605     previous[1] = length;
01606     if (length < 255) ptr--;
01607     break;
01608     }
01609   }                   /* end of big loop */
01610
01611 /* Control never reaches here by falling through, only by a goto for all the
01612 error states. Pass back the position in the pattern so that it can be displayed
01613 to the user for diagnosing the error. */
01614
01615 FAILED:
01616 *ptrptr = ptr;
01617 return FALSE;
01618 }
01619
01620
01621
01622
01623 /*************************************************
01624 *     Compile sequence of alternatives           *
01625 *************************************************/
01626
01627 /* On entry, ptr is pointing past the bracket character, but on return
01628 it points to the closing bracket, or vertical bar, or end of string.
01629 The code variable is pointing at the byte into which the BRA operator has been
01630 stored. If the ims options are changed at the start (for a (?ims: group) or
01631 during any branch, we need to insert an OP_OPT item at the start of every
01632 following branch to ensure they get set correctly at run time, and also pass
01633 the new options into every subsequent branch compile.
01634
01635 Argument:
01636   options     the option bits
01637   optchanged  new ims options to set as if (?ims) were at the start, or -1
01638                for no change
01639   brackets    -> int containing the number of extracting brackets used
01640   codeptr     -> the address of the current code pointer
01641   ptrptr      -> the address of the current pattern pointer
01642   errorptr    -> pointer to error message
01643   lookbehind  TRUE if this is a lookbehind assertion
01644   condref     > 0 for OPT_CREF setting at start of conditional group
01645   reqchar     -> place to put the last required character, or a negative number
01646   countlits   -> place to put the shortest literal count of any branch
01647   cd          points to the data block with tables pointers
01648
01649 Returns:      TRUE on success
01650 */
01651
01652 static BOOL
01653 compile_regex(int options, int optchanged, int *brackets, uschar **codeptr,
01654   const uschar **ptrptr, const char **errorptr, BOOL lookbehind, int condref,
01655   int *reqchar, int *countlits, compile_data *cd)
01656 {
01657 const uschar *ptr = *ptrptr;
01658 uschar *code = *codeptr;
01659 uschar *last_branch = code;
01660 uschar *start_bracket = code;
01661 uschar *reverse_count = NULL;
01662 int oldoptions = options & PCRE_IMS;
01663 int branchreqchar, branchcountlits;
01664
01665 *reqchar = -1;
01666 *countlits = PCRE_MAX_POS;
01667 code += 3;
01668
01669 /* At the start of a reference-based conditional group, insert the reference
01670 number as an OP_CREF item. */
01671
01672 if (condref > 0)
01673   {
01674   *code++ = OP_CREF;
01675   *code++ = condref;
01676   }
01677
01678 /* Loop for each alternative branch */
01679
01680 for (;;)
01681   {
01682   int length;
01683
01684   /* Handle change of options */
01685
01686   if (optchanged >= 0)
01687     {
01688     *code++ = OP_OPT;
01689     *code++ = optchanged;
01690     options = (options & ~PCRE_IMS) | optchanged;
01691     }
01692
01693   /* Set up dummy OP_REVERSE if lookbehind assertion */
01694
01695   if (lookbehind)
01696     {
01697     *code++ = OP_REVERSE;
01698     reverse_count = code;
01699     *code++ = 0;
01700     *code++ = 0;
01701     }
01702
01703   /* Now compile the branch */
01704
01705   if (!compile_branch(options, brackets, &code, &ptr, errorptr, &optchanged,
01706       &branchreqchar, &branchcountlits, cd))
01707     {
01708     *ptrptr = ptr;
01709     return FALSE;
01710     }
01711
01712   /* Fill in the length of the last branch */
01713
01714   length = code - last_branch;
01715   last_branch[1] = length >> 8;
01716   last_branch[2] = length & 255;
01717
01718   /* Save the last required character if all branches have the same; a current
01719   value of -1 means unset, while -2 means "previous branch had no last required
01720   char".  */
01721
01722   if (*reqchar != -2)
01723     {
01724     if (branchreqchar >= 0)
01725       {
01726       if (*reqchar == -1) *reqchar = branchreqchar;
01727       else if (*reqchar != branchreqchar) *reqchar = -2;
01728       }
01729     else *reqchar = -2;
01730     }
01731
01732   /* Keep the shortest literal count */
01733
01734   if (branchcountlits < *countlits) *countlits = branchcountlits;
01735   DPRINTF(("literal count = %d min=%d\n", branchcountlits, *countlits));
01736
01737   /* If lookbehind, check that this branch matches a fixed-length string,
01738   and put the length into the OP_REVERSE item. Temporarily mark the end of
01739   the branch with OP_END. */
01740
01741   if (lookbehind)
01742     {
01743     *code = OP_END;
01744     length = find_fixedlength(last_branch);
01745     DPRINTF(("fixed length = %d\n", length));
01746     if (length < 0)
01747       {
01748       *errorptr = ERR25;
01749       *ptrptr = ptr;
01750       return FALSE;
01751       }
01752     reverse_count[0] = (length >> 8);
01753     reverse_count[1] = length & 255;
01754     }
01755
01756   /* Reached end of expression, either ')' or end of pattern. Insert a
01757   terminating ket and the length of the whole bracketed item, and return,
01758   leaving the pointer at the terminating char. If any of the ims options
01759   were changed inside the group, compile a resetting op-code following. */
01760
01761   if (*ptr != '|')
01762     {
01763     length = code - start_bracket;
01764     *code++ = OP_KET;
01765     *code++ = length >> 8;
01766     *code++ = length & 255;
01767     if (optchanged >= 0)
01768       {
01769       *code++ = OP_OPT;
01770       *code++ = oldoptions;
01771       }
01772     *codeptr = code;
01773     *ptrptr = ptr;
01774     return TRUE;
01775     }
01776
01777   /* Another branch follows; insert an "or" node and advance the pointer. */
01778
01779   *code = OP_ALT;
01780   last_branch = code;
01781   code += 3;
01782   ptr++;
01783   }
01784 /* Control never reaches here */
01785 }
01786
01787
01788
01789
01790 /*************************************************
01791 *      Find first significant op code            *
01792 *************************************************/
01793
01794 /* This is called by several functions that scan a compiled expression looking
01795 for a fixed first character, or an anchoring op code etc. It skips over things
01796 that do not influence this. For one application, a change of caseless option is
01797 important.
01798
01799 Arguments:
01800   code       pointer to the start of the group
01801   options    pointer to external options
01802   optbit     the option bit whose changing is significant, or
01803              zero if none are
01804   optstop    TRUE to return on option change, otherwise change the options
01805                value and continue
01806
01807 Returns:     pointer to the first significant opcode
01808 */
01809
01810 static const uschar*
01811 first_significant_code(const uschar *code, int *options, int optbit,
01812   BOOL optstop)
01813 {
01814 for (;;)
01815   {
01816   switch ((int)*code)
01817     {
01818     case OP_OPT:
01819     if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit))
01820       {
01821       if (optstop) return code;
01822       *options = (int)code[1];
01823       }
01824     code += 2;
01825     break;
01826
01827     case OP_CREF:
01828     code += 2;
01829     break;
01830
01831     case OP_WORD_BOUNDARY:
01832     case OP_NOT_WORD_BOUNDARY:
01833     code++;
01834     break;
01835
01836     case OP_ASSERT_NOT:
01837     case OP_ASSERTBACK:
01838     case OP_ASSERTBACK_NOT:
01839     do code += (code[1] << 8) + code[2]; while (*code == OP_ALT);
01840     code += 3;
01841     break;
01842
01843     default:
01844     return code;
01845     }
01846   }
01847 /* Control never reaches here */
01848 }
01849
01850
01851
01852
01853 /*************************************************
01854 *          Check for anchored expression         *
01855 *************************************************/
01856
01857 /* Try to find out if this is an anchored regular expression. Consider each
01858 alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
01859 all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
01860 it's anchored. However, if this is a multiline pattern, then only OP_SOD
01861 counts, since OP_CIRC can match in the middle.
01862
01863 A branch is also implicitly anchored if it starts with .* and DOTALL is set,
01864 because that will try the rest of the pattern at all possible matching points,
01865 so there is no point trying them again.
01866
01867 Arguments:
01868   code       points to start of expression (the bracket)
01869   options    points to the options setting
01870
01871 Returns:     TRUE or FALSE
01872 */
01873
01874 static BOOL
01875 is_anchored(register const uschar *code, int *options)
01876 {
01877 do {
01878    const uschar *scode = first_significant_code(code + 3, options,
01879      PCRE_MULTILINE, FALSE);
01880    register int op = *scode;
01881    if (op >= OP_BRA || op == OP_ASSERT || op == OP_ONCE || op == OP_COND)
01882      { if (!is_anchored(scode, options)) return FALSE; }
01883    else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR) &&
01884             (*options & PCRE_DOTALL) != 0)
01885      { if (scode[1] != OP_ANY) return FALSE; }
01886    else if (op != OP_SOD &&
01887            ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC))
01888      return FALSE;
01889    code += (code[1] << 8) + code[2];
01890    }
01891 while (*code == OP_ALT);
01892 return TRUE;
01893 }
01894
01895
01896
01897 /*************************************************
01898 *         Check for starting with ^ or .*        *
01899 *************************************************/
01900
01901 /* This is called to find out if every branch starts with ^ or .* so that
01902 "first char" processing can be done to speed things up in multiline
01903 matching and for non-DOTALL patterns that start with .* (which must start at
01904 the beginning or after \n).
01905
01906 Argument:  points to start of expression (the bracket)
01907 Returns:   TRUE or FALSE
01908 */
01909
01910 static BOOL
01911 is_startline(const uschar *code)
01912 {
01913 do {
01914    const uschar *scode = first_significant_code(code + 3, NULL, 0, FALSE);
01915    register int op = *scode;
01916    if (op >= OP_BRA || op == OP_ASSERT || op == OP_ONCE || op == OP_COND)
01917      { if (!is_startline(scode)) return FALSE; }
01918    else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR)
01919      { if (scode[1] != OP_ANY) return FALSE; }
01920    else if (op != OP_CIRC) return FALSE;
01921    code += (code[1] << 8) + code[2];
01922    }
01923 while (*code == OP_ALT);
01924 return TRUE;
01925 }
01926
01927
01928
01929 /*************************************************
01930 *          Check for fixed first char            *
01931 *************************************************/
01932
01933 /* Try to find out if there is a fixed first character. This is called for
01934 unanchored expressions, as it speeds up their processing quite considerably.
01935 Consider each alternative branch. If they all start with the same char, or with
01936 a bracket all of whose alternatives start with the same char (recurse ad lib),
01937 then we return that char, otherwise -1.
01938
01939 Arguments:
01940   code       points to start of expression (the bracket)
01941   options    pointer to the options (used to check casing changes)
01942
01943 Returns:     -1 or the fixed first char
01944 */
01945
01946 static int
01947 find_firstchar(const uschar *code, int *options)
01948 {
01949 register int c = -1;
01950 do {
01951    int d;
01952    const uschar *scode = first_significant_code(code + 3, options,
01953      PCRE_CASELESS, TRUE);
01954    register int op = *scode;
01955
01956    if (op >= OP_BRA) op = OP_BRA;
01957
01958    switch(op)
01959      {
01960      default:
01961      return -1;
01962
01963      case OP_BRA:
01964      case OP_ASSERT:
01965      case OP_ONCE:
01966      case OP_COND:
01967      if ((d = find_firstchar(scode, options)) < 0) return -1;
01968      if (c < 0) c = d; else if (c != d) return -1;
01969      break;
01970
01971      case OP_EXACT:       /* Fall through */
01972      scode++;
01973
01974      case OP_CHARS:       /* Fall through */
01975      scode++;
01976
01977      case OP_PLUS:
01978      case OP_MINPLUS:
01979      if (c < 0) c = scode[1]; else if (c != scode[1]) return -1;
01980      break;
01981      }
01982
01983    code += (code[1] << 8) + code[2];
01984    }
01985 while (*code == OP_ALT);
01986 return c;
01987 }
01988
01989
01990
01991
01992
01993 /*************************************************
01994 *        Compile a Regular Expression            *
01995 *************************************************/
01996
01997 /* This function takes a string and returns a pointer to a block of store
01998 holding a compiled version of the expression.
01999
02000 Arguments:
02001   pattern      the regular expression
02002   options      various option bits
02003   errorptr     pointer to pointer to error text
02004   erroroffset  ptr offset in pattern where error was detected
02005   tables       pointer to character tables or NULL
02006
02007 Returns:       pointer to compiled data block, or NULL on error,
02008                with errorptr and erroroffset set
02009 */
02010
02011 pcre *
02012 pcre_compile(const char *pattern, int options, const char **errorptr,
02013   int *erroroffset, const unsigned char *tables)
02014 {
02015 real_pcre *re;
02016 int length = 3;      /* For initial BRA plus length */
02017 int runlength;
02018 int c, size, reqchar, countlits;
02019 int bracount = 0;
02020 int top_backref = 0;
02021 int branch_extra = 0;
02022 int branch_newextra;
02023 unsigned int brastackptr = 0;
02024 uschar *code;
02025 const uschar *ptr;
02026 compile_data compile_block;
02027 int brastack[BRASTACK_SIZE];
02028 uschar bralenstack[BRASTACK_SIZE];
02029
02030 #ifdef DEBUG
02031 uschar *code_base, *code_end;
02032 #endif
02033
02034 /* We can't pass back an error message if errorptr is NULL; I guess the best we
02035 can do is just return NULL. */
02036
02037 if (errorptr == NULL) return NULL;
02038 *errorptr = NULL;
02039
02040 /* However, we can give a message for this error */
02041
02042 if (erroroffset == NULL)
02043   {
02044   *errorptr = ERR16;
02045   return NULL;
02046   }
02047 *erroroffset = 0;
02048
02049 if ((options & ~PUBLIC_OPTIONS) != 0)
02050   {
02051   *errorptr = ERR17;
02052   return NULL;
02053   }
02054
02055 /* Set up pointers to the individual character tables */
02056
02057 if (tables == NULL) tables = pcre_default_tables;
02058 compile_block.lcc = tables + lcc_offset;
02059 compile_block.fcc = tables + fcc_offset;
02060 compile_block.cbits = tables + cbits_offset;
02061 compile_block.ctypes = tables + ctypes_offset;
02062
02063 /* Reflect pattern for debugging output */
02064
02065 DPRINTF(("------------------------------------------------------------------\n"));
02066 DPRINTF(("%s\n", pattern));
02067
02068 /* The first thing to do is to make a pass over the pattern to compute the
02069 amount of store required to hold the compiled code. This does not have to be
02070 perfect as long as errors are overestimates. At the same time we can detect any
02071 internal flag settings. Make an attempt to correct for any counted white space
02072 if an "extended" flag setting appears late in the pattern. We can't be so
02073 clever for #-comments. */
02074
02075 ptr = (const uschar *)(pattern - 1);
02076 while ((c = *(++ptr)) != 0)
02077   {
02078   int min, max;
02079   int class_charcount;
02080
02081   if ((options & PCRE_EXTENDED) != 0)
02082     {
02083     if ((compile_block.ctypes[c] & ctype_space) != 0) continue;
02084     if (c == '#')
02085       {
02086       while ((c = *(++ptr)) != 0 && c != '\n');
02087       continue;
02088       }
02089     }
02090
02091   switch(c)
02092     {
02093     /* A backslashed item may be an escaped "normal" character or a
02094     character type. For a "normal" character, put the pointers and
02095     character back so that tests for whitespace etc. in the input
02096     are done correctly. */
02097
02098     case '\\':
02099       {
02100       const uschar *save_ptr = ptr;
02101       c = check_escape(&ptr, errorptr, bracount, options, FALSE, &compile_block);
02102       if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02103       if (c >= 0)
02104         {
02105         ptr = save_ptr;
02106         c = '\\';
02107         goto NORMAL_CHAR;
02108         }
02109       }
02110     length++;
02111
02112     /* A back reference needs an additional char, plus either one or 5
02113     bytes for a repeat. We also need to keep the value of the highest
02114     back reference. */
02115
02116     if (c <= -ESC_REF)
02117       {
02118       int refnum = -c - ESC_REF;
02119       if (refnum > top_backref) top_backref = refnum;
02120       length++;   /* For single back reference */
02121       if (ptr[1] == '{' && is_counted_repeat(ptr+2, &compile_block))
02122         {
02123         ptr = read_repeat_counts(ptr+2, &min, &max, errorptr, &compile_block);
02124         if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02125         if ((min == 0 && (max == 1 || max == -1)) ||
02126           (min == 1 && max == -1))
02127             length++;
02128         else length += 5;
02129         if (ptr[1] == '?') ptr++;
02130         }
02131       }
02132     continue;
02133
02134     case '^':
02135     case '.':
02136     case '$':
02137     case '*':     /* These repeats won't be after brackets; */
02138     case '+':     /* those are handled separately */
02139     case '?':
02140     length++;
02141     continue;
02142
02143     /* This covers the cases of repeats after a single char, metachar, class,
02144     or back reference. */
02145
02146     case '{':
02147     if (!is_counted_repeat(ptr+1, &compile_block)) goto NORMAL_CHAR;
02148     ptr = read_repeat_counts(ptr+1, &min, &max, errorptr, &compile_block);
02149     if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02150     if ((min == 0 && (max == 1 || max == -1)) ||
02151       (min == 1 && max == -1))
02152         length++;
02153     else
02154       {
02155       length--;   /* Uncount the original char or metachar */
02156       if (min == 1) length++; else if (min > 0) length += 4;
02157       if (max > 0) length += 4; else length += 2;
02158       }
02159     if (ptr[1] == '?') ptr++;
02160     continue;
02161
02162     /* An alternation contains an offset to the next branch or ket. If any ims
02163     options changed in the previous branch(es), and/or if we are in a
02164     lookbehind assertion, extra space will be needed at the start of the
02165     branch. This is handled by branch_extra. */
02166
02167     case '|':
02168     length += 3 + branch_extra;
02169     continue;
02170
02171     /* A character class uses 33 characters. Don't worry about character types
02172     that aren't allowed in classes - they'll get picked up during the compile.
02173     A character class that contains only one character uses 2 or 3 bytes,
02174     depending on whether it is negated or not. Notice this where we can. */
02175
02176     case '[':
02177     class_charcount = 0;
02178     if (*(++ptr) == '^') ptr++;
02179     do
02180       {
02181       if (*ptr == '\\')
02182         {
02183         int ch = check_escape(&ptr, errorptr, bracount, options, TRUE,
02184           &compile_block);
02185         if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02186         if (-ch == ESC_b) class_charcount++; else class_charcount = 10;
02187         }
02188       else class_charcount++;
02189       ptr++;
02190       }
02191     while (*ptr != 0 && *ptr != ']');
02192
02193     /* Repeats for negated single chars are handled by the general code */
02194
02195     if (class_charcount == 1) length += 3; else
02196       {
02197       length += 33;
02198
02199       /* A repeat needs either 1 or 5 bytes. */
02200
02201       if (*ptr != 0 && ptr[1] == '{' && is_counted_repeat(ptr+2, &compile_block))
02202         {
02203         ptr = read_repeat_counts(ptr+2, &min, &max, errorptr, &compile_block);
02204         if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02205         if ((min == 0 && (max == 1 || max == -1)) ||
02206           (min == 1 && max == -1))
02207             length++;
02208         else length += 5;
02209         if (ptr[1] == '?') ptr++;
02210         }
02211       }
02212     continue;
02213
02214     /* Brackets may be genuine groups or special things */
02215
02216     case '(':
02217     branch_newextra = 0;
02218
02219     /* Handle special forms of bracket, which all start (? */
02220
02221     if (ptr[1] == '?')
02222       {
02223       int set, unset;
02224       int *optset;
02225
02226       switch (c = ptr[2])
02227         {
02228         /* Skip over comments entirely */
02229         case '#':
02230         ptr += 3;
02231         while (*ptr != 0 && *ptr != ')') ptr++;
02232         if (*ptr == 0)
02233           {
02234           *errorptr = ERR18;
02235           goto PCRE_ERROR_RETURN;
02236           }
02237         continue;
02238
02239         /* Non-referencing groups and lookaheads just move the pointer on, and
02240         then behave like a non-special bracket, except that they don't increment
02241         the count of extracting brackets. Ditto for the "once only" bracket,
02242         which is in Perl from version 5.005. */
02243
02244         case ':':
02245         case '=':
02246         case '!':
02247         case '>':
02248         ptr += 2;
02249         break;
02250
02251         /* Lookbehinds are in Perl from version 5.005 */
02252
02253         case '<':
02254         if (ptr[3] == '=' || ptr[3] == '!')
02255           {
02256           ptr += 3;
02257           branch_newextra = 3;
02258           length += 3;         /* For the first branch */
02259           break;
02260           }
02261         *errorptr = ERR24;
02262         goto PCRE_ERROR_RETURN;
02263
02264         /* Conditionals are in Perl from version 5.005. The bracket must either
02265         be followed by a number (for bracket reference) or by an assertion
02266         group. */
02267
02268         case '(':
02269         if ((compile_block.ctypes[ptr[3]] & ctype_digit) != 0)
02270           {
02271           ptr += 4;
02272           length += 2;
02273           while ((compile_block.ctypes[*ptr] & ctype_digit) != 0) ptr++;
02274           if (*ptr != ')')
02275             {
02276             *errorptr = ERR26;
02277             goto PCRE_ERROR_RETURN;
02278             }
02279           }
02280         else   /* An assertion must follow */
02281           {
02282           ptr++;   /* Can treat like ':' as far as spacing is concerned */
02283
02284           if (ptr[2] != '?' || strchr("=!<", ptr[3]) == NULL)
02285             {
02286             ptr += 2;    /* To get right offset in message */
02287             *errorptr = ERR28;
02288             goto PCRE_ERROR_RETURN;
02289             }
02290           }
02291         break;
02292
02293         /* Else loop checking valid options until ) is met. Anything else is an
02294         error. If we are without any brackets, i.e. at top level, the settings
02295         act as if specified in the options, so massage the options immediately.
02296         This is for backward compatibility with Perl 5.004. */
02297
02298         default:
02299         set = unset = 0;
02300         optset = &set;
02301         ptr += 2;
02302
02303         for (;; ptr++)
02304           {
02305           c = *ptr;
02306           switch (c)
02307             {
02308             case 'i':
02309             *optset |= PCRE_CASELESS;
02310             continue;
02311
02312             case 'm':
02313             *optset |= PCRE_MULTILINE;
02314             continue;
02315
02316             case 's':
02317             *optset |= PCRE_DOTALL;
02318             continue;
02319
02320             case 'x':
02321             *optset |= PCRE_EXTENDED;
02322             continue;
02323
02324             case 'X':
02325             *optset |= PCRE_EXTRA;
02326             continue;
02327
02328             case 'U':
02329             *optset |= PCRE_UNGREEDY;
02330             continue;
02331
02332             case '-':
02333             optset = &unset;
02334             continue;
02335
02336             /* A termination by ')' indicates an options-setting-only item;
02337             this is global at top level; otherwise nothing is done here and
02338             it is handled during the compiling process on a per-bracket-group
02339             basis. */
02340
02341             case ')':
02342             if (brastackptr == 0)
02343               {
02344               options = (options | set) & (~unset);
02345               set = unset = 0;     /* To save length */
02346               }
02347             /* Fall through */
02348
02349             /* A termination by ':' indicates the start of a nested group with
02350             the given options set. This is again handled at compile time, but
02351             we must allow for compiled space if any of the ims options are
02352             set. We also have to allow for resetting space at the end of
02353             the group, which is why 4 is added to the length and not just 2.
02354             If there are several changes of options within the same group, this
02355             will lead to an over-estimate on the length, but this shouldn't
02356             matter very much. We also have to allow for resetting options at
02357             the start of any alternations, which we do by setting
02358             branch_newextra to 2. Finally, we record whether the case-dependent
02359             flag ever changes within the regex. This is used by the "required
02360             character" code. */
02361
02362             case ':':
02363             if (((set|unset) & PCRE_IMS) != 0)
02364               {
02365               length += 4;
02366               branch_newextra = 2;
02367               if (((set|unset) & PCRE_CASELESS) != 0) options |= PCRE_ICHANGED;
02368               }
02369             goto END_OPTIONS;
02370
02371             /* Unrecognized option character */
02372
02373             default:
02374             *errorptr = ERR12;
02375             goto PCRE_ERROR_RETURN;
02376             }
02377           }
02378
02379         /* If we hit a closing bracket, that's it - this is a freestanding
02380         option-setting. We need to ensure that branch_extra is updated if
02381         necessary. The only values branch_newextra can have here are 0 or 2.
02382         If the value is 2, then branch_extra must either be 2 or 5, depending
02383         on whether this is a lookbehind group or not. */
02384
02385         END_OPTIONS:
02386         if (c == ')')
02387           {
02388           if (branch_newextra == 2 && (branch_extra == 0 || branch_extra == 3))
02389             branch_extra += branch_newextra;
02390           continue;
02391           }
02392
02393         /* If options were terminated by ':' control comes here. Fall through
02394         to handle the group below. */
02395         }
02396       }
02397
02398     /* Extracting brackets must be counted so we can process escapes in a
02399     Perlish way. */
02400
02401     else bracount++;
02402
02403     /* Non-special forms of bracket. Save length for computing whole length
02404     at end if there's a repeat that requires duplication of the group. Also
02405     save the current value of branch_extra, and start the new group with
02406     the new value. If non-zero, this will either be 2 for a (?imsx: group, or 3
02407     for a lookbehind assertion. */
02408
02409     if (brastackptr >= sizeof(brastack)/sizeof(int))
02410       {
02411       *errorptr = ERR19;
02412       goto PCRE_ERROR_RETURN;
02413       }
02414
02415     bralenstack[brastackptr] = branch_extra;
02416     branch_extra = branch_newextra;
02417
02418     brastack[brastackptr++] = length;
02419     length += 3;
02420     continue;
02421
02422     /* Handle ket. Look for subsequent max/min; for certain sets of values we
02423     have to replicate this bracket up to that many times. If brastackptr is
02424     0 this is an unmatched bracket which will generate an error, but take care
02425     not to try to access brastack[-1] when computing the length and restoring
02426     the branch_extra value. */
02427
02428     case ')':
02429     length += 3;
02430       {
02431       int minval = 1;
02432       int maxval = 1;
02433       int duplength;
02434
02435       if (brastackptr > 0)
02436         {
02437         duplength = length - brastack[--brastackptr];
02438         branch_extra = bralenstack[brastackptr];
02439         }
02440       else duplength = 0;
02441
02442       /* Leave ptr at the final char; for read_repeat_counts this happens
02443       automatically; for the others we need an increment. */
02444
02445       if ((c = ptr[1]) == '{' && is_counted_repeat(ptr+2, &compile_block))
02446         {
02447         ptr = read_repeat_counts(ptr+2, &minval, &maxval, errorptr,
02448           &compile_block);
02449         if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02450         }
02451       else if (c == '*') { minval = 0; maxval = -1; ptr++; }
02452       else if (c == '+') { maxval = -1; ptr++; }
02453       else if (c == '?') { minval = 0; ptr++; }
02454
02455       /* If the minimum is zero, we have to allow for an OP_BRAZERO before the
02456       group, and if the maximum is greater than zero, we have to replicate
02457       maxval-1 times; each replication acquires an OP_BRAZERO plus a nesting
02458       bracket set - hence the 7. */
02459
02460       if (minval == 0)
02461         {
02462         length++;
02463         if (maxval > 0) length += (maxval - 1) * (duplength + 7);
02464         }
02465
02466       /* When the minimum is greater than zero, 1 we have to replicate up to
02467       minval-1 times, with no additions required in the copies. Then, if
02468       there is a limited maximum we have to replicate up to maxval-1 times
02469       allowing for a BRAZERO item before each optional copy and nesting
02470       brackets for all but one of the optional copies. */
02471
02472       else
02473         {
02474         length += (minval - 1) * duplength;
02475         if (maxval > minval)   /* Need this test as maxval=-1 means no limit */
02476           length += (maxval - minval) * (duplength + 7) - 6;
02477         }
02478       }
02479     continue;
02480
02481     /* Non-special character. For a run of such characters the length required
02482     is the number of characters + 2, except that the maximum run length is 255.
02483     We won't get a skipped space or a non-data escape or the start of a #
02484     comment as the first character, so the length can't be zero. */
02485
02486     NORMAL_CHAR:
02487     default:
02488     length += 2;
02489     runlength = 0;
02490     do
02491       {
02492       if ((options & PCRE_EXTENDED) != 0)
02493         {
02494         if ((compile_block.ctypes[c] & ctype_space) != 0) continue;
02495         if (c == '#')
02496           {
02497           while ((c = *(++ptr)) != 0 && c != '\n');
02498           continue;
02499           }
02500         }
02501
02502       /* Backslash may introduce a data char or a metacharacter; stop the
02503       string before the latter. */
02504
02505       if (c == '\\')
02506         {
02507         const uschar *saveptr = ptr;
02508         c = check_escape(&ptr, errorptr, bracount, options, FALSE,
02509           &compile_block);
02510         if (*errorptr != NULL) goto PCRE_ERROR_RETURN;
02511         if (c < 0) { ptr = saveptr; break; }
02512         }
02513
02514       /* Ordinary character or single-char escape */
02515
02516       runlength++;
02517       }
02518
02519     /* This "while" is the end of the "do" above. */
02520
02521     while (runlength < 255 &&
02522       (compile_block.ctypes[c = *(++ptr)] & ctype_meta) == 0);
02523
02524     ptr--;
02525     length += runlength;
02526     continue;
02527     }
02528   }
02529
02530 length += 4;    /* For final KET and END */
02531
02532 if (length > 65539)
02533   {
02534   *errorptr = ERR20;
02535   return NULL;
02536   }
02537
02538 /* Compute the size of data block needed and get it, either from malloc or
02539 externally provided function. We specify "code[0]" in the offsetof() expression
02540 rather than just "code", because it has been reported that one broken compiler
02541 fails on "code" because it is also an independent variable. It should make no
02542 difference to the value of the offsetof(). */
02543
02544 size = length + offsetof(real_pcre, code[0]);
02545 re = (real_pcre *)(pcre_malloc)(size);
02546
02547 if (re == NULL)
02548   {
02549   *errorptr = ERR21;
02550   return NULL;
02551   }
02552
02553 /* Put in the magic number and the options. */
02554
02555 re->magic_number = MAGIC_NUMBER;
02556 re->options = options;
02557 re->tables = tables;
02558
02559 /* Set up a starting, non-extracting bracket, then compile the expression. On
02560 error, *errorptr will be set non-NULL, so we don't need to look at the result
02561 of the function here. */
02562
02563 ptr = (const uschar *)pattern;
02564 code = re->code;
02565 *code = OP_BRA;
02566 bracount = 0;
02567 (void)compile_regex(options, -1, &bracount, &code, &ptr, errorptr, FALSE, -1,
02568   &reqchar, &countlits, &compile_block);
02569 re->top_bracket = bracount;
02570 re->top_backref = top_backref;
02571
02572 /* If not reached end of pattern on success, there's an excess bracket. */
02573
02574 if (*errorptr == NULL && *ptr != 0) *errorptr = ERR22;
02575
02576 /* Fill in the terminating state and check for disastrous overflow, but
02577 if debugging, leave the test till after things are printed out. */
02578
02579 *code++ = OP_END;
02580
02581 #ifndef DEBUG
02582 if (code - re->code > length) *errorptr = ERR23;
02583 #endif
02584
02585 /* Give an error if there's back reference to a non-existent capturing
02586 subpattern. */
02587
02588 if (top_backref > re->top_bracket) *errorptr = ERR15;
02589
02590 /* Failed to compile */
02591
02592 if (*errorptr != NULL)
02593   {
02594   (pcre_free)(re);
02595   PCRE_ERROR_RETURN:
02596   *erroroffset = ptr - (const uschar *)pattern;
02597   return NULL;
02598   }
02599
02600 /* If the anchored option was not passed, set flag if we can determine that the
02601 pattern is anchored by virtue of ^ characters or \A or anything else (such as
02602 starting with .* when DOTALL is set).
02603
02604 Otherwise, see if we can determine what the first character has to be, because
02605 that speeds up unanchored matches no end. If not, see if we can set the
02606 PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
02607 start with ^. and also when all branches start with .* for non-DOTALL matches.
02608 */
02609
02610 if ((options & PCRE_ANCHORED) == 0)
02611   {
02612   int temp_options = options;
02613   if (is_anchored(re->code, &temp_options))
02614     re->options |= PCRE_ANCHORED;
02615   else
02616     {
02617     int ch = find_firstchar(re->code, &temp_options);
02618     if (ch >= 0)
02619       {
02620       re->first_char = ch;
02621       re->options |= PCRE_FIRSTSET;
02622       }
02623     else if (is_startline(re->code))
02624       re->options |= PCRE_STARTLINE;
02625     }
02626   }
02627
02628 /* Save the last required character if there are at least two literal
02629 characters on all paths, or if there is no first character setting. */
02630
02631 if (reqchar >= 0 && (countlits > 1 || (re->options & PCRE_FIRSTSET) == 0))
02632   {
02633   re->req_char = reqchar;
02634   re->options |= PCRE_REQCHSET;
02635   }
02636
02637 /* Print out the compiled data for debugging */
02638
02639 #ifdef DEBUG
02640
02641 printf("Length = %d top_bracket = %d top_backref = %d\n",
02642   length, re->top_bracket, re->top_backref);
02643
02644 if (re->options != 0)
02645   {
02646   printf("%s%s%s%s%s%s%s%s%s\n",
02647     ((re->options & PCRE_ANCHORED) != 0)? "anchored " : "",
02648     ((re->options & PCRE_CASELESS) != 0)? "caseless " : "",
02649     ((re->options & PCRE_ICHANGED) != 0)? "case state changed " : "",
02650     ((re->options & PCRE_EXTENDED) != 0)? "extended " : "",
02651     ((re->options & PCRE_MULTILINE) != 0)? "multiline " : "",
02652     ((re->options & PCRE_DOTALL) != 0)? "dotall " : "",
02653     ((re->options & PCRE_DOLLAR_ENDONLY) != 0)? "endonly " : "",
02654     ((re->options & PCRE_EXTRA) != 0)? "extra " : "",
02655     ((re->options & PCRE_UNGREEDY) != 0)? "ungreedy " : "");
02656   }
02657
02658 if ((re->options & PCRE_FIRSTSET) != 0)
02659   {
02660   if (isprint(re->first_char)) printf("First char = %c\n", re->first_char);
02661     else printf("First char = \\x%02x\n", re->first_char);
02662   }
02663
02664 if ((re->options & PCRE_REQCHSET) != 0)
02665   {
02666   if (isprint(re->req_char)) printf("Req char = %c\n", re->req_char);
02667     else printf("Req char = \\x%02x\n", re->req_char);
02668   }
02669
02670 code_end = code;
02671 code_base = code = re->code;
02672
02673 while (code < code_end)
02674   {
02675   int charlength;
02676
02677   printf("%3d ", code - code_base);
02678
02679   if (*code >= OP_BRA)
02680     {
02681     printf("%3d Bra %d", (code[1] << 8) + code[2], *code - OP_BRA);
02682     code += 2;
02683     }
02684
02685   else switch(*code)
02686     {
02687     case OP_OPT:
02688     printf(" %.2x %s", code[1], OP_names[*code]);
02689     code++;
02690     break;
02691
02692     case OP_COND:
02693     printf("%3d Cond", (code[1] << 8) + code[2]);
02694     code += 2;
02695     break;
02696
02697     case OP_CREF:
02698     printf(" %.2d %s", code[1], OP_names[*code]);
02699     code++;
02700     break;
02701
02702     case OP_CHARS:
02703     charlength = *(++code);
02704     printf("%3d ", charlength);
02705     while (charlength-- > 0)
02706       if (isprint(c = *(++code))) printf("%c", c); else printf("\\x%02x", c);
02707     break;
02708
02709     case OP_KETRMAX:
02710     case OP_KETRMIN:
02711     case OP_ALT:
02712     case OP_KET:
02713     case OP_ASSERT:
02714     case OP_ASSERT_NOT:
02715     case OP_ASSERTBACK:
02716     case OP_ASSERTBACK_NOT:
02717     case OP_ONCE:
02718     printf("%3d %s", (code[1] << 8) + code[2], OP_names[*code]);
02719     code += 2;
02720     break;
02721
02722     case OP_REVERSE:
02723     printf("%3d %s", (code[1] << 8) + code[2], OP_names[*code]);
02724     code += 2;
02725     break;
02726
02727     case OP_STAR:
02728     case OP_MINSTAR:
02729     case OP_PLUS:
02730     case OP_MINPLUS:
02731     case OP_QUERY:
02732     case OP_MINQUERY:
02733     case OP_TYPESTAR:
02734     case OP_TYPEMINSTAR:
02735     case OP_TYPEPLUS:
02736     case OP_TYPEMINPLUS:
02737     case OP_TYPEQUERY:
02738     case OP_TYPEMINQUERY:
02739     if (*code >= OP_TYPESTAR)
02740       printf("    %s", OP_names[code[1]]);
02741     else if (isprint(c = code[1])) printf("    %c", c);
02742       else printf("    \\x%02x", c);
02743     printf("%s", OP_names[*code++]);
02744     break;
02745
02746     case OP_EXACT:
02747     case OP_UPTO:
02748     case OP_MINUPTO:
02749     if (isprint(c = code[3])) printf("    %c{", c);
02750       else printf("    \\x%02x{", c);
02751     if (*code != OP_EXACT) printf("0,");
02752     printf("%d}", (code[1] << 8) + code[2]);
02753     if (*code == OP_MINUPTO) printf("?");
02754     code += 3;
02755     break;
02756
02757     case OP_TYPEEXACT:
02758     case OP_TYPEUPTO:
02759     case OP_TYPEMINUPTO:
02760     printf("    %s{", OP_names[code[3]]);
02761     if (*code != OP_TYPEEXACT) printf(",");
02762     printf("%d}", (code[1] << 8) + code[2]);
02763     if (*code == OP_TYPEMINUPTO) printf("?");
02764     code += 3;
02765     break;
02766
02767     case OP_NOT:
02768     if (isprint(c = *(++code))) printf("    [^%c]", c);
02769       else printf("    [^\\x%02x]", c);
02770     break;
02771
02772     case OP_NOTSTAR:
02773     case OP_NOTMINSTAR:
02774     case OP_NOTPLUS:
02775     case OP_NOTMINPLUS:
02776     case OP_NOTQUERY:
02777     case OP_NOTMINQUERY:
02778     if (isprint(c = code[1])) printf("    [^%c]", c);
02779       else printf("    [^\\x%02x]", c);
02780     printf("%s", OP_names[*code++]);
02781     break;
02782
02783     case OP_NOTEXACT:
02784     case OP_NOTUPTO:
02785     case OP_NOTMINUPTO:
02786     if (isprint(c = code[3])) printf("    [^%c]{", c);
02787       else printf("    [^\\x%02x]{", c);
02788     if (*code != OP_NOTEXACT) printf(",");
02789     printf("%d}", (code[1] << 8) + code[2]);
02790     if (*code == OP_NOTMINUPTO) printf("?");
02791     code += 3;
02792     break;
02793
02794     case OP_REF:
02795     printf("    \\%d", *(++code));
02796     code ++;
02797     goto CLASS_REF_REPEAT;
02798
02799     case OP_CLASS:
02800       {
02801       int i, min, max;
02802       code++;
02803       printf("    [");
02804
02805       for (i = 0; i < 256; i++)
02806         {
02807         if ((code[i/8] & (1 << (i&7))) != 0)
02808           {
02809           int j;
02810           for (j = i+1; j < 256; j++)
02811             if ((code[j/8] & (1 << (j&7))) == 0) break;
02812           if (i == '-' || i == ']') printf("\\");
02813           if (isprint(i)) printf("%c", i); else printf("\\x%02x", i);
02814           if (--j > i)
02815             {
02816             printf("-");
02817             if (j == '-' || j == ']') printf("\\");
02818             if (isprint(j)) printf("%c", j); else printf("\\x%02x", j);
02819             }
02820           i = j;
02821           }
02822         }
02823       printf("]");
02824       code += 32;
02825
02826       CLASS_REF_REPEAT:
02827
02828       switch(*code)
02829         {
02830         case OP_CRSTAR:
02831         case OP_CRMINSTAR:
02832         case OP_CRPLUS:
02833         case OP_CRMINPLUS:
02834         case OP_CRQUERY:
02835         case OP_CRMINQUERY:
02836         printf("%s", OP_names[*code]);
02837         break;
02838
02839         case OP_CRRANGE:
02840         case OP_CRMINRANGE:
02841         min = (code[1] << 8) + code[2];
02842         max = (code[3] << 8) + code[4];
02843         if (max == 0) printf("{%d,}", min);
02844         else printf("{%d,%d}", min, max);
02845         if (*code == OP_CRMINRANGE) printf("?");
02846         code += 4;
02847         break;
02848
02849         default:
02850         code--;
02851         }
02852       }
02853     break;
02854
02855     /* Anything else is just a one-node item */
02856
02857     default:
02858     printf("    %s", OP_names[*code]);
02859     break;
02860     }
02861
02862   code++;
02863   printf("\n");
02864   }
02865 printf("------------------------------------------------------------------\n");
02866
02867 /* This check is done here in the debugging case so that the code that
02868 was compiled can be seen. */
02869
02870 if (code - re->code > length)
02871   {
02872   *errorptr = ERR23;
02873   (pcre_free)(re);
02874   *erroroffset = ptr - (uschar *)pattern;
02875   return NULL;
02876   }
02877 #endif
02878
02879 return (pcre *)re;
02880 }
02881
02882
02883
02884 /*************************************************
02885 *          Match a back-reference                *
02886 *************************************************/
02887
02888 /* If a back reference hasn't been set, the length that is passed is greater
02889 than the number of characters left in the string, so the match fails.
02890
02891 Arguments:
02892   offset      index into the offset vector
02893   eptr        points into the subject
02894   length      length to be matched
02895   md          points to match data block
02896   ims         the ims flags
02897
02898 Returns:      TRUE if matched
02899 */
02900
02901 static BOOL
02902 match_ref(int offset, register const uschar *eptr, int length, match_data *md,
02903   unsigned long int ims)
02904 {
02905 const uschar *p = md->start_subject + md->offset_vector[offset];
02906
02907 #ifdef DEBUG
02908 if (eptr >= md->end_subject)
02909   printf("matching subject <null>");
02910 else
02911   {
02912   printf("matching subject ");
02913   pchars(eptr, length, TRUE, md);
02914   }
02915 printf(" against backref ");
02916 pchars(p, length, FALSE, md);
02917 printf("\n");
02918 #endif
02919
02920 /* Always fail if not enough characters left */
02921
02922 if (length > md->end_subject - eptr) return FALSE;
02923
02924 /* Separate the caselesss case for speed */
02925
02926 if ((ims & PCRE_CASELESS) != 0)
02927   {
02928   while (length-- > 0)
02929     if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;
02930   }
02931 else
02932   { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
02933
02934 return TRUE;
02935 }
02936
02937
02938
02939 /*************************************************
02940 *         Match from current position            *
02941 *************************************************/
02942
02943 /* On entry ecode points to the first opcode, and eptr to the first character
02944 in the subject string, while eptrb holds the value of eptr at the start of the
02945 last bracketed group - used for breaking infinite loops matching zero-length
02946 strings.
02947
02948 Arguments:
02949    eptr        pointer in subject
02950    ecode       position in code
02951    offset_top  current top pointer
02952    md          pointer to "static" info for the match
02953    ims         current /i, /m, and /s options
02954    condassert  TRUE if called to check a condition assertion
02955    eptrb       eptr at start of last bracket
02956
02957 Returns:       TRUE if matched
02958 */
02959
02960 static BOOL
02961 match(register const uschar *eptr, register const uschar *ecode,
02962   int offset_top, match_data *md, unsigned long int ims, BOOL condassert,
02963   const uschar *eptrb)
02964 {
02965 unsigned long int original_ims = ims;   /* Save for resetting on ')' */
02966
02967 for (;;)
02968   {
02969   int op = (int)*ecode;
02970   int min, max, ctype;
02971   register int i;
02972   register int c;
02973   BOOL minimize = FALSE;
02974
02975   /* Opening capturing bracket. If there is space in the offset vector, save
02976   the current subject position in the working slot at the top of the vector. We
02977   mustn't change the current values of the data slot, because they may be set
02978   from a previous iteration of this group, and be referred to by a reference
02979   inside the group.
02980
02981   If the bracket fails to match, we need to restore this value and also the
02982   values of the final offsets, in case they were set by a previous iteration of
02983   the same bracket.
02984
02985   If there isn't enough space in the offset vector, treat this as if it were a
02986   non-capturing bracket. Don't worry about setting the flag for the error case
02987   here; that is handled in the code for KET. */
02988
02989   if (op > OP_BRA)
02990     {
02991     int number = op - OP_BRA;
02992     int offset = number << 1;
02993
02994 #ifdef DEBUG
02995     printf("start bracket %d subject=", number);
02996     pchars(eptr, 16, TRUE, md);
02997     printf("\n");
02998 #endif
02999
03000     if (offset < md->offset_max)
03001       {
03002       int save_offset1 = md->offset_vector[offset];
03003       int save_offset2 = md->offset_vector[offset+1];
03004       int save_offset3 = md->offset_vector[md->offset_end - number];
03005
03006       DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
03007       md->offset_vector[md->offset_end - number] = eptr - md->start_subject;
03008
03009       do
03010         {
03011         if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
03012         ecode += (ecode[1] << 8) + ecode[2];
03013         }
03014       while (*ecode == OP_ALT);
03015
03016       DPRINTF(("bracket %d failed\n", number));
03017
03018       md->offset_vector[offset] = save_offset1;
03019       md->offset_vector[offset+1] = save_offset2;
03020       md->offset_vector[md->offset_end - number] = save_offset3;
03021       return FALSE;
03022       }
03023
03024     /* Insufficient room for saving captured contents */
03025
03026     else op = OP_BRA;
03027     }
03028
03029   /* Other types of node can be handled by a switch */
03030
03031   switch(op)
03032     {
03033     case OP_BRA:     /* Non-capturing bracket: optimized */
03034     DPRINTF(("start bracket 0\n"));
03035     do
03036       {
03037       if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
03038       ecode += (ecode[1] << 8) + ecode[2];
03039       }
03040     while (*ecode == OP_ALT);
03041     DPRINTF(("bracket 0 failed\n"));
03042     return FALSE;
03043
03044     /* Conditional group: compilation checked that there are no more than
03045     two branches. If the condition is false, skipping the first branch takes us
03046     past the end if there is only one branch, but that's OK because that is
03047     exactly what going to the ket would do. */
03048
03049     case OP_COND:
03050     if (ecode[3] == OP_CREF)         /* Condition is extraction test */
03051       {
03052       int offset = ecode[4] << 1;    /* Doubled reference number */
03053       return match(eptr,
03054         ecode + ((offset < offset_top && md->offset_vector[offset] >= 0)?
03055           5 : 3 + (ecode[1] << 8) + ecode[2]),
03056         offset_top, md, ims, FALSE, eptr);
03057       }
03058
03059     /* The condition is an assertion. Call match() to evaluate it - setting
03060     the final argument TRUE causes it to stop at the end of an assertion. */
03061
03062     else
03063       {
03064       if (match(eptr, ecode+3, offset_top, md, ims, TRUE, NULL))
03065         {
03066         ecode += 3 + (ecode[4] << 8) + ecode[5];
03067         while (*ecode == OP_ALT) ecode += (ecode[1] << 8) + ecode[2];
03068         }
03069       else ecode += (ecode[1] << 8) + ecode[2];
03070       return match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr);
03071       }
03072     /* Control never reaches here */
03073
03074     /* Skip over conditional reference data if encountered (should not be) */
03075
03076     case OP_CREF:
03077     ecode += 2;
03078     break;
03079
03080     /* End of the pattern. If PCRE_NOTEMPTY is set, fail if we have matched
03081     an empty string - recursion will then try other alternatives, if any. */
03082
03083     case OP_END:
03084     if (md->notempty && eptr == md->start_match) return FALSE;
03085     md->end_match_ptr = eptr;          /* Record where we ended */
03086     md->end_offset_top = offset_top;   /* and how many extracts were taken */
03087     return TRUE;
03088
03089     /* Change option settings */
03090
03091     case OP_OPT:
03092     ims = ecode[1];
03093     ecode += 2;
03094     DPRINTF(("ims set to %02lx\n", ims));
03095     break;
03096
03097     /* Assertion brackets. Check the alternative branches in turn - the
03098     matching won't pass the KET for an assertion. If any one branch matches,
03099     the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
03100     start of each branch to move the current point backwards, so the code at
03101     this level is identical to the lookahead case. */
03102
03103     case OP_ASSERT:
03104     case OP_ASSERTBACK:
03105     do
03106       {
03107       if (match(eptr, ecode+3, offset_top, md, ims, FALSE, NULL)) break;
03108       ecode += (ecode[1] << 8) + ecode[2];
03109       }
03110     while (*ecode == OP_ALT);
03111     if (*ecode == OP_KET) return FALSE;
03112
03113     /* If checking an assertion for a condition, return TRUE. */
03114
03115     if (condassert) return TRUE;
03116
03117     /* Continue from after the assertion, updating the offsets high water
03118     mark, since extracts may have been taken during the assertion. */
03119
03120     do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT);
03121     ecode += 3;
03122     offset_top = md->end_offset_top;
03123     continue;
03124
03125     /* Negative assertion: all branches must fail to match */
03126
03127     case OP_ASSERT_NOT:
03128     case OP_ASSERTBACK_NOT:
03129     do
03130       {
03131       if (match(eptr, ecode+3, offset_top, md, ims, FALSE, NULL)) return FALSE;
03132       ecode += (ecode[1] << 8) + ecode[2];
03133       }
03134     while (*ecode == OP_ALT);
03135
03136     if (condassert) return TRUE;
03137     ecode += 3;
03138     continue;
03139
03140     /* Move the subject pointer back. This occurs only at the start of
03141     each branch of a lookbehind assertion. If we are too close to the start to
03142     move back, this match function fails. */
03143
03144     case OP_REVERSE:
03145     eptr -= (ecode[1] << 8) + ecode[2];
03146     if (eptr < md->start_subject) return FALSE;
03147     ecode += 3;
03148     break;
03149
03150
03151     /* "Once" brackets are like assertion brackets except that after a match,
03152     the point in the subject string is not moved back. Thus there can never be
03153     a move back into the brackets. Check the alternative branches in turn - the
03154     matching won't pass the KET for this kind of subpattern. If any one branch
03155     matches, we carry on as at the end of a normal bracket, leaving the subject
03156     pointer. */
03157
03158     case OP_ONCE:
03159       {
03160       const uschar *prev = ecode;
03161
03162       do
03163         {
03164         if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) break;
03165         ecode += (ecode[1] << 8) + ecode[2];
03166         }
03167       while (*ecode == OP_ALT);
03168
03169       /* If hit the end of the group (which could be repeated), fail */
03170
03171       if (*ecode != OP_ONCE && *ecode != OP_ALT) return FALSE;
03172
03173       /* Continue as from after the assertion, updating the offsets high water
03174       mark, since extracts may have been taken. */
03175
03176       do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT);
03177
03178       offset_top = md->end_offset_top;
03179       eptr = md->end_match_ptr;
03180
03181       /* For a non-repeating ket, just continue at this level. This also
03182       happens for a repeating ket if no characters were matched in the group.
03183       This is the forcible breaking of infinite loops as implemented in Perl
03184       5.005. If there is an options reset, it will get obeyed in the normal
03185       course of events. */
03186
03187       if (*ecode == OP_KET || eptr == eptrb)
03188         {
03189         ecode += 3;
03190         break;
03191         }
03192
03193       /* The repeating kets try the rest of the pattern or restart from the
03194       preceding bracket, in the appropriate order. We need to reset any options
03195       that changed within the bracket before re-running it, so check the next
03196       opcode. */
03197
03198       if (ecode[3] == OP_OPT)
03199         {
03200         ims = (ims & ~PCRE_IMS) | ecode[4];
03201         DPRINTF(("ims set to %02lx at group repeat\n", ims));
03202         }
03203
03204       if (*ecode == OP_KETRMIN)
03205         {
03206         if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr) ||
03207             match(eptr, prev, offset_top, md, ims, FALSE, eptr)) return TRUE;
03208         }
03209       else  /* OP_KETRMAX */
03210         {
03211         if (match(eptr, prev, offset_top, md, ims, FALSE, eptr) ||
03212             match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
03213         }
03214       }
03215     return FALSE;
03216
03217     /* An alternation is the end of a branch; scan along to find the end of the
03218     bracketed group and go to there. */
03219
03220     case OP_ALT:
03221     do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT);
03222     break;
03223
03224     /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating
03225     that it may occur zero times. It may repeat infinitely, or not at all -
03226     i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper
03227     repeat limits are compiled as a number of copies, with the optional ones
03228     preceded by BRAZERO or BRAMINZERO. */
03229
03230     case OP_BRAZERO:
03231       {
03232       const uschar *next = ecode+1;
03233       if (match(eptr, next, offset_top, md, ims, FALSE, eptr)) return TRUE;
03234       do next += (next[1] << 8) + next[2]; while (*next == OP_ALT);
03235       ecode = next + 3;
03236       }
03237     break;
03238
03239     case OP_BRAMINZERO:
03240       {
03241       const uschar *next = ecode+1;
03242       do next += (next[1] << 8) + next[2]; while (*next == OP_ALT);
03243       if (match(eptr, next+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
03244       ecode++;
03245       }
03246     break;
03247
03248     /* End of a group, repeated or non-repeating. If we are at the end of
03249     an assertion "group", stop matching and return TRUE, but record the
03250     current high water mark for use by positive assertions. Do this also
03251     for the "once" (not-backup up) groups. */
03252
03253     case OP_KET:
03254     case OP_KETRMIN:
03255     case OP_KETRMAX:
03256       {
03257       const uschar *prev = ecode - (ecode[1] << 8) - ecode[2];
03258
03259       if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
03260           *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
03261           *prev == OP_ONCE)
03262         {
03263         md->end_match_ptr = eptr;      /* For ONCE */
03264         md->end_offset_top = offset_top;
03265         return TRUE;
03266         }
03267
03268       /* In all other cases except a conditional group we have to check the
03269       group number back at the start and if necessary complete handling an
03270       extraction by setting the offsets and bumping the high water mark. */
03271
03272       if (*prev != OP_COND)
03273         {
03274         int number = *prev - OP_BRA;
03275         int offset = number << 1;
03276
03277         DPRINTF(("end bracket %d\n", number));
03278
03279         if (number > 0)
03280           {
03281           if (offset >= md->offset_max) md->offset_overflow = TRUE; else
03282             {
03283             md->offset_vector[offset] =
03284               md->offset_vector[md->offset_end - number];
03285             md->offset_vector[offset+1] = eptr - md->start_subject;
03286             if (offset_top <= offset) offset_top = offset + 2;
03287             }
03288           }
03289         }
03290
03291       /* Reset the value of the ims flags, in case they got changed during
03292       the group. */
03293
03294       ims = original_ims;
03295       DPRINTF(("ims reset to %02lx\n", ims));
03296
03297       /* For a non-repeating ket, just continue at this level. This also
03298       happens for a repeating ket if no characters were matched in the group.
03299       This is the forcible breaking of infinite loops as implemented in Perl
03300       5.005. If there is an options reset, it will get obeyed in the normal
03301       course of events. */
03302
03303       if (*ecode == OP_KET || eptr == eptrb)
03304         {
03305         ecode += 3;
03306         break;
03307         }
03308
03309       /* The repeating kets try the rest of the pattern or restart from the
03310       preceding bracket, in the appropriate order. */
03311
03312       if (*ecode == OP_KETRMIN)
03313         {
03314         if (match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr) ||
03315             match(eptr, prev, offset_top, md, ims, FALSE, eptr)) return TRUE;
03316         }
03317       else  /* OP_KETRMAX */
03318         {
03319         if (match(eptr, prev, offset_top, md, ims, FALSE, eptr) ||
03320             match(eptr, ecode+3, offset_top, md, ims, FALSE, eptr)) return TRUE;
03321         }
03322       }
03323     return FALSE;
03324
03325     /* Start of subject unless notbol, or after internal newline if multiline */
03326
03327     case OP_CIRC:
03328     if (md->notbol && eptr == md->start_subject) return FALSE;
03329     if ((ims & PCRE_MULTILINE) != 0)
03330       {
03331       if (eptr != md->start_subject && eptr[-1] != '\n') return FALSE;
03332       ecode++;
03333       break;
03334       }
03335     /* ... else fall through */
03336
03337     /* Start of subject assertion */
03338
03339     case OP_SOD:
03340     if (eptr != md->start_subject) return FALSE;
03341     ecode++;
03342     break;
03343
03344     /* Assert before internal newline if multiline, or before a terminating
03345     newline unless endonly is set, else end of subject unless noteol is set. */
03346
03347     case OP_DOLL:
03348     if ((ims & PCRE_MULTILINE) != 0)
03349       {
03350       if (eptr < md->end_subject) { if (*eptr != '\n') return FALSE; }
03351         else { if (md->noteol) return FALSE; }
03352       ecode++;
03353       break;
03354       }
03355     else
03356       {
03357       if (md->noteol) return FALSE;
03358       if (!md->endonly)
03359         {
03360         if (eptr < md->end_subject - 1 ||
03361            (eptr == md->end_subject - 1 && *eptr != '\n')) return FALSE;
03362
03363         ecode++;
03364         break;
03365         }
03366       }
03367     /* ... else fall through */
03368
03369     /* End of subject assertion (\z) */
03370
03371     case OP_EOD:
03372     if (eptr < md->end_subject) return FALSE;
03373     ecode++;
03374     break;
03375
03376     /* End of subject or ending \n assertion (\Z) */
03377
03378     case OP_EODN:
03379     if (eptr < md->end_subject - 1 ||
03380        (eptr == md->end_subject - 1 && *eptr != '\n')) return FALSE;
03381     ecode++;
03382     break;
03383
03384     /* Word boundary assertions */
03385
03386     case OP_NOT_WORD_BOUNDARY:
03387     case OP_WORD_BOUNDARY:
03388       {
03389       BOOL prev_is_word = (eptr != md->start_subject) &&
03390         ((md->ctypes[eptr[-1]] & ctype_word) != 0);
03391       BOOL cur_is_word = (eptr < md->end_subject) &&
03392         ((md->ctypes[*eptr] & ctype_word) != 0);
03393       if ((*ecode++ == OP_WORD_BOUNDARY)?
03394            cur_is_word == prev_is_word : cur_is_word != prev_is_word)
03395         return FALSE;
03396       }
03397     break;
03398
03399     /* Match a single character type; inline for speed */
03400
03401     case OP_ANY:
03402     if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == '\n')
03403       return FALSE;
03404     if (eptr++ >= md->end_subject) return FALSE;
03405     ecode++;
03406     break;
03407
03408     case OP_NOT_DIGIT:
03409     if (eptr >= md->end_subject ||
03410        (md->ctypes[*eptr++] & ctype_digit) != 0)
03411       return FALSE;
03412     ecode++;
03413     break;
03414
03415     case OP_DIGIT:
03416     if (eptr >= md->end_subject ||
03417        (md->ctypes[*eptr++] & ctype_digit) == 0)
03418       return FALSE;
03419     ecode++;
03420     break;
03421
03422     case OP_NOT_WHITESPACE:
03423     if (eptr >= md->end_subject ||
03424        (md->ctypes[*eptr++] & ctype_space) != 0)
03425       return FALSE;
03426     ecode++;
03427     break;
03428
03429     case OP_WHITESPACE:
03430     if (eptr >= md->end_subject ||
03431        (md->ctypes[*eptr++] & ctype_space) == 0)
03432       return FALSE;
03433     ecode++;
03434     break;
03435
03436     case OP_NOT_WORDCHAR:
03437     if (eptr >= md->end_subject ||
03438        (md->ctypes[*eptr++] & ctype_word) != 0)
03439       return FALSE;
03440     ecode++;
03441     break;
03442
03443     case OP_WORDCHAR:
03444     if (eptr >= md->end_subject ||
03445        (md->ctypes[*eptr++] & ctype_word) == 0)
03446       return FALSE;
03447     ecode++;
03448     break;
03449
03450     /* Match a back reference, possibly repeatedly. Look past the end of the
03451     item to see if there is repeat information following. The code is similar
03452     to that for character classes, but repeated for efficiency. Then obey
03453     similar code to character type repeats - written out again for speed.
03454     However, if the referenced string is the empty string, always treat
03455     it as matched, any number of times (otherwise there could be infinite
03456     loops). */
03457
03458     case OP_REF:
03459       {
03460       int length;
03461       int offset = ecode[1] << 1;                /* Doubled reference number */
03462       ecode += 2;                                /* Advance past the item */
03463
03464       /* If the reference is unset, set the length to be longer than the amount
03465       of subject left; this ensures that every attempt at a match fails. We
03466       can't just fail here, because of the possibility of quantifiers with zero
03467       minima. */
03468
03469       length = (offset >= offset_top || md->offset_vector[offset] < 0)?
03470         md->end_subject - eptr + 1 :
03471         md->offset_vector[offset+1] - md->offset_vector[offset];
03472
03473       /* Set up for repetition, or handle the non-repeated case */
03474
03475       switch (*ecode)
03476         {
03477         case OP_CRSTAR:
03478         case OP_CRMINSTAR:
03479         case OP_CRPLUS:
03480         case OP_CRMINPLUS:
03481         case OP_CRQUERY:
03482         case OP_CRMINQUERY:
03483         c = *ecode++ - OP_CRSTAR;
03484         minimize = (c & 1) != 0;
03485         min = rep_min[c];                 /* Pick up values from tables; */
03486         max = rep_max[c];                 /* zero for max => infinity */
03487         if (max == 0) max = PCRE_MAX_POS;
03488         break;
03489
03490         case OP_CRRANGE:
03491         case OP_CRMINRANGE:
03492         minimize = (*ecode == OP_CRMINRANGE);
03493         min = (ecode[1] << 8) + ecode[2];
03494         max = (ecode[3] << 8) + ecode[4];
03495         if (max == 0) max = PCRE_MAX_POS;
03496         ecode += 5;
03497         break;
03498
03499         default:               /* No repeat follows */
03500         if (!match_ref(offset, eptr, length, md, ims)) return FALSE;
03501         eptr += length;
03502         continue;              /* With the main loop */
03503         }
03504
03505       /* If the length of the reference is zero, just continue with the
03506       main loop. */
03507
03508       if (length == 0) continue;
03509
03510       /* First, ensure the minimum number of matches are present. We get back
03511       the length of the reference string explicitly rather than passing the
03512       address of eptr, so that eptr can be a register variable. */
03513
03514       for (i = 1; i <= min; i++)
03515         {
03516         if (!match_ref(offset, eptr, length, md, ims)) return FALSE;
03517         eptr += length;
03518         }
03519
03520       /* If min = max, continue at the same level without recursion.
03521       They are not both allowed to be zero. */
03522
03523       if (min == max) continue;
03524
03525       /* If minimizing, keep trying and advancing the pointer */
03526
03527       if (minimize)
03528         {
03529         for (i = min;; i++)
03530           {
03531           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03532             return TRUE;
03533           if (i >= max || !match_ref(offset, eptr, length, md, ims))
03534             return FALSE;
03535           eptr += length;
03536           }
03537         /* Control never gets here */
03538         }
03539
03540       /* If maximizing, find the longest string and work backwards */
03541
03542       else
03543         {
03544         const uschar *pp = eptr;
03545         for (i = min; i < max; i++)
03546           {
03547           if (!match_ref(offset, eptr, length, md, ims)) break;
03548           eptr += length;
03549           }
03550         while (eptr >= pp)
03551           {
03552           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03553             return TRUE;
03554           eptr -= length;
03555           }
03556         return FALSE;
03557         }
03558       }
03559     /* Control never gets here */
03560
03561
03562
03563     /* Match a character class, possibly repeatedly. Look past the end of the
03564     item to see if there is repeat information following. Then obey similar
03565     code to character type repeats - written out again for speed. */
03566
03567     case OP_CLASS:
03568       {
03569       const uschar *data = ecode + 1;  /* Save for matching */
03570       ecode += 33;                     /* Advance past the item */
03571
03572       switch (*ecode)
03573         {
03574         case OP_CRSTAR:
03575         case OP_CRMINSTAR:
03576         case OP_CRPLUS:
03577         case OP_CRMINPLUS:
03578         case OP_CRQUERY:
03579         case OP_CRMINQUERY:
03580         c = *ecode++ - OP_CRSTAR;
03581         minimize = (c & 1) != 0;
03582         min = rep_min[c];                 /* Pick up values from tables; */
03583         max = rep_max[c];                 /* zero for max => infinity */
03584         if (max == 0) max = PCRE_MAX_POS;
03585         break;
03586
03587         case OP_CRRANGE:
03588         case OP_CRMINRANGE:
03589         minimize = (*ecode == OP_CRMINRANGE);
03590         min = (ecode[1] << 8) + ecode[2];
03591         max = (ecode[3] << 8) + ecode[4];
03592         if (max == 0) max = PCRE_MAX_POS;
03593         ecode += 5;
03594         break;
03595
03596         default:               /* No repeat follows */
03597         min = max = 1;
03598         break;
03599         }
03600
03601       /* First, ensure the minimum number of matches are present. */
03602
03603       for (i = 1; i <= min; i++)
03604         {
03605         if (eptr >= md->end_subject) return FALSE;
03606         c = *eptr++;
03607         if ((data[c/8] & (1 << (c&7))) != 0) continue;
03608         return FALSE;
03609         }
03610
03611       /* If max == min we can continue with the main loop without the
03612       need to recurse. */
03613
03614       if (min == max) continue;
03615
03616       /* If minimizing, keep testing the rest of the expression and advancing
03617       the pointer while it matches the class. */
03618
03619       if (minimize)
03620         {
03621         for (i = min;; i++)
03622           {
03623           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03624             return TRUE;
03625           if (i >= max || eptr >= md->end_subject) return FALSE;
03626           c = *eptr++;
03627           if ((data[c/8] & (1 << (c&7))) != 0) continue;
03628           return FALSE;
03629           }
03630         /* Control never gets here */
03631         }
03632
03633       /* If maximizing, find the longest possible run, then work backwards. */
03634
03635       else
03636         {
03637         const uschar *pp = eptr;
03638         for (i = min; i < max; eptr++, i++)
03639           {
03640           if (eptr >= md->end_subject) break;
03641           c = *eptr;
03642           if ((data[c/8] & (1 << (c&7))) != 0) continue;
03643           break;
03644           }
03645
03646         while (eptr >= pp)
03647           if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
03648             return TRUE;
03649         return FALSE;
03650         }
03651       }
03652     /* Control never gets here */
03653
03654     /* Match a run of characters */
03655
03656     case OP_CHARS:
03657       {
03658       register int length = ecode[1];
03659       ecode += 2;
03660
03661 #ifdef DEBUG    /* Sigh. Some compilers never learn. */
03662       if (eptr >= md->end_subject)
03663         printf("matching subject <null> against pattern ");
03664       else
03665         {
03666         printf("matching subject ");
03667         pchars(eptr, length, TRUE, md);
03668         printf(" against pattern ");
03669         }
03670       pchars(ecode, length, FALSE, md);
03671       printf("\n");
03672 #endif
03673
03674       if (length > md->end_subject - eptr) return FALSE;
03675       if ((ims & PCRE_CASELESS) != 0)
03676         {
03677         while (length-- > 0)
03678           if (md->lcc[*ecode++] != md->lcc[*eptr++])
03679             return FALSE;
03680         }
03681       else
03682         {
03683         while (length-- > 0) if (*ecode++ != *eptr++) return FALSE;
03684         }
03685       }
03686     break;
03687
03688     /* Match a single character repeatedly; different opcodes share code. */
03689
03690     case OP_EXACT:
03691     min = max = (ecode[1] << 8) + ecode[2];
03692     ecode += 3;
03693     goto REPEATCHAR;
03694
03695     case OP_UPTO:
03696     case OP_MINUPTO:
03697     min = 0;
03698     max = (ecode[1] << 8) + ecode[2];
03699     minimize = *ecode == OP_MINUPTO;
03700     ecode += 3;
03701     goto REPEATCHAR;
03702
03703     case OP_STAR:
03704     case OP_MINSTAR:
03705     case OP_PLUS:
03706     case OP_MINPLUS:
03707     case OP_QUERY:
03708     case OP_MINQUERY:
03709     c = *ecode++ - OP_STAR;
03710     minimize = (c & 1) != 0;
03711     min = rep_min[c];                 /* Pick up values from tables; */
03712     max = rep_max[c];                 /* zero for max => infinity */
03713     if (max == 0) max = PCRE_MAX_POS;
03714
03715     /* Common code for all repeated single-character matches. We can give
03716     up quickly if there are fewer than the minimum number of characters left in
03717     the subject. */
03718
03719     REPEATCHAR:
03720     if (min > md->end_subject - eptr) return FALSE;
03721     c = *ecode++;
03722
03723     /* The code is duplicated for the caseless and caseful cases, for speed,
03724     since matching characters is likely to be quite common. First, ensure the
03725     minimum number of matches are present. If min = max, continue at the same
03726     level without recursing. Otherwise, if minimizing, keep trying the rest of
03727     the expression and advancing one matching character if failing, up to the
03728     maximum. Alternatively, if maximizing, find the maximum number of
03729     characters and work backwards. */
03730
03731     DPRINTF(("matching %c{%d,%d} against subject %.*s\n", c, min, max,
03732       max, eptr));
03733
03734     if ((ims & PCRE_CASELESS) != 0)
03735       {
03736       c = md->lcc[c];
03737       for (i = 1; i <= min; i++)
03738         if (c != md->lcc[*eptr++]) return FALSE;
03739       if (min == max) continue;
03740       if (minimize)
03741         {
03742         for (i = min;; i++)
03743           {
03744           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03745             return TRUE;
03746           if (i >= max || eptr >= md->end_subject ||
03747               c != md->lcc[*eptr++])
03748             return FALSE;
03749           }
03750         /* Control never gets here */
03751         }
03752       else
03753         {
03754         const uschar *pp = eptr;
03755         for (i = min; i < max; i++)
03756           {
03757           if (eptr >= md->end_subject || c != md->lcc[*eptr]) break;
03758           eptr++;
03759           }
03760         while (eptr >= pp)
03761           if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
03762             return TRUE;
03763         return FALSE;
03764         }
03765       /* Control never gets here */
03766       }
03767
03768     /* Caseful comparisons */
03769
03770     else
03771       {
03772       for (i = 1; i <= min; i++) if (c != *eptr++) return FALSE;
03773       if (min == max) continue;
03774       if (minimize)
03775         {
03776         for (i = min;; i++)
03777           {
03778           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03779             return TRUE;
03780           if (i >= max || eptr >= md->end_subject || c != *eptr++) return FALSE;
03781           }
03782         /* Control never gets here */
03783         }
03784       else
03785         {
03786         const uschar *pp = eptr;
03787         for (i = min; i < max; i++)
03788           {
03789           if (eptr >= md->end_subject || c != *eptr) break;
03790           eptr++;
03791           }
03792         while (eptr >= pp)
03793          if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
03794            return TRUE;
03795         return FALSE;
03796         }
03797       }
03798     /* Control never gets here */
03799
03800     /* Match a negated single character */
03801
03802     case OP_NOT:
03803     if (eptr >= md->end_subject) return FALSE;
03804     ecode++;
03805     if ((ims & PCRE_CASELESS) != 0)
03806       {
03807       if (md->lcc[*ecode++] == md->lcc[*eptr++]) return FALSE;
03808       }
03809     else
03810       {
03811       if (*ecode++ == *eptr++) return FALSE;
03812       }
03813     break;
03814
03815     /* Match a negated single character repeatedly. This is almost a repeat of
03816     the code for a repeated single character, but I haven't found a nice way of
03817     commoning these up that doesn't require a test of the positive/negative
03818     option for each character match. Maybe that wouldn't add very much to the
03819     time taken, but character matching *is* what this is all about... */
03820
03821     case OP_NOTEXACT:
03822     min = max = (ecode[1] << 8) + ecode[2];
03823     ecode += 3;
03824     goto REPEATNOTCHAR;
03825
03826     case OP_NOTUPTO:
03827     case OP_NOTMINUPTO:
03828     min = 0;
03829     max = (ecode[1] << 8) + ecode[2];
03830     minimize = *ecode == OP_NOTMINUPTO;
03831     ecode += 3;
03832     goto REPEATNOTCHAR;
03833
03834     case OP_NOTSTAR:
03835     case OP_NOTMINSTAR:
03836     case OP_NOTPLUS:
03837     case OP_NOTMINPLUS:
03838     case OP_NOTQUERY:
03839     case OP_NOTMINQUERY:
03840     c = *ecode++ - OP_NOTSTAR;
03841     minimize = (c & 1) != 0;
03842     min = rep_min[c];                 /* Pick up values from tables; */
03843     max = rep_max[c];                 /* zero for max => infinity */
03844     if (max == 0) max = PCRE_MAX_POS;
03845
03846     /* Common code for all repeated single-character matches. We can give
03847     up quickly if there are fewer than the minimum number of characters left in
03848     the subject. */
03849
03850     REPEATNOTCHAR:
03851     if (min > md->end_subject - eptr) return FALSE;
03852     c = *ecode++;
03853
03854     /* The code is duplicated for the caseless and caseful cases, for speed,
03855     since matching characters is likely to be quite common. First, ensure the
03856     minimum number of matches are present. If min = max, continue at the same
03857     level without recursing. Otherwise, if minimizing, keep trying the rest of
03858     the expression and advancing one matching character if failing, up to the
03859     maximum. Alternatively, if maximizing, find the maximum number of
03860     characters and work backwards. */
03861
03862     DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", c, min, max,
03863       max, eptr));
03864
03865     if ((ims & PCRE_CASELESS) != 0)
03866       {
03867       c = md->lcc[c];
03868       for (i = 1; i <= min; i++)
03869         if (c == md->lcc[*eptr++]) return FALSE;
03870       if (min == max) continue;
03871       if (minimize)
03872         {
03873         for (i = min;; i++)
03874           {
03875           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03876             return TRUE;
03877           if (i >= max || eptr >= md->end_subject ||
03878               c == md->lcc[*eptr++])
03879             return FALSE;
03880           }
03881         /* Control never gets here */
03882         }
03883       else
03884         {
03885         const uschar *pp = eptr;
03886         for (i = min; i < max; i++)
03887           {
03888           if (eptr >= md->end_subject || c == md->lcc[*eptr]) break;
03889           eptr++;
03890           }
03891         while (eptr >= pp)
03892           if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
03893             return TRUE;
03894         return FALSE;
03895         }
03896       /* Control never gets here */
03897       }
03898
03899     /* Caseful comparisons */
03900
03901     else
03902       {
03903       for (i = 1; i <= min; i++) if (c == *eptr++) return FALSE;
03904       if (min == max) continue;
03905       if (minimize)
03906         {
03907         for (i = min;; i++)
03908           {
03909           if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb))
03910             return TRUE;
03911           if (i >= max || eptr >= md->end_subject || c == *eptr++) return FALSE;
03912           }
03913         /* Control never gets here */
03914         }
03915       else
03916         {
03917         const uschar *pp = eptr;
03918         for (i = min; i < max; i++)
03919           {
03920           if (eptr >= md->end_subject || c == *eptr) break;
03921           eptr++;
03922           }
03923         while (eptr >= pp)
03924          if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
03925            return TRUE;
03926         return FALSE;
03927         }
03928       }
03929     /* Control never gets here */
03930
03931     /* Match a single character type repeatedly; several different opcodes
03932     share code. This is very similar to the code for single characters, but we
03933     repeat it in the interests of efficiency. */
03934
03935     case OP_TYPEEXACT:
03936     min = max = (ecode[1] << 8) + ecode[2];
03937     minimize = TRUE;
03938     ecode += 3;
03939     goto REPEATTYPE;
03940
03941     case OP_TYPEUPTO:
03942     case OP_TYPEMINUPTO:
03943     min = 0;
03944     max = (ecode[1] << 8) + ecode[2];
03945     minimize = *ecode == OP_TYPEMINUPTO;
03946     ecode += 3;
03947     goto REPEATTYPE;
03948
03949     case OP_TYPESTAR:
03950     case OP_TYPEMINSTAR:
03951     case OP_TYPEPLUS:
03952     case OP_TYPEMINPLUS:
03953     case OP_TYPEQUERY:
03954     case OP_TYPEMINQUERY:
03955     c = *ecode++ - OP_TYPESTAR;
03956     minimize = (c & 1) != 0;
03957     min = rep_min[c];                 /* Pick up values from tables; */
03958     max = rep_max[c];                 /* zero for max => infinity */
03959     if (max == 0) max = PCRE_MAX_POS;
03960
03961     /* Common code for all repeated single character type matches */
03962
03963     REPEATTYPE:
03964     ctype = *ecode++;      /* Code for the character type */
03965
03966     /* First, ensure the minimum number of matches are present. Use inline
03967     code for maximizing the speed, and do the type test once at the start
03968     (i.e. keep it out of the loop). Also test that there are at least the
03969     minimum number of characters before we start. */
03970
03971     if (min > md->end_subject - eptr) return FALSE;
03972     if (min > 0) switch(ctype)
03973       {
03974       case OP_ANY:
03975       if ((ims & PCRE_DOTALL) == 0)
03976         { for (i = 1; i <= min; i++) if (*eptr++ == '\n') return FALSE; }
03977       else eptr += min;
03978       break;
03979
03980       case OP_NOT_DIGIT:
03981       for (i = 1; i <= min; i++)
03982         if ((md->ctypes[*eptr++] & ctype_digit) != 0) return FALSE;
03983       break;
03984
03985       case OP_DIGIT:
03986       for (i = 1; i <= min; i++)
03987         if ((md->ctypes[*eptr++] & ctype_digit) == 0) return FALSE;
03988       break;
03989
03990       case OP_NOT_WHITESPACE:
03991       for (i = 1; i <= min; i++)
03992         if ((md->ctypes[*eptr++] & ctype_space) != 0) return FALSE;
03993       break;
03994
03995       case OP_WHITESPACE:
03996       for (i = 1; i <= min; i++)
03997         if ((md->ctypes[*eptr++] & ctype_space) == 0) return FALSE;
03998       break;
03999
04000       case OP_NOT_WORDCHAR:
04001       for (i = 1; i <= min; i++)
04002         if ((md->ctypes[*eptr++] & ctype_word) != 0)
04003           return FALSE;
04004       break;
04005
04006       case OP_WORDCHAR:
04007       for (i = 1; i <= min; i++)
04008         if ((md->ctypes[*eptr++] & ctype_word) == 0)
04009           return FALSE;
04010       break;
04011       }
04012
04013     /* If min = max, continue at the same level without recursing */
04014
04015     if (min == max) continue;
04016
04017     /* If minimizing, we have to test the rest of the pattern before each
04018     subsequent match. */
04019
04020     if (minimize)
04021       {
04022       for (i = min;; i++)
04023         {
04024         if (match(eptr, ecode, offset_top, md, ims, FALSE, eptrb)) return TRUE;
04025         if (i >= max || eptr >= md->end_subject) return FALSE;
04026
04027         c = *eptr++;
04028         switch(ctype)
04029           {
04030           case OP_ANY:
04031           if ((ims & PCRE_DOTALL) == 0 && c == '\n') return FALSE;
04032           break;
04033
04034           case OP_NOT_DIGIT:
04035           if ((md->ctypes[c] & ctype_digit) != 0) return FALSE;
04036           break;
04037
04038           case OP_DIGIT:
04039           if ((md->ctypes[c] & ctype_digit) == 0) return FALSE;
04040           break;
04041
04042           case OP_NOT_WHITESPACE:
04043           if ((md->ctypes[c] & ctype_space) != 0) return FALSE;
04044           break;
04045
04046           case OP_WHITESPACE:
04047           if  ((md->ctypes[c] & ctype_space) == 0) return FALSE;
04048           break;
04049
04050           case OP_NOT_WORDCHAR:
04051           if ((md->ctypes[c] & ctype_word) != 0) return FALSE;
04052           break;
04053
04054           case OP_WORDCHAR:
04055           if ((md->ctypes[c] & ctype_word) == 0) return FALSE;
04056           break;
04057           }
04058         }
04059       /* Control never gets here */
04060       }
04061
04062     /* If maximizing it is worth using inline code for speed, doing the type
04063     test once at the start (i.e. keep it out of the loop). */
04064
04065     else
04066       {
04067       const uschar *pp = eptr;
04068       switch(ctype)
04069         {
04070         case OP_ANY:
04071         if ((ims & PCRE_DOTALL) == 0)
04072           {
04073           for (i = min; i < max; i++)
04074             {
04075             if (eptr >= md->end_subject || *eptr == '\n') break;
04076             eptr++;
04077             }
04078           }
04079         else
04080           {
04081           c = max - min;
04082           if (c > md->end_subject - eptr) c = md->end_subject - eptr;
04083           eptr += c;
04084           }
04085         break;
04086
04087         case OP_NOT_DIGIT:
04088         for (i = min; i < max; i++)
04089           {
04090           if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0)
04091             break;
04092           eptr++;
04093           }
04094         break;
04095
04096         case OP_DIGIT:
04097         for (i = min; i < max; i++)
04098           {
04099           if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0)
04100             break;
04101           eptr++;
04102           }
04103         break;
04104
04105         case OP_NOT_WHITESPACE:
04106         for (i = min; i < max; i++)
04107           {
04108           if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0)
04109             break;
04110           eptr++;
04111           }
04112         break;
04113
04114         case OP_WHITESPACE:
04115         for (i = min; i < max; i++)
04116           {
04117           if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0)
04118             break;
04119           eptr++;
04120           }
04121         break;
04122
04123         case OP_NOT_WORDCHAR:
04124         for (i = min; i < max; i++)
04125           {
04126           if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0)
04127             break;
04128           eptr++;
04129           }
04130         break;
04131
04132         case OP_WORDCHAR:
04133         for (i = min; i < max; i++)
04134           {
04135           if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0)
04136             break;
04137           eptr++;
04138           }
04139         break;
04140         }
04141
04142       while (eptr >= pp)
04143         if (match(eptr--, ecode, offset_top, md, ims, FALSE, eptrb))
04144           return TRUE;
04145       return FALSE;
04146       }
04147     /* Control never gets here */
04148
04149     /* There's been some horrible disaster. */
04150
04151     default:
04152     DPRINTF(("Unknown opcode %d\n", *ecode));
04153     md->errorcode = PCRE_ERROR_UNKNOWN_NODE;
04154     return FALSE;
04155     }
04156
04157   /* Do not stick any code in here without much thought; it is assumed
04158   that "continue" in the code above comes out to here to repeat the main
04159   loop. */
04160
04161   }             /* End of main loop */
04162 /* Control never reaches here */
04163 }
04164
04165
04166
04167
04168 /*************************************************
04169 *         Execute a Regular Expression           *
04170 *************************************************/
04171
04172 /* This function applies a compiled re to a subject string and picks out
04173 portions of the string if it matches. Two elements in the vector are set for
04174 each substring: the offsets to the start and end of the substring.
04175
04176 Arguments:
04177   external_re     points to the compiled expression
04178   external_extra  points to "hints" from pcre_study() or is NULL
04179   subject         points to the subject string
04180   length          length of subject string (may contain binary zeros)
04181   start_offset    where to start in the subject string
04182   options         option bits
04183   offsets         points to a vector of ints to be filled in with offsets
04184   offsetcount     the number of elements in the vector
04185
04186 Returns:          > 0 => success; value is the number of elements filled in
04187                   = 0 => success, but offsets is not big enough
04188                    -1 => failed to match
04189                  < -1 => some kind of unexpected problem
04190 */
04191
04192 int
04193 pcre_exec(const pcre *external_re, const pcre_extra *external_extra,
04194   const char *subject, int length, int start_offset, int options, int *offsets,
04195   int offsetcount)
04196 {
04197 int resetcount, ocount;
04198 int first_char = -1;
04199 int req_char = -1;
04200 int req_char2 = -1;
04201 unsigned long int ims = 0;
04202 match_data match_block;
04203 const uschar *start_bits = NULL;
04204 const uschar *start_match = (const uschar *)subject + start_offset;
04205 const uschar *end_subject;
04206 const uschar *req_char_ptr = start_match - 1;
04207 const real_pcre *re = (const real_pcre *)external_re;
04208 const real_pcre_extra *extra = (const real_pcre_extra *)external_extra;
04209 BOOL using_temporary_offsets = FALSE;
04210 BOOL anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
04211 BOOL startline = (re->options & PCRE_STARTLINE) != 0;
04212
04213 if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
04214
04215 if (re == NULL || subject == NULL ||
04216    (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
04217 if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
04218
04219 match_block.start_subject = (const uschar *)subject;
04220 match_block.end_subject = match_block.start_subject + length;
04221 end_subject = match_block.end_subject;
04222
04223 match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
04224
04225 match_block.notbol = (options & PCRE_NOTBOL) != 0;
04226 match_block.noteol = (options & PCRE_NOTEOL) != 0;
04227 match_block.notempty = (options & PCRE_NOTEMPTY) != 0;
04228
04229 match_block.errorcode = PCRE_ERROR_NOMATCH;     /* Default error */
04230
04231 match_block.lcc = re->tables + lcc_offset;
04232 match_block.ctypes = re->tables + ctypes_offset;
04233
04234 /* The ims options can vary during the matching as a result of the presence
04235 of (?ims) items in the pattern. They are kept in a local variable so that
04236 restoring at the exit of a group is easy. */
04237
04238 ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);
04239
04240 /* If the expression has got more back references than the offsets supplied can
04241 hold, we get a temporary bit of working store to use during the matching.
04242 Otherwise, we can use the vector supplied, rounding down its size to a multiple
04243 of 3. */
04244
04245 ocount = offsetcount - (offsetcount % 3);
04246
04247 if (re->top_backref > 0 && re->top_backref >= ocount/3)
04248   {
04249   ocount = re->top_backref * 3 + 3;
04250   match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
04251   if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
04252   using_temporary_offsets = TRUE;
04253   DPRINTF(("Got memory to hold back references\n"));
04254   }
04255 else match_block.offset_vector = offsets;
04256
04257 match_block.offset_end = ocount;
04258 match_block.offset_max = (2*ocount)/3;
04259 match_block.offset_overflow = FALSE;
04260
04261 /* Compute the minimum number of offsets that we need to reset each time. Doing
04262 this makes a huge difference to execution time when there aren't many brackets
04263 in the pattern. */
04264
04265 resetcount = 2 + re->top_bracket * 2;
04266 if (resetcount > offsetcount) resetcount = ocount;
04267
04268 /* Reset the working variable associated with each extraction. These should
04269 never be used unless previously set, but they get saved and restored, and so we
04270 initialize them to avoid reading uninitialized locations. */
04271
04272 if (match_block.offset_vector != NULL)
04273   {
04274   register int *iptr = match_block.offset_vector + ocount;
04275   register int *iend = iptr - resetcount/2 + 1;
04276   while (--iptr >= iend) *iptr = -1;
04277   }
04278
04279 /* Set up the first character to match, if available. The first_char value is
04280 never set for an anchored regular expression, but the anchoring may be forced
04281 at run time, so we have to test for anchoring. The first char may be unset for
04282 an unanchored pattern, of course. If there's no first char and the pattern was
04283 studied, there may be a bitmap of possible first characters. */
04284
04285 if (!anchored)
04286   {
04287   if ((re->options & PCRE_FIRSTSET) != 0)
04288     {
04289     first_char = re->first_char;
04290     if ((ims & PCRE_CASELESS) != 0) first_char = match_block.lcc[first_char];
04291     }
04292   else
04293     if (!startline && extra != NULL &&
04294       (extra->options & PCRE_STUDY_MAPPED) != 0)
04295         start_bits = extra->start_bits;
04296   }
04297
04298 /* For anchored or unanchored matches, there may be a "last known required
04299 character" set. If the PCRE_CASELESS is set, implying that the match starts
04300 caselessly, or if there are any changes of this flag within the regex, set up
04301 both cases of the character. Otherwise set the two values the same, which will
04302 avoid duplicate testing (which takes significant time). This covers the vast
04303 majority of cases. It will be suboptimal when the case flag changes in a regex
04304 and the required character in fact is caseful. */
04305
04306 if ((re->options & PCRE_REQCHSET) != 0)
04307   {
04308   req_char = re->req_char;
04309   req_char2 = ((re->options & (PCRE_CASELESS | PCRE_ICHANGED)) != 0)?
04310     (re->tables + fcc_offset)[req_char] : req_char;
04311   }
04312
04313 /* Loop for handling unanchored repeated matching attempts; for anchored regexs
04314 the loop runs just once. */
04315
04316 do
04317   {
04318   int rc;
04319   register int *iptr = match_block.offset_vector;
04320   register int *iend = iptr + resetcount;
04321
04322   /* Reset the maximum number of extractions we might see. */
04323
04324   while (iptr < iend) *iptr++ = -1;
04325
04326   /* Advance to a unique first char if possible */
04327
04328   if (first_char >= 0)
04329     {
04330     if ((ims & PCRE_CASELESS) != 0)
04331       while (start_match < end_subject &&
04332              match_block.lcc[*start_match] != first_char)
04333         start_match++;
04334     else
04335       while (start_match < end_subject && *start_match != first_char)
04336         start_match++;
04337     }
04338
04339   /* Or to just after \n for a multiline match if possible */
04340
04341   else if (startline)
04342     {
04343     if (start_match > match_block.start_subject + start_offset)
04344       {
04345       while (start_match < end_subject && start_match[-1] != '\n')
04346         start_match++;
04347       }
04348     }
04349
04350   /* Or to a non-unique first char after study */
04351
04352   else if (start_bits != NULL)
04353     {
04354     while (start_match < end_subject)
04355       {
04356       register int c = *start_match;
04357       if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break;
04358       }
04359     }
04360
04361 #ifdef DEBUG  /* Sigh. Some compilers never learn. */
04362   printf(">>>> Match against: ");
04363   pchars(start_match, end_subject - start_match, TRUE, &match_block);
04364   printf("\n");
04365 #endif
04366
04367   /* If req_char is set, we know that that character must appear in the subject
04368   for the match to succeed. If the first character is set, req_char must be
04369   later in the subject; otherwise the test starts at the match point. This
04370   optimization can save a huge amount of backtracking in patterns with nested
04371   unlimited repeats that aren't going to match. We don't know what the state of
04372   case matching may be when this character is hit, so test for it in both its
04373   cases if necessary. However, the different cased versions will not be set up
04374   unless PCRE_CASELESS was given or the casing state changes within the regex.
04375   Writing separate code makes it go faster, as does using an autoincrement and
04376   backing off on a match. */
04377
04378   if (req_char >= 0)
04379     {
04380     register const uschar *p = start_match + ((first_char >= 0)? 1 : 0);
04381
04382     /* We don't need to repeat the search if we haven't yet reached the
04383     place we found it at last time. */
04384
04385     if (p > req_char_ptr)
04386       {
04387       /* Do a single test if no case difference is set up */
04388
04389       if (req_char == req_char2)
04390         {
04391         while (p < end_subject)
04392           {
04393           if (*p++ == req_char) { p--; break; }
04394           }
04395         }
04396
04397       /* Otherwise test for either case */
04398
04399       else
04400         {
04401         while (p < end_subject)
04402           {
04403           register int pp = *p++;
04404           if (pp == req_char || pp == req_char2) { p--; break; }
04405           }
04406         }
04407
04408       /* If we can't find the required character, break the matching loop */
04409
04410       if (p >= end_subject) break;
04411
04412       /* If we have found the required character, save the point where we
04413       found it, so that we don't search again next time round the loop if
04414       the start hasn't passed this character yet. */
04415
04416       req_char_ptr = p;
04417       }
04418     }
04419
04420   /* When a match occurs, substrings will be set for all internal extractions;
04421   we just need to set up the whole thing as substring 0 before returning. If
04422   there were too many extractions, set the return code to zero. In the case
04423   where we had to get some local store to hold offsets for backreferences, copy
04424   those back references that we can. In this case there need not be overflow
04425   if certain parts of the pattern were not used. */
04426
04427   match_block.start_match = start_match;
04428   if (!match(start_match, re->code, 2, &match_block, ims, FALSE, start_match))
04429     continue;
04430
04431   /* Copy the offset information from temporary store if necessary */
04432
04433   if (using_temporary_offsets)
04434     {
04435     if (offsetcount >= 4)
04436       {
04437       memcpy(offsets + 2, match_block.offset_vector + 2,
04438         (offsetcount - 2) * sizeof(int));
04439       DPRINTF(("Copied offsets from temporary memory\n"));
04440       }
04441     if (match_block.end_offset_top > offsetcount)
04442       match_block.offset_overflow = TRUE;
04443
04444     DPRINTF(("Freeing temporary memory\n"));
04445     (pcre_free)(match_block.offset_vector);
04446     }
04447
04448   rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2;
04449
04450   if (match_block.offset_end < 2) rc = 0; else
04451     {
04452     offsets[0] = start_match - match_block.start_subject;
04453     offsets[1] = match_block.end_match_ptr - match_block.start_subject;
04454     }
04455
04456   DPRINTF((">>>> returning %d\n", rc));
04457   return rc;
04458   }
04459
04460 /* This "while" is the end of the "do" above */
04461
04462 while (!anchored &&
04463        match_block.errorcode == PCRE_ERROR_NOMATCH &&
04464        start_match++ < end_subject);
04465
04466 if (using_temporary_offsets)
04467   {
04468   DPRINTF(("Freeing temporary memory\n"));
04469   (pcre_free)(match_block.offset_vector);
04470   }
04471
04472 DPRINTF((">>>> returning %d\n", match_block.errorcode));
04473
04474 return match_block.errorcode;
04475 }
04476
04477 /* End of pcre.c */


pcre.h File Reference

Include dependency graph for pcre.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | PCRE_MAJOR 2
#define | PCRE_MINOR 08
#define | PCRE_DATE 31-Aug-1999
#define | PCRE_DL_IMPORT
#define | PCRE_CASELESS 0x0001
#define | PCRE_MULTILINE 0x0002
#define | PCRE_DOTALL 0x0004
#define | PCRE_EXTENDED 0x0008
#define | PCRE_ANCHORED 0x0010
#define | PCRE_DOLLAR_ENDONLY 0x0020
#define | PCRE_EXTRA 0x0040
#define | PCRE_NOTBOL 0x0080
#define | PCRE_NOTEOL 0x0100
#define | PCRE_UNGREEDY 0x0200
#define | PCRE_NOTEMPTY 0x0400
#define | PCRE_ERROR_NOMATCH (-1)
#define | PCRE_ERROR_NULL (-2)
#define | PCRE_ERROR_BADOPTION (-3)
#define | PCRE_ERROR_BADMAGIC (-4)
#define | PCRE_ERROR_UNKNOWN_NODE (-5)
#define | PCRE_ERROR_NOMEMORY (-6)
#define | PCRE_ERROR_NOSUBSTRING (-7)

Typedefs

typedef void | pcre
typedef void | pcre_extra

Functions

pcre * | pcre_compile (const char *, int, const char **, int *, const unsigned char *)
int | pcre_copy_substring (const char *, int *, int, int, char *, int)
int | pcre_exec (const pcre *, const pcre_extra *, const char *, int, int, int, int *, int)
int | pcre_get_substring (const char *, int *, int, int, const char **)
int | pcre_get_substring_list (const char *, int *, int, const char ***)
int | pcre_info (const pcre *, int *, int *)
unsigned const char * | pcre_maketables (void)
pcre_extra * | pcre_study (const pcre *, int, const char **)
const char * | pcre_version (void)

Variables

PCRE_DL_IMPORT void *(* | pcre_malloc )(size_t)
PCRE_DL_IMPORT void(* | pcre_free )(void *)

Define Documentation

#define PCRE_MAJOR 2

Definition at line 10 of file pcre.h.

Referenced by pcre_version().

#define PCRE_MINOR 08

Definition at line 11 of file pcre.h.

Referenced by pcre_version().

#define PCRE_DATE 31-Aug-1999

Definition at line 12 of file pcre.h.

Referenced by pcre_version().

#define PCRE_DL_IMPORT

Definition at line 14 of file pcre.h.

#define PCRE_CASELESS 0x0001

Definition at line 30 of file pcre.h.

Referenced by compile_branch(), find_firstchar(), match(), match_ref(), pcre_compile(), pcre_exec(), pcre_study(), regex_options(), and set_start_bits().

#define PCRE_MULTILINE 0x0002

Definition at line 31 of file pcre.h.

Referenced by compile_branch(), is_anchored(), match(), pcre_compile(), pcre_exec(), and regex_options().

#define PCRE_DOTALL 0x0004

Definition at line 32 of file pcre.h.

Referenced by _list(), compile_branch(), is_anchored(), match(), pcre_compile(), pcre_exec(), and regex_options().

#define PCRE_EXTENDED 0x0008

Definition at line 33 of file pcre.h.

Referenced by compile_branch(), pcre_compile(), and regex_options().

#define PCRE_ANCHORED 0x0010

Definition at line 34 of file pcre.h.

Referenced by pcre_compile(), pcre_exec(), and pcre_study().

#define PCRE_DOLLAR_ENDONLY 0x0020

Definition at line 35 of file pcre.h.

Referenced by pcre_compile(), pcre_exec(), and regex_options().

#define PCRE_EXTRA 0x0040

Definition at line 36 of file pcre.h.

Referenced by _list(), check_escape(), compile_branch(), pcre_compile(), and regex_options().

#define PCRE_NOTBOL 0x0080

Definition at line 37 of file pcre.h.

Referenced by pcre_exec().

#define PCRE_NOTEOL 0x0100

Definition at line 38 of file pcre.h.

Referenced by pcre_exec().

#define PCRE_UNGREEDY 0x0200

Definition at line 39 of file pcre.h.

Referenced by compile_branch(), and pcre_compile().

#define PCRE_NOTEMPTY 0x0400

Definition at line 40 of file pcre.h.

Referenced by pcre_exec().

#define PCRE_ERROR_NOMATCH (-1)

Definition at line 44 of file pcre.h.

Referenced by _list(), String::match(), and pcre_exec().

#define PCRE_ERROR_NULL (-2)

Definition at line 45 of file pcre.h.

Referenced by pcre_exec(), and pcre_info().

#define PCRE_ERROR_BADOPTION (-3)

Definition at line 46 of file pcre.h.

Referenced by pcre_exec().

#define PCRE_ERROR_BADMAGIC (-4)

Definition at line 47 of file pcre.h.

Referenced by pcre_exec(), and pcre_info().

#define PCRE_ERROR_UNKNOWN_NODE (-5)

Definition at line 48 of file pcre.h.

Referenced by match().

#define PCRE_ERROR_NOMEMORY (-6)

Definition at line 49 of file pcre.h.

Referenced by pcre_copy_substring(), pcre_exec(), pcre_get_substring(), and pcre_get_substring_list().

#define PCRE_ERROR_NOSUBSTRING (-7)

Definition at line 50 of file pcre.h.

Referenced by pcre_copy_substring(), and pcre_get_substring().

Typedef Documentation

typedef void pcre

Definition at line 54 of file pcre.h.

Referenced by _list(), String::match(), pcre_compile(), pcre_exec(), pcre_info(), and pcre_study().

typedef void pcre_extra

Definition at line 55 of file pcre.h.

Referenced by pcre_exec(), and pcre_study().

Function Documentation

pcre* pcre_compile | ( | const char * | ,
 |  | int | ,
 |  | const char ** | ,
 |  | int * | ,
 |  | const unsigned char * |
 | ) |

Definition at line 2012 of file pcre.c.

References BRASTACK_SIZE, compile_data::cbits, cbits_offset, check_escape(), real_pcre::code, compile_regex(), ctype_digit, ctype_meta, ctype_space, compile_data::ctypes, ctypes_offset, DPRINTF, ERR12, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, ERR21, ERR22, ERR23, ERR24, ERR26, ERR28, ESC_b, ESC_REF, compile_data::fcc, fcc_offset, find_firstchar(), real_pcre::first_char, is_anchored(), is_counted_repeat(), is_startline(), compile_data::lcc, lcc_offset, MAGIC_NUMBER, real_pcre::magic_number, offsetof, OP_ALT, OP_ASSERT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_BRA, OP_CHARS, OP_CLASS, OP_COND, OP_CREF, OP_CRMINPLUS, OP_CRMINQUERY, OP_CRMINRANGE, OP_CRMINSTAR, OP_CRPLUS, OP_CRQUERY, OP_CRRANGE, OP_CRSTAR, OP_END, OP_EXACT, OP_KET, OP_KETRMAX, OP_KETRMIN, OP_MINPLUS, OP_MINQUERY, OP_MINSTAR, OP_MINUPTO, OP_NOTEXACT, OP_NOTMINPLUS, OP_NOTMINQUERY, OP_NOTMINSTAR, OP_NOTMINUPTO, OP_NOTPLUS, OP_NOTQUERY, OP_NOTSTAR, OP_NOTUPTO, OP_ONCE, OP_OPT, OP_PLUS, OP_QUERY, OP_REF, OP_REVERSE, OP_STAR, OP_TYPEEXACT, OP_TYPEMINPLUS, OP_TYPEMINQUERY, OP_TYPEMINSTAR, OP_TYPEMINUPTO, OP_TYPEPLUS, OP_TYPEQUERY, OP_TYPESTAR, OP_TYPEUPTO, OP_UPTO, real_pcre::options, pcre, PCRE_ANCHORED, PCRE_CASELESS, PCRE_DOLLAR_ENDONLY, PCRE_DOTALL, PCRE_EXTENDED, PCRE_EXTRA, PCRE_FIRSTSET, PCRE_ICHANGED, PCRE_IMS, PCRE_MULTILINE, PCRE_REQCHSET, PCRE_STARTLINE, PCRE_UNGREEDY, PUBLIC_OPTIONS, read_repeat_counts(), real_pcre::req_char, size, real_pcre::tables, real_pcre::top_backref, real_pcre::top_bracket, and uschar.

Referenced by _list(), and String::match().

int pcre_copy_substring | ( | const char * | ,
 |  | int * | ,
 |  | int | ,
 |  | int | ,
 |  | char * | ,
 |  | int |
 | ) |

Definition at line 75 of file get.c.

References PCRE_ERROR_NOMEMORY, PCRE_ERROR_NOSUBSTRING, and size.

int pcre_exec | ( | const pcre * | ,
 |  | const pcre_extra * | ,
 |  | const char * | ,
 |  | int | ,
 |  | int | ,
 |  | int | ,
 |  | int * | ,
 |  | int |
 | ) |

Definition at line 4193 of file pcre.c.

References BOOL, real_pcre::code, match_data::ctypes, ctypes_offset, DPRINTF, match_data::end_match_ptr, match_data::end_offset_top, match_data::end_subject, match_data::endonly, match_data::errorcode, fcc_offset, real_pcre::first_char, match_data::lcc, lcc_offset, MAGIC_NUMBER, real_pcre::magic_number, match(), match_data::notbol, match_data::notempty, match_data::noteol, match_data::offset_end, match_data::offset_max, match_data::offset_overflow, match_data::offset_vector, real_pcre_extra::options, real_pcre::options, p, pcre, PCRE_ANCHORED, PCRE_CASELESS, PCRE_DOLLAR_ENDONLY, PCRE_DOTALL, PCRE_ERROR_BADMAGIC, PCRE_ERROR_BADOPTION, PCRE_ERROR_NOMATCH, PCRE_ERROR_NOMEMORY, PCRE_ERROR_NULL, pcre_extra, PCRE_FIRSTSET, PCRE_ICHANGED, PCRE_MULTILINE, PCRE_NOTBOL, PCRE_NOTEMPTY, PCRE_NOTEOL, PCRE_REQCHSET, PCRE_STARTLINE, PCRE_STUDY_MAPPED, PUBLIC_EXEC_OPTIONS, real_pcre::req_char, real_pcre_extra::start_bits, match_data::start_match, match_data::start_subject, real_pcre::tables, real_pcre::top_backref, real_pcre::top_bracket, and uschar.

Referenced by _list(), and String::match().

int pcre_get_substring | ( | const char * | ,
 |  | int * | ,
 |  | int | ,
 |  | int | ,
 |  | const char ** |
 | ) |

Definition at line 172 of file get.c.

References PCRE_ERROR_NOMEMORY, and PCRE_ERROR_NOSUBSTRING.

int pcre_get_substring_list | ( | const char * | ,
 |  | int * | ,
 |  | int | ,
 |  | const char *** |
 | ) |

Definition at line 113 of file get.c.

References p, PCRE_ERROR_NOMEMORY, and size.

int pcre_info | ( | const pcre * | ,
 |  | int * | ,
 |  | int * |
 | ) |

Definition at line 185 of file pcre.c.

References real_pcre::first_char, MAGIC_NUMBER, real_pcre::magic_number, real_pcre::options, pcre, PCRE_ERROR_BADMAGIC, PCRE_ERROR_NULL, PCRE_FIRSTSET, PCRE_STARTLINE, PUBLIC_OPTIONS, and real_pcre::top_bracket.

Referenced by String::match().

unsigned const char* pcre_maketables ( void )

Definition at line 62 of file maketables.c.

References cbit_digit, cbit_length, cbit_space, cbit_word, ctype_digit, ctype_letter, ctype_meta, ctype_space, ctype_word, ctype_xdigit, p, and tables_length.

Referenced by main().

pcre_extra* pcre_study | ( | const pcre * | ,
 |  | int | ,
 |  | const char ** |
 | ) |

Definition at line 340 of file study.c.

References compile_data::cbits, cbits_offset, real_pcre::code, compile_data::ctypes, ctypes_offset, compile_data::fcc, fcc_offset, compile_data::lcc, lcc_offset, real_pcre::magic_number, MAGIC_NUMBER, real_pcre::options, real_pcre_extra::options, pcre, PCRE_ANCHORED, PCRE_CASELESS, pcre_extra, PCRE_FIRSTSET, PCRE_STARTLINE, PCRE_STUDY_MAPPED, PUBLIC_STUDY_OPTIONS, set_start_bits(), real_pcre_extra::start_bits, real_pcre::tables, and uschar.

const char* pcre_version ( void )

Definition at line 155 of file pcre.c.

References PCRE_DATE, PCRE_MAJOR, PCRE_MINOR, and XSTRING.

Variable Documentation

PCRE_DL_IMPORT void*(* pcre_malloc)(size_t)

Definition at line 61 of file pcre.h.

PCRE_DL_IMPORT void(* pcre_free)(void *)

Definition at line 62 of file pcre.h.

Referenced by _list(), and String::match().


pcre.h Source File

pcre.h

Go to the documentation of this file.
00001 /*************************************************
00002 *       Perl-Compatible Regular Expressions      *
00003 *************************************************/
00004
00005 /* Copyright (c) 1997-1999 University of Cambridge */
00006
00007 #ifndef _PCRE_H
00008 #define _PCRE_H
00009
00010 #define PCRE_MAJOR 2
00011 #define PCRE_MINOR 08
00012 #define PCRE_DATE  31-Aug-1999
00013
00014 # define PCRE_DL_IMPORT
00015
00016 /* Have to include stdlib.h in order to ensure that size_t is defined;
00017 it is needed here for malloc. */
00018
00019 #include <sys/types.h>
00020 #include <stdlib.h>
00021
00022 /* Allow for C++ users */
00023
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027
00028 /* Options */
00029
00030 #define PCRE_CASELESS        0x0001
00031 #define PCRE_MULTILINE       0x0002
00032 #define PCRE_DOTALL          0x0004
00033 #define PCRE_EXTENDED        0x0008
00034 #define PCRE_ANCHORED        0x0010
00035 #define PCRE_DOLLAR_ENDONLY  0x0020
00036 #define PCRE_EXTRA           0x0040
00037 #define PCRE_NOTBOL          0x0080
00038 #define PCRE_NOTEOL          0x0100
00039 #define PCRE_UNGREEDY        0x0200
00040 #define PCRE_NOTEMPTY        0x0400
00041
00042 /* Exec-time and get-time error codes */
00043
00044 #define PCRE_ERROR_NOMATCH        (-1)
00045 #define PCRE_ERROR_NULL           (-2)
00046 #define PCRE_ERROR_BADOPTION      (-3)
00047 #define PCRE_ERROR_BADMAGIC       (-4)
00048 #define PCRE_ERROR_UNKNOWN_NODE   (-5)
00049 #define PCRE_ERROR_NOMEMORY       (-6)
00050 #define PCRE_ERROR_NOSUBSTRING    (-7)
00051
00052 /* Types */
00053
00054 typedef void pcre;
00055 typedef void pcre_extra;
00056
00057 /* Store get and free functions. These can be set to alternative malloc/free
00058 functions if required. Some magic is required for Win32 DLL; it is null on
00059 other OS. */
00060
00061 PCRE_DL_IMPORT extern void *(*pcre_malloc)(size_t);
00062 PCRE_DL_IMPORT extern void  (*pcre_free)(void *);
00063
00064 #undef PCRE_DL_IMPORT
00065
00066 /* Functions */
00067
00068 extern pcre *pcre_compile(const char *, int, const char **, int *,
00069   const unsigned char *);
00070 extern int pcre_copy_substring(const char *, int *, int, int, char *, int);
00071 extern int pcre_exec(const pcre *, const pcre_extra *, const char *,
00072   int, int, int, int *, int);
00073 extern int pcre_get_substring(const char *, int *, int, int, const char **);
00074 extern int pcre_get_substring_list(const char *, int *, int, const char ***);
00075 extern int pcre_info(const pcre *, int *, int *);
00076 #ifndef DFTABLES
00077 extern unsigned const char *pcre_maketables(void);
00078 #endif
00079 extern pcre_extra *pcre_study(const pcre *, int, const char **);
00080 extern const char *pcre_version(void);
00081
00082 #ifdef __cplusplus
00083 }  /* extern "C" */
00084 #endif
00085
00086 #endif /* End of pcre.h */


pcre_parser_ctype.c File Reference

Parser: $MAIN:CTYPE character types for Perl-Compatible Regular Expressions. More...

Include dependency graph for pcre_parser_ctype.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | DFTABLES
#define | TABLE_WRAP_COL 62
#define | MAX_UCM 2

Functions

const char * | out_c (char *buf, int c)
int | read_ucm (const char *file)
int | main (int argc, char *argv[])

Variables

const char * | RCSId = "$Date: 2004/07/28 14:38:20 $"
unsigned int | ucm [0x100][MAX_UCM]

Detailed Description

Parser: $MAIN:CTYPE character types for Perl-Compatible Regular Expressions.

Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)

Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Perl-Compatible Regular ExpressionsThis is a support program to generate part of auto.p, containing character tables of various kinds. They are built according to specified locale and used as the default tables by PCRE. Now that pcre_maketables is a function visible to the outside world, we make use of its code from here in order to be consistent.

PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language.

Written by: Philip Hazel <ph10@cam.ac.uk>

Copyright (c) 1997-1999 University of Cambridge

----------------------------------------------------------------------------- Permission is granted to anyone to use this software for any purpose on any computer system, and to redistribute it freely, subject to the following restrictions:

1. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2. The origin of this software must not be misrepresented, either by explicit claim or by omission.

3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software.

4. If PCRE is embedded in any software that is released under the GNU General Purpose Licence (GPL), then the terms of that licence shall supersede any condition above with which it is incompatible. -----------------------------------------------------------------------------

See the file Tech.Notes for some information on the internals.

Definition in file pcre_parser_ctype.c.

Define Documentation

#define DFTABLES

Definition at line 52 of file pcre_parser_ctype.c.

#define TABLE_WRAP_COL 62

Definition at line 56 of file pcre_parser_ctype.c.

#define MAX_UCM 2

Definition at line 69 of file pcre_parser_ctype.c.

Referenced by main(), and read_ucm().

Function Documentation

const char* out_c | ( | char * | buf,
 |  | int | c
 | ) |

Definition at line 58 of file pcre_parser_ctype.c.

Referenced by main().

int read_ucm ( const char * file )

Definition at line 72 of file pcre_parser_ctype.c.

References file, MAX_UCM, and ucm.

Referenced by main().

int main | ( | int | argc,
 |  | char * | argv[]
 | ) |

Definition at line 105 of file pcre_parser_ctype.c.

References ctype_digit, ctype_letter, ctype_space, ctype_word, ctype_xdigit, ctypes_offset, lcc_offset, MAX_UCM, out_c(), pcre_maketables(), read_ucm(), and ucm.

Variable Documentation

const char* RCSId = "$Date: 2004/07/28 14:38:20 $" [static]

Definition at line 45 of file pcre_parser_ctype.c.

unsigned int ucm[0x100][MAX_UCM]

Definition at line 70 of file pcre_parser_ctype.c.

Referenced by main(), and read_ucm().


pcre_parser_ctype.c Source File

pcre_parser_ctype.c

Go to the documentation of this file.
00001
00045 static const char *RCSId="$Date: 2004/07/28 14:38:20 $";
00046
00047 #include <ctype.h>
00048 #include <stdio.h>
00049 #include <string.h>
00050 #include <locale.h>
00051
00052 #define DFTABLES
00053 #include "internal.h"
00054 #include "maketables.c"
00055
00056 #define TABLE_WRAP_COL 62
00057
00058 const char *out_c(char *buf, int c) {
00059     sprintf(buf,
00060         isprint((unsigned char)c)&&
00061         !isspace((unsigned char)c) &&
00062         c!='#' &&
00063         c!='"' &&
00064         c<128?
00065         "%c":"0x%02X", c);
00066     return buf;
00067 }
00068
00069 #define MAX_UCM 2
00070 unsigned int ucm[0x100][MAX_UCM];
00071
00072 int read_ucm(const char *file) {
00073     unsigned int unicode;
00074     unsigned int ch;
00075     char buf[0x400];
00076     int i;
00077     int ok;
00078
00079     FILE *f=fopen(file, "rt");
00080
00081     if(!f)
00082         return 1;
00083
00084     memset(ucm, 0, sizeof(ucm));
00085
00086     while(!feof(f)) {
00087         fgets(buf, sizeof(buf), f);
00088         if(sscanf(buf, "<U%04X> \\x%02X", &unicode, &ch)) {
00089             ok=0;
00090             for(i=0; i<MAX_UCM; i++)
00091                 if(ucm[ch][i]==0) {
00092                     ucm[ch][i]=unicode;
00093                     ok=1;
00094                     break;
00095                 }
00096             if(!ok)
00097                 return 2;
00098         }
00099     }
00100
00101     fclose(f);
00102     return 0;
00103 }
00104
00105 int main(int argc, char *argv[])
00106 {
00107     unsigned const char *tables, *ctypes_table, *case_table;
00108     unsigned int c;
00109     char buf_c[0x100];
00110     char buf_lc[0x100];
00111     int error;
00112     int i, printed;
00113
00114     if(argc<3) {
00115         printf("Usage: %s Russian_Russia.1251 ibm-1251.ucm  (locale-name)\n", argv[0]?argv[0]:"pcre_parser_ctype");
00116         return 1;
00117     }
00118
00119     // Russian_Russia.1251
00120     if(!setlocale(LC_CTYPE, argv[1])) {
00121         printf("locale '%s' is invalid", argv[1]);
00122         return 2;
00123     }
00124     // ibm-1251.ucm
00125     error=read_ucm(argv[2]);
00126     if(error) {
00127         switch(error) {
00128         case 1:
00129             printf("could not read '%s'", argv[2]);
00130             break;
00131         case 2:
00132             printf("could store all unicode variants of  '%s'", argv[2]);
00133             break;
00134         default:
00135             printf("problem with '%s'", argv[2]);
00136             break;
00137         }
00138         return 3;
00139     }
00140
00141     tables = pcre_maketables();
00142     ctypes_table=tables+ctypes_offset;
00143     case_table=tables+lcc_offset;
00144
00145     printf(
00146         "char\t"
00147         "white-space\t"
00148         "digit\t"
00149         "hex-digit\t"
00150         "letter\t"
00151         "word\t"
00152         "lowercase\t"
00153         "unicode1\t"
00154         "unicode2\t"
00155         "\n");
00156
00157     for(c=0; c<0x100; c++)
00158         if(
00159             ctypes_table[c]&(ctype_space|ctype_digit|ctype_xdigit|ctype_letter|ctype_word) ||
00160             ispunct((unsigned char)c) ||
00161             c!=case_table[c] /*||
00162             !(c==ucm[c][0] && ucm[c][1]==0)*/
00163             ) {
00164             printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t",
00165                 out_c(buf_c, c),
00166                 ctypes_table[c]&ctype_space?"x":"",
00167                 ctypes_table[c]&ctype_digit?"x":"",
00168                 ctypes_table[c]&ctype_xdigit?"x":"",
00169                 ctypes_table[c]&ctype_letter?"x":"",
00170                 ctypes_table[c]&ctype_word?"x":"",
00171                 case_table[c]&&c!=case_table[c]?out_c(buf_lc, case_table[c]):""
00172             );
00173             if(!(c==ucm[c][0] && ucm[c][1]==0)) {
00174                 printed=0;
00175                 for(i=0; i<MAX_UCM; i++) {
00176                     if(ucm[c][i]) {
00177                         if(printed!=0)
00178                             printf("\t");
00179                         printf("0x%04X", ucm[c][i]);
00180                         printed++;
00181                     }
00182                 }
00183             }
00184             printf("\n");
00185         }
00186
00187     return 0;
00188 }


pooled.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


response.C File Reference

Parser: response parser class. More...

Include dependency graph for response.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MResponse

Functions

DECLARE_CLASS_VAR (response, new MResponse, 0)
void | _clear (Request &r, MethodParams &)

Variables

const char *const | IDENT_RESPONSE_C = "$Date: 2005/08/09 08:14:48 $"

Detailed Description

Parser: response parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file response.C.

Function Documentation

DECLARE_CLASS_VAR | ( | response | ,
 |  | new | MResponse,
 |  | 0 |
 | ) |

void _clear | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 31 of file response.C.

References GET_SELF.

Referenced by MResponse::MResponse().

Variable Documentation

const char* const IDENT_RESPONSE_C = "$Date: 2005/08/09 08:14:48 $" [static]

Definition at line 8 of file response.C.


response.C Source File

response.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_RESPONSE_C="$Date: 2005/08/09 08:14:48 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vresponse.h"
00015
00016 // class
00017
00018 class MResponse: public Methoded {
00019 public:
00020     MResponse();
00021 public: // Methoded
00022     bool used_directly() { return false; }
00023 };
00024
00025 // global variable
00026
00027 DECLARE_CLASS_VAR(response, new MResponse, 0);
00028
00029 // methods
00030
00031 static void _clear(Request& r, MethodParams&) {
00032     GET_SELF(r, VResponse).fields().clear();
00033 }
00034
00035 // constructor
00036
00037 MResponse::MResponse(): Methoded("response") {
00038     // ^clear[]
00039     add_native_method("clear", Method::CT_DYNAMIC, _clear, 0, 0);
00040 }


sdbm.c File Reference

Include dependency graph for sdbm.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | bad(x) ((x).dptr == NULL || (x).dsize <= 0)
#define | exhash(item) sdbm_hash((item).dptr, (item).dsize)
#define | sdbm_dirfno(db) ((db)->dirf)
#define | sdbm_pagfno(db) ((db)->pagf)
#define | OFF_PAG(off) (apr_off_t) (off) * PBLKSIZ
#define | OFF_DIR(off) (apr_off_t) (off) * DBLKSIZ

Functions

int | getdbit (apr_sdbm_t *, long)
apr_status_t | setdbit (apr_sdbm_t *, long)
apr_status_t | getpage (apr_sdbm_t *db, long)
apr_status_t | getnext (apr_sdbm_datum_t *key, apr_sdbm_t *db)
apr_status_t | makroom (apr_sdbm_t *, long, int)
apr_status_t | database_cleanup (void *data)
apr_status_t | prep (apr_sdbm_t **pdb, const char *dirname, const char *pagname, apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p)
APU_DECLARE (apr_status_t) apr_sdbm_open(apr_sdbm_t **db

Variables

long | masks []
const apr_sdbm_datum_t | sdbm_nullitem = { NULL, 0 }
const char * | file
const char apr_int32_t | flags
const char apr_int32_t apr_fileperms_t | perms

Define Documentation

#define bad ( x ) ((x).dptr == NULL || (x).dsize <= 0)

Definition at line 88 of file sdbm.c.

#define exhash ( item ) sdbm_hash((item).dptr, (item).dsize)

Definition at line 89 of file sdbm.c.

#define sdbm_dirfno ( db ) ((db)->dirf)

Definition at line 92 of file sdbm.c.

#define sdbm_pagfno ( db ) ((db)->pagf)

Definition at line 93 of file sdbm.c.

#define OFF_PAG ( off ) (apr_off_t) (off) * PBLKSIZ

Definition at line 95 of file sdbm.c.

#define OFF_DIR ( off ) (apr_off_t) (off) * DBLKSIZ

Definition at line 96 of file sdbm.c.

Function Documentation

int getdbit | ( | apr_sdbm_t * | ,
 |  | long |
 | ) | [static]

apr_status_t setdbit | ( | apr_sdbm_t * | ,
 |  | long |
 | ) | [static]

apr_status_t getpage | ( | apr_sdbm_t * | db,
 |  | long |
 | ) | [static]

apr_status_t getnext | ( | apr_sdbm_datum_t * | key,
 |  | apr_sdbm_t * | db
 | ) | [static]

apr_status_t makroom | ( | apr_sdbm_t * | ,
 |  | long | ,
 |  | int |
 | ) | [static]

apr_status_t database_cleanup ( void * data ) [static]

Definition at line 111 of file sdbm.c.

References apr_status_t, APR_SUCCESS, data, apr_sdbm_t::dirf, apr_sdbm_t::flags, apr_sdbm_t::pagf, SDBM_EXCLUSIVE_LOCK, and SDBM_SHARED_LOCK.

apr_status_t prep | ( | apr_sdbm_t ** | pdb,
 |  | const char * | dirname,
 |  | const char * | pagname,
 |  | apr_int32_t | flags,
 |  | apr_fileperms_t | perms,
 |  | apr_pool_t * | p
 | ) | [static]

Definition at line 128 of file sdbm.c.

References APR_BINARY, apr_fileperms_t, APR_FLOCK_EXCLUSIVE, APR_FLOCK_SHARED, apr_int32_t, apr_pool_t, APR_READ, APR_SHARELOCK, apr_status_t, APR_SUCCESS, APR_WRITE, apr_sdbm_t::dirf, dirname, apr_sdbm_t::flags, flags, p, apr_sdbm_t::pagf, perms, apr_sdbm_t::pool, SDBM_RDONLY, and SDBM_SHARED.

Variable Documentation

long masks[] [static]

Initial value:

 {
        000000000000, 000000000001, 000000000003, 000000000007,
        000000000017, 000000000037, 000000000077, 000000000177,
        000000000377, 000000000777, 000000001777, 000000003777,
        000000007777, 000000017777, 000000037777, 000000077777,
        000000177777, 000000377777, 000000777777, 000001777777,
        000003777777, 000007777777, 000017777777, 000037777777,
        000077777777, 000177777777, 000377777777, 000777777777,
        001777777777, 003777777777, 007777777777, 017777777777
}

Definition at line 98 of file sdbm.c.

const apr_sdbm_datum_t sdbm_nullitem = { NULL, 0 }

Definition at line 109 of file sdbm.c.

const char* file

Definition at line 212 of file sdbm.c.

Referenced by _load(), cache_get(), file_read_text(), MFile::MFile(), pa_ap_log_error(), pa_ap_log_rerror(), and read_ucm().

const char apr_int32_t flags

Definition at line 212 of file sdbm.c.

Referenced by prep().

const char apr_int32_t apr_fileperms_t perms

Definition at line 212 of file sdbm.c.

Referenced by prep().


sdbm.c Source File

sdbm.c

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * sdbm - ndbm work-alike hashed database library
00057  * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
00058  * author: oz@nexus.yorku.ca
00059  * ex-public domain, ported to APR for Apache 2
00060  * core routines
00061  */
00062
00063 #include "apr.h"
00064 #include "apr_file_io.h"
00065 #include "apr_strings.h"
00066 #include "apr_errno.h"
00067 #include "apr_sdbm.h"
00068
00069 #include "sdbm_tune.h"
00070 #include "sdbm_pair.h"
00071 #include "sdbm_private.h"
00072
00073 #include <string.h>     /* for memset() */
00074 #include <stdlib.h>     /* for malloc() and free() */
00075
00076 /*
00077  * forward
00078  */
00079 static int getdbit (apr_sdbm_t *, long);
00080 static apr_status_t setdbit(apr_sdbm_t *, long);
00081 static apr_status_t getpage(apr_sdbm_t *db, long);
00082 static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db);
00083 static apr_status_t makroom(apr_sdbm_t *, long, int);
00084
00085 /*
00086  * useful macros
00087  */
00088 #define bad(x)      ((x).dptr == NULL || (x).dsize <= 0)
00089 #define exhash(item)    sdbm_hash((item).dptr, (item).dsize)
00090
00091 /* ### Does anything need these externally? */
00092 #define sdbm_dirfno(db) ((db)->dirf)
00093 #define sdbm_pagfno(db) ((db)->pagf)
00094
00095 #define OFF_PAG(off)    (apr_off_t) (off) * PBLKSIZ
00096 #define OFF_DIR(off)    (apr_off_t) (off) * DBLKSIZ
00097
00098 static long masks[] = {
00099         000000000000, 000000000001, 000000000003, 000000000007,
00100         000000000017, 000000000037, 000000000077, 000000000177,
00101         000000000377, 000000000777, 000000001777, 000000003777,
00102         000000007777, 000000017777, 000000037777, 000000077777,
00103         000000177777, 000000377777, 000000777777, 000001777777,
00104         000003777777, 000007777777, 000017777777, 000037777777,
00105         000077777777, 000177777777, 000377777777, 000777777777,
00106         001777777777, 003777777777, 007777777777, 017777777777
00107 };
00108
00109 const apr_sdbm_datum_t sdbm_nullitem = { NULL, 0 };
00110
00111 static apr_status_t database_cleanup(void *data)
00112 {
00113     apr_sdbm_t *db = data;
00114
00115     /*
00116      * Can't rely on apr_sdbm_unlock, since it will merely
00117      * decrement the refcnt if several locks are held.
00118      */
00119     if (db->flags & (SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK))
00120         (void) apr_file_unlock(db->dirf);
00121     (void) apr_file_close(db->dirf);
00122     (void) apr_file_close(db->pagf);
00123     free(db);
00124
00125     return APR_SUCCESS;
00126 }
00127
00128 static apr_status_t prep(apr_sdbm_t **pdb, const char *dirname, const char *pagname,
00129                          apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p)
00130 {
00131     apr_sdbm_t *db;
00132     apr_status_t status;
00133
00134     *pdb = NULL;
00135
00136     db = malloc(sizeof(*db));
00137     memset(db, 0, sizeof(*db));
00138
00139     db->pool = p;
00140
00141     /*
00142      * adjust user flags so that WRONLY becomes RDWR,
00143      * as required by this package. Also set our internal
00144      * flag for RDONLY if needed.
00145      */
00146     if (!(flags & APR_WRITE)) {
00147         db->flags |= SDBM_RDONLY;
00148     }
00149
00150     /*
00151      * adjust the file open flags so that we handle locking
00152      * on our own (don't rely on any locking behavior within
00153      * an apr_file_t, in case it's ever introduced, and set
00154      * our own flag.
00155      */
00156     if (flags & APR_SHARELOCK) {
00157         db->flags |= SDBM_SHARED;
00158         flags &= ~APR_SHARELOCK;
00159     }
00160
00161     flags |= APR_BINARY | APR_READ;
00162
00163     /*
00164      * open the files in sequence, and stat the dirfile.
00165      * If we fail anywhere, undo everything, return NULL.
00166      */
00167
00168     if ((status = apr_file_open(&db->dirf, dirname, flags, perms, p))
00169                 != APR_SUCCESS)
00170         goto error;
00171
00172     if ((status = apr_file_open(&db->pagf, pagname, flags, perms, p))
00173                 != APR_SUCCESS)
00174         goto error;
00175
00176     if ((status = apr_sdbm_lock(db, (db->flags & SDBM_RDONLY)
00177                                         ? APR_FLOCK_SHARED
00178                                         : APR_FLOCK_EXCLUSIVE))
00179                 != APR_SUCCESS)
00180         goto error;
00181
00182     /* apr_pcalloc zeroed the buffers
00183      * apr_sdbm_lock stated the dirf->size and invalidated the cache
00184      */
00185
00186     /*
00187      * if we are opened in SHARED mode, unlock ourself
00188      */
00189     if (db->flags & SDBM_SHARED)
00190         if ((status = apr_sdbm_unlock(db)) != APR_SUCCESS)
00191             goto error;
00192
00193     /* make sure that we close the database at some point */
00194     //apr_pool_cleanup_register(p, db, database_cleanup, apr_pool_cleanup_null);
00195
00196     /* Done! */
00197     *pdb = db;
00198     return APR_SUCCESS;
00199
00200 error:
00201     if (db->dirf && db->pagf)
00202         (void) apr_sdbm_unlock(db);
00203     if (db->dirf != NULL)
00204         (void) apr_file_close(db->dirf);
00205     if (db->pagf != NULL) {
00206         (void) apr_file_close(db->pagf);
00207     }
00208     free(db);
00209     return status;
00210 }
00211
00212 APU_DECLARE(apr_status_t) apr_sdbm_open(apr_sdbm_t **db, const char *file,
00213                                         apr_int32_t flags,
00214                                         apr_fileperms_t perms, apr_pool_t *p)
00215 {
00216     char *dirname = apr_pstrcat(p, file, APR_SDBM_DIRFEXT, NULL);
00217     char *pagname = apr_pstrcat(p, file, APR_SDBM_PAGFEXT, NULL);
00218
00219     return prep(db, dirname, pagname, flags, perms, p);
00220 }
00221
00222 APU_DECLARE(apr_status_t) apr_sdbm_close(apr_sdbm_t *db)
00223 {
00224     database_cleanup(db); return APR_SUCCESS;
00225     //return apr_pool_cleanup_run(db->pool, db, database_cleanup);
00226 }
00227
00228 APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db, apr_sdbm_datum_t *val,
00229                                          apr_sdbm_datum_t key)
00230 {
00231     apr_status_t status;
00232
00233     if (db == NULL || bad(key))
00234         return APR_EINVAL;
00235
00236     if ((status = apr_sdbm_lock(db, APR_FLOCK_SHARED)) != APR_SUCCESS)
00237         return status;
00238
00239     if ((status = getpage(db, exhash(key))) == APR_SUCCESS) {
00240         *val = getpair(db->pagbuf, key);
00241         /* ### do we want a not-found result? */
00242     }
00243
00244     (void) apr_sdbm_unlock(db);
00245
00246     return status;
00247 }
00248
00249 static apr_status_t write_page(apr_sdbm_t *db, const char *buf, long pagno)
00250 {
00251     apr_status_t status;
00252     apr_off_t off = OFF_PAG(pagno);
00253
00254     if ((status = apr_file_seek(db->pagf, APR_SET, &off)) == APR_SUCCESS)
00255         status = apr_file_write_full(db->pagf, buf, PBLKSIZ, NULL);
00256
00257     return status;
00258 }
00259
00260 APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db,
00261                                           const apr_sdbm_datum_t key)
00262 {
00263     apr_status_t status;
00264
00265     if (db == NULL || bad(key))
00266         return APR_EINVAL;
00267     if (apr_sdbm_rdonly(db))
00268         return APR_EINVAL;
00269
00270     if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS)
00271         return status;
00272
00273     if ((status = getpage(db, exhash(key))) == APR_SUCCESS) {
00274         if (!delpair(db->pagbuf, key))
00275             /* ### should we define some APRUTIL codes? */
00276             status = APR_SUCCESS; /* PAF: were APR_EGENERAL, contradicting comment in .h file :( */
00277         else
00278             status = write_page(db, db->pagbuf, db->pagbno);
00279     }
00280
00281     (void) apr_sdbm_unlock(db);
00282
00283     return status;
00284 }
00285
00286 APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key,
00287                                          apr_sdbm_datum_t val, int flags)
00288 {
00289     int need;
00290     register long hash;
00291     apr_status_t status;
00292
00293     if (db == NULL || bad(key))
00294         return APR_EINVAL;
00295     if (apr_sdbm_rdonly(db))
00296         return APR_EINVAL;
00297     need = key.dsize + val.dsize;
00298     /*
00299      * is the pair too big (or too small) for this database ??
00300      */
00301     if (need < 0 || need > PAIRMAX)
00302         return APR_EINVAL;
00303
00304     if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS)
00305         return status;
00306
00307     if ((status = getpage(db, (hash = exhash(key)))) == APR_SUCCESS) {
00308
00309         /*
00310          * if we need to replace, delete the key/data pair
00311          * first. If it is not there, ignore.
00312          */
00313         if (flags == APR_SDBM_REPLACE)
00314             (void) delpair(db->pagbuf, key);
00315         else if (!(flags & APR_SDBM_INSERTDUP) && duppair(db->pagbuf, key)) {
00316             status = APR_EEXIST;
00317             goto error;
00318         }
00319         /*
00320          * if we do not have enough room, we have to split.
00321          */
00322         if (!fitpair(db->pagbuf, need))
00323             if ((status = makroom(db, hash, need)) != APR_SUCCESS)
00324                 goto error;
00325         /*
00326          * we have enough room or split is successful. insert the key,
00327          * and update the page file.
00328          */
00329         (void) putpair(db->pagbuf, key, val);
00330
00331         status = write_page(db, db->pagbuf, db->pagbno);
00332     }
00333
00334 error:
00335     (void) apr_sdbm_unlock(db);
00336
00337     return status;
00338 }
00339
00340 /*
00341  * makroom - make room by splitting the overfull page
00342  * this routine will attempt to make room for SPLTMAX times before
00343  * giving up.
00344  */
00345 static apr_status_t makroom(apr_sdbm_t *db, long hash, int need)
00346 {
00347     long newp;
00348     char twin[PBLKSIZ];
00349     char *pag = db->pagbuf;
00350     char *new = twin;
00351     register int smax = SPLTMAX;
00352     apr_status_t status;
00353
00354     do {
00355         /*
00356          * split the current page
00357          */
00358         (void) splpage(pag, new, db->hmask + 1);
00359         /*
00360          * address of the new page
00361          */
00362         newp = (hash & db->hmask) | (db->hmask + 1);
00363
00364         /*
00365          * write delay, read avoidence/cache shuffle:
00366          * select the page for incoming pair: if key is to go to the new page,
00367          * write out the previous one, and copy the new one over, thus making
00368          * it the current page. If not, simply write the new page, and we are
00369          * still looking at the page of interest. current page is not updated
00370          * here, as sdbm_store will do so, after it inserts the incoming pair.
00371          */
00372         if (hash & (db->hmask + 1)) {
00373             if ((status = write_page(db, db->pagbuf, db->pagbno))
00374                         != APR_SUCCESS)
00375                 return status;
00376
00377             db->pagbno = newp;
00378             (void) memcpy(pag, new, PBLKSIZ);
00379         }
00380         else {
00381             if ((status = write_page(db, new, newp)) != APR_SUCCESS)
00382                 return status;
00383         }
00384
00385         if ((status = setdbit(db, db->curbit)) != APR_SUCCESS)
00386             return status;
00387         /*
00388          * see if we have enough room now
00389          */
00390         if (fitpair(pag, need))
00391             return APR_SUCCESS;
00392         /*
00393          * try again... update curbit and hmask as getpage would have
00394          * done. because of our update of the current page, we do not
00395          * need to read in anything. BUT we have to write the current
00396          * [deferred] page out, as the window of failure is too great.
00397          */
00398         db->curbit = 2 * db->curbit
00399                    + ((hash & (db->hmask + 1)) ? 2 : 1);
00400         db->hmask |= db->hmask + 1;
00401
00402         if ((status = write_page(db, db->pagbuf, db->pagbno))
00403                     != APR_SUCCESS)
00404             return status;
00405
00406     } while (--smax);
00407
00408     /*
00409      * if we are here, this is real bad news. After SPLTMAX splits,
00410      * we still cannot fit the key. say goodnight.
00411      */
00412 #if 0
00413     (void) write(2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44);
00414 #endif
00415     /* ### ENOSPC not really appropriate but better than nothing */
00416     return APR_ENOSPC;
00417
00418 }
00419
00420 /* Reads 'len' bytes from file 'f' at offset 'off' into buf.
00421  * 'off' is given relative to the start of the file.
00422  * If EOF is returned while reading, this is taken as success.
00423  */
00424 static apr_status_t read_from(apr_file_t *f, void *buf,
00425              apr_off_t off, apr_size_t len)
00426 {
00427     apr_status_t status;
00428
00429     if ((status = apr_file_seek(f, APR_SET, &off)) != APR_SUCCESS ||
00430         ((status = apr_file_read_full(f, buf, len, NULL)) != APR_SUCCESS)) {
00431         /* if EOF is reached, pretend we read all zero's */
00432         if (status == APR_EOF) {
00433             memset(buf, 0, len);
00434             status = APR_SUCCESS;
00435         }
00436     }
00437
00438     return status;
00439 }
00440
00441 /*
00442  * the following two routines will break if
00443  * deletions aren't taken into account. (ndbm bug)
00444  */
00445 APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db,
00446                                             apr_sdbm_datum_t *key)
00447 {
00448     apr_status_t status;
00449
00450     if ((status = apr_sdbm_lock(db, APR_FLOCK_SHARED)) != APR_SUCCESS)
00451         return status;
00452
00453     /*
00454      * start at page 0
00455      */
00456     if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(0), PBLKSIZ))
00457                 == APR_SUCCESS) {
00458         db->pagbno = 0;
00459         db->blkptr = 0;
00460         db->keyptr = 0;
00461         status = getnext(key, db);
00462     }
00463
00464     (void) apr_sdbm_unlock(db);
00465
00466     return status;
00467 }
00468
00469 APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db,
00470                                            apr_sdbm_datum_t *key)
00471 {
00472     apr_status_t status;
00473
00474     if ((status = apr_sdbm_lock(db, APR_FLOCK_SHARED)) != APR_SUCCESS)
00475         return status;
00476
00477     status = getnext(key, db);
00478
00479     (void) apr_sdbm_unlock(db);
00480
00481     return status;
00482 }
00483
00484 /*
00485  * all important binary tree traversal
00486  */
00487 static apr_status_t getpage(apr_sdbm_t *db, long hash)
00488 {
00489     register int hbit;
00490     register long dbit;
00491     register long pagb;
00492     apr_status_t status;
00493
00494     dbit = 0;
00495     hbit = 0;
00496     while (dbit < db->maxbno && getdbit(db, dbit))
00497     dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
00498
00499     debug(("dbit: %d...", dbit));
00500
00501     db->curbit = dbit;
00502     db->hmask = masks[hbit];
00503
00504     pagb = hash & db->hmask;
00505     /*
00506      * see if the block we need is already in memory.
00507      * note: this lookaside cache has about 10% hit rate.
00508      */
00509     if (pagb != db->pagbno) {
00510         /*
00511          * note: here, we assume a "hole" is read as 0s.
00512          * if not, must zero pagbuf first.
00513          * ### joe: this assumption was surely never correct? but
00514          * ### we make it so in read_from anyway.
00515          */
00516         if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(pagb), PBLKSIZ))
00517                     != APR_SUCCESS)
00518             return status;
00519
00520         if (!chkpage(db->pagbuf))
00521             return APR_ENOSPC; /* ### better error? */
00522         db->pagbno = pagb;
00523
00524         debug(("pag read: %d\n", pagb));
00525     }
00526     return APR_SUCCESS;
00527 }
00528
00529 static int getdbit(apr_sdbm_t *db, long dbit)
00530 {
00531     register long c;
00532     register long dirb;
00533
00534     c = dbit / BYTESIZ;
00535     dirb = c / DBLKSIZ;
00536
00537     if (dirb != db->dirbno) {
00538         if (read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ)
00539                     != APR_SUCCESS)
00540             return 0;
00541
00542         db->dirbno = dirb;
00543
00544         debug(("dir read: %d\n", dirb));
00545     }
00546
00547     return db->dirbuf[c % DBLKSIZ] & (1 << dbit % BYTESIZ);
00548 }
00549
00550 static apr_status_t setdbit(apr_sdbm_t *db, long dbit)
00551 {
00552     register long c;
00553     register long dirb;
00554     apr_status_t status;
00555     apr_off_t off;
00556
00557     c = dbit / BYTESIZ;
00558     dirb = c / DBLKSIZ;
00559
00560     if (dirb != db->dirbno) {
00561         if ((status = read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ))
00562                     != APR_SUCCESS)
00563             return status;
00564
00565         db->dirbno = dirb;
00566
00567         debug(("dir read: %d\n", dirb));
00568     }
00569
00570     db->dirbuf[c % DBLKSIZ] |= (1 << dbit % BYTESIZ);
00571
00572     if (dbit >= db->maxbno)
00573         db->maxbno += DBLKSIZ * BYTESIZ;
00574
00575     off = OFF_DIR(dirb);
00576     if ((status = apr_file_seek(db->dirf, APR_SET, &off)) == APR_SUCCESS)
00577         status = apr_file_write_full(db->dirf, db->dirbuf, DBLKSIZ, NULL);
00578
00579     return status;
00580 }
00581
00582 /*
00583 * getnext - get the next key in the page, and if done with
00584 * the page, try the next page in sequence
00585 */
00586 static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db)
00587 {
00588     apr_status_t status;
00589     for (;;) {
00590         db->keyptr++;
00591         *key = getnkey(db->pagbuf, db->keyptr);
00592         if (key->dptr != NULL)
00593             return APR_SUCCESS;
00594         /*
00595          * we either run out, or there is nothing on this page..
00596          * try the next one... If we lost our position on the
00597          * file, we will have to seek.
00598          */
00599         db->keyptr = 0;
00600         if (db->pagbno != db->blkptr++) {
00601             apr_off_t off = OFF_PAG(db->blkptr);
00602             if ((status = apr_file_seek(db->pagf, APR_SET, &off)
00603                         != APR_SUCCESS))
00604                 return status;
00605         }
00606
00607         db->pagbno = db->blkptr;
00608         /* ### EOF acceptable here too? */
00609         if ((status = apr_file_read_full(db->pagf, db->pagbuf, PBLKSIZ, NULL))
00610                     != APR_SUCCESS)
00611             return status;
00612         if (!chkpage(db->pagbuf))
00613             return APR_EGENERAL;     /* ### need better error */
00614     }
00615
00616     /* NOTREACHED */
00617 }
00618
00619
00620 APU_DECLARE(int) apr_sdbm_rdonly(apr_sdbm_t *db)
00621 {
00622     /* ### Should we return true if the first lock is a share lock,
00623      *     to reflect that apr_sdbm_store and apr_sdbm_delete will fail?
00624      */
00625     return (db->flags & SDBM_RDONLY) != 0;
00626 }
00627


sdbm_hash.c File Reference

Include dependency graph for sdbm_hash.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | DUFF
#define | HASHC n = *str++ + 65599 * n

Functions

long | sdbm_hash (const char *str, int len)

Define Documentation

#define DUFF

#define HASHC n = *str++ + 65599 * n

Function Documentation

long sdbm_hash | ( | const char * | str,
 |  | int | len
 | ) |

Definition at line 74 of file sdbm_hash.c.

References str.


sdbm_hash.c Source File

sdbm_hash.c

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * sdbm - ndbm work-alike hashed database library
00057  * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
00058  * author: oz@nexus.yorku.ca
00059  * status: ex-public domain. keep it that way.
00060  *
00061  * hashing routine
00062  */
00063
00064 #include "apr_sdbm.h"
00065 #include "sdbm_private.h"
00066
00067 /*
00068  * polynomial conversion ignoring overflows
00069  * [this seems to work remarkably well, in fact better
00070  * then the ndbm hash function. Replace at your own risk]
00071  * use: 65599   nice.
00072  *      65587   even better.
00073  */
00074 long sdbm_hash(const char *str, int len)
00075 {
00076     register unsigned long n = 0;
00077
00078 #define DUFF    /* go ahead and use the loop-unrolled version */
00079 #ifdef DUFF
00080
00081 #define HASHC   n = *str++ + 65599 * n
00082
00083     if (len > 0) {
00084         register int loop = (len + 8 - 1) >> 3;
00085
00086         switch(len & (8 - 1)) {
00087         case 0: do {
00088             HASHC;  case 7: HASHC;
00089         case 6: HASHC;  case 5: HASHC;
00090         case 4: HASHC;  case 3: HASHC;
00091         case 2: HASHC;  case 1: HASHC;
00092             } while (--loop);
00093         }
00094
00095     }
00096 #else
00097     while (len--)
00098         n = *str++ + 65599 * n;
00099 #endif
00100     return n;
00101 }


sdbm_lock.c File Reference

Include dependency graph for sdbm_lock.c:

Include dependency graph

Go to the source code of this file.

Functions

APU_DECLARE (apr_status_t) apr_sdbm_lock(apr_sdbm_t *db


sdbm_lock.c Source File

sdbm_lock.c

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #include "apr_file_info.h"
00056 #include "apr_file_io.h"
00057 #include "apr_sdbm.h"
00058
00059 #include "sdbm_private.h"
00060 #include "sdbm_tune.h"
00061
00062 /* NOTE: this function blocks until it acquires the lock */
00063 APU_DECLARE(apr_status_t) apr_sdbm_lock(apr_sdbm_t *db, int type)
00064 {
00065     apr_status_t status;
00066
00067     if (!(type == APR_FLOCK_SHARED || type == APR_FLOCK_EXCLUSIVE))
00068         return APR_EINVAL;
00069
00070     if (db->flags & SDBM_EXCLUSIVE_LOCK) {
00071         ++db->lckcnt;
00072         return APR_SUCCESS;
00073     }
00074     else if (db->flags & SDBM_SHARED_LOCK) {
00075         /*
00076          * Cannot promote a shared lock to an exlusive lock
00077          * in a cross-platform compatibile manner.
00078          */
00079         if (type == APR_FLOCK_EXCLUSIVE)
00080             return APR_EINVAL;
00081         ++db->lckcnt;
00082         return APR_SUCCESS;
00083     }
00084     /*
00085      * zero size: either a fresh database, or one with a single,
00086      * unsplit data page: dirpage is all zeros.
00087      */
00088     if ((status = apr_file_lock(db->dirf, type)) == APR_SUCCESS)
00089     {
00090         apr_finfo_t finfo;
00091         if ((status = apr_file_info_get(&finfo, APR_FINFO_SIZE, db->dirf))
00092                 != APR_SUCCESS) {
00093             (void) apr_file_unlock(db->dirf);
00094             return status;
00095         }
00096
00097         SDBM_INVALIDATE_CACHE(db, finfo);
00098
00099         ++db->lckcnt;
00100         if (type == APR_FLOCK_SHARED)
00101             db->flags |= SDBM_SHARED_LOCK;
00102         else if (type == APR_FLOCK_EXCLUSIVE)
00103             db->flags |= SDBM_EXCLUSIVE_LOCK;
00104     }
00105     return status;
00106 }
00107
00108 APU_DECLARE(apr_status_t) apr_sdbm_unlock(apr_sdbm_t *db)
00109 {
00110     if (!(db->flags & (SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK)))
00111         return APR_EINVAL;
00112     if (--db->lckcnt > 0)
00113         return APR_SUCCESS;
00114     db->flags &= ~(SDBM_SHARED_LOCK | SDBM_EXCLUSIVE_LOCK);
00115     return apr_file_unlock(db->dirf);
00116 }


sdbm_pair.c File Reference

Include dependency graph for sdbm_pair.c:

Include dependency graph

Go to the source code of this file.

Defines

#define | exhash(item) sdbm_hash((item).dptr, (item).dsize)

Functions

int | seepair (char *, int, char *, int)
int | fitpair (pag, need) char *pag

Variables

int | need
apr_sdbm_datum_t key
apr_sdbm_datum_t val
int | num
register int | n
register int | siz
char * | new
long | sbit

Define Documentation

#define exhash ( item ) sdbm_hash((item).dptr, (item).dsize)

Definition at line 73 of file sdbm_pair.c.

Function Documentation

int seepair | ( | char * | ,
 |  | int | ,
 |  | char * | ,
 |  | int |
 | ) | [static]

int fitpair | ( | pag | ,
 |  | need |
 | ) |

Variable Documentation

int need

Definition at line 103 of file sdbm_pair.c.

register char* key

Definition at line 275 of file sdbm_pair.c.

apr_sdbm_datum_t val

Definition at line 123 of file sdbm_pair.c.

Referenced by _sql(), pa_ap_table_addn(), and SAPI_environment_append().

int num

Definition at line 181 of file sdbm_pair.c.

register int n

Definition at line 274 of file sdbm_pair.c.

register int siz

Definition at line 276 of file sdbm_pair.c.

char* new

Definition at line 294 of file sdbm_pair.c.

Referenced by Methoded::Methoded(), PA_exec_result::PA_exec_result(), Request::Request(), Table::Table(), TableSeparators::TableSeparators(), VString::VString(), and WContext::WContext().

long sbit

Definition at line 295 of file sdbm_pair.c.


sdbm_pair.c Source File

sdbm_pair.c

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * sdbm - ndbm work-alike hashed database library
00057  * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
00058  * author: oz@nexus.yorku.ca
00059  * status: ex-public domain.
00060  *
00061  * page-level routines
00062  */
00063
00064 #include "apr_sdbm.h"
00065
00066 #include "sdbm_tune.h"
00067 #include "sdbm_pair.h"
00068 #include "sdbm_private.h"
00069
00070 #include <string.h> /* for memset() */
00071
00072
00073 #define exhash(item)    sdbm_hash((item).dptr, (item).dsize)
00074
00075 /*
00076  * forward
00077  */
00078 static int seepair(char *, int, char *, int);
00079
00080 /*
00081  * page format:
00082  *  +------------------------------+
00083  * ino  | n | keyoff | datoff | keyoff |
00084  *  +------------+--------+--------+
00085  *  | datoff | - - - ---->         |
00086  *  +--------+---------------------+
00087  *  |    F R E E A R E A       |
00088  *  +--------------+---------------+
00089  *  |  <---- - - - | data          |
00090  *  +--------+-----+----+----------+
00091  *  |  key   | data     | key      |
00092  *  +--------+----------+----------+
00093  *
00094  * calculating the offsets for free area:  if the number
00095  * of entries (ino[0]) is zero, the offset to the END of
00096  * the free area is the block size. Otherwise, it is the
00097  * nth (ino[ino[0]]) entry's offset.
00098  */
00099
00100 int
00101 fitpair(pag, need)
00102 char *pag;
00103 int need;
00104 {
00105     register int n;
00106     register int off;
00107     register int avail;
00108     register short *ino = (short *) pag;
00109
00110     off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
00111     avail = off - (n + 1) * sizeof(short);
00112     need += 2 * sizeof(short);
00113
00114     debug(("avail %d need %d\n", avail, need));
00115
00116     return need <= avail;
00117 }
00118
00119 void
00120 putpair(pag, key, val)
00121 char *pag;
00122 apr_sdbm_datum_t key;
00123 apr_sdbm_datum_t val;
00124 {
00125     register int n;
00126     register int off;
00127     register short *ino = (short *) pag;
00128
00129     off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
00130 /*
00131  * enter the key first
00132  */
00133     off -= key.dsize;
00134     (void) memcpy(pag + off, key.dptr, key.dsize);
00135     ino[n + 1] = off;
00136 /*
00137  * now the data
00138  */
00139     off -= val.dsize;
00140     (void) memcpy(pag + off, val.dptr, val.dsize);
00141     ino[n + 2] = off;
00142 /*
00143  * adjust item count
00144  */
00145     ino[0] += 2;
00146 }
00147
00148 apr_sdbm_datum_t
00149 getpair(pag, key)
00150 char *pag;
00151 apr_sdbm_datum_t key;
00152 {
00153     register int i;
00154     register int n;
00155     apr_sdbm_datum_t val;
00156     register short *ino = (short *) pag;
00157
00158     if ((n = ino[0]) == 0)
00159         return sdbm_nullitem;
00160
00161     if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
00162         return sdbm_nullitem;
00163
00164     val.dptr = pag + ino[i + 1];
00165     val.dsize = ino[i] - ino[i + 1];
00166     return val;
00167 }
00168
00169 int
00170 duppair(pag, key)
00171 char *pag;
00172 apr_sdbm_datum_t key;
00173 {
00174     register short *ino = (short *) pag;
00175     return ino[0] > 0 && seepair(pag, ino[0], key.dptr, key.dsize) > 0;
00176 }
00177
00178 apr_sdbm_datum_t
00179 getnkey(pag, num)
00180 char *pag;
00181 int num;
00182 {
00183     apr_sdbm_datum_t key;
00184     register int off;
00185     register short *ino = (short *) pag;
00186
00187     num = num * 2 - 1;
00188     if (ino[0] == 0 || num > ino[0])
00189         return sdbm_nullitem;
00190
00191     off = (num > 1) ? ino[num - 1] : PBLKSIZ;
00192
00193     key.dptr = pag + ino[num];
00194     key.dsize = off - ino[num];
00195
00196     return key;
00197 }
00198
00199 int
00200 delpair(pag, key)
00201 char *pag;
00202 apr_sdbm_datum_t key;
00203 {
00204     register int n;
00205     register int i;
00206     register short *ino = (short *) pag;
00207
00208     if ((n = ino[0]) == 0)
00209         return 0;
00210
00211     if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
00212         return 0;
00213 /*
00214  * found the key. if it is the last entry
00215  * [i.e. i == n - 1] we just adjust the entry count.
00216  * hard case: move all data down onto the deleted pair,
00217  * shift offsets onto deleted offsets, and adjust them.
00218  * [note: 0 < i < n]
00219  */
00220     if (i < n - 1) {
00221         register int m;
00222         register char *dst = pag + (i == 1 ? PBLKSIZ : ino[i - 1]);
00223         register char *src = pag + ino[i + 1];
00224         register int   zoo = dst - src;
00225
00226         debug(("free-up %d ", zoo));
00227 /*
00228  * shift data/keys down
00229  */
00230         m = ino[i + 1] - ino[n];
00231
00232 #undef DUFF /* just use memmove. it should be plenty fast. */
00233 #ifdef DUFF
00234 #define MOVB    *--dst = *--src
00235
00236         if (m > 0) {
00237             register int loop = (m + 8 - 1) >> 3;
00238
00239             switch (m & (8 - 1)) {
00240             case 0: do {
00241                 MOVB;   case 7: MOVB;
00242             case 6: MOVB;   case 5: MOVB;
00243             case 4: MOVB;   case 3: MOVB;
00244             case 2: MOVB;   case 1: MOVB;
00245                 } while (--loop);
00246             }
00247         }
00248 #else
00249         dst -= m;
00250         src -= m;
00251         memmove(dst, src, m);
00252 #endif
00253
00254 /*
00255  * adjust offset index up
00256  */
00257         while (i < n - 1) {
00258             ino[i] = ino[i + 2] + zoo;
00259             i++;
00260         }
00261     }
00262     ino[0] -= 2;
00263     return 1;
00264 }
00265
00266 /*
00267  * search for the key in the page.
00268  * return offset index in the range 0 < i < n.
00269  * return 0 if not found.
00270  */
00271 static int
00272 seepair(pag, n, key, siz)
00273 char *pag;
00274 register int n;
00275 register char *key;
00276 register int siz;
00277 {
00278     register int i;
00279     register int off = PBLKSIZ;
00280     register short *ino = (short *) pag;
00281
00282     for (i = 1; i < n; i += 2) {
00283         if (siz == off - ino[i] &&
00284             memcmp(key, pag + ino[i], siz) == 0)
00285             return i;
00286         off = ino[i + 1];
00287     }
00288     return 0;
00289 }
00290
00291 void
00292 splpage(pag, new, sbit)
00293 char *pag;
00294 char *new;
00295 long sbit;
00296 {
00297     apr_sdbm_datum_t key;
00298     apr_sdbm_datum_t val;
00299
00300     register int n;
00301     register int off = PBLKSIZ;
00302     char cur[PBLKSIZ];
00303     register short *ino = (short *) cur;
00304
00305     (void) memcpy(cur, pag, PBLKSIZ);
00306     (void) memset(pag, 0, PBLKSIZ);
00307     (void) memset(new, 0, PBLKSIZ);
00308
00309     n = ino[0];
00310     for (ino++; n > 0; ino += 2) {
00311         key.dptr = cur + ino[0];
00312         key.dsize = off - ino[0];
00313         val.dptr = cur + ino[1];
00314         val.dsize = ino[0] - ino[1];
00315 /*
00316  * select the page pointer (by looking at sbit) and insert
00317  */
00318         (void) putpair((exhash(key) & sbit) ? new : pag, key, val);
00319
00320         off = ino[1];
00321         n -= 2;
00322     }
00323
00324     debug(("%d split %d/%d\n", ((short *) cur)[0] / 2,
00325            ((short *) new)[0] / 2,
00326            ((short *) pag)[0] / 2));
00327 }
00328
00329 /*
00330  * check page sanity:
00331  * number of entries should be something
00332  * reasonable, and all offsets in the index should be in order.
00333  * this could be made more rigorous.
00334  */
00335 int
00336 chkpage(pag)
00337 char *pag;
00338 {
00339     register int n;
00340     register int off;
00341     register short *ino = (short *) pag;
00342
00343     if ((n = ino[0]) < 0 || n > PBLKSIZ / sizeof(short))
00344         return 0;
00345
00346     if (n > 0) {
00347         off = PBLKSIZ;
00348         for (ino++; n > 0; ino += 2) {
00349             if (ino[0] > off || ino[1] > off ||
00350                 ino[1] > ino[0])
00351                 return 0;
00352             off = ino[1];
00353             n -= 2;
00354         }
00355     }
00356     return 1;
00357 }


sdbm_pair.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | chkpage sdbm__chkpage
#define | delpair sdbm__delpair
#define | duppair sdbm__duppair
#define | fitpair sdbm__fitpair
#define | getnkey sdbm__getnkey
#define | getpair sdbm__getpair
#define | putpair sdbm__putpair
#define | splpage sdbm__splpage

Functions

int | fitpair (char *, int)
void | putpair (char *, apr_sdbm_datum_t, apr_sdbm_datum_t)
apr_sdbm_datum_t | getpair (char *, apr_sdbm_datum_t)
int | delpair (char *, apr_sdbm_datum_t)
int | chkpage (char *)
apr_sdbm_datum_t | getnkey (char *, int)
void | splpage (char *, char *, long)
int | duppair (char *, apr_sdbm_datum_t)

Define Documentation

#define chkpage sdbm__chkpage

Definition at line 59 of file sdbm_pair.h.

#define delpair sdbm__delpair

Definition at line 60 of file sdbm_pair.h.

#define duppair sdbm__duppair

Definition at line 61 of file sdbm_pair.h.

#define fitpair sdbm__fitpair

Definition at line 62 of file sdbm_pair.h.

#define getnkey sdbm__getnkey

Definition at line 63 of file sdbm_pair.h.

#define getpair sdbm__getpair

Definition at line 64 of file sdbm_pair.h.

#define putpair sdbm__putpair

Definition at line 65 of file sdbm_pair.h.

#define splpage sdbm__splpage

Definition at line 66 of file sdbm_pair.h.

Function Documentation

int fitpair | ( | char * | ,
 |  | int |
 | ) |

void putpair | ( | char * | ,
 |  | apr_sdbm_datum_t | ,
 |  | apr_sdbm_datum_t |
 | ) |

apr_sdbm_datum_t getpair | ( | char * | ,
 |  | apr_sdbm_datum_t |
 | ) |

int delpair | ( | char * | ,
 |  | apr_sdbm_datum_t |
 | ) |

int chkpage ( char * )

apr_sdbm_datum_t getnkey | ( | char * | ,
 |  | int |
 | ) |

void splpage | ( | char * | ,
 |  | char * | ,
 |  | long |
 | ) |

int duppair | ( | char * | ,
 |  | apr_sdbm_datum_t |
 | ) |


sdbm_pair.h Source File

sdbm_pair.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 #ifndef SDBM_PAIR_H
00056 #define SDBM_PAIR_H
00057
00058 /* Mini EMBED (pair.c) */
00059 #define chkpage sdbm__chkpage
00060 #define delpair sdbm__delpair
00061 #define duppair sdbm__duppair
00062 #define fitpair sdbm__fitpair
00063 #define getnkey sdbm__getnkey
00064 #define getpair sdbm__getpair
00065 #define putpair sdbm__putpair
00066 #define splpage sdbm__splpage
00067
00068 int fitpair(char *, int);
00069 void  putpair(char *, apr_sdbm_datum_t, apr_sdbm_datum_t);
00070 apr_sdbm_datum_t getpair(char *, apr_sdbm_datum_t);
00071 int  delpair(char *, apr_sdbm_datum_t);
00072 int  chkpage (char *);
00073 apr_sdbm_datum_t getnkey(char *, int);
00074 void splpage(char *, char *, long);
00075 int duppair(char *, apr_sdbm_datum_t);
00076
00077 #endif /* SDBM_PAIR_H */
00078


sdbm_private.h File Reference

Include dependency graph for sdbm_private.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

struct | apr_sdbm_t

Defines

#define | DBLKSIZ 16384
#define | PBLKSIZ 8192
#define | PAIRMAX 8008
#define | SPLTMAX 10
#define | SDBM_RDONLY 0x1
#define | SDBM_SHARED 0x2
#define | SDBM_SHARED_LOCK 0x4
#define | SDBM_EXCLUSIVE_LOCK 0x8
#define | SDBM_INVALIDATE_CACHE(db, finfo)

Functions

long | sdbm_hash (const char *str, int len)

Variables

const apr_sdbm_datum_t | sdbm_nullitem

Define Documentation

#define DBLKSIZ 16384

Definition at line 71 of file sdbm_private.h.

#define PBLKSIZ 8192

Definition at line 72 of file sdbm_private.h.

#define PAIRMAX 8008

Definition at line 73 of file sdbm_private.h.

#define SPLTMAX 10

Definition at line 79 of file sdbm_private.h.

#define SDBM_RDONLY 0x1

Definition at line 82 of file sdbm_private.h.

Referenced by prep().

#define SDBM_SHARED 0x2

Definition at line 83 of file sdbm_private.h.

Referenced by prep().

#define SDBM_SHARED_LOCK 0x4

Definition at line 84 of file sdbm_private.h.

Referenced by database_cleanup().

#define SDBM_EXCLUSIVE_LOCK 0x8

Definition at line 85 of file sdbm_private.h.

Referenced by database_cleanup().

#define SDBM_INVALIDATE_CACHE | ( | db,
 |  | finfo | )

Value:

do { db->dirbno = (!finfo.size) ? 0 : -1; \
         db->pagbno = -1; \
         db->maxbno = (long)(finfo.size * BYTESIZ); \
    } while (0);

Definition at line 112 of file sdbm_private.h.

Function Documentation

long sdbm_hash | ( | const char * | str,
 |  | int | len
 | ) |

Definition at line 74 of file sdbm_hash.c.

References str.

Variable Documentation

const apr_sdbm_datum_t sdbm_nullitem

Definition at line 105 of file sdbm_private.h.


sdbm_private.h Source File

sdbm_private.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * sdbm - ndbm work-alike hashed database library
00057  * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
00058  * author: oz@nexus.yorku.ca
00059  */
00060
00061 #ifndef SDBM_PRIVATE_H
00062 #define SDBM_PRIVATE_H
00063
00064 #include "apr.h"
00065 #include "apr_pools.h"
00066 #include "apr_file_io.h"
00067 #include "apr_errno.h" /* for apr_status_t */
00068
00069 #if 1
00070 /* if the block/page size is increased, it breaks perl apr_sdbm_t compatibility */
00071 #define DBLKSIZ 16384
00072 #define PBLKSIZ 8192
00073 #define PAIRMAX 8008            /* arbitrary on PBLKSIZ-N */
00074 #else
00075 #define DBLKSIZ 4096
00076 #define PBLKSIZ 1024
00077 #define PAIRMAX 1008            /* arbitrary on PBLKSIZ-N */
00078 #endif
00079 #define SPLTMAX 10          /* maximum allowed splits */
00080
00081 /* for apr_sdbm_t.flags */
00082 #define SDBM_RDONLY         0x1    /* data base open read-only */
00083 #define SDBM_SHARED         0x2    /* data base open for sharing */
00084 #define SDBM_SHARED_LOCK    0x4    /* data base locked for shared read */
00085 #define SDBM_EXCLUSIVE_LOCK 0x8    /* data base locked for write */
00086
00087 struct apr_sdbm_t {
00088     apr_pool_t *pool;
00089     apr_file_t *dirf;              /* directory file descriptor */
00090     apr_file_t *pagf;              /* page file descriptor */
00091     apr_int32_t flags;             /* status/error flags, see below */
00092     long maxbno;               /* size of dirfile in bits */
00093     long curbit;               /* current bit number */
00094     long hmask;                /* current hash mask */
00095     long blkptr;               /* current block for nextkey */
00096     int  keyptr;               /* current key for nextkey */
00097     long blkno;                /* current page to read/write */
00098     long pagbno;               /* current page in pagbuf */
00099     char pagbuf[PBLKSIZ];          /* page file block buffer */
00100     long dirbno;               /* current block in dirbuf */
00101     char dirbuf[DBLKSIZ];          /* directory file block buffer */
00102     int  lckcnt;                       /* number of calls to sdbm_lock */
00103 };
00104
00105 extern const apr_sdbm_datum_t sdbm_nullitem;
00106
00107 long sdbm_hash(const char *str, int len);
00108
00109 /*
00110  * zero the cache
00111  */
00112 #define SDBM_INVALIDATE_CACHE(db, finfo) \
00113     do { db->dirbno = (!finfo.size) ? 0 : -1; \
00114          db->pagbno = -1; \
00115          db->maxbno = (long)(finfo.size * BYTESIZ); \
00116     } while (0);
00117
00118 #endif /* SDBM_PRIVATE_H */


sdbm_tune.h File Reference

Include dependency graph for sdbm_tune.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define | BYTESIZ 8
#define | debug(x)

Define Documentation

#define BYTESIZ 8

Definition at line 67 of file sdbm_tune.h.

#define debug ( x )

Definition at line 75 of file sdbm_tune.h.


sdbm_tune.h Source File

sdbm_tune.h

Go to the documentation of this file.
00001 /* ====================================================================
00002  * The Apache Software License, Version 1.1
00003  *
00004  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
00005  * reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  *
00026  * 4. The names "Apache" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written
00029  *    permission, please contact apache@apache.org.
00030  *
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  *
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  *
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation.  For more
00051  * information on the Apache Software Foundation, please see
00052  * <http://www.apache.org/>.
00053  */
00054
00055 /*
00056  * sdbm - ndbm work-alike hashed database library
00057  * tuning and portability constructs [not nearly enough]
00058  * author: oz@nexus.yorku.ca
00059  */
00060
00061 #ifndef SDBM_TUNE_H
00062 #define SDBM_TUNE_H
00063
00064 #include "apr_errno.h"
00065
00066 /* ### this might be better off as sizeof(char *) */
00067 #define BYTESIZ     8
00068
00069 /*
00070  * misc
00071  */
00072 #ifdef DEBUG
00073 #define debug(x)    printf x
00074 #else
00075 #define debug(x)
00076 #endif
00077
00078 #endif /* SDBM_TUNE_H */


smtp.C File Reference

Parser: SMTP sender. More...

Include dependency graph for smtp.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | snprintf __snprintf

Functions

int | __snprintf (char *, size_t, const char *,...)

Variables

const char *const | IDENT_SMTP_C = "$Date: 2005/08/09 08:14:51 $"

Detailed Description

Parser: SMTP sender.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Parts of the code here is based upon an early gensock and blat

Definition in file smtp.C.

Define Documentation

#define snprintf __snprintf

Definition at line 18 of file smtp.C.

Function Documentation

int __snprintf | ( | char * | ,
 |  | size_t | ,
 |  | const char * | ,
 |  | ... |
 | ) |

Definition at line 703 of file pa_common.C.

References __vsnprintf().

Variable Documentation

const char* const IDENT_SMTP_C = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 10 of file smtp.C.


smtp.C Source File

smtp.C

Go to the documentation of this file.
00001
00010 static const char * const IDENT_SMTP_C="$Date: 2005/08/09 08:14:51 $";
00011
00012 #include "pa_exception.h"
00013 #include "smtp.h"
00014
00015 #undef snprintf
00016 // pa_common.C
00017 extern int __snprintf(char *, size_t, const char* , ...);
00018 #define snprintf __snprintf
00019
00020 //#define DEBUG_SHOW
00021
00022 SMTP::SMTP() {
00023     the_socket  = 0;
00024     in_index    = 0;
00025     out_index   = 0;
00026     in_buffer   = 0;
00027     in_buffer_total  = 0;
00028     out_buffer_total = 0;
00029
00030     in_buffer  = (char *)malloc(SOCKET_BUFFER_SIZE);
00031     out_buffer = (char *)malloc(SOCKET_BUFFER_SIZE);
00032
00033     last_winsock_error = 0;
00034 }
00035
00036 SMTP::~SMTP() {
00037     free(in_buffer);
00038     free(out_buffer);
00039 }
00040
00041
00042 // ---------------------------------------------------------------------------
00043 void
00044 SMTP:: ConnectToHost(const char* hostname, const char* service)
00045 {
00046     struct sockaddr_in  sa_in;
00047     memset(&sa_in, 0, sizeof(sa_in));
00048     u_short our_port;
00049
00050     if( !ResolveService(service, &our_port) )
00051     {
00052         if( !ResolveHostname(hostname, &sa_in) )
00053         {
00054             sa_in.sin_family = AF_INET;
00055             sa_in.sin_port   = (unsigned short)our_port;
00056
00057             if( !GetAndSetTheSocket(&the_socket) )
00058             {
00059                 if( !GetConnection(the_socket, &sa_in) )
00060                 {
00061                     MiscSocketSetup(the_socket, &fds, &timeout);
00062
00063                     return;
00064                 }
00065             }
00066         }
00067     }
00068
00069     CloseConnect();
00070
00071     throw Exception("smtp.connect",
00072         0,
00073         "connect to %s:%s failed",
00074             hostname, service);
00075 }
00076
00077 //---------------------------------------------------------------------------
00078 // returns 0 if all is OK
00079 int
00080 SMTP:: GetBuffer(int wait)
00081 {
00082     int             retval;
00083     int             bytes_read = 0;
00084
00085     // Use select to see if data is waiting...
00086     FD_ZERO(&fds);
00087     FD_SET(the_socket, &fds);
00088
00089     // if wait is set, we are polling, return immediately
00090     if( wait )
00091     {
00092         timeout.tv_sec = 0;
00093     }
00094     else
00095     {
00096         timeout.tv_sec = 30;
00097     }
00098
00099     if( (retval = select(1+the_socket, &fds, NULL, NULL, &timeout))<0 )
00100     {
00101 #ifdef WIN32
00102         int     error_code = WSAGetLastError();
00103
00104         if( error_code == WSAEINPROGRESS && wait )
00105         {
00106             return WAIT_A_BIT;
00107         }
00108 #else
00109     if( errno == EAGAIN && wait )
00110         return WAIT_A_BIT;
00111 #endif
00112     }
00113
00114     // if we don't want to wait
00115     if( !retval && wait )
00116     {
00117         return WAIT_A_BIT;
00118     }
00119
00120     // we have data waiting...
00121     bytes_read = recv(the_socket,
00122                      in_buffer,
00123                      SOCKET_BUFFER_SIZE,
00124                      0);
00125
00126     // just in case.
00127     if( 0 == bytes_read )
00128     {
00129         // connection terminated (semi-) gracefully by the other side
00130         return WSAENOTCONN;
00131     }
00132
00133     if( bytes_read <0 )
00134     {
00135         //char    what_error[256];
00136         int     ws_error = WSAGetLastError();
00137
00138         switch( ws_error )
00139         {
00140             // all these indicate loss of connection (are there more?)
00141             case WSAENOTCONN:
00142             case WSAENETDOWN:
00143             case WSAENETUNREACH:
00144             case WSAENETRESET:
00145             case WSAECONNABORTED:
00146             case WSAECONNRESET:
00147                 return WSAENOTCONN;
00148
00149             case WSAEWOULDBLOCK:
00150                 return WAIT_A_BIT;
00151
00152             default:
00153                 /*wsprintf(what_error,
00154                         "GetBuffer() unexpected error: %d",
00155                         ws_error);
00156                 ShowError(what_error);
00157                 */
00158                 break;
00159         }
00160     }
00161
00162     // reset buffer indices.
00163     in_buffer_total = bytes_read;
00164     in_index = 0;
00165
00166     return 0;
00167 }
00168
00169 //---------------------------------------------------------------------------
00170 // returns 0 if all is OK
00171 int
00172 SMTP:: GetChar(int wait, char *ch)
00173 {
00174     int         retval = 0;
00175
00176     if( in_index >= in_buffer_total )
00177     {
00178         if( 0 != (retval = GetBuffer(wait)) )
00179             return retval;
00180     }
00181     *ch = in_buffer[in_index++];
00182
00183     return 0;
00184 }
00185
00186 //----------------------------------------------------------------------
00187 int
00188 SMTP::get_line( void )
00189 {
00190     char    ch = '.';
00191     char    in_data[MAXOUTLINE];
00192     char    *index;
00193
00194     index = in_data;
00195
00196     while( ch != '\n' )
00197     {
00198         if( 0 != GetChar(0, &ch) )
00199         {
00200             return -1;
00201         }
00202         else
00203         {
00204             *index = ch;
00205             index++;
00206         }
00207     }
00208
00209     if( in_data[3] == '-' )
00210         return get_line();
00211     else {
00212         char *error_pos;
00213         return strtol(in_data, &error_pos, 0);
00214     }
00215 }
00216
00217 //---------------------------------------------------------------------------
00218 // returns 0 if all is OK
00219 void
00220 SMTP:: SendLine(const char* data, unsigned long length)
00221 {
00222     int         num_sent;
00223
00224     FD_ZERO(&fds);
00225     FD_SET(the_socket, &fds);
00226
00227     timeout.tv_sec = 30;
00228
00229     while( length > 0 )
00230     {
00231         if( select(1+the_socket, NULL, &fds, NULL, &timeout)<0 )
00232             throw Exception("smtp.execute",
00233                 0,
00234                 "connection::put_data() unexpected error from select: %d",
00235                     WSAGetLastError());
00236
00237         num_sent = send(the_socket,
00238                         data,
00239                         length > 1024 ? 1024 : (int)length,
00240                         0);
00241
00242         if( num_sent<0 )
00243         {
00244             int  ws_error = WSAGetLastError();
00245
00246             switch( ws_error )
00247             {
00248                 // this is the only error we really expect to see.
00249                 case WSAENOTCONN:
00250                     return;
00251
00252                 // seems that we can still get a block
00253                 case WSAEWOULDBLOCK:
00254                     break;
00255
00256                 default:
00257                     throw Exception("smtp.execute",
00258                         0,
00259                         "connection::put_data() unexpected error from send(): %d",
00260                             ws_error);
00261             }
00262         }
00263         else
00264         {
00265             length -= num_sent;
00266             data += num_sent;
00267         }
00268     }
00269 }
00270
00271 //---------------------------------------------------------------------------
00272 // returns 0 if all is OK
00273 void
00274 SMTP:: SendBuffer(const char* data, unsigned long length)
00275 {
00276     while( length )
00277     {
00278         if( (out_index + length) < SOCKET_BUFFER_SIZE )
00279         {
00280             // we won't overflow, simply copy into the buffer
00281             memcpy(out_buffer + out_index, data, length);
00282             out_index += length;
00283             length = 0;
00284         }
00285         else
00286         {
00287             unsigned int orphaned_chunk = SOCKET_BUFFER_SIZE - out_index;
00288
00289             // we will overflow, handle it
00290             memcpy(out_buffer + out_index, data, orphaned_chunk);
00291
00292             // send this buffer...
00293             SendLine(out_buffer, SOCKET_BUFFER_SIZE);
00294
00295             length -= orphaned_chunk;
00296             out_index = 0;
00297             data += orphaned_chunk;
00298         }
00299     }
00300 }
00301
00302 //---------------------------------------------------------------------------
00303 // returns 0 if all is OK
00304 void
00305 SMTP:: FlushBuffer()
00306 {
00307     SendLine(out_buffer, out_index);
00308     out_index = 0;
00309 }
00310
00311 //---------------------------------------------------------------------------
00312 bool
00313 SMTP:: CloseConnect()
00314 {
00315     if( closesocket(the_socket) <0 )
00316         return false;
00317
00318     return true;
00319 }
00320
00321 //----------------------------------------------------------------------
00322 void
00323 SMTP::SendSmtpError(const char*  message)
00324 {
00325     SendLine("QUIT\r\n", 6);
00326     CloseConnect();
00327
00328     throw Exception("smtp.execute",
00329         0,
00330         "failed: %s", message);
00331 }
00332
00333 //----------------------------------------------------------------------
00334 // returns 0 if all is OK
00335 // returns 20, 21, 22, 23, 24, 25 if SendBuffer() fails
00336 // returns 26 if FlushBuffer() fails
00337 void
00338 SMTP::transform_and_send_edit_data(const char*  editptr )
00339 {
00340     const char      *index;
00341     char            previous_char = 'x';
00342     unsigned int    send_len;
00343     bool            done = false;
00344
00345     send_len = strlen(editptr);
00346     index = editptr;
00347
00348     while( !done )
00349     {
00350         // room for extra char for double dot on end case
00351         while( (unsigned int)(index - editptr) < send_len )
00352         {
00353             switch( *index )
00354             {
00355                 case '.':
00356                     if( previous_char == '\n' )
00357                         SendBuffer(index, 1); // send _two_ dots...
00358                     SendBuffer(index, 1);
00359                     break;
00360
00361                 case '\n': // x\n -> \r\n
00362                     if( previous_char != '\r' ) {
00363                         SendBuffer("\r", 1);
00364                         SendBuffer(index, 1);
00365                     }
00366                     break;
00367
00368                 default:
00369                     SendBuffer(index, 1);
00370                     break;
00371             }
00372             previous_char = *index;
00373             index++;
00374         }
00375
00376         if( (unsigned int)(index - editptr) == send_len )
00377             done = true;
00378     }
00379
00380     // this handles the case where the user doesn't end the last
00381     // line with a <return>
00382
00383     if( editptr[send_len-1] != '\n' )
00384         SendBuffer("\r\n.\r\n", 5);
00385     else
00386         SendBuffer(".\r\n", 3);
00387     /* now make sure it's all sent... */
00388     FlushBuffer();
00389 }
00390
00391 //----------------------------------------------------------------------
00392 // returns 0 if all is OK
00393 // returns 16 if any get_line()'s fail
00394 // returns 20, 21, 22, 23, 24, 25, 26 if transform_and_send_edit_data() fails
00395 void
00396 SMTP::send_data(const char*  message)
00397 {
00398     transform_and_send_edit_data(message);
00399     if( 250 != get_line() )
00400         SendSmtpError("Message not accepted by server");
00401 }
00402
00403 //----------------------------------------------------------------------
00404 // returns 0 if all is OK
00405 // returns 50, 51, 52 if fails
00406 void
00407 SMTP::open_socket( const char* server, const char* service )
00408 {
00409     ConnectToHost(server, service);
00410
00411     if( gethostname(my_hostname, sizeof(my_hostname)) )
00412         throw Exception("smtp.connect",
00413             0,
00414             "lookup of '%s' failed", my_hostname);
00415 }
00416
00417 //----------------------------------------------------------------------
00418 // returns 0 if all is OK
00419 // returns 50, 51, 52 if open_socket() fails
00420 // returns 10, 11, 12, 13, 14, 15 if any get_line()'s fail
00421 void
00422 SMTP::prepare_message(char *from, char *to, const char* server, const char* service)
00423 {
00424     char    out_data[MAXOUTLINE];
00425     char    *ptr;
00426     int     len;
00427     int     startLen;
00428
00429     open_socket(server, service);
00430
00431     if( 220 != get_line() )
00432         SendSmtpError("SMTP server error");
00433
00434     snprintf(out_data, sizeof(out_data), "HELO %s\r\n", my_hostname );
00435     SendLine(out_data, strlen(out_data) );
00436
00437     if( 250 != get_line() )
00438         SendSmtpError("SMTP server error");
00439
00440     snprintf(out_data, sizeof(out_data), "MAIL From: <%s>\r\n", from);
00441     SendLine(out_data, strlen(out_data) );
00442
00443     if( 250 != get_line() )
00444         SendSmtpError("The mail server doesn't like the sender name, have you set your mail address correctly?");
00445
00446     // do a series of RCPT lines for each name in address line
00447     for( ptr = to; *ptr; ptr += len + 1 )
00448     {
00449         // if there's only one token left, then len will = startLen,
00450         // and we'll iterate once only
00451         startLen = strlen(ptr);
00452         if( (len = strcspn(ptr, " ,\n\t\r")) != startLen )
00453         {
00454             ptr[len] = '\0';            // replace delim with NULL char
00455             while( strchr (" ,\n\t\r", ptr[len+1]) )    // eat white space
00456                 ptr[len++] = '\0';
00457         }
00458
00459         snprintf(out_data, sizeof(out_data), "RCPT To: <%s>\r\n", ptr);
00460         SendLine(out_data, strlen(out_data) );
00461
00462         if( 250 != get_line() )
00463             throw Exception("smtp.execute",
00464                 0,
00465                 "The mail server doesn't like the name %s. Have you set the 'To: ' field correctly?",
00466                     ptr);
00467
00468         if( len == startLen )   // last token, we're done
00469             break;
00470     }
00471
00472     snprintf(out_data, sizeof(out_data), "DATA\r\n");
00473     SendLine(out_data, strlen(out_data));
00474
00475     if( 354 != get_line() )
00476         SendSmtpError("Mail server error accepting message data");
00477 }
00478
00479
00480 //----------------------------------------------------------------------------
00481 //----------------------------------------------------------------------------
00482 // returns 0 if all is OK
00483 // returns 1 if MakeSmtpHeader() fails
00484 // returns 10, 11, 12, 13, 14, 15, 50, 51, 52 if prepare_message() fails
00485 void
00486 SMTP::Send(const char* server, const char* service, const char* msg, char *from, char *to)
00487 {
00488 #ifdef DEBUG_SHOW
00489     throw Exception("paf.debug",0,"from=%s|to=%s|msg=%s", from,to,msg);
00490 #endif
00491
00492     prepare_message( from, to, server, service);
00493
00494     send_data(msg);
00495
00496     SendLine("QUIT\r\n", 6 );
00497     CloseConnect();
00498 }


smtp.h File Reference

Parser: SMTP sender decl. More...

Include dependency graph for smtp.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Compounds

class | SMTP
SIMPLE MAIL TRANSPORT PROTOCOL Win32 realization. More...

Defines

#define | SOCKET_BUFFER_SIZE 512
#define | ERR_SENDING_DATA 4002
#define | ERR_NOT_A_SOCKET 4010
#define | ERR_CLOSING 4012
#define | WAIT_A_BIT 4013
#define | MAXOUTLINE (SOCKET_BUFFER_SIZE*2)
must be >=SOCKET_BUFFER_SIZE, thanks to Lev Walkin <vlm@netli.com> for pointing that out. More...

Variables

const char *const | IDENT_SMTP_H = "$Date: 2005/08/09 08:14:51 $"

Detailed Description

Parser: SMTP sender decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file smtp.h.

Define Documentation

#define SOCKET_BUFFER_SIZE 512

Definition at line 93 of file smtp.h.

Referenced by SMTP::GetBuffer(), SMTP::SendBuffer(), and SMTP::SMTP().

#define ERR_SENDING_DATA 4002

Definition at line 95 of file smtp.h.

#define ERR_NOT_A_SOCKET 4010

Definition at line 96 of file smtp.h.

#define ERR_CLOSING 4012

Definition at line 97 of file smtp.h.

#define WAIT_A_BIT 4013

Definition at line 98 of file smtp.h.

Referenced by SMTP::GetBuffer().

#define MAXOUTLINE (SOCKET_BUFFER_SIZE*2)

must be >=SOCKET_BUFFER_SIZE, thanks to Lev Walkin <vlm@netli.com> for pointing that out.

Definition at line 101 of file smtp.h.

Referenced by SMTP::get_line(), and SMTP::prepare_message().

Variable Documentation

const char* const IDENT_SMTP_H = "$Date: 2005/08/09 08:14:51 $" [static]

Definition at line 8 of file smtp.h.


smtp.h Source File

smtp.h

Go to the documentation of this file.
00001
00008 static const char * const IDENT_SMTP_H="$Date: 2005/08/09 08:14:51 $";
00009
00010
00011 #include "pa_string.h"
00012
00013 #ifdef CYGWIN
00014 #define _GNU_H_WINDOWS32_SOCKETS
00015 // for PASCAL
00016 #include <windows.h>
00017 // SOCKET
00018 typedef u_int   SOCKET;
00019 int PASCAL closesocket(SOCKET);
00020 #else
00021 #   if defined(WIN32)
00022 #       include <windows.h>
00023 #   else
00024         typedef char    CHAR;
00025         typedef u_int   SOCKET;
00026 #       define closesocket close
00027         inline int WSAGetLastError() { return errno; }
00028
00029 #ifdef EPROTONOSUPPORT
00030 #       define WSAEPROTONOSUPPORT EPROTONOSUPPORT
00031 #else
00032 #       define WSAEPROTONOSUPPORT (10000)
00033 #endif
00034 #ifdef ESOCKTNOSUPPORT
00035 #       define WSAESOCKTNOSUPPORT ESOCKTNOSUPPORT
00036 #else
00037 #       define WSAESOCKTNOSUPPORT (10001)
00038 #endif
00039 #ifdef ENOTCONN
00040 #       define WSAENOTCONN ENOTCONN
00041 #else
00042 #       define WSAENOTCONN (10002)
00043 #endif
00044 #ifdef ESHUTDOWN
00045 #       define WSAENETDOWN ESHUTDOWN
00046 #else
00047 #       define WSAENETDOWN (10003)
00048 #endif
00049 #ifdef EHOSTUNREACH
00050 #       define WSAENETUNREACH EHOSTUNREACH
00051 #else
00052 #       define WSAENETUNREACH (10004)
00053 #endif
00054 #ifdef ENETRESET
00055 #       define WSAENETRESET ENETRESET
00056 #else
00057 #       define WSAENETRESET (10005)
00058 #endif
00059 #ifdef ECONNABORTED
00060 #       define WSAECONNABORTED ECONNABORTED
00061 #else
00062 #       define WSAECONNABORTED (10006)
00063 #endif
00064 #ifdef ECONNRESET
00065 #       define WSAECONNRESET ECONNRESET
00066 #else
00067 #       define WSAECONNRESET (10007)
00068 #endif
00069 #ifdef EWOULDBLOCK
00070 #       define WSAEWOULDBLOCK EWOULDBLOCK
00071 #else
00072 #       define WSAEWOULDBLOCK (10008)
00073 #endif
00074 #ifdef ECONNREFUSED
00075 #       define WSAECONNREFUSED ECONNREFUSED
00076 #else
00077 #       define WSAECONNREFUSED (10009)
00078 #endif
00079 #       define WSAHOST_NOT_FOUND (10010)
00080
00081 #       ifndef INADDR_NONE
00082 #           define INADDR_NONE ((unsigned long) -1)
00083 #       endif
00084
00085 #       ifndef INVALID_SOCKET
00086 #           define INVALID_SOCKET  (SOCKET)(~0)
00087 #       endif
00088 #   endif
00089 #endif
00090
00092
00093 #define SOCKET_BUFFER_SIZE  512
00094
00095 #define ERR_SENDING_DATA        4002
00096 #define ERR_NOT_A_SOCKET        4010
00097 #define ERR_CLOSING         4012
00098 #define WAIT_A_BIT          4013
00099
00101 #define MAXOUTLINE (SOCKET_BUFFER_SIZE*2)
00102
00104
00106 class SMTP: public PA_Object {
00107     char            *in_buffer;
00108     char            *out_buffer;
00109     unsigned int    in_index;
00110     unsigned int    out_index;
00111     unsigned int    in_buffer_total;
00112     unsigned int    out_buffer_total;
00113     unsigned int    last_winsock_error;
00114     fd_set          fds;
00115     struct timeval  timeout;
00116
00117     SOCKET  the_socket;
00118
00119     char    my_hostname[1024];
00120
00121     CHAR    ServerProtocol[100];
00122     CHAR    RemoteAddress[100];
00123     CHAR    RemoteHost[100];
00124     CHAR    RemoteUser[100];
00125     CHAR    HttpAccept[100];
00126     CHAR    HttpUserAgent[256];
00127
00128     CHAR    FirstName[100];
00129     CHAR    LastName[100];
00130     CHAR    WebUse[100];
00131     CHAR    EMail[100];
00132     CHAR    HomePage[100];
00133     CHAR    text[500];
00134
00135 public:
00136     SMTP();
00137     override ~SMTP();
00138
00139     // smtp.C
00140     void    Send(const char* , const char* , const char* ,  char *, char *);
00141     bool    MakeSmtpHeader(char *, char *, char *, char *);
00142     void    prepare_message(char *, char *,  const char* , const char* );
00143     void    open_socket(const char* , const char* );
00144     int     get_line(void);
00145     void    SendSmtpError(const char* );
00146     void    transform_and_send_edit_data(const char* );
00147     void    send_data(const char* );
00148     void    ConnectToHost(const char* , const char* );
00149     int     GetBuffer(int);
00150     int     GetChar(int, char *);
00151     void    SendLine(const char* , unsigned long);
00152     void    SendBuffer(const char* , unsigned long);
00153     void    FlushBuffer();
00154     bool    CloseConnect();
00155
00156     // comms.C
00157     int      IsAddressARawIpaddress(const char* );
00158     int      ResolveService(const char* , u_short *);
00159     int      ResolveHostname(const char* , struct sockaddr_in *);
00160     int      GetAndSetTheSocket(SOCKET *);
00161     int      GetConnection(SOCKET, struct sockaddr_in *);
00162     void     MiscSocketSetup(SOCKET, fd_set *, struct timeval *);
00163 };


string.C File Reference

Parser: string parser class. More...

Include dependency graph for string.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MString

Defines

#define | MATCH_VAR_NAME "match"
#define | TRIM_START_OPTION "start"
#define | TRIM_BOTH_OPTION "both"
#define | TRIM_END_OPTION "end"
#define | SPLIT_LEFT 0x0001
#define | SPLIT_RIGHT 0x0010
#define | SPLIT_HORIZONTAL 0x0100
#define | SPLIT_VERTICAL 0x1000

Functions

DECLARE_CLASS_VAR (string, new MString, 0)
const String | match_var_name (MATCH_VAR_NAME)
void | _length (Request &r, MethodParams &)
void | _int (Request &r, MethodParams &params)
void | _double (Request &r, MethodParams &params)
void | _string_format (Request &r, MethodParams &params)
void | _left (Request &r, MethodParams &params)
void | _right (Request &r, MethodParams &params)
void | _mid (Request &r, MethodParams &params)
void | _pos (Request &r, MethodParams &params)
void | split_list (MethodParams &params, int paramIndex, const String &string, ArrayString &result)
int | split_options (const String *options)
Table & | split_vertical (ArrayString &pieces, bool right)
Table & | split_horizontal (ArrayString &pieces, bool right)
void | split_with_options (Request &r, MethodParams &params, int bits)
void | _split (Request &r, MethodParams &params)
void | _lsplit (Request &r, MethodParams &params)
void | _rsplit (Request &r, MethodParams &params)
void | search_action (Table &table, Table::element_type row, int, int, int, int, void *)
void | replace_action (Table &table, ArrayString *row, int prestart, int prefinish, int poststart, int postfinish, void *info)
void | _match (Request &r, MethodParams &params)
void | change_case (Request &r, MethodParams &, String::Change_case_kind kind)
void | _upper (Request &r, MethodParams &params)
void | _lower (Request &r, MethodParams &params)
int | marshal_binds (HashStringValue &hash, SQL_Driver::Placeholder *&placeholders)
void | unmarshal_bind_updates (HashStringValue &hash, int placeholder_count, SQL_Driver::Placeholder *placeholders)
const String * | sql_result_string (Request &r, MethodParams &params, HashStringValue *&options, Value *&default_code)
void | _sql (Request &r, MethodParams &params)
void | _replace (Request &r, MethodParams &params)
void | _save (Request &r, MethodParams &params)
void | _normalize (Request &r, MethodParams &)
void | _trim (Request &r, MethodParams &params)
void | _append (Request &r, MethodParams &params)
void | _base64 (Request &r, MethodParams &params)

Variables

const char *const | IDENT_STRING_C = "$Date: 2005/11/22 12:14:36 $"
String sql_bind_name
String sql_limit_name
String sql_offset_name
String sql_default_name
String sql_distinct_name

Detailed Description

Parser: string parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file string.C.

Define Documentation

#define MATCH_VAR_NAME "match"

Definition at line 38 of file string.C.

#define TRIM_START_OPTION "start"

Definition at line 39 of file string.C.

Referenced by _trim().

#define TRIM_BOTH_OPTION "both"

Definition at line 40 of file string.C.

Referenced by _trim().

#define TRIM_END_OPTION "end"

Definition at line 41 of file string.C.

Referenced by _trim().

#define SPLIT_LEFT 0x0001

Definition at line 168 of file string.C.

Referenced by _lsplit(), and split_options().

#define SPLIT_RIGHT 0x0010

Definition at line 169 of file string.C.

Referenced by _rsplit(), split_options(), and split_with_options().

#define SPLIT_HORIZONTAL 0x0100

Definition at line 170 of file string.C.

Referenced by split_options(), and split_with_options().

#define SPLIT_VERTICAL 0x1000

Definition at line 171 of file string.C.

Referenced by split_options().

Function Documentation

DECLARE_CLASS_VAR | ( | string | ,
 |  | new | MString,
 |  | 0 |
 | ) |

const String match_var_name ( MATCH_VAR_NAME ) [static]

void _length | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 49 of file string.C.

References GET_SELF, result, and Request::write_no_lang().

Referenced by MString::MString().

void _int | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 54 of file string.C.

References MethodParams::as_int(), String::as_int(), Array< Value * >::count(), GET_SELF, String::is_empty(), rethrow, and Request::write_no_lang().

Referenced by MString::MString().

void _double | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 72 of file string.C.

References MethodParams::as_double(), String::as_double(), Array< Value * >::count(), GET_SELF, String::is_empty(), rethrow, and Request::write_no_lang().

Referenced by MString::MString().

void _string_format | ( | Request & | r,
 |  | MethodParams & | params
 | ) |

Definition at line 91 of file string.C.

References Value::as_double(), String::cstrm(), format(), Request::get_self(), Request::process_to_string(), and Request::write_no_lang().

void _left | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 102 of file string.C.

References MethodParams::as_int(), GET_SELF, String::mid(), ssize_t, and Request::write_assign_lang().

Referenced by MString::MString().

void _right | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 114 of file string.C.

References MethodParams::as_int(), GET_SELF, String::length(), String::mid(), ssize_t, and Request::write_assign_lang().

Referenced by MString::MString().

void _mid | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 128 of file string.C.

References MethodParams::as_int(), Array< Value * >::count(), GET_SELF, String::length(), String::mid(), ssize_t, and Request::write_assign_lang().

Referenced by MString::MString().

void _pos | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 152 of file string.C.

References MethodParams::as_no_junction(), Value::as_string(), GET_SELF, String::pos(), and Request::write_assign_lang().

Referenced by MString::MString().

void split_list | ( | MethodParams & | params,
 |  | int | paramIndex,
 |  | const String & | string,
 |  | ArrayString & | result
 | ) | [static]

Definition at line 159 of file string.C.

References MethodParams::as_no_junction(), Value::as_string(), result, and String::split().

Referenced by split_with_options().

int split_options ( const String * options ) [static]

Definition at line 173 of file string.C.

References String::pos(), result, SPLIT_HORIZONTAL, SPLIT_LEFT, SPLIT_RIGHT, SPLIT_VERTICAL, and STRING_NOT_FOUND.

Referenced by split_with_options().

Table& split_vertical | ( | ArrayString & | pieces,
 |  | bool | right
 | ) | [static]

Definition at line 203 of file string.C.

References Table::columns_type, Array< const String * >::count(), Array< ArrayString * >::element_type, Array_iterator< T >::has_next(), and Array_iterator< T >::next().

Referenced by split_with_options().

Table& split_horizontal | ( | ArrayString & | pieces,
 |  | bool | right
 | ) | [static]

Definition at line 226 of file string.C.

References ArrayString, Table::columns_type, Array< const String * >::count(), Array< ArrayString * >::element_type, Array_iterator< T >::has_next(), and Array_iterator< T >::next().

Referenced by split_with_options().

void split_with_options | ( | Request & | r,
 |  | MethodParams & | params,
 |  | int | bits
 | ) | [static]

Definition at line 241 of file string.C.

References MethodParams::as_string(), Array< Value * >::count(), GET_SELF, split_horizontal(), SPLIT_HORIZONTAL, split_list(), split_options(), SPLIT_RIGHT, split_vertical(), and Request::write_no_lang().

Referenced by _lsplit(), _rsplit(), and _split().

void _split | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 263 of file string.C.

References split_with_options().

Referenced by MString::MString().

void _lsplit | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 266 of file string.C.

References SPLIT_LEFT, and split_with_options().

Referenced by MString::MString().

void _rsplit | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 269 of file string.C.

References SPLIT_RIGHT, and split_with_options().

Referenced by MString::MString().

void search_action | ( | Table & | table,
 |  | Table::element_type | row,
 |  | int | ,
 |  | int | ,
 |  | int | ,
 |  | int | ,
 |  | void * |
 | ) | [static]

Definition at line 273 of file string.C.

References Array< ArrayString * >::element_type.

Referenced by _match().

void replace_action | ( | Table & | table,
 |  | ArrayString * | row,
 |  | int | prestart,
 |  | int | prefinish,
 |  | int | poststart,
 |  | int | postfinish,
 |  | void * | info
 | ) | [static]

Todo:
they can do $global[$result] there, getting pointer to later-invalid local var, kill this

Definition at line 287 of file string.C.

References Array< ArrayString * >::count(), and Array< ArrayString * >::put().

Referenced by _match().

void _match | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Todo:
use pcre:study somehow

Definition at line 311 of file string.C.

References MethodParams::as_junction(), MethodParams::as_no_junction(), Value::as_string(), Request::charsets, Array< Value * >::count(), Value::get_junction(), GET_SELF, String::L_PASS_APPENDED, String::match(), Junction::method_frame, Request::process_to_string(), replace_action(), result, search_action(), Request_charsets::source(), and Request::write_assign_lang().

Referenced by MString::MString().

void change_case | ( | Request & | r,
 |  | MethodParams & | ,
 |  | String::Change_case_kind | kind
 | ) | [static]

Definition at line 355 of file string.C.

References String::change_case(), String::Change_case_kind, Request::charsets, GET_SELF, Request_charsets::source(), and Request::write_assign_lang().

Referenced by _lower(), _upper(), pa_internal_file_read_http(), VResponse::put_element(), and VRequest::put_element().

void _upper | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 361 of file string.C.

References String::CC_UPPER, and change_case().

Referenced by MString::MString().

void _lower | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 364 of file string.C.

References String::CC_LOWER, and change_case().

Referenced by MString::MString().

int marshal_binds | ( | HashStringValue & | hash,
 |  | SQL_Driver::Placeholder *& | placeholders
 | ) |

Definition at line 916 of file table.C.

void unmarshal_bind_updates | ( | HashStringValue & | hash,
 |  | int | placeholder_count,
 |  | SQL_Driver::Placeholder * | placeholders
 | ) |

Definition at line 925 of file table.C.

const String* sql_result_string | ( | Request & | r,
 |  | MethodParams & | params,
 |  | HashStringValue *& | options,
 |  | Value *& | default_code
 | ) |

Definition at line 422 of file string.C.

References Value::as_double(), MethodParams::as_junction(), MethodParams::as_no_junction(), Request::connection(), Hash< const String::Body, Value * >::count(), Array< Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::is_defined(), Value::is_string(), String::L_SQL, String::L_UNSPECIFIED, marshal_binds(), offset, Request::process_to_string(), Request::process_to_value(), SQL_Connection::query(), uint, ulong, and unmarshal_bind_updates().

Referenced by _sql().

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 487 of file string.C.

References Request::process_to_string(), sql_result_string(), and Request::write_assign_lang().

Referenced by MString::MString().

void _replace | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 504 of file string.C.

References MethodParams::as_no_junction(), GET_SELF, Value::get_table(), String::replace(), and Request::write_assign_lang().

Referenced by MString::MString().

void _save | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 517 of file string.C.

References Request::absolute(), MethodParams::as_string(), Request::connection(), Array< Value * >::count(), String::cstr(), file_write(), GET_SELF, String::L_UNSPECIFIED, and mode.

Referenced by MString::MString().

void _normalize | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 540 of file string.C.

References GET_SELF, and Request::write_assign_lang().

Referenced by MString::MString().

void _trim | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 546 of file string.C.

References MethodParams::as_string(), Array< Value * >::count(), String::cstr(), GET_SELF, String::length(), String::trim(), String::TRIM_BOTH, TRIM_BOTH_OPTION, String::TRIM_END, TRIM_END_OPTION, String::Trim_kind, String::TRIM_START, TRIM_START_OPTION, and Request::write_assign_lang().

Referenced by MString::MString().

void _append | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 576 of file string.C.

References String::append(), MethodParams::as_string(), GET_SELF, String::L_PASS_APPENDED, VString::set_string(), and VString::string().

Referenced by MString::MString().

void _base64 | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 586 of file string.C.

References MethodParams::as_string(), Array< Value * >::count(), String::cstr(), GET_SELF, pa_base64_decode(), pa_base64_encode(), VString::string(), and Request::write_assign_lang().

Referenced by MString::MString().

Variable Documentation

const char* const IDENT_STRING_C = "$Date: 2005/11/22 12:14:36 $" [static]

Definition at line 8 of file string.C.

String sql_bind_name

Definition at line 414 of file string.C.

String sql_limit_name

Definition at line 415 of file string.C.

String sql_offset_name

Definition at line 416 of file string.C.

String sql_default_name

Definition at line 417 of file string.C.

String sql_distinct_name

Definition at line 418 of file string.C.


string.C Source File

string.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_STRING_C="$Date: 2005/11/22 12:14:36 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vdouble.h"
00015 #include "pa_vint.h"
00016 #include "pa_vtable.h"
00017 #include "pa_vbool.h"
00018 #include "pa_string.h"
00019 #include "pa_sql_connection.h"
00020 #include "pa_dictionary.h"
00021 #include "pa_vmethod_frame.h"
00022
00023 // class
00024
00025 class MString: public Methoded {
00026 public:
00027     MString();
00028 public: // Methoded
00029     bool used_directly() { return true; }
00030 };
00031
00032 // global variable
00033
00034 DECLARE_CLASS_VAR(string, new MString, 0);
00035
00036 // defines for statics
00037
00038 #define MATCH_VAR_NAME "match"
00039 #define TRIM_START_OPTION "start"
00040 #define TRIM_BOTH_OPTION "both"
00041 #define TRIM_END_OPTION "end"
00042
00043 // statics
00044
00045 static const String match_var_name(MATCH_VAR_NAME);
00046
00047 // methods
00048
00049 static void _length(Request& r, MethodParams&) {
00050     double result=GET_SELF(r, VString).string().length();
00051     r.write_no_lang(*new VDouble(result));
00052 }
00053
00054 static void _int(Request& r, MethodParams& params) {
00055     const String& self_string=GET_SELF(r, VString).string();
00056     int converted;
00057     try {
00058         if(self_string.is_empty())
00059             throw Exception("parser.runtime",
00060                 0,
00061                 "parameter is empty string, error converting");
00062         converted=self_string.as_int();
00063     } catch(...) { // convert problem
00064         if(params.count()>0)
00065             converted=params.as_int(0, "default must be int", r); // (default)
00066         else
00067             rethrow; // we have a problem when no default
00068     }
00069     r.write_no_lang(*new VInt(converted));
00070 }
00071
00072 static void _double(Request& r, MethodParams& params) {
00073     const String& self_string=GET_SELF(r, VString).string();
00074     double converted;
00075     try {
00076         if(self_string.is_empty())
00077             throw Exception("parser.runtime",
00078                 0,
00079                 "parameter is empty string, error converting");
00080         converted=self_string.as_double();
00081     } catch(...) { // convert problem
00082         if(params.count()>0)
00083             converted=params.as_double(0, "default must be double", r); // (default)
00084         else
00085             rethrow; // we have a problem when no default
00086     }
00087
00088     r.write_no_lang(*new VDouble(converted));
00089 }
00090
00091 /*not static*/void _string_format(Request& r, MethodParams& params) {
00092
00093     Value& fmt_maybe_code=params[0];
00094     // for some time due to stupid {} in original design
00095     const String& fmt=r.process_to_string(fmt_maybe_code);
00096
00097     const char* buf=format(r.get_self().as_double(), fmt.cstrm());
00098
00099     r.write_no_lang(String(buf));
00100 }
00101
00102 static void _left(Request& r, MethodParams& params) {
00103     ssize_t sn=params.as_int(0, "n must be int", r);
00104     if(sn<0)
00105         throw Exception("parser.runtime",
00106             0,
00107             "n(%d) must be >=0", sn);
00108     size_t n=(size_t)sn;
00109
00110     const String& string=GET_SELF(r, VString).string();
00111     r.write_assign_lang(string.mid(0, n));
00112 }
00113
00114 static void _right(Request& r, MethodParams& params) {
00115     ssize_t sn=(size_t)params.as_int(0, "n must be int", r);
00116     if(sn<0)
00117         throw Exception("parser.runtime",
00118             0,
00119             "n(%d) must be >=0", sn);
00120     size_t n=(size_t)sn;
00121
00122
00123     const String& string=GET_SELF(r, VString).string();
00124     size_t length=string.length();
00125     r.write_assign_lang(n<length?string.mid(length-n, string.length()):string);
00126 }
00127
00128 static void _mid(Request& r, MethodParams& params) {
00129     const String& string=GET_SELF(r, VString).string();
00130
00131     ssize_t sbegin=params.as_int(0, "p must be int", r);
00132     if(sbegin<0)
00133         throw Exception("parser.runtime",
00134             0,
00135             "p(%d) must be >=0", sbegin);
00136     size_t begin=(size_t)sbegin;
00137
00138     size_t end;
00139     if(params.count()>1) {
00140         ssize_t sn=params.as_int(1, "n must be int", r);
00141         if(sn<0)
00142             throw Exception("parser.runtime",
00143                 0,
00144                 "n(%d) must be >=0", sn);
00145         end=begin+(size_t)sn;
00146     } else
00147         end=string.length();
00148
00149     r.write_assign_lang(string.mid(begin, end));
00150 }
00151
00152 static void _pos(Request& r, MethodParams& params) {
00153     Value& substr=params.as_no_junction(0, "substr must not be code");
00154
00155     const String& string=GET_SELF(r, VString).string();
00156     r.write_assign_lang(*new VInt((int)string.pos(substr.as_string())));
00157 }
00158
00159 static void split_list(MethodParams& params, int paramIndex,
00160                const String& string,
00161                ArrayString& result) {
00162     Value& delim_value=params.as_no_junction(paramIndex, "delimiter must not be code");
00163
00164     size_t pos_after=0;
00165     string.split(result, pos_after, delim_value.as_string());
00166 }
00167
00168 #define SPLIT_LEFT 0x0001
00169 #define SPLIT_RIGHT 0x0010
00170 #define SPLIT_HORIZONTAL 0x0100
00171 #define SPLIT_VERTICAL 0x1000
00172
00173 static int split_options(const String* options) {
00174     struct Split_option {
00175         const char* keyL;
00176         const char* keyU;
00177         int setBit;
00178         int checkBit;
00179     } split_option[]={
00180         {"l", "L", SPLIT_LEFT, SPLIT_RIGHT}, // 0xVHRL
00181         {"r", "R", SPLIT_RIGHT, SPLIT_LEFT},
00182         {"h", "H", SPLIT_HORIZONTAL, SPLIT_VERTICAL},
00183         {"v", "V", SPLIT_VERTICAL, SPLIT_HORIZONTAL},
00184         {0, 0, 0, 0}
00185     };
00186
00187     int result=0;
00188     if(options) {
00189         for(Split_option *o=split_option; o->keyL; o++)
00190             if(options->pos(o->keyL)!=STRING_NOT_FOUND
00191                 || (o->keyU && options->pos(o->keyU)!=STRING_NOT_FOUND)) {
00192                 if(result & o->checkBit)
00193                     throw Exception("parser.runtime",
00194                         options,
00195                         "conflicting split options");
00196                 result |= o->setBit;
00197             }
00198     }
00199
00200     return result;
00201 }
00202
00203 static Table& split_vertical(ArrayString& pieces, bool right) {
00204     Table::columns_type columns(new ArrayString);
00205     *columns+=new String("piece");
00206
00207     Table& table=*new Table(columns, pieces.count());
00208     if(right) { // right
00209         for(int i=pieces.count(); --i>=0; ) {
00210             Table::element_type row(new ArrayString);
00211             *row+=pieces[i];
00212             table+=row;
00213         }
00214     } else { // left
00215         Array_iterator<const String*> i(pieces);
00216         while(i.has_next()) {
00217             Table::element_type row(new ArrayString);
00218             *row+=i.next();
00219             table+=row;
00220         }
00221     }
00222
00223     return table;
00224 }
00225
00226 static Table& split_horizontal(ArrayString& pieces, bool right) {
00227     Table& table=*new Table(Table::columns_type(0) /* nameless */);
00228     Table::element_type row(new ArrayString(pieces.count()));
00229     if(right) { // right
00230         for(int i=pieces.count(); --i>=0; )
00231             *row+=pieces[i];
00232     } else { // left
00233         for(Array_iterator<const String*> i(pieces); i.has_next(); )
00234             *row+=i.next();
00235     }
00236     table+=row;
00237
00238     return table;
00239 }
00240
00241 static void split_with_options(Request& r, MethodParams& params,
00242                                int bits) {
00243     const String& string=GET_SELF(r, VString).string();
00244
00245     ArrayString pieces;
00246     split_list(params, 0, string, pieces);
00247
00248     if(!bits) {
00249         const String* options=0;
00250         if(params.count()>1)
00251             options=&params.as_string(1, "options must not be code");
00252
00253         bits=split_options(options);
00254     }
00255
00256     bool right=(bits & SPLIT_RIGHT) != 0;
00257     bool horizontal=(bits & SPLIT_HORIZONTAL) !=0;
00258     Table& table=horizontal?split_horizontal(pieces, right)
00259         :split_vertical(pieces, right);
00260
00261     r.write_no_lang(*new VTable(&table));
00262 }
00263 static void _split(Request& r, MethodParams& params) {
00264     split_with_options(r, params, 0 /* maybe-determine from param #2 */);
00265 }
00266 static void _lsplit(Request& r, MethodParams& params) {
00267     split_with_options(r, params, SPLIT_LEFT);
00268 }
00269 static void _rsplit(Request& r, MethodParams& params) {
00270     split_with_options(r, params, SPLIT_RIGHT);
00271 }
00272
00273 static void search_action(Table& table, Table::element_type row, int, int, int, int, void *) {
00274     if(row)
00275         table+=row;
00276 }
00277
00278 #ifndef DOXYGEN
00279 struct Replace_action_info {
00280     Request* request;
00281     const String* src;  String* dest;
00282     VTable* vtable;
00283     Value* replacement_code;
00284 };
00285 #endif
00286
00287 static void replace_action(Table& table, ArrayString* row,
00288                int prestart, int prefinish,
00289                int poststart, int postfinish,
00290                void *info) {
00291     Replace_action_info& ai=*static_cast<Replace_action_info *>(info);
00292     if(row) { // begin&middle
00293         // piece from last match['prestart'] to beginning of this match['prefinish']
00294         if(prestart!=prefinish)
00295             *ai.dest << ai.src->mid(prestart, prefinish);//ai.dest->APPEND_CONST("-");
00296         // store found parts in one-record VTable
00297         if(table.count()) // middle
00298             table.put(0, row);
00299         else // begin
00300             table+=row;
00301         { // execute 'replacement_code' in 'table' context
00302             ai.vtable->set_table(table);
00303
00304             *ai.dest << ai.request->process_to_string(*ai.replacement_code);
00305         }
00306     } else // end
00307         *ai.dest << ai.src->mid(poststart, postfinish);
00308 }
00309
00311 static void _match(Request& r, MethodParams& params) {
00312     Value& regexp=params.as_no_junction(0, "regexp must not be code");
00313
00314     const String* options=
00315         params.count()>1?
00316         &params.as_no_junction(1, "options must not be code").as_string():0;
00317
00318     Temp_lang temp_lang(r, String::L_PASS_APPENDED);
00319     const String& src=GET_SELF(r, VString).string();
00320     bool just_matched;
00321     if(params.count()<3) { // search
00322         Table* table=src.match(r.charsets.source(),
00323             regexp.as_string(), options,
00324             search_action, 0,
00325             just_matched);
00326         Value* result;
00327         if(table)
00328             result=new VTable(table); // table of pre/match/post+substrings
00329         else
00330             result=new VBool(just_matched);
00331         r.write_assign_lang(*result);
00332     } else { // replace
00333         Value& replacement_code=params.as_junction(2, "replacement param must be code");
00334
00335         String result;
00336         VTable* vtable=new VTable;
00337         Replace_action_info info={
00338             &r,
00339             &src,
00340             &result,
00341             vtable,
00342             &replacement_code
00343         };
00344         Temp_value_element temp_match_var(
00345             *replacement_code.get_junction()->method_frame,
00346             match_var_name, vtable);
00347         src.match(r.charsets.source(),
00348             r.process_to_string(regexp), options,
00349             replace_action, &info,
00350             just_matched);
00351         r.write_assign_lang(result);
00352     }
00353 }
00354
00355 static void change_case(Request& r, MethodParams&,
00356                         String::Change_case_kind kind) {
00357     const String& src=GET_SELF(r, VString).string();
00358
00359     r.write_assign_lang(src.change_case(r.charsets.source(), kind));
00360 }
00361 static void _upper(Request& r, MethodParams& params) {
00362     change_case(r, params, String::CC_UPPER);
00363 }
00364 static void _lower(Request& r, MethodParams& params) {
00365     change_case(r, params, String::CC_LOWER);
00366 }
00367
00368 #ifndef DOXYGEN
00369 class String_sql_event_handlers: public SQL_Driver_query_event_handlers {
00370     const String& statement_string; const char* statement_cstr;
00371     bool got_column;
00372 public:
00373     bool got_cell;
00374     String& result;
00375 public:
00376     String_sql_event_handlers(
00377         const String& astatement_string, const char* astatement_cstr):
00378         statement_string(astatement_string), statement_cstr(astatement_cstr),
00379         got_column(false),
00380         got_cell(false),
00381         result(*new String) {}
00382
00383     bool add_column(SQL_Error& error, const char* /*str*/, size_t /*length*/) {
00384         if(got_column) {
00385             error=SQL_Error("parser.runtime",
00386                 //statement_string,
00387                 "result must contain exactly one column");
00388             return true;
00389         }
00390         got_column=true;
00391         return false;
00392     }
00393     bool before_rows(SQL_Error& /*error*/ ) { /* ignore */ return false; }
00394     bool add_row(SQL_Error& /*error*/) { /* ignore */ return false; }
00395     bool add_row_cell(SQL_Error& error, const char* str, size_t length) {
00396         if(got_cell) {
00397             error=SQL_Error("parser.runtime",
00398                 //statement_string,
00399                 "result must not contain more then one row");
00400             return true;
00401         }
00402
00403         try {
00404             got_cell=true;
00405             result.append_know_length(str, length, String::L_TAINTED);
00406             return false;
00407         } catch(...) {
00408             error=SQL_Error("exception occured in String_sql_event_handlers::add_row_cell");
00409             return true;
00410         }
00411     }
00412 };
00413 #endif
00414 extern String sql_bind_name;
00415 extern String sql_limit_name;
00416 extern String sql_offset_name;
00417 extern String sql_default_name;
00418 extern String sql_distinct_name;
00419 extern int marshal_binds(HashStringValue& hash, SQL_Driver::Placeholder*& placeholders);
00420 extern void unmarshal_bind_updates(HashStringValue& hash, int placeholder_count, SQL_Driver::Placeholder* placeholders);
00421
00422 const String* sql_result_string(Request& r, MethodParams& params,
00423                 HashStringValue*& options, Value*& default_code) {
00424     Value& statement=params.as_junction(0, "statement must be code");
00425
00426     HashStringValue* bind=0;
00427     ulong limit=0;
00428     ulong offset=0;
00429     default_code=0;
00430     if(params.count()>1) {
00431         Value& voptions=params.as_no_junction(1, "options must be hash, not code");
00432         if(voptions.is_defined() && !voptions.is_string())
00433             if((options=voptions.get_hash())) {
00434                 int valid_options=0;
00435                 if(Value* vbind=options->get(sql_bind_name)) {
00436                     valid_options++;
00437                     bind=vbind->get_hash();
00438                 }
00439                 if(Value* vlimit=options->get(sql_limit_name)) {
00440                     valid_options++;
00441                     limit=(ulong)r.process_to_value(*vlimit).as_double();
00442                 }
00443                 if(Value* voffset=options->get(sql_offset_name)) {
00444                     valid_options++;
00445                     offset=(ulong)r.process_to_value(*voffset).as_double();
00446                 }
00447                 if((default_code=options->get(sql_default_name))) {
00448                     valid_options++;
00449                 }
00450                 if(valid_options!=options->count())
00451                     throw Exception("parser.runtime",
00452                         0,
00453                         "called with invalid option");
00454             } else
00455                 throw Exception("parser.runtime",
00456                     0,
00457                     "options must be hash");
00458     } else
00459         options=0;
00460
00461     SQL_Driver::Placeholder* placeholders=0;
00462     uint placeholders_count=0;
00463     if(bind)
00464         placeholders_count=marshal_binds(*bind, placeholders);
00465
00466     Temp_lang temp_lang(r, String::L_SQL);
00467     const String& statement_string=r.process_to_string(statement);
00468     const char* statement_cstr=
00469         statement_string.cstr(String::L_UNSPECIFIED, r.connection());
00470     String_sql_event_handlers handlers(statement_string, statement_cstr);
00471     r.connection()->query(
00472         statement_cstr,
00473         placeholders_count, placeholders,
00474         offset, limit,
00475         handlers,
00476         statement_string);
00477
00478     if(bind)
00479         unmarshal_bind_updates(*bind, placeholders_count, placeholders);
00480
00481     if(!handlers.got_cell)
00482         return 0; // no lines, caller should return second param[default value]
00483
00484     return &handlers.result;
00485 }
00486
00487 static void _sql(Request& r, MethodParams& params) {
00488
00489     HashStringValue* options;
00490     Value* default_code;
00491     const String* string=sql_result_string(r, params, options, default_code);
00492     if(!string) {
00493         if(default_code) {
00494             string=&r.process_to_string(*default_code);
00495         } else
00496             throw Exception("parser.runtime",
00497                 0,
00498                 "produced no result, but no default option specified");
00499     }
00500
00501     r.write_assign_lang(*string);
00502 }
00503
00504 static void _replace(Request& r, MethodParams& params) {
00505     const String& src=GET_SELF(r, VString).string();
00506
00507     Table* table=params.as_no_junction(0, "parameter must not be code").get_table();
00508     if(!table)
00509         throw Exception("parser.runtime",
00510             0,
00511             "parameter must be table");
00512
00513     Dictionary dict(*table);
00514     r.write_assign_lang(src.replace(dict));
00515 }
00516
00517 static void _save(Request& r, MethodParams& params) {
00518     const String& file_name=params.as_string(params.count()-1,
00519         "file name must be string");
00520
00521     const String& src=GET_SELF(r, VString).string();
00522
00523     bool do_append=false;
00524     if(params.count()>1) {
00525         const String& mode=params.as_string(0, "mode must be string");
00526         if(mode=="append")
00527             do_append=true;
00528         else
00529             throw Exception("parser.runtime",
00530                 &mode,
00531                 "unknown mode, must be 'append'");
00532     }
00533
00534     // write
00535     const char* buf=src.cstr(String::L_UNSPECIFIED, r.connection(false/*no error if none*/));
00536     file_write(r.absolute(file_name),
00537         buf, strlen(buf), true, do_append);
00538 }
00539
00540 static void _normalize(Request& r, MethodParams&) {
00541     const String& src=GET_SELF(r, VString).string();
00542
00543     r.write_assign_lang(src);
00544 }
00545
00546 static void _trim(Request& r, MethodParams& params) {
00547     const String& src=GET_SELF(r, VString).string();
00548
00549     String::Trim_kind kind=String::TRIM_BOTH;
00550     const char* chars=0;
00551     if(params.count()>0) {
00552         const String& skind=params.as_string(0,
00553             "'where' must be string");
00554         if(skind.length())
00555             if(skind==TRIM_START_OPTION)
00556                 kind=String::TRIM_START;
00557             else if(skind==TRIM_END_OPTION)
00558                 kind=String::TRIM_END;
00559             else if(skind==TRIM_BOTH_OPTION)
00560                 kind=String::TRIM_BOTH;
00561             else
00562                 throw Exception("parser.runtime",
00563                     &skind,
00564                     "'kind' must be one of "TRIM_START_OPTION", "TRIM_BOTH_OPTION", "TRIM_END_OPTION);
00565
00566         if(params.count()>1) {
00567             const String& schars=params.as_string(1, "'chars' must be string");
00568             if(schars.length())
00569                 chars=schars.cstr();
00570         }
00571     }
00572
00573     r.write_assign_lang(src.trim(kind, chars));
00574 }
00575
00576 static void _append(Request& r, MethodParams& params) {
00577     // c=a+b
00578     VString& va=GET_SELF(r, VString);
00579     const String& a=va.string();
00580     const String& b=params.as_string(0, "parameter must be string");
00581     String& c=*new String(a);
00582     c.append(b, String::L_PASS_APPENDED);
00583     va.set_string(c);
00584 }
00585
00586 static void _base64(Request& r, MethodParams& params) {
00587     if(params.count()) {
00588         // decode
00589         const char* cstr=params.as_string(0, "parameter must be string").cstr();
00590         char* decoded_cstr=0;
00591         size_t decoded_size=0;
00592         pa_base64_decode(cstr, strlen(cstr), decoded_cstr, decoded_size);
00593         if(decoded_cstr && decoded_size)
00594             r.write_assign_lang(*new String(decoded_cstr, decoded_size, true));
00595     } else {
00596         // encode
00597         VString& self=GET_SELF(r, VString);
00598         const char* cstr=self.string().cstr();
00599         const char* encoded=pa_base64_encode(cstr, strlen(cstr));
00600         r.write_assign_lang(*new String(encoded, 0, true/*once ?param=base64(something) was needed*/));
00601     }
00602 }
00603
00604 // constructor
00605
00606 MString::MString(): Methoded("string") {
00607     // ^string.length[]
00608     add_native_method("length", Method::CT_DYNAMIC, _length, 0, 0);
00609
00610     // ^string.int[]
00611     // ^string.int(default)
00612     add_native_method("int", Method::CT_DYNAMIC, _int, 0, 1);
00613     // ^string.double[]
00614     // ^string.double(default)
00615     add_native_method("double", Method::CT_DYNAMIC, _double, 0, 1);
00616
00617     // ^string.format{format}
00618     add_native_method("format", Method::CT_DYNAMIC, _string_format, 1, 1);
00619
00620     // ^string.left(n)
00621     add_native_method("left", Method::CT_DYNAMIC, _left, 1, 1);
00622     // ^string.right(n)
00623     add_native_method("right", Method::CT_DYNAMIC, _right, 1, 1);
00624     // ^string.mid(p;n)
00625     add_native_method("mid", Method::CT_DYNAMIC, _mid, 1, 2);
00626
00627     // ^string.pos[substr]
00628     add_native_method("pos", Method::CT_DYNAMIC, _pos, 1, 1);
00629
00630     // ^string.split[delim]
00631     // ^string.split[delim][options]
00632     add_native_method("split", Method::CT_DYNAMIC, _split, 1, 2);
00633         // old names for backward compatibility
00634         // ^string.lsplit[delim]
00635         add_native_method("lsplit", Method::CT_DYNAMIC, _lsplit, 1, 1);
00636         // ^string.rsplit[delim]
00637         add_native_method("rsplit", Method::CT_DYNAMIC, _rsplit, 1, 1);
00638
00639     // ^string.match[regexp][options]
00640     // ^string.match[regexp][options]{replacement-code}
00641     add_native_method("match", Method::CT_DYNAMIC, _match, 1, 3);
00642
00643     // ^string.toupper[]
00644     add_native_method("upper", Method::CT_DYNAMIC, _upper, 0, 0);
00645     // ^string.tolower[]
00646     add_native_method("lower", Method::CT_DYNAMIC, _lower, 0, 0);
00647
00648     // ^sql[query]
00649     // ^sql[query][options hash]
00650     add_native_method("sql", Method::CT_STATIC, _sql, 1, 2);
00651
00652     // ^string.replace[table]
00653     add_native_method("replace", Method::CT_DYNAMIC, _replace, 1, 1);
00654
00655     // ^string.save[file]
00656     add_native_method("save", Method::CT_DYNAMIC, _save, 1, 2);
00657
00658     // ^string.normalize[]
00659     add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0);
00660
00661     // ^string.trim[[start|both|end][;chars]]
00662     add_native_method("trim", Method::CT_DYNAMIC, _trim, 0, 2);
00663
00664     // ^string.append[string]
00665     add_native_method("append", Method::CT_DYNAMIC, _append, 1, 1);
00666
00667     // ^string.base64[] << encode
00668     // ^string:base64[encoded string] << decode
00669     add_native_method("base64", Method::CT_ANY, _base64, 0, 1);
00670 }


string.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


study.c File Reference

Include dependency graph for study.c:

Include dependency graph

Go to the source code of this file.

Functions

void | set_bit (uschar *start_bits, int c, BOOL caseless, compile_data *cd)
BOOL | set_start_bits (const uschar *code, uschar *start_bits, BOOL caseless, compile_data *cd)
pcre_extra * | pcre_study (const pcre *external_re, int options, const char **errorptr)

Function Documentation

void set_bit | ( | uschar * | start_bits,
 |  | int | c,
 |  | BOOL | caseless,
 |  | compile_data * | cd
 | ) | [static]

Definition at line 60 of file study.c.

References BOOL, ctype_letter, compile_data::ctypes, compile_data::fcc, and uschar.

Referenced by set_start_bits().

BOOL set_start_bits | ( | const uschar * | code,
 |  | uschar * | start_bits,
 |  | BOOL | caseless,
 |  | compile_data * | cd
 | ) | [static]

Definition at line 87 of file study.c.

References BOOL, cbit_digit, cbit_space, cbit_word, compile_data::cbits, OP_ALT, OP_ASSERT, OP_ASSERT_NOT, OP_ASSERTBACK, OP_ASSERTBACK_NOT, OP_BRA, OP_BRAMINZERO, OP_BRAZERO, OP_CHARS, OP_CLASS, OP_CRMINQUERY, OP_CRMINRANGE, OP_CRMINSTAR, OP_CRQUERY, OP_CRRANGE, OP_CRSTAR, OP_DIGIT, OP_EXACT, OP_MINPLUS, OP_MINQUERY, OP_MINSTAR, OP_MINUPTO, OP_NOT_DIGIT, OP_NOT_WHITESPACE, OP_NOT_WORDCHAR, OP_OPT, OP_PLUS, OP_QUERY, OP_STAR, OP_TYPEEXACT, OP_TYPEMINPLUS, OP_TYPEMINQUERY, OP_TYPEMINSTAR, OP_TYPEMINUPTO, OP_TYPEPLUS, OP_TYPEQUERY, OP_TYPESTAR, OP_TYPEUPTO, OP_UPTO, OP_WHITESPACE, OP_WORDCHAR, PCRE_CASELESS, set_bit(), and uschar.

Referenced by pcre_study().

pcre_extra* pcre_study | ( | const pcre * | external_re,
 |  | int | options,
 |  | const char ** | errorptr
 | ) |

Definition at line 340 of file study.c.

References compile_data::cbits, cbits_offset, real_pcre::code, compile_data::ctypes, ctypes_offset, compile_data::fcc, fcc_offset, compile_data::lcc, lcc_offset, MAGIC_NUMBER, real_pcre::magic_number, real_pcre_extra::options, real_pcre::options, pcre, PCRE_ANCHORED, PCRE_CASELESS, pcre_extra, PCRE_FIRSTSET, PCRE_STARTLINE, PCRE_STUDY_MAPPED, PUBLIC_STUDY_OPTIONS, set_start_bits(), real_pcre_extra::start_bits, real_pcre::tables, and uschar.


study.c Source File

study.c

Go to the documentation of this file.
00001 /*************************************************
00002 *      Perl-Compatible Regular Expressions       *
00003 *************************************************/
00004
00005 /*
00006 This is a library of functions to support regular expressions whose syntax
00007 and semantics are as close as possible to those of the Perl 5 language. See
00008 the file Tech.Notes for some information on the internals.
00009
00010 Written by: Philip Hazel <ph10@cam.ac.uk>
00011
00012            Copyright (c) 1997-1999 University of Cambridge
00013
00014 -----------------------------------------------------------------------------
00015 Permission is granted to anyone to use this software for any purpose on any
00016 computer system, and to redistribute it freely, subject to the following
00017 restrictions:
00018
00019 1. This software is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022
00023 2. The origin of this software must not be misrepresented, either by
00024    explicit claim or by omission.
00025
00026 3. Altered versions must be plainly marked as such, and must not be
00027    misrepresented as being the original software.
00028
00029 4. If PCRE is embedded in any software that is released under the GNU
00030    General Purpose Licence (GPL), then the terms of that licence shall
00031    supersede any condition above with which it is incompatible.
00032 -----------------------------------------------------------------------------
00033 */
00034
00035
00036 /* Include the internals header, which itself includes Standard C headers plus
00037 the external pcre header. */
00038
00039 #include "internal.h"
00040
00041
00042
00043 /*************************************************
00044 *      Set a bit and maybe its alternate case    *
00045 *************************************************/
00046
00047 /* Given a character, set its bit in the table, and also the bit for the other
00048 version of a letter if we are caseless.
00049
00050 Arguments:
00051   start_bits    points to the bit map
00052   c             is the character
00053   caseless      the caseless flag
00054   cd            the block with char table pointers
00055
00056 Returns:        nothing
00057 */
00058
00059 static void
00060 set_bit(uschar *start_bits, int c, BOOL caseless, compile_data *cd)
00061 {
00062 start_bits[c/8] |= (1 << (c&7));
00063 if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
00064   start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
00065 }
00066
00067
00068
00069 /*************************************************
00070 *          Create bitmap of starting chars       *
00071 *************************************************/
00072
00073 /* This function scans a compiled unanchored expression and attempts to build a
00074 bitmap of the set of initial characters. If it can't, it returns FALSE. As time
00075 goes by, we may be able to get more clever at doing this.
00076
00077 Arguments:
00078   code         points to an expression
00079   start_bits   points to a 32-byte table, initialized to 0
00080   caseless     the current state of the caseless flag
00081   cd           the block with char table pointers
00082
00083 Returns:       TRUE if table built, FALSE otherwise
00084 */
00085
00086 static BOOL
00087 set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
00088   compile_data *cd)
00089 {
00090 register int c;
00091
00092 /* This next statement and the later reference to dummy are here in order to
00093 trick the optimizer of the IBM C compiler for OS/2 into generating correct
00094 code. Apparently IBM isn't going to fix the problem, and we would rather not
00095 disable optimization (in this module it actually makes a big difference, and
00096 the pcre module can use all the optimization it can get). */
00097
00098 volatile int dummy;
00099
00100 do
00101   {
00102   const uschar *tcode = code + 3;
00103   BOOL try_next = TRUE;
00104
00105   while (try_next)
00106     {
00107     try_next = FALSE;
00108
00109     /* If a branch starts with a bracket or a positive lookahead assertion,
00110     recurse to set bits from within them. That's all for this branch. */
00111
00112     if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT)
00113       {
00114       if (!set_start_bits(tcode, start_bits, caseless, cd))
00115         return FALSE;
00116       }
00117
00118     else switch(*tcode)
00119       {
00120       default:
00121       return FALSE;
00122
00123       /* Skip over lookbehind and negative lookahead assertions */
00124
00125       case OP_ASSERT_NOT:
00126       case OP_ASSERTBACK:
00127       case OP_ASSERTBACK_NOT:
00128       try_next = TRUE;
00129       do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT);
00130       tcode += 3;
00131       break;
00132
00133       /* Skip over an option setting, changing the caseless flag */
00134
00135       case OP_OPT:
00136       caseless = (tcode[1] & PCRE_CASELESS) != 0;
00137       tcode += 2;
00138       try_next = TRUE;
00139       break;
00140
00141       /* BRAZERO does the bracket, but carries on. */
00142
00143       case OP_BRAZERO:
00144       case OP_BRAMINZERO:
00145       if (!set_start_bits(++tcode, start_bits, caseless, cd))
00146         return FALSE;
00147       dummy = 1;
00148       do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT);
00149       tcode += 3;
00150       try_next = TRUE;
00151       break;
00152
00153       /* Single-char * or ? sets the bit and tries the next item */
00154
00155       case OP_STAR:
00156       case OP_MINSTAR:
00157       case OP_QUERY:
00158       case OP_MINQUERY:
00159       set_bit(start_bits, tcode[1], caseless, cd);
00160       tcode += 2;
00161       try_next = TRUE;
00162       break;
00163
00164       /* Single-char upto sets the bit and tries the next */
00165
00166       case OP_UPTO:
00167       case OP_MINUPTO:
00168       set_bit(start_bits, tcode[3], caseless, cd);
00169       tcode += 4;
00170       try_next = TRUE;
00171       break;
00172
00173       /* At least one single char sets the bit and stops */
00174
00175       case OP_EXACT:       /* Fall through */
00176       tcode++;
00177
00178       case OP_CHARS:       /* Fall through */
00179       tcode++;
00180
00181       case OP_PLUS:
00182       case OP_MINPLUS:
00183       set_bit(start_bits, tcode[1], caseless, cd);
00184       break;
00185
00186       /* Single character type sets the bits and stops */
00187
00188       case OP_NOT_DIGIT:
00189       for (c = 0; c < 32; c++)
00190         start_bits[c] |= ~cd->cbits[c+cbit_digit];
00191       break;
00192
00193       case OP_DIGIT:
00194       for (c = 0; c < 32; c++)
00195         start_bits[c] |= cd->cbits[c+cbit_digit];
00196       break;
00197
00198       case OP_NOT_WHITESPACE:
00199       for (c = 0; c < 32; c++)
00200         start_bits[c] |= ~cd->cbits[c+cbit_space];
00201       break;
00202
00203       case OP_WHITESPACE:
00204       for (c = 0; c < 32; c++)
00205         start_bits[c] |= cd->cbits[c+cbit_space];
00206       break;
00207
00208       case OP_NOT_WORDCHAR:
00209       for (c = 0; c < 32; c++)
00210         start_bits[c] |= ~(cd->cbits[c] | cd->cbits[c+cbit_word]);
00211       break;
00212
00213       case OP_WORDCHAR:
00214       for (c = 0; c < 32; c++)
00215         start_bits[c] |= (cd->cbits[c] | cd->cbits[c+cbit_word]);
00216       break;
00217
00218       /* One or more character type fudges the pointer and restarts, knowing
00219       it will hit a single character type and stop there. */
00220
00221       case OP_TYPEPLUS:
00222       case OP_TYPEMINPLUS:
00223       tcode++;
00224       try_next = TRUE;
00225       break;
00226
00227       case OP_TYPEEXACT:
00228       tcode += 3;
00229       try_next = TRUE;
00230       break;
00231
00232       /* Zero or more repeats of character types set the bits and then
00233       try again. */
00234
00235       case OP_TYPEUPTO:
00236       case OP_TYPEMINUPTO:
00237       tcode += 2;               /* Fall through */
00238
00239       case OP_TYPESTAR:
00240       case OP_TYPEMINSTAR:
00241       case OP_TYPEQUERY:
00242       case OP_TYPEMINQUERY:
00243       switch(tcode[1])
00244         {
00245         case OP_NOT_DIGIT:
00246         for (c = 0; c < 32; c++)
00247           start_bits[c] |= ~cd->cbits[c+cbit_digit];
00248         break;
00249
00250         case OP_DIGIT:
00251         for (c = 0; c < 32; c++)
00252           start_bits[c] |= cd->cbits[c+cbit_digit];
00253         break;
00254
00255         case OP_NOT_WHITESPACE:
00256         for (c = 0; c < 32; c++)
00257           start_bits[c] |= ~cd->cbits[c+cbit_space];
00258         break;
00259
00260         case OP_WHITESPACE:
00261         for (c = 0; c < 32; c++)
00262           start_bits[c] |= cd->cbits[c+cbit_space];
00263         break;
00264
00265         case OP_NOT_WORDCHAR:
00266         for (c = 0; c < 32; c++)
00267           start_bits[c] |= ~(cd->cbits[c] | cd->cbits[c+cbit_word]);
00268         break;
00269
00270         case OP_WORDCHAR:
00271         for (c = 0; c < 32; c++)
00272           start_bits[c] |= (cd->cbits[c] | cd->cbits[c+cbit_word]);
00273         break;
00274         }
00275
00276       tcode += 2;
00277       try_next = TRUE;
00278       break;
00279
00280       /* Character class: set the bits and either carry on or not,
00281       according to the repeat count. */
00282
00283       case OP_CLASS:
00284         {
00285         tcode++;
00286         for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
00287         tcode += 32;
00288         switch (*tcode)
00289           {
00290           case OP_CRSTAR:
00291           case OP_CRMINSTAR:
00292           case OP_CRQUERY:
00293           case OP_CRMINQUERY:
00294           tcode++;
00295           try_next = TRUE;
00296           break;
00297
00298           case OP_CRRANGE:
00299           case OP_CRMINRANGE:
00300           if (((tcode[1] << 8) + tcode[2]) == 0)
00301             {
00302             tcode += 5;
00303             try_next = TRUE;
00304             }
00305           break;
00306           }
00307         }
00308       break; /* End of class handling */
00309
00310       }      /* End of switch */
00311     }        /* End of try_next loop */
00312
00313   code += (code[1] << 8) + code[2];   /* Advance to next branch */
00314   }
00315 while (*code == OP_ALT);
00316 return TRUE;
00317 }
00318
00319
00320
00321 /*************************************************
00322 *          Study a compiled expression           *
00323 *************************************************/
00324
00325 /* This function is handed a compiled expression that it must study to produce
00326 information that will speed up the matching. It returns a pcre_extra block
00327 which then gets handed back to pcre_exec().
00328
00329 Arguments:
00330   re        points to the compiled expression
00331   options   contains option bits
00332   errorptr  points to where to place error messages;
00333             set NULL unless error
00334
00335 Returns:    pointer to a pcre_extra block,
00336             NULL on error or if no optimization possible
00337 */
00338
00339 pcre_extra *
00340 pcre_study(const pcre *external_re, int options, const char **errorptr)
00341 {
00342 uschar start_bits[32];
00343 real_pcre_extra *extra;
00344 const real_pcre *re = (const real_pcre *)external_re;
00345 compile_data compile_block;
00346
00347 *errorptr = NULL;
00348
00349 if (re == NULL || re->magic_number != MAGIC_NUMBER)
00350   {
00351   *errorptr = "argument is not a compiled regular expression";
00352   return NULL;
00353   }
00354
00355 if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
00356   {
00357   *errorptr = "unknown or incorrect option bit(s) set";
00358   return NULL;
00359   }
00360
00361 /* For an anchored pattern, or an unchored pattern that has a first char, or a
00362 multiline pattern that matches only at "line starts", no further processing at
00363 present. */
00364
00365 if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
00366   return NULL;
00367
00368 /* Set the character tables in the block which is passed around */
00369
00370 compile_block.lcc = re->tables + lcc_offset;
00371 compile_block.fcc = re->tables + fcc_offset;
00372 compile_block.cbits = re->tables + cbits_offset;
00373 compile_block.ctypes = re->tables + ctypes_offset;
00374
00375 /* See if we can find a fixed set of initial characters for the pattern. */
00376
00377 memset(start_bits, 0, 32 * sizeof(uschar));
00378 if (!set_start_bits(re->code, start_bits, (re->options & PCRE_CASELESS) != 0,
00379   &compile_block)) return NULL;
00380
00381 /* Get an "extra" block and put the information therein. */
00382
00383 extra = (real_pcre_extra *)(pcre_malloc)(sizeof(real_pcre_extra));
00384
00385 if (extra == NULL)
00386   {
00387   *errorptr = "failed to get memory";
00388   return NULL;
00389   }
00390
00391 extra->options = PCRE_STUDY_MAPPED;
00392 memcpy(extra->start_bits, start_bits, sizeof(start_bits));
00393
00394 return (pcre_extra *)extra;
00395 }
00396
00397 /* End of study.c */


table.C File Reference

Parser: table parser class. More...

Include dependency graph for table.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MTable
struct | lsplit_result
struct | TableSeparators

Defines

#define | SQL_BIND_NAME "bind"
#define | SQL_DEFAULT_NAME "default"
#define | SQL_DISTINCT_NAME "distinct"
#define | TABLE_REVERSE_NAME "reverse"

Functions

DECLARE_CLASS_VAR (table, new MTable, 0)
String | sql_bind_name (SQL_BIND_NAME)
String | sql_limit_name (PA_SQL_LIMIT_NAME)
String | sql_offset_name (PA_SQL_OFFSET_NAME)
String | sql_default_name (SQL_DEFAULT_NAME)
String | sql_distinct_name (SQL_DISTINCT_NAME)
String | table_reverse_name (TABLE_REVERSE_NAME)
Table::Action_options | get_action_options (Request &r, MethodParams &params, const Table &source)
void | check_option_param (bool options_defined, MethodParams &params, size_t next_param_index, const char *msg)
void | _create (Request &r, MethodParams &params)
lsplit_result | lsplit (char *string, char delim1, char delim2)
lsplit_result | lsplit (char **string_ref, char delim1, char delim2)
lsplit_result | lsplit (char **string_ref, char delim1, char delim2, char encloser)
void | skip_empty_and_comment_lines (char **data_ref)
void | _load (Request &r, MethodParams &params)
void | maybe_enclose (String &to, const String &from, char encloser, const String *sencloser)
void | _save (Request &r, MethodParams &params)
void | _count (Request &r, MethodParams &)
void | _line (Request &r, MethodParams &)
void | _offset (Request &r, MethodParams &params)
void | _menu (Request &r, MethodParams &params)
void | table_row_to_hash (Table::element_type row, Row_info *info)
void | _hash (Request &r, MethodParams &params)
int | sort_cmp_string (const void *a, const void *b)
int | sort_cmp_double (const void *a, const void *b)
void | _sort (Request &r, MethodParams &params)
bool | expression_is_true (Table &, Expression_is_true_info *info)
bool | _locate_expression (Table &table, Table::Action_options o, Request &r, MethodParams &params)
bool | _locate_name_value (Table &table, Table::Action_options o, Request &, MethodParams &params)
void | _locate (Request &r, MethodParams &params)
void | _flip (Request &r, MethodParams &)
void | _append (Request &r, MethodParams &params)
void | join_named_row (Table &src, Table *dest)
void | join_nameless_row (Table &src, Table *dest)
void | _join (Request &r, MethodParams &params)
void | marshal_bind (HashStringValue::key_type aname, HashStringValue::value_type avalue, SQL_Driver::Placeholder **pptr)
int | marshal_binds (HashStringValue &hash, SQL_Driver::Placeholder *&placeholders)
void | unmarshal_bind_updates (HashStringValue &hash, int placeholder_count, SQL_Driver::Placeholder *placeholders)
void | _sql (Request &r, MethodParams &params)
void | _columns (Request &r, MethodParams &)
void | _select (Request &r, MethodParams &params)

Variables

const char *const | IDENT_TABLE_C = "$Date: 2005/11/28 12:50:18 $"

Detailed Description

Parser: table parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file table.C.

Define Documentation

#define SQL_BIND_NAME "bind"

Definition at line 38 of file table.C.

#define SQL_DEFAULT_NAME "default"

Definition at line 39 of file table.C.

#define SQL_DISTINCT_NAME "distinct"

Definition at line 40 of file table.C.

#define TABLE_REVERSE_NAME "reverse"

Definition at line 41 of file table.C.

Function Documentation

DECLARE_CLASS_VAR | ( | table | ,
 |  | new | MTable,
 |  | 0 |
 | ) |

String sql_bind_name ( SQL_BIND_NAME )

String sql_limit_name ( PA_SQL_LIMIT_NAME )

String sql_offset_name ( PA_SQL_OFFSET_NAME )

String sql_default_name ( SQL_DEFAULT_NAME )

String sql_distinct_name ( SQL_DISTINCT_NAME )

String table_reverse_name ( TABLE_REVERSE_NAME )

Table::Action_options get_action_options | ( | Request & | r,
 |  | MethodParams & | params,
 |  | const Table & | source
 | ) | [static]

Definition at line 54 of file table.C.

References Value::as_bool(), Value::as_int(), Hash< const String::Body, Value * >::count(), Array< ArrayString * >::count(), Array< Value * >::count(), Table::current(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_string(), Value::is_string(), MethodParams::last(), Request::process_to_value(), and result.

Referenced by _create(), _join(), and _locate().

void check_option_param | ( | bool | options_defined,
 |  | MethodParams & | params,
 |  | size_t | next_param_index,
 |  | const char * | msg
 | ) | [static]

Definition at line 113 of file table.C.

References Array< Value * >::count().

Referenced by _create(), _join(), _locate_expression(), and _locate_name_value().

void _create | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 122 of file table.C.

References check_option_param(), Table::columns_type, Array< const String * >::count(), Array< ArrayString * >::count(), data, Array< ArrayString * >::element_type, get_action_options(), GET_SELF, Array_iterator< T >::has_next(), String::L_AS_IS, String::L_PASS_APPENDED, String::length(), Array_iterator< T >::next(), Request::process_to_string(), and String::split().

Referenced by MTable::MTable().

lsplit_result lsplit | ( | char * | string,
 |  | char | delim1,
 |  | char | delim2
 | ) | [inline]

Definition at line 187 of file table.C.

References lsplit_result::delim, lsplit_result::piece, result, and v.

lsplit_result lsplit | ( | char ** | string_ref,
 |  | char | delim1,
 |  | char | delim2
 | ) | [inline]

Definition at line 203 of file table.C.

References lsplit_result::delim, lsplit(), lsplit_result::piece, and result.

lsplit_result lsplit | ( | char ** | string_ref,
 |  | char | delim1,
 |  | char | delim2,
 |  | char | encloser
 | ) | [static]

Definition at line 212 of file table.C.

References lsplit_result::delim, lsplit(), lsplit_result::piece, and result.

void skip_empty_and_comment_lines ( char ** data_ref ) [static]

Definition at line 248 of file table.C.

References data, and getrow().

Referenced by _load().

void _load | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 294 of file table.C.

References Request::absolute(), ArrayString, MethodParams::as_no_junction(), MethodParams::as_string(), Request::charsets, TableSeparators::column, Table::columns_type, Array< Value * >::count(), data, lsplit_result::delim, Array< ArrayString * >::element_type, TableSeparators::encloser, file_read_text(), Value::get_hash(), GET_SELF, HashStringValue, TableSeparators::load(), lsplit(), lsplit_result::piece, and skip_empty_and_comment_lines().

Referenced by MTable::MTable().

void maybe_enclose | ( | String & | to,
 |  | const String & | from,
 |  | char | encloser,
 |  | const String * | sencloser
 | ) | [static]

Definition at line 357 of file table.C.

References String::length(), String::mid(), String::pos(), and STRING_NOT_FOUND.

Referenced by _save().

void _save | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 377 of file table.C.

References Request::absolute(), String::append_help_length(), String::append_know_length(), MethodParams::as_no_junction(), MethodParams::as_string(), TableSeparators::column, Table::columns(), Array< ArrayString * >::count(), Hash< const String::Body, Value * >::count(), Array< Value * >::count(), String::cstr(), TableSeparators::encloser, file_write(), Value::get_hash(), GET_SELF, Array_iterator< T >::has_next(), String::L_CLEAN, String::length(), TableSeparators::load(), MAX_NUMBER, maybe_enclose(), Array_iterator< T >::next(), pa_free(), TableSeparators::scolumn, TableSeparators::sencloser, and snprintf.

Referenced by MTable::MTable().

void _count | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 459 of file table.C.

References GET_SELF, result, and Request::write_no_lang().

Referenced by MTable::MTable().

void _line | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 464 of file table.C.

References GET_SELF, result, and Request::write_no_lang().

Referenced by MTable::MTable().

void _offset | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 469 of file table.C.

References MethodParams::as_int(), MethodParams::as_string(), Array< Value * >::count(), Table::current(), GET_SELF, Table::offset(), offset, and Request::write_no_lang().

Referenced by MTable::MTable().

void _menu | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 491 of file table.C.

References MethodParams::as_junction(), Array< ArrayString * >::count(), Array< Value * >::count(), Table::current(), GET_SELF, StringOrValue::get_string(), String::length(), Request::process(), Table::set_current(), size, and Request::write_pass_lang().

Referenced by MTable::MTable().

void table_row_to_hash | ( | Table::element_type | row,
 |  | Row_info * | info
 | ) | [static]

Definition at line 528 of file table.C.

References StringOrValue::as_string(), Array< ArrayString * >::element_type, VTable::get_table(), Array_iterator< T >::has_next(), VHash::hash(), Array_iterator< T >::next(), and Hash< const String::Body, Value * >::put().

Referenced by _hash().

void _hash | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 581 of file table.C.

References Value::as_bool(), MethodParams::as_no_junction(), Value::as_string(), Table::column_name2index(), Table::columns(), Table::columns_type, Hash< const String::Body, Value * >::count(), Array< Value * >::count(), Table::current(), VHash::extract_default(), Array< ArrayString * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_junction(), GET_SELF, Value::get_string(), Value::get_table(), Array_iterator< T >::has_next(), VHash::hash(), Value::is_string(), Array_iterator< T >::next(), Request::process_to_value(), result, Table::set_current(), table_row_to_hash(), and Request::write_no_lang().

Referenced by MTable::MTable().

int sort_cmp_string | ( | const void * | a,
 |  | const void * | b
 | ) | [static]

Definition at line 682 of file table.C.

References value.

int sort_cmp_double | ( | const void * | a,
 |  | const void * | b
 | ) | [static]

Definition at line 688 of file table.C.

void _sort | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 698 of file table.C.

References _qsort, Value::as_double(), Value::as_expr_result(), MethodParams::as_junction(), MethodParams::as_no_junction(), Value::as_string(), Table::columns(), Array< ArrayString * >::count(), Array< Value * >::count(), String::cstr(), Array< ArrayString * >::element_type, GET_SELF, Value::is_string(), Request::process_to_value(), Table::set_current(), and value.

Referenced by MTable::MTable().

bool expression_is_true | ( | Table & | ,
 |  | Expression_is_true_info * | info
 | ) | [static]

Definition at line 747 of file table.C.

Referenced by _locate_expression().

bool _locate_expression | ( | Table & | table,
 |  | Table::Action_options | o,
 |  | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 750 of file table.C.

References MethodParams::as_junction(), check_option_param(), expression_is_true(), and Table::table_first_that().

Referenced by _locate().

bool _locate_name_value | ( | Table & | table,
 |  | Table::Action_options | o,
 |  | Request & | ,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 759 of file table.C.

References MethodParams::as_string(), check_option_param(), Table::locate(), and value.

Referenced by _locate().

void _locate | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 767 of file table.C.

References _locate_expression(), _locate_name_value(), get_action_options(), GET_SELF, result, and Request::write_no_lang().

Referenced by MTable::MTable().

void _flip | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 779 of file table.C.

References ArrayString, Array< ArrayString * >::count(), Array< ArrayString * >::element_type, GET_SELF, and Request::write_no_lang().

Referenced by MTable::MTable().

void _append | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 796 of file table.C.

References MethodParams::as_junction(), Array< ArrayString * >::element_type, GET_SELF, String::L_AS_IS, String::L_PASS_APPENDED, Request::process_to_string(), and String::split().

Referenced by MTable::MTable().

void join_named_row | ( | Table & | src,
 |  | Table * | dest
 | ) | [static]

Definition at line 809 of file table.C.

References ArrayString, Table::columns(), Table::columns_type, Array< ArrayString * >::element_type, and Table::item().

Referenced by _join().

void join_nameless_row | ( | Table & | src,
 |  | Table * | dest
 | ) | [static]

Definition at line 819 of file table.C.

References Table::current().

Referenced by _join().

void _join | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 822 of file table.C.

References MethodParams::as_no_junction(), check_option_param(), Table::columns(), get_action_options(), GET_SELF, Value::get_table(), join_named_row(), join_nameless_row(), and Table::table_for_each().

Referenced by MTable::MTable().

void marshal_bind | ( | HashStringValue::key_type | aname,
 |  | HashStringValue::value_type | avalue,
 |  | SQL_Driver::Placeholder ** | pptr
 | ) | [static]

Definition at line 901 of file table.C.

References SQL_Driver::Placeholder::is_null, String::L_UNSPECIFIED, SQL_Driver::Placeholder::name, SQL_Driver::Placeholder::value, void_class, and SQL_Driver::Placeholder::were_updated.

Referenced by marshal_binds().

int marshal_binds | ( | HashStringValue & | hash,
 |  | SQL_Driver::Placeholder *& | placeholders
 | ) |

Definition at line 916 of file table.C.

References Hash< const String::Body, Value * >::count(), Hash< const String::Body, Value * >::for_each(), and marshal_bind().

Referenced by _sql(), and sql_result_string().

void unmarshal_bind_updates | ( | HashStringValue & | hash,
 |  | int | placeholder_count,
 |  | SQL_Driver::Placeholder * | placeholders
 | ) |

Definition at line 925 of file table.C.

References SQL_Driver::Placeholder::is_null, SQL_Driver::Placeholder::name, Hash< const String::Body, Value * >::put(), value, SQL_Driver::Placeholder::value, and SQL_Driver::Placeholder::were_updated.

Referenced by _sql(), and sql_result_string().

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 941 of file table.C.

References Value::as_double(), MethodParams::as_junction(), MethodParams::as_no_junction(), Table::columns_type, Request::connection(), Hash< const String::Body, Value * >::count(), Array< Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), Value::get_hash(), GET_SELF, Value::is_defined(), Value::is_string(), String::L_SQL, String::L_UNSPECIFIED, marshal_binds(), offset, Request::process_to_string(), Request::process_to_value(), SQL_Connection::query(), result, uint, ulong, and unmarshal_bind_updates().

Referenced by MTable::MTable().

void _columns | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 1018 of file table.C.

References Table::columns(), Table::columns_type, Array< ArrayString * >::element_type, GET_SELF, Array_iterator< T >::has_next(), Array_iterator< T >::next(), and Request::write_no_lang().

Referenced by MTable::MTable().

void _select | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 1036 of file table.C.

References Value::as_bool(), MethodParams::as_junction(), Table::columns(), Array< ArrayString * >::count(), Table::current(), GET_SELF, Request::process_to_value(), Table::set_current(), size, and Request::write_no_lang().

Referenced by MTable::MTable().

Variable Documentation

const char* const IDENT_TABLE_C = "$Date: 2005/11/28 12:50:18 $" [static]

Definition at line 7 of file table.C.


table.C Source File

table.C

Go to the documentation of this file.
00001
00007 static const char * const IDENT_TABLE_C="$Date: 2005/11/28 12:50:18 $";
00008
00009 #include "classes.h"
00010 #include "pa_vmethod_frame.h"
00011
00012 #include "pa_common.h"
00013 #include "pa_request.h"
00014 #include "pa_vtable.h"
00015 #include "pa_vint.h"
00016 #include "pa_sql_connection.h"
00017 #include "pa_vbool.h"
00018
00019 // class
00020
00021 class MTable: public Methoded {
00022 public: // VStateless_class
00023     Value* create_new_value(Pool&, HashStringValue&) { return new VTable(); }
00024
00025 public:
00026     MTable();
00027
00028 public: // Methoded
00029     bool used_directly() { return true; }
00030 };
00031
00032 // global variable
00033
00034 DECLARE_CLASS_VAR(table, new MTable, 0);
00035
00036 // defines for globals
00037
00038 #define SQL_BIND_NAME "bind"
00039 #define SQL_DEFAULT_NAME "default"
00040 #define SQL_DISTINCT_NAME "distinct"
00041 #define TABLE_REVERSE_NAME "reverse"
00042
00043 // globals
00044
00045 String sql_bind_name(SQL_BIND_NAME);
00046 String sql_limit_name(PA_SQL_LIMIT_NAME);
00047 String sql_offset_name(PA_SQL_OFFSET_NAME);
00048 String sql_default_name(SQL_DEFAULT_NAME);
00049 String sql_distinct_name(SQL_DISTINCT_NAME);
00050 String table_reverse_name(TABLE_REVERSE_NAME);
00051
00052 // methods
00053
00054 static Table::Action_options get_action_options(Request& r, MethodParams& params,
00055                         const Table& source) {
00056     Table::Action_options result;
00057     if(!params.count())
00058         return result;
00059
00060     Value& maybe_options=params.last();
00061 /* can not do it:
00062     want to enable ^table::create[$source;
00063 #       $.option[]
00064     ]
00065     but there is ^table.locate[name;value]
00066
00067     ...if(voptions.is_defined() && !voptions.is_string()))
00068     if(maybe_options.is_string()) { // allow empty options
00069         result.defined=true;
00070         return result;
00071     }
00072 */
00073     HashStringValue* options=maybe_options.get_hash();
00074     if(!options)
00075         return result;
00076
00077     result.defined=true;
00078     bool defined_offset=false;
00079
00080     int valid_options=0;
00081     if(Value* voffset=options->get(sql_offset_name)) {
00082         valid_options++;
00083         defined_offset=true;
00084         if(voffset->is_string()) {
00085             const String&  soffset=*voffset->get_string();
00086             if(soffset == "cur")
00087                 result.offset=source.current();
00088             else
00089                 throw Exception("parser.runtime",
00090                     &soffset,
00091                     "must be 'cur' string or expression");
00092         } else
00093             result.offset=r.process_to_value(*voffset).as_int();
00094     }
00095     if(Value* vlimit=options->get(sql_limit_name)) {
00096         valid_options++;
00097         result.limit=r.process_to_value(*vlimit).as_int();
00098     }
00099     if(Value *vreverse=(Value *)options->get(table_reverse_name)) {
00100         valid_options++;
00101         result.reverse=r.process_to_value(*vreverse).as_bool();
00102         if(result.reverse && !defined_offset)
00103             result.offset=source.count()-1;
00104     }
00105
00106     if(valid_options!=options->count())
00107         throw Exception("parser.runtime",
00108             0,
00109             "called with invalid option");
00110
00111     return result;
00112 }
00113 static void check_option_param(bool options_defined,
00114               MethodParams& params, size_t next_param_index,
00115               const char *msg) {
00116     if(next_param_index+(options_defined?1:0) != params.count())
00117         throw Exception("parser.runtime",
00118             0,
00119             "%s", msg);
00120 }
00121
00122 static void _create(Request& r, MethodParams& params) {
00123     // clone/copy part?
00124     if(Table *source=params[0].get_table()) {
00125         Table::Action_options o=get_action_options(r, params, *source);
00126         check_option_param(o.defined, params, 1,
00127             "too many parameters");
00128         GET_SELF(r, VTable).set_table(*new Table(*source, o));
00129         return;
00130     }
00131
00132     // data is last parameter
00133     Temp_lang temp_lang(r, String::L_PASS_APPENDED);
00134     const String&  data=
00135         r.process_to_string(params.as_junction(params.count()-1, "body must be code"));
00136
00137     // parse columns
00138     size_t raw_pos_after=0;
00139     Table::columns_type columns;
00140     if(params.count()==2) {
00141         const String& snameless=params.as_string(0, "called with two params, first param may only be string 'nameless'");
00142         if(snameless!="nameless")
00143             throw Exception("parser.runtime",
00144                 &snameless,
00145                 "table::create called with two params, first param may only be 'nameless'");
00146         columns=Table::columns_type(0); // nameless
00147     } else {
00148         columns=Table::columns_type(new ArrayString);
00149
00150         ArrayString head;
00151         data.split(head, raw_pos_after, "\n", String::L_AS_IS, 1);
00152         if(head.count()) {
00153             size_t col_pos_after=0;
00154             head[0]->split(*columns, col_pos_after, "\t", String::L_AS_IS);
00155         }
00156     }
00157
00158     Table& table=*new Table(columns);
00159     // parse cells
00160
00161     ArrayString rows;
00162     data.split(rows, raw_pos_after, "\n", String::L_AS_IS);
00163     Array_iterator<const String*> i(rows);
00164     while(i.has_next()) {
00165         Table::element_type row(new ArrayString);
00166         const String&  string=*i.next();
00167         // remove comment lines
00168         if(!string.length())
00169             continue;
00170
00171         size_t col_pos_after=0;
00172         string.split(*row, col_pos_after, "\t", String::L_AS_IS);
00173         table+=row;
00174     }
00175
00176     // replace any previous table value
00177     GET_SELF(r, VTable).set_table(table);
00178 }
00179
00180 struct lsplit_result {
00181     char* piece;
00182     char delim;
00183
00184     operator bool() { return piece!=0; }
00185 };
00186
00187 inline lsplit_result lsplit(char* string, char delim1, char delim2) {
00188     lsplit_result result;
00189     if(string) {
00190         char delims[]={delim1, delim2, 0};
00191         if(char* v=strpbrk(string, delims)) {
00192             result.delim=*v;
00193             *v=0;
00194             result.piece=v+1;
00195             return result;
00196         }
00197     }
00198     result.piece=0;
00199     result.delim=0;
00200     return result;
00201 }
00202
00203 inline lsplit_result lsplit(char* *string_ref, char delim1, char delim2) {
00204     lsplit_result result;
00205     result.piece=*string_ref;
00206     lsplit_result next=lsplit(*string_ref, delim1, delim2);
00207     result.delim=next.delim;
00208     *string_ref=next.piece;
00209     return result;
00210 }
00211
00212 static lsplit_result lsplit(char** string_ref, char delim1, char delim2, char encloser) {
00213     lsplit_result result;
00214
00215     if(char* string=*string_ref) {
00216         if(encloser && *string==encloser) {
00217             string++;
00218
00219             char *read;
00220             char *write;
00221             write=read=string;
00222             char c;
00223             while((c=*read++)) {
00224                 if(c==encloser) {
00225                     char n=*read;
00226                     if(n==encloser) // double-encloser stands for encloser
00227                         read++;
00228                     else if(n==delim1 || n==delim2) {
00229                         result.delim=n;
00230                         read++;
00231                         break;
00232                     }
00233                 }
00234
00235                 *write++=c;
00236             }
00237             *write=0; // terminate
00238             *string_ref=c? read: 0;
00239             result.piece=string;
00240             return result;
00241         } else
00242             return lsplit(string_ref, delim1, delim2);
00243     }
00244     result.piece=0;
00245     return result;
00246 }
00247
00248 static void skip_empty_and_comment_lines( char** data_ref ) {
00249     if(char *data=*data_ref) {
00250         while( char c=*data ) {
00251             if( c== '\n' || c == '#' ) {
00252                 /*nowhere=*/getrow(&data); // remove empty&comment lines
00253                 if(!(*data_ref=data))
00254                     break;
00255                 continue;
00256             }
00257             break;
00258         }
00259     }
00260 }
00261
00262 struct TableSeparators {
00263     char column;  const String* scolumn;
00264     char encloser; const String* sencloser;
00265
00266     TableSeparators():
00267         column('\t'), scolumn(new String("\t", false)),
00268         encloser(0), sencloser(0)
00269     {}
00270     int load( HashStringValue& options ) {
00271         int result=0;
00272         if(Value* vseparator=options.get(PA_COLUMN_SEPARATOR_NAME)) {
00273             scolumn=&vseparator->as_string();
00274             if(scolumn->length()!=1)
00275                 throw Exception("parser.runtime",
00276                     scolumn,
00277                     "separator must be one character long");
00278             column=scolumn->first_char();
00279             result++;
00280         }
00281         if(Value* vencloser=options.get(PA_COLUMN_ENCLOSER_NAME)) {
00282             sencloser=&vencloser->as_string();
00283             if(sencloser->length()!=1)
00284                 throw Exception("parser.runtime",
00285                     sencloser,
00286                     "encloser must be one character long");
00287             encloser=sencloser->first_char();
00288             result++;
00289         }
00290         return result;
00291     }
00292 };
00293
00294 static void _load(Request& r, MethodParams& params) {
00295     const String&  first_param=params.as_string(0, "file name must be string");
00296     int filename_param_index=0;
00297     bool nameless=first_param=="nameless";
00298     if(nameless)
00299         filename_param_index++;
00300     size_t options_param_index=filename_param_index+1;
00301
00302     HashStringValue *options=0;
00303     TableSeparators separators;
00304     if(options_param_index<params.count()
00305         && (options=params.as_no_junction(options_param_index, "additional params must be hash").get_hash())) {
00306         // cloning, so that we could change [to simplify checks on params inside file_read_text
00307         options=new HashStringValue(*options);
00308         separators.load(*options);
00309     }
00310
00311     // loading text
00312     char *data=file_read_text(r.charsets,
00313         r.absolute(params.as_string(filename_param_index, "file name must be string")),
00314         true,
00315         options
00316     );
00317
00318     // parse columns
00319     Table::columns_type columns;
00320     if(nameless) {
00321         columns=Table::columns_type(0); // nameless
00322     } else {
00323         columns=Table::columns_type(new ArrayString);
00324
00325         skip_empty_and_comment_lines(&data);
00326         while( lsplit_result sr=lsplit(&data, separators.column, '\n', separators.encloser) ) {
00327             *columns+=new String(sr.piece, 0, true);
00328             if(sr.delim=='\n')
00329                 break;
00330         }
00331     }
00332
00333     Table& table=*new Table(columns);
00334     int columns_count=columns? columns->count(): 0;
00335
00336     // parse cells
00337     Table::element_type row(new ArrayString(columns_count));
00338     skip_empty_and_comment_lines(&data);
00339     while( lsplit_result sr=lsplit(&data, separators.column, '\n', separators.encloser) ) {
00340         if(!*sr.piece && !sr.delim && !row->count()) // append last empty column [if without \n]
00341             break;
00342         *row+=new String(sr.piece, 0, true);
00343         if(sr.delim=='\n') {
00344             table+=row;
00345             row=new ArrayString(columns_count);
00346             skip_empty_and_comment_lines(&data);
00347         }
00348     }
00349     // last line [if without \n]
00350     if(row->count())
00351         table+=row;
00352
00353     // replace any previous table value
00354     GET_SELF(r, VTable).set_table(table);
00355 }
00356
00357 static void maybe_enclose( String& to, const String& from, char encloser, const String* sencloser ) {
00358     if(encloser) {
00359         to<<*sencloser;
00360         // while we have 'encloser'...
00361         size_t pos_after=0;
00362         for( size_t pos_before; (pos_before=from.pos( encloser, pos_after ))!=STRING_NOT_FOUND; pos_after=pos_before+1) {
00363             to<<from.mid(pos_before+1/*+found encloser*/, pos_after-pos_before);
00364             to<<*sencloser;  to<<*sencloser; // doubling encloser
00365         }
00366         // last piece
00367         size_t from_length=from.length();
00368         if(pos_after<from_length)
00369             to<<from.mid(pos_after, from_length);
00370
00371         to<<*sencloser;
00372     } else
00373         to<<from;
00374 }
00375
00376
00377 static void _save(Request& r, MethodParams& params) {
00378     const String& first_arg=params.as_string(0, "first argument must not be code");
00379     size_t param_index=1;
00380
00381     bool do_append=false;
00382     bool output_column_names=true;
00383
00384     // mode?
00385     if(first_arg=="append")
00386         do_append=true;
00387     else if(first_arg=="nameless")
00388         output_column_names=false;
00389     else
00390         --param_index;
00391
00392     const String& file_name=params.as_string(param_index++, "file name must not be code");
00393
00394     TableSeparators separators;
00395     if(param_index<params.count()) {
00396         if(HashStringValue *options=params.as_no_junction(param_index++, "additional params must be hash").get_hash()) {
00397             int valid_options=separators.load(*options);
00398             if(valid_options!=options->count())
00399                 throw Exception("parser.runtime",
00400                     0,
00401                     "invalid option passed");
00402         } else
00403             throw Exception("parser.runtime",
00404                 0,
00405                 "additional params must be hash (did you spell mode parameter correctly?)");
00406
00407     }
00408     if(param_index<params.count())
00409         throw Exception("parser.runtime",
00410             0,
00411             "bad mode (must be nameless or append)");
00412
00413     Table& table=GET_SELF(r, VTable).table();
00414
00415     String sdata;
00416     if(output_column_names) {
00417         if(table.columns()) { // named table
00418             for(Array_iterator<const String*> i(*table.columns()); i.has_next(); ) {
00419                 maybe_enclose( sdata, *i.next(), separators.encloser, separators.sencloser );
00420                 if(i.has_next())
00421                     sdata<<*separators.scolumn;
00422             }
00423         } else { // nameless table [we were asked to output column names]
00424             if(int lsize=table.count()?table[0]->count():0)
00425                 for(int column=0; column<lsize; column++) {
00426                     char *cindex_tab=new(PointerFreeGC) char[MAX_NUMBER];
00427                     sdata.append_know_length(cindex_tab,
00428                         snprintf(cindex_tab, MAX_NUMBER,
00429                             column<lsize-1?"%d%c":"%d", column, separators.column),
00430                             String::L_CLEAN);
00431                 }
00432             else
00433                 sdata.append_help_length("empty nameless table", 0, String::L_CLEAN);
00434         }
00435         sdata.append_know_length("\n", 1, String::L_CLEAN);
00436     }
00437
00438     // data lines
00439     Array_iterator<ArrayString*> i(table);
00440     while(i.has_next()) {
00441         for(Array_iterator<const String*> c(*i.next()); c.has_next(); ) {
00442             maybe_enclose( sdata, *c.next(), separators.encloser, separators.sencloser );
00443             if(c.has_next())
00444                 sdata<<*separators.scolumn;
00445         }
00446         sdata.append_know_length("\n", 1, String::L_CLEAN);
00447     }
00448
00449     // write
00450     {
00451         const char* data_cstr=sdata.cstr();
00452         file_write(r.absolute(file_name),
00453             data_cstr, sdata.length(), true, do_append);
00454         if(*data_cstr) // not empty (when empty it's not heap memory)
00455             pa_free((void*)data_cstr); // not needed anymore
00456     }
00457 }
00458
00459 static void _count(Request& r, MethodParams&) {
00460     int result=GET_SELF(r, VTable).table().count();
00461     r.write_no_lang(*new VInt(result));
00462 }
00463
00464 static void _line(Request& r, MethodParams&) {
00465     int result=1+GET_SELF(r, VTable).table().current();
00466     r.write_no_lang(*new VInt(result));
00467 }
00468
00469 static void _offset(Request& r, MethodParams& params) {
00470     Table& table=GET_SELF(r, VTable).table();
00471     if(params.count()) {
00472         bool absolute=false;
00473         if(params.count()>1) {
00474             const String&  whence=params.as_string(0, "whence must be string");
00475             if(whence=="cur")
00476                 absolute=false;
00477             else if(whence=="set")
00478                 absolute=true;
00479             else
00480                 throw Exception("parser.runtime",
00481                     &whence,
00482                     "is invalid whence, valid are 'cur' or 'set'");
00483         }
00484
00485         int offset=params.as_int(params.count()-1, "offset must be expression", r);
00486         table.offset(absolute, offset);
00487     } else
00488         r.write_no_lang(*new VInt(table.current()));
00489 }
00490
00491 static void _menu(Request& r, MethodParams& params) {
00492     Value& body_code=params.as_junction(0, "body must be code");
00493
00494     Value* delim_maybe_code=params.count()>1?&params[1]:0;
00495
00496     Table& table=GET_SELF(r, VTable).table();
00497     bool need_delim=false;
00498     int saved_current=table.current();
00499     int size=table.count();
00500     for(int row=0; row<size; row++) {
00501         table.set_current(row);
00502
00503         StringOrValue sv_processed=r.process(body_code);
00504         const String* s_processed=sv_processed.get_string();
00505         if(delim_maybe_code && s_processed && s_processed->length()) { // delimiter set and we have body
00506             if(need_delim) // need delim & iteration produced string?
00507                 r.write_pass_lang(r.process(*delim_maybe_code));
00508             need_delim=true;
00509         }
00510         r.write_pass_lang(sv_processed);
00511     }
00512     table.set_current(saved_current);
00513 }
00514
00515 #ifndef DOXYGEN
00516 enum Table2hash_distint { D_ILLEGAL, D_FIRST, D_TABLES };
00517 struct Row_info {
00518     Request *r;
00519     Table *table;
00520     Value* key_code;
00521     size_t key_field;
00522     Array<int>* value_fields;
00523     HashStringValue* hash;
00524     Table2hash_distint distinct;
00525     size_t row;
00526 };
00527 #endif
00528 static void table_row_to_hash(Table::element_type row, Row_info *info) {
00529     const String* key;
00530     if(info->key_code) {
00531         info->table->set_current(info->row++); // change context row
00532         StringOrValue sv_processed=info->r->process(*info->key_code);
00533         key=&sv_processed.as_string();
00534     } else
00535         key=info->key_field<row->count()?row->get(info->key_field):0;
00536
00537     if(!key)
00538         return; // ignore rows without key [too-short-record_array if-indexed]
00539
00540     switch(info->distinct) {
00541     case D_ILLEGAL: case D_FIRST:
00542         {
00543             VHash* vhash=new VHash;
00544             HashStringValue& hash=vhash->hash();
00545             for(Array_iterator<int> i(*info->value_fields); i.has_next(); ) {
00546                 size_t value_field=i.next();
00547                 if(value_field<row->count())
00548                     hash.put(
00549                         *info->table->columns()->get(value_field),
00550                         new VString(*row->get(value_field)));
00551             }
00552
00553             if(info->hash->put_dont_replace(*key, vhash)) // put. existed?
00554                 if(info->distinct==D_ILLEGAL)
00555                     throw Exception("parser.runtime",
00556                         key,
00557                         "duplicate key");
00558         }
00559         break;
00560     case D_TABLES:
00561         {
00562             VTable* vtable=(VTable*)info->hash->get(*key); // put. table existed?
00563             Table* table;
00564             if(vtable)
00565                 table=vtable->get_table();
00566             else {
00567                 // no? creating table of same structure as source
00568                 Table::Action_options table_options(0, 0);
00569                 table=new Table(*info->table, table_options/*no rows, just structure*/);
00570                 info->hash->put(*key, new VTable(table));
00571             }
00572             *table+=row;
00573         }
00574         break;
00575     default:
00576         throw Exception(0,
00577             0,
00578             "invalid distinct code (#%d)", info->distinct);
00579     }
00580 }
00581 static void _hash(Request& r, MethodParams& params) {
00582     Table& self_table=GET_SELF(r, VTable).table();
00583     VHash& result=*new VHash;
00584     if(Table::columns_type columns=self_table.columns())
00585         if(columns->count()>0) {
00586             Table2hash_distint distinct=D_ILLEGAL;
00587             int param_index=params.count()-1;
00588             if(param_index>0) {
00589                 if(HashStringValue* options=
00590                     params.as_no_junction(param_index, "param must not be code").get_hash()) {
00591                     --param_index;
00592                     int valid_options=0;
00593                     if(Value* vdistinct_code=options->get(sql_distinct_name)) {
00594                         valid_options++;
00595                         Value& vdistinct_value=r.process_to_value(*vdistinct_code);
00596                         if(vdistinct_value.is_string()) {
00597                             const String& sdistinct=*vdistinct_value.get_string();
00598                             if(sdistinct=="tables")
00599                                 distinct=D_TABLES;
00600                             else
00601                                 throw Exception("parser.runtime",
00602                                     &sdistinct,
00603                                     "must be 'tables' or true/false");
00604                         } else
00605                             distinct=vdistinct_value.as_bool()?D_FIRST:D_ILLEGAL;
00606                     }
00607                     if(valid_options!=options->count())
00608                         throw Exception("parser.runtime",
00609                             0,
00610                             "called with invalid option");
00611                 }
00612             }
00613             if(param_index==2) // bad options param type
00614                 throw Exception("parser.runtime",
00615                     0,
00616                     "options must be hash");
00617
00618             Array<int> value_fields;
00619             if(param_index>0) {
00620                 if(distinct!=D_ILLEGAL && distinct!=D_FIRST)
00621                     throw Exception("parser.runtime",
00622                         0,
00623                         "in distinct[tables] mode you may not specify value field(s)");
00624                 Value& value_fields_param=params.as_no_junction(param_index, "value field(s) must not be code");
00625                 if(value_fields_param.is_string()) {
00626                     value_fields+=self_table.column_name2index(
00627                         *value_fields_param.get_string(), true);
00628                 } else if(Table* value_fields_table=value_fields_param.get_table()) {
00629                     for(Array_iterator<Table::element_type> i(*value_fields_table);
00630                         i.has_next(); ) {
00631                         const String& value_field_name
00632                             =*i.next()->get(0);
00633                         value_fields
00634                             +=self_table.column_name2index(value_field_name, true);
00635                     }
00636                 } else
00637                     throw Exception("parser.runtime",
00638                         0,
00639                         "value field(s) must be string or table"
00640                     );
00641             } else { // by all columns, including key
00642                 if(!(distinct!=D_ILLEGAL && distinct!=D_FIRST))
00643                     for(size_t i=0; i<columns->count(); i++)
00644                         value_fields+=i;
00645             }
00646
00647
00648             {
00649                 Value* key_param=&params[0];
00650                 Row_info info={
00651                     &r,
00652                     &self_table,
00653                     /*key_code=*/key_param->get_junction()?key_param:0,
00654                     /*key_field=*/0/*filled below*/,
00655                     &value_fields,
00656                     &result.hash(),
00657                     distinct,
00658                     /*row=*/0
00659                 };
00660                 info.key_field=(info.key_code?-1
00661                         :self_table.column_name2index(key_param->as_string(), true));
00662
00663                 int saved_current=self_table.current();
00664                 self_table.for_each(table_row_to_hash, &info);
00665                 self_table.set_current(saved_current);
00666
00667                 result.extract_default();
00668             }
00669         }
00670     r.write_no_lang(result);
00671 }
00672
00673 #ifndef DOXYGEN
00674 struct Table_seq_item {
00675     ArrayString* row;
00676     union {
00677         const char *c_str;
00678         double d;
00679     } value;
00680 };
00681 #endif
00682 static int sort_cmp_string(const void *a, const void *b) {
00683     return strcmp(
00684         static_cast<const Table_seq_item *>(a)->value.c_str,
00685         static_cast<const Table_seq_item *>(b)->value.c_str
00686     );
00687 }
00688 static int sort_cmp_double(const void *a, const void *b) {
00689     double va=static_cast<const Table_seq_item *>(a)->value.d;
00690     double vb=static_cast<const Table_seq_item *>(b)->value.d;
00691     if(va<vb)
00692         return -1;
00693     else if(va>vb)
00694         return +1;
00695     else
00696         return 0;
00697 }
00698 static void _sort(Request& r, MethodParams& params) {
00699     Value& key_maker=params.as_junction(0, "key-maker must be code");
00700
00701     bool reverse=params.count()>1/*..[desc|asc|]*/?
00702         reverse=params.as_no_junction(1, "order must not be code").as_string()=="desc":
00703         false; // default=asc
00704
00705     Table& old_table=GET_SELF(r, VTable).table();
00706     Table& new_table=*new Table(old_table.columns());
00707
00708     Table_seq_item* seq=new(PointerFreeGC) Table_seq_item[old_table.count()];
00709     int i;
00710
00711     // calculate key values
00712     bool key_values_are_strings=true;
00713     int old_count=old_table.count();
00714     for(i=0; i<old_count; i++) {
00715         old_table.set_current(i);
00716         // calculate key value
00717         seq[i].row=old_table[i];
00718         Value& value=r.process_to_value(key_maker).as_expr_result(true/*return string as-is*/);
00719         if(i==0) // determining key values type by first one
00720             key_values_are_strings=value.is_string();
00721
00722         if(key_values_are_strings)
00723             seq[i].value.c_str=value.as_string().cstr();
00724         else
00725             seq[i].value.d=value.as_double();
00726     }
00727     // sort keys
00728     _qsort(seq, old_count, sizeof(Table_seq_item),
00729         key_values_are_strings?sort_cmp_string:sort_cmp_double);
00730
00731     // reorder table as they require in 'seq'
00732     for(i=0; i<old_count; i++)
00733         new_table+=Table::element_type(seq[reverse?old_count-1-i:i].row);
00734
00735     delete[] seq;
00736
00737     // replace any previous table value
00738     GET_SELF(r, VTable).set_table(new_table);
00739 }
00740
00741 #ifndef DOXYGEN
00742 struct Expression_is_true_info {
00743     Request* r;
00744     Value* expression_code;
00745 };
00746 #endif
00747 static bool expression_is_true(Table&, Expression_is_true_info* info) {
00748     return info->r->process_to_value(*info->expression_code).as_bool();
00749 }
00750 static bool _locate_expression(Table& table, Table::Action_options o,
00751                    Request& r, MethodParams& params) {
00752     check_option_param(o.defined, params, 1,
00753         "locate by expression only has parameters: expression and, maybe, options");
00754     Value& expression_code=params.as_junction(0, "must be expression");
00755
00756     Expression_is_true_info info={&r, &expression_code};
00757     return table.table_first_that(expression_is_true, &info, o);
00758 }
00759 static bool _locate_name_value(Table& table, Table::Action_options o,
00760                    Request&, MethodParams& params) {
00761     check_option_param(o.defined, params, 2,
00762         "locate by locate by name has parameters: name, value and, maybe, options");
00763     const String& name=params.as_string(0, "column name must be string");
00764     const String& value=params.as_string(1, "value must be string");
00765     return table.locate(name, value, o);
00766 }
00767 static void _locate(Request& r, MethodParams& params) {
00768     Table& table=GET_SELF(r, VTable).table();
00769
00770     Table::Action_options o=get_action_options(r, params, table);
00771
00772     bool result=params[0].get_junction()?
00773         _locate_expression(table, o, r, params) :
00774         _locate_name_value(table, o, r, params);
00775     r.write_no_lang(*new VBool(result));
00776 }
00777
00778
00779 static void _flip(Request& r, MethodParams&) {
00780     Table& old_table=GET_SELF(r, VTable).table();
00781     Table& new_table=*new Table(0);
00782     if(size_t old_count=old_table.count())
00783         if(size_t old_cols=old_table[0]->count())
00784             for(size_t column=0; column<old_cols; column++) {
00785                 Table::element_type new_row(new ArrayString(old_count));
00786                 for(size_t i=0; i<old_count; i++) {
00787                     Table::element_type old_row=old_table[i];
00788                     *new_row+=column<old_row->count()?old_row->get(column):new String;
00789                 }
00790                 new_table+=new_row;
00791             }
00792
00793     r.write_no_lang(*new VTable(&new_table));
00794 }
00795
00796 static void _append(Request& r, MethodParams& params) {
00797     // data
00798     Temp_lang temp_lang(r, String::L_PASS_APPENDED);
00799     const String& string=r.process_to_string(params.as_junction(0, "body must be code"));
00800
00801     // parse cells
00802     Table::element_type row=new ArrayString;
00803     size_t pos_after=0;
00804     string.split(*row, pos_after, "\t", String::L_AS_IS);
00805
00806     GET_SELF(r, VTable).table()+=row;
00807 }
00808
00809 static void join_named_row(Table& src, Table* dest) {
00810     Table::columns_type dest_columns=dest->columns();
00811     size_t dest_columns_count=dest_columns->count();
00812     Table::element_type dest_row(new ArrayString(dest_columns_count));
00813     for(size_t dest_column=0; dest_column<dest_columns_count; dest_column++) {
00814         const String* src_item=src.item(*dest_columns->get(dest_column));
00815         *dest_row+=src_item?src_item:new String;
00816     }
00817     *dest+=dest_row;
00818 }
00819 static void join_nameless_row(Table& src, Table* dest) {
00820     *dest+=src[src.current()];
00821 }
00822 static void _join(Request& r, MethodParams& params) {
00823     Table* maybe_src=params.as_no_junction(0, "table ref must not be code").get_table();
00824     if(!maybe_src)
00825         throw Exception("parser.runtime",
00826             0,
00827             "source is not a table");
00828     Table& src=*maybe_src;
00829
00830     Table::Action_options o=get_action_options(r, params, src);
00831     check_option_param(o.defined, params, 1,
00832         "invalid extra parameter");
00833
00834     Table& dest=GET_SELF(r, VTable).table();
00835     if(&src == &dest)
00836         throw Exception("parser.runtime",
00837             0,
00838             "source and destination are same table");
00839
00840     if(dest.columns()) // dest is named
00841         src.table_for_each(join_named_row, &dest, o);
00842     else // dest is nameless
00843         src.table_for_each(join_nameless_row, &dest, o);
00844 }
00845
00846 #ifndef DOXYGEN
00847 class Table_sql_event_handlers: public SQL_Driver_query_event_handlers {
00848     ArrayString& columns;
00849     int columns_count;
00850     ArrayString* row;
00851 public:
00852     Table* table;
00853 public:
00854     Table_sql_event_handlers() :
00855         columns(*new ArrayString), row(0), table(0) {
00856     }
00857
00858     bool add_column(SQL_Error& error, const char *str, size_t length) {
00859         try {
00860             columns+=new String(str, length, true);
00861             return false;
00862         } catch(...) {
00863             error=SQL_Error("exception occured in Table_sql_event_handlers::add_column");
00864             return true;
00865         }
00866     }
00867     bool before_rows(SQL_Error& error) {
00868         try {
00869             table=new Table(&columns);
00870             columns_count=columns.count();
00871             return false;
00872         } catch(...) {
00873             error=SQL_Error("exception occured in Table_sql_event_handlers::before_rows");
00874             return true;
00875         }
00876     }
00877     bool add_row(SQL_Error& error) {
00878         try {
00879             *table+=row=new ArrayString(columns_count);
00880             return false;
00881         } catch(...) {
00882             error=SQL_Error("exception occured in Table_sql_event_handlers::add_row");
00883             return true;
00884         }
00885     }
00886     bool add_row_cell(SQL_Error& error, const char* str, size_t length) {
00887         try {
00888             String& cell=*new String;
00889             if(length)
00890                 cell.append_know_length(str, length, String::L_TAINTED);
00891             *row+=&cell;
00892             return false;
00893         } catch(...) {
00894             error=SQL_Error("exception occured in Table_sql_event_handlers::add_row_cell");
00895             return true;
00896         }
00897     }
00898 };
00899 #endif
00900
00901 static void marshal_bind(
00902                          HashStringValue::key_type aname,
00903                          HashStringValue::value_type avalue,
00904                          SQL_Driver::Placeholder** pptr)
00905 {
00906     SQL_Driver::Placeholder& ph=**pptr;
00907     ph.name=aname.cstr();
00908     ph.value=avalue->as_string().cstr(String::L_UNSPECIFIED);
00909     ph.is_null=avalue->get_class()==void_class;
00910     ph.were_updated=false;
00911
00912     (*pptr)++;
00913 }
00914
00915 // not static, used elsewhere
00916 int marshal_binds(HashStringValue& hash, SQL_Driver::Placeholder*& placeholders) {
00917     int hash_count=hash.count();
00918     placeholders=new(UseGC) SQL_Driver::Placeholder[hash_count];
00919     SQL_Driver::Placeholder* ptr=placeholders;
00920     hash.for_each(marshal_bind, &ptr);
00921     return hash_count;
00922 }
00923
00924 // not static, used elsewhere
00925 void unmarshal_bind_updates(HashStringValue& hash, int placeholder_count, SQL_Driver::Placeholder* placeholders) {
00926     SQL_Driver::Placeholder* ph=placeholders;
00927     for(int i=0; i<placeholder_count; i++, ph++)
00928         if(ph->were_updated) {
00929             Value* value;
00930             if(ph->is_null)
00931                 value=new VVoid();
00932             else
00933                 if(ph->value)
00934                     value=new VString(*new String(ph->value, 0, true/*tainted*/));
00935                 else
00936                     value=new VString(*new String());
00937             hash.put(ph->name, value);
00938         }
00939 }
00940
00941 static void _sql(Request& r, MethodParams& params) {
00942     Value& statement=params.as_junction(0, "statement must be code");
00943
00944     HashStringValue* bind=0;
00945     ulong limit=0;
00946     ulong offset=0;
00947     if(params.count()>1) {
00948         Value& voptions=params.as_no_junction(1, "options must be hash, not code");
00949         if(voptions.is_defined() && !voptions.is_string())
00950             if(HashStringValue* options=voptions.get_hash()) {
00951                 int valid_options=0;
00952                 if(Value* vbind=options->get(sql_bind_name)) {
00953                     valid_options++;
00954                     bind=vbind->get_hash();
00955                 }
00956                 if(Value* vlimit=options->get(sql_limit_name)) {
00957                     valid_options++;
00958                     limit=(ulong)r.process_to_value(*vlimit).as_double();
00959                 }
00960                 if(Value* voffset=options->get(sql_offset_name)) {
00961                     valid_options++;
00962                     offset=(ulong)r.process_to_value(*voffset).as_double();
00963                 }
00964                 if(valid_options!=options->count())
00965                     throw Exception("parser.runtime",
00966                         0,
00967                         "called with invalid option");
00968             } else
00969                 throw Exception("parser.runtime",
00970                     0,
00971                     "options must be hash");
00972     }
00973
00974     SQL_Driver::Placeholder* placeholders=0;
00975     uint placeholders_count=0;
00976     if(bind)
00977         placeholders_count=marshal_binds(*bind, placeholders);
00978
00979     Temp_lang temp_lang(r, String::L_SQL);
00980     const String&  statement_string=r.process_to_string(statement);
00981     const char* statement_cstr=
00982         statement_string.cstr(String::L_UNSPECIFIED, r.connection());
00983     Table_sql_event_handlers handlers;
00984 #ifdef RESOURCES_DEBUG
00985     struct timeval mt[2];
00986     //measure:before
00987     gettimeofday(&mt[0],NULL);
00988 #endif
00989     r.connection()->query(
00990         statement_cstr,
00991         placeholders_count, placeholders,
00992         offset, limit,
00993         handlers,
00994         statement_string);
00995
00996 #ifdef RESOURCES_DEBUG
00997         //measure:after connect
00998     gettimeofday(&mt[1],NULL);
00999
01000     double t[2];
01001     for(int i=0;i<2;i++)
01002         t[i]=mt[i].tv_sec+mt[i].tv_usec/1000000.0;
01003
01004     r.sql_request_time+=t[1]-t[0];
01005 #endif
01006
01007     if(bind)
01008         unmarshal_bind_updates(*bind, placeholders_count, placeholders);
01009
01010     Table& result=
01011         handlers.table?*handlers.table: // query resulted in table? return it
01012         *new Table(Table::columns_type(0)); // query returned no table, fake it
01013
01014     // replace any previous table value
01015     GET_SELF(r, VTable).set_table(result);
01016 }
01017
01018 static void _columns(Request& r, MethodParams&) {
01019
01020     Table::columns_type result_columns(new ArrayString);
01021     *result_columns+=new String("column");
01022     Table& result_table=*new Table(result_columns);
01023
01024     Table& source_table=GET_SELF(r, VTable).table();
01025     if(Table::columns_type source_columns=source_table.columns()) {
01026         for(Array_iterator<const String*> i(*source_columns); i.has_next(); ) {
01027             Table::element_type result_row(new ArrayString);
01028             *result_row+=i.next();
01029             result_table+=result_row;
01030         }
01031     }
01032
01033     r.write_no_lang(*new VTable(&result_table));
01034 }
01035
01036 static void _select(Request& r, MethodParams& params) {
01037     Value& vcondition=params.as_junction(0, "condition must be expression");
01038
01039     Table& source_table=GET_SELF(r, VTable).table();
01040     Table& result_table=*new Table(source_table.columns());
01041
01042     int saved_current=source_table.current();
01043     int size=source_table.count();
01044     for(int row=0; row<size; row++) {
01045         source_table.set_current(row);
01046
01047         bool condition=r.process_to_value(vcondition,
01048                 false/*don't intercept string*/).as_bool();
01049
01050         if(condition) // ...condition is true=
01051             result_table+=source_table[row]; // =green light to go to result
01052     }
01053     source_table.set_current(saved_current);
01054
01055     r.write_no_lang(*new VTable(&result_table));
01056 }
01057
01058 // constructor
01059
01060 MTable::MTable(): Methoded("table") {
01061     // ^table::create{data}
01062     // ^table::create[nameless]{data}
01063     // ^table::create[table]
01064     add_native_method("create", Method::CT_DYNAMIC, _create, 1, 2);
01065     // old name for compatibility with <= v 1.141 2002/01/25 11:33:45 paf
01066     add_native_method("set", Method::CT_DYNAMIC, _create, 1, 2);
01067
01068     // ^table::load[file]
01069     // ^table::load[nameless;file]
01070     add_native_method("load", Method::CT_DYNAMIC, _load, 1, 3);
01071
01072     // ^table.save[file]
01073     // ^table.save[nameless;file]
01074     add_native_method("save", Method::CT_DYNAMIC, _save, 1, 3);
01075
01076     // ^table.count[]
01077     add_native_method("count", Method::CT_DYNAMIC, _count, 0, 0);
01078
01079     // ^table.line[]
01080     add_native_method("line", Method::CT_DYNAMIC, _line, 0, 0);
01081
01082     // ^table.offset[]
01083     // ^table.offset(offset)
01084     // ^table.offset[cur|set](offset)
01085     add_native_method("offset", Method::CT_DYNAMIC, _offset, 0, 2);
01086
01087     // ^table.menu{code}
01088     // ^table.menu{code}[delim]
01089     add_native_method("menu", Method::CT_DYNAMIC, _menu, 1, 2);
01090
01091     // ^table:hash[key field name]
01092     // ^table:hash[key field name][value field name(s) string/table]
01093     add_native_method("hash", Method::CT_DYNAMIC, _hash, 1, 3);
01094
01095     // ^table.sort{string-key-maker} ^table.sort{string-key-maker}[desc|asc]
01096     // ^table.sort(numeric-key-maker) ^table.sort(numeric-key-maker)[desc|asc]
01097     add_native_method("sort", Method::CT_DYNAMIC, _sort, 1, 2);
01098
01099     // ^table.locate[field;value]
01100     add_native_method("locate", Method::CT_DYNAMIC, _locate, 1, 3);
01101
01102     // ^table.flip[]
01103     add_native_method("flip", Method::CT_DYNAMIC, _flip, 0, 0);
01104
01105     // ^table.append{r{tab}e{tab}c{tab}o{tab}r{tab}d}
01106     add_native_method("append", Method::CT_DYNAMIC, _append, 1, 1);
01107
01108     // ^table.join[table][$.limit(10) $.offset(1) $.offset[cur] ]
01109     add_native_method("join", Method::CT_DYNAMIC, _join, 1, 2);
01110
01111
01112     // ^table:sql[query]
01113     // ^table:sql[query][$.limit(1) $.offset(2)]
01114     add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2);
01115
01116     // ^table:columns[]
01117     add_native_method("columns", Method::CT_DYNAMIC, _columns, 0, 0);
01118
01119     // ^table.select(expression) = table
01120     add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1);
01121 }


targets.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


untaint.C File Reference

Parser: String class part: untaint mechanizm. More...

Include dependency graph for untaint.C:

Include dependency graph

Go to the source code of this file.

Defines

#define | CORD_ec_append(x, c)
#define | escape(action)
#define | _default CORD_ec_append(info->result, c)
#define | encode(need_encode_func, prefix, otherwise)
#define | to_char(c) { CORD_ec_append(info->result, c); whitespace=false; }
#define | to_string(s) { CORD_ec_append_cord(info->result, s); whitespace=false; }

Functions

bool | need_file_encode (unsigned char c)
bool | need_uri_encode (unsigned char c)
bool | need_http_header_encode (unsigned char c)
bool | need_regex_escape (unsigned char c)
bool | need_quote_http_header (const char *ptr, size_t size)
int | append_fragment_optimizing (char alang, size_t asize, Append_fragment_info *info)
int | append_fragment_nonoptimizing (char alang, size_t asize, Append_fragment_info *info)
bool | mail_header_char_valid_within_Qencoded (char c)
http://www.ietf.org/rfc/rfc2047.txt RFC (3) As a replacement for a 'word' entity within a 'phrase', for example, one that precedes an address in a From, To, or Cc header. More...

bool | addr_spec_soon (const char *src)
bool | mail_header_nonspace_char (char c)
RFC Upper case should be used for hexadecimal digits "A" through "F" The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be represented as "_". More...

void | ec_append (CORD_ec &result, bool &optimize, bool &whitespace, CORD_pos pos, size_t size)
void | pa_CORD_pos_advance (CORD_pos pos, size_t n)
int | cstr_to_string_body_block (char alang, size_t fragment_length, Cstr_to_string_body_block_info *info)

Variables

const char *const | IDENT_UNTAINT_C = "$Date: 2005/11/22 15:09:10 $"

Detailed Description

Parser: String class part: untaint mechanizm.

Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file untaint.C.

Define Documentation

#define CORD_ec_append | ( | x,
 |  | c | )

Value:

{  \
    bool skip=false; \
    if(optimize) switch(c) { \
    case ' ': case '\n': case '\t': \
        if(whitespace) \
            skip=true;   \
        else \
            whitespace=true; \
        break; \
    default: \
        whitespace=false; \
        break; \
    } \
    if(!skip) { \
        if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \
            CORD_ec_flush_buf(x); \
        } \
        *((x)[0].ec_bufptr)++ = (c); \
    } \
    }

Definition at line 33 of file untaint.C.

#define escape ( action )

Value:

for(; fragment_length--; CORD_next(info->pos)) { \
        char c=CORD_pos_fetch(info->pos); \
        action \
    }

Definition at line 56 of file untaint.C.

Referenced by cstr_to_string_body_block().

#define _default CORD_ec_append(info->result, c)

Definition at line 61 of file untaint.C.

Referenced by cstr_to_string_body_block().

#define encode | ( | need_encode_func,
 |  | prefix,
 |  | otherwise | )

Value:

if(need_encode_func(c)) { \
        static const char* hex="0123456789ABCDEF"; \
        CORD_ec_append(info->result, prefix); \
        CORD_ec_append(info->result, hex[((unsigned char)c)/0x10]); \
        CORD_ec_append(info->result, hex[((unsigned char)c)%0x10]); \
    } else \
        CORD_ec_append(info->result, otherwise);

Definition at line 62 of file untaint.C.

Referenced by cstr_to_string_body_block().

#define to_char ( c ) { CORD_ec_append(info->result, c); whitespace=false; }

Definition at line 70 of file untaint.C.

Referenced by cstr_to_string_body_block().

#define to_string ( s ) { CORD_ec_append_cord(info->result, s); whitespace=false; }

Definition at line 71 of file untaint.C.

Referenced by cstr_to_string_body_block().

Function Documentation

bool need_file_encode ( unsigned char c ) [inline]

Definition at line 73 of file untaint.C.

Referenced by cstr_to_string_body_block().

bool need_uri_encode ( unsigned char c ) [inline]

Definition at line 83 of file untaint.C.

Referenced by cstr_to_string_body_block(), and need_http_header_encode().

bool need_http_header_encode ( unsigned char c ) [inline]

Definition at line 89 of file untaint.C.

References need_uri_encode().

bool need_regex_escape ( unsigned char c ) [inline]

Definition at line 95 of file untaint.C.

Referenced by cstr_to_string_body_block().

bool need_quote_http_header | ( | const char * | ptr,
 |  | size_t | size
 | ) | [inline]

Definition at line 135 of file untaint.C.

References size.

int append_fragment_optimizing | ( | char | alang,
 |  | size_t | asize,
 |  | Append_fragment_info * | info
 | ) |

Definition at line 149 of file untaint.C.

References String::L_CLEAN, String::L_OPTIMIZE_BIT, String::L_TAINTED, and String::Language.

Referenced by String::append_to().

int append_fragment_nonoptimizing | ( | char | alang,
 |  | size_t | asize,
 |  | Append_fragment_info * | info
 | ) |

Definition at line 166 of file untaint.C.

References String::L_TAINTED, and String::Language.

Referenced by String::append_to().

bool mail_header_char_valid_within_Qencoded ( char c ) [inline]

http://www.ietf.org/rfc/rfc2047.txt RFC (3) As a replacement for a 'word' entity within a 'phrase', for example, one that precedes an address in a From, To, or Cc header.

The ABNF definition for 'phrase' from RFC 822 thus becomes:

phrase = 1*( encoded-word / word )

In this case the set of characters that may be used in a "Q"-encoded 'encoded-word' is restricted to: <upper and lower case ASCII letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_" (underscore, ASCII 95.)>. An 'encoded-word' that appears within a 'phrase' MUST be separated from any adjacent 'word', 'text' or 'special' by 'linear-white-space'. ... (2) The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be represented as "_" (underscore, ASCII 95.). (This character may not pass through some internetwork mail gateways, but its use will greatly enhance readability of "Q" encoded data with mail readers that do not support this encoding.) Note that the "_" always represents hexadecimal 20, even if the SPACE character occupies a different code position in the character set in use.

paf: obviously, without "=", or one could not differ "=E0" and "russian letter a" and without "_", or in would mean 0x20

Definition at line 236 of file untaint.C.

Referenced by cstr_to_string_body_block().

bool addr_spec_soon ( const char * src ) [inline]

Definition at line 242 of file untaint.C.

Referenced by cstr_to_string_body_block().

bool mail_header_nonspace_char ( char c ) [inline]

RFC Upper case should be used for hexadecimal digits "A" through "F" The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be represented as "_".

Definition at line 256 of file untaint.C.

Referenced by cstr_to_string_body_block().

void ec_append | ( | CORD_ec & | result,
 |  | bool & | optimize,
 |  | bool & | whitespace,
 |  | CORD_pos | pos,
 |  | size_t | size
 | ) | [inline]

Definition at line 260 of file untaint.C.

References CORD_ec_append, CORD_next, CORD_pos_fetch, result, and size.

Referenced by cstr_to_string_body_block().

void pa_CORD_pos_advance | ( | CORD_pos | pos,
 |  | size_t | n
 | ) | [inline]

Definition at line 266 of file untaint.C.

References CORD_next, CORD_pos_advance, and CORD_pos_chars_left.

Referenced by cstr_to_string_body_block().

int cstr_to_string_body_block | ( | char | alang,
 |  | size_t | fragment_length,
 |  | Cstr_to_string_body_block_info * | info
 | ) |

Definition at line 300 of file untaint.C.

References _default, SAPI::abort(), addr_spec_soon(), ec_append(), encode, escape, String::L_AS_IS, String::L_CLEAN, String::L_FILE_SPEC, String::L_HTML, String::L_HTTP_HEADER, String::L_JS, String::L_MAIL_HEADER, String::L_OPTIMIZE_BIT, String::L_REGEX, String::L_SQL, String::L_TAINTED, String::L_UNSPECIFIED, String::L_URI, String::L_XML, String::Language, mail_header_char_valid_within_Qencoded(), mail_header_nonspace_char(), need_file_encode(), need_regex_escape(), need_uri_encode(), pa_CORD_pos_advance(), String::C::str, to_char, to_string, Charset::transcode(), and uchar.

Referenced by String::cstr_to_string_body().

Variable Documentation

const char* const IDENT_UNTAINT_C = "$Date: 2005/11/22 15:09:10 $" [static]

Definition at line 8 of file untaint.C.


untaint.C Source File

untaint.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_UNTAINT_C="$Date: 2005/11/22 15:09:10 $";
00009
00010
00011 #include "pa_string.h"
00012 #include "pa_hash.h"
00013 #include "pa_exception.h"
00014 #include "pa_table.h"
00015 #include "pa_globals.h"
00016 #include "pa_dictionary.h"
00017 #include "pa_common.h"
00018 #include "pa_charset.h"
00019 #include "pa_request_charsets.h"
00020 #include "pa_sapi.h"
00021
00022 extern "C" { // author forgot to do that
00023 #include "ec.h"
00024 }
00025
00026 #include "pa_sql_connection.h"
00027
00028 // defines
00029
00030 #undef CORD_ec_append
00031 // redefining to intercept flushes and implement whitespace optimization
00032 // of all consequent white space chars leaving only first one
00033 #define CORD_ec_append(x, c) \
00034     {  \
00035     bool skip=false; \
00036     if(optimize) switch(c) { \
00037     case ' ': case '\n': case '\t': \
00038         if(whitespace) \
00039             skip=true; /*skipping subsequent*/ \
00040         else \
00041             whitespace=true; \
00042         break; \
00043     default: \
00044         whitespace=false; \
00045         break; \
00046     } \
00047     if(!skip) { \
00048         if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \
00049             CORD_ec_flush_buf(x); \
00050         } \
00051         *((x)[0].ec_bufptr)++ = (c); \
00052     } \
00053     }
00054
00055
00056 #define escape(action) \
00057     for(; fragment_length--; CORD_next(info->pos)) { \
00058         char c=CORD_pos_fetch(info->pos); \
00059         action \
00060     }
00061 #define _default CORD_ec_append(info->result, c)
00062 #define encode(need_encode_func, prefix, otherwise)  \
00063     if(need_encode_func(c)) { \
00064         static const char* hex="0123456789ABCDEF"; \
00065         CORD_ec_append(info->result, prefix); \
00066         CORD_ec_append(info->result, hex[((unsigned char)c)/0x10]); \
00067         CORD_ec_append(info->result, hex[((unsigned char)c)%0x10]); \
00068     } else \
00069         CORD_ec_append(info->result, otherwise);
00070 #define to_char(c)  { CORD_ec_append(info->result, c); whitespace=false; }
00071 #define to_string(s)  { CORD_ec_append_cord(info->result, s); whitespace=false; }
00072
00073 inline bool need_file_encode(unsigned char c){
00074     // russian letters and space ENABLED
00075     // encoding only these...
00076     return strchr(
00077               "*?'\"<>|"
00078 #ifndef WIN32
00079               ":\\"
00080 #endif
00081               , c)!=0;
00082 }
00083 inline bool need_uri_encode(unsigned char c){
00084     if((c>='0') &&(c<='9') ||(c>='A') &&(c<='Z') ||(c>='a') &&(c<='z'))
00085         return false;
00086
00087     return !strchr("_-./", c);
00088 }
00089 inline bool need_http_header_encode(unsigned char c){
00090     if(strchr(" , :", c))
00091         return false;
00092
00093     return need_uri_encode(c);
00094 }
00095 inline bool need_regex_escape(unsigned char c){
00096     return strchr("\\^$.[]|()?*+{}", c)!=0;
00097 }
00098
00099 // String
00100
00101 /*
00102 HTTP-header    = field-name ":" [ field-value ] CRLF
00103
00104        field-name     = token
00105        field-value    = *( field-content | LWS )
00106
00107        field-content  = <the OCTETs making up the field-value
00108                         and consisting of either *TEXT or combinations
00109                         of token, tspecials, and quoted-string>
00110
00111
00112
00113 word           = token | quoted-string
00114
00115 token          = 1*<any CHAR except CTLs or tspecials>
00116
00117
00118
00119 tspecials      = "(" | ")" | "<" | ">" | "@"
00120                       | "," | ";" | ":" | "\" | <">
00121                       | "/" | "[" | "]" | "?" | "="
00122                       | "{" | "}" | SP | HT
00123
00124 SP             = <US-ASCII SP, space (32)>
00125 HT             = <US-ASCII HT, horizontal-tab (9)>
00126
00127 LWS            = [CRLF] 1*( SP | HT )
00128 TEXT           = <any OCTET except CTLs,
00129                         but including LWS>
00130
00131 quoted-pair    = "\" CHAR
00132
00133   if(strchr("()<>@,;:\\\"/[]?={} \t", *ptr))
00134 */
00135 inline bool need_quote_http_header(const char* ptr, size_t size) {
00136     for(; size--; ptr++)
00137         if(strchr(";\\\"= \t" /* excluded ()<>@, :/ ? []{} */, *ptr))
00138             return true;
00139     return false;
00140 }
00141
00142 #ifndef DOXYGEN
00143 struct Append_fragment_info {
00144     String::Language lang;
00145     String::Languages* dest_languages;
00146     size_t dest_body_plan_length;
00147 };
00148 #endif
00149 int append_fragment_optimizing(char alang, size_t asize, Append_fragment_info* info) {
00150     const String::Language lang=(String::Language)(unsigned char)alang;
00151     // main idea here:
00152     // tainted piece would get OPTIMIZED bit from 'lang'
00153     // clean piece would be marked OPTIMIZED manually
00154     // pieces with determined languages [not tainted|clean] would retain theirs langs
00155     info->dest_languages->append(info->dest_body_plan_length,
00156         lang==String::L_TAINTED?
00157             info->lang
00158             :lang==String::L_CLEAN?
00159                 (String::Language)(String::L_CLEAN|String::L_OPTIMIZE_BIT) // ORing with OPTIMIZED flag
00160                 :lang,
00161         asize);
00162     info->dest_body_plan_length+=asize;
00163
00164     return 0; // 0=continue
00165 }
00166 int append_fragment_nonoptimizing(char alang, size_t asize, Append_fragment_info* info) {
00167     const String::Language lang=(String::Language)(unsigned char)alang;
00168     // The core idea: tainted pieces got marked with context's lang
00169     info->dest_languages->append(info->dest_body_plan_length,
00170         lang==String::L_TAINTED?
00171             info->lang
00172             :lang,
00173         asize);
00174     info->dest_body_plan_length+=asize;
00175
00176     return 0; // 0=continue
00177 }
00178
00185 String& String::append_to(String& dest, Language lang, bool forced) const {
00186     if(is_empty())
00187         return dest;
00188
00189     // first: fragment infos
00190
00191     if(lang==L_PASS_APPENDED) // without language-change?
00192         dest.langs.append(dest.body, body.length(), langs);
00193     else if(forced) //forcing passed lang?
00194         dest.langs.append(dest.body, lang, length());
00195     else {
00196         Append_fragment_info info={lang, &dest.langs, dest.body.length()};
00197         langs.for_each(body, lang&L_OPTIMIZE_BIT?
00198             append_fragment_optimizing
00199             :append_fragment_nonoptimizing, &info);
00200     }
00201
00202     // next: letters
00203     dest.body<<body;
00204
00205     ASSERT_STRING_INVARIANT(dest);
00206     return dest;
00207 }
00208
00236 inline bool mail_header_char_valid_within_Qencoded(char c) {
00237     return c>='A' && c<='Z'
00238         || c>='a' && c<='Z'
00239         || c>='0' && c<='9'
00240         || strchr("!*+-/", c);
00241 }
00242 inline bool addr_spec_soon(const char *src) {
00243     for(char c; (c=*src); src++)
00244         if(c=='<')
00245             return true;
00246         else if(!(c==' ' || c=='\t'))
00247             return false;
00248     return false;
00249 }
00256 inline bool mail_header_nonspace_char(char c) {
00257     return c != 0x20;
00258 }
00259
00260 inline void ec_append(CORD_ec& result, bool& optimize, bool& whitespace, CORD_pos pos, size_t size) {
00261     while(size--) {
00262         CORD_ec_append(result, CORD_pos_fetch(pos));
00263         CORD_next(pos);
00264     }
00265 }
00266 inline void pa_CORD_pos_advance(CORD_pos pos, size_t n) {
00267     while(true) {
00268         long avail=CORD_pos_chars_left(pos);
00269         if(avail<=0) {
00270             CORD_next(pos);
00271             if(!--n)
00272                 break;
00273         } else if((size_t)avail<n) {
00274             CORD_pos_advance(pos, avail);
00275             n-=avail;
00276         } else { // avail>=n
00277             CORD_pos_advance(pos, n);
00278             break;
00279         }
00280     }
00281 }
00282
00283 #ifndef DOXYGEN
00284 struct Cstr_to_string_body_block_info {
00285     // input
00286     String::Language lang;
00287     SQL_Connection* connection;
00288     const Request_charsets* charsets;
00289     const String::Body* body;
00290
00291     // output
00292     CORD_ec result;
00293
00294     // private
00295     CORD_pos pos;
00296     size_t fragment_begin;
00297     bool whitespace;
00298 };
00299 #endif
00300 int cstr_to_string_body_block(char alang, size_t fragment_length, Cstr_to_string_body_block_info* info) {
00301     const String::Language fragment_lang=(String::Language)(unsigned char)alang;
00302     bool& whitespace=info->whitespace;
00303     size_t fragment_end=info->fragment_begin+fragment_length;
00304     //fprintf(stderr, "%d, %d\n", fragment.lang, fragment.length);
00305
00306
00307     String::Language to_lang=info->lang==String::L_UNSPECIFIED?fragment_lang:info->lang;
00308     bool optimize=(to_lang & String::L_OPTIMIZE_BIT)!=0;
00309     if(!optimize)
00310         whitespace=false;
00311
00312     switch(to_lang & ~String::L_OPTIMIZE_BIT) {
00313     case String::L_CLEAN:
00314     case String::L_TAINTED:
00315     case String::L_AS_IS:
00316         // clean piece
00317
00318         // tainted piece, but undefined untaint language
00319         // for VString.as_double of tainted values
00320         // for ^process{body} evaluation
00321
00322         // tainted, untaint language: as-is
00323         ec_append(info->result, optimize, whitespace, info->pos, fragment_length);
00324         break;
00325     case String::L_FILE_SPEC:
00326         // tainted, untaint language: file [name]
00327         escape(
00328             // Macintosh has problems with small Russian letter 'r'
00329             if( c=='\xF0' && info->charsets && info->charsets->source().NAME()=="WINDOWS-1251" ) {
00330                 // fixing that letter for most common charset
00331                 to_char('p');
00332             } else // fallback to default
00333                 encode(need_file_encode, '_', c);
00334         );
00335         break;
00336     case String::L_URI:
00337         // tainted, untaint language: uri
00338         {
00339             const char *fragment_str=info->body->mid(info->fragment_begin, fragment_length).cstr();
00340             // skip source [we use recoded version]
00341             pa_CORD_pos_advance(info->pos, fragment_length);
00342             String::C output(fragment_str, fragment_length);
00343             if(info->charsets)
00344                 output=Charset::transcode(output,
00345                     info->charsets->source(),
00346                     info->charsets->client());
00347
00348             char c;
00349             for(const char* src=output.str; (c=*src++); )
00350                 encode(need_uri_encode, '%', c);
00351         }
00352         break;
00353     case String::L_HTTP_HEADER:
00354         // tainted, untaint language: http-field-content-text
00355         escape(
00356             encode(need_uri_encode, '%', c);
00357         );
00358         break;
00359     case String::L_MAIL_HEADER:
00360         // tainted, untaint language: mail-header
00361         // http://www.ietf.org/rfc/rfc2047.txt
00362         if(info->charsets) {
00363             size_t mail_size;
00364             const char *mail_ptr=
00365                 info->body->mid(info->fragment_begin, mail_size=fragment_length).cstr();
00366             // skip source [we use recoded version]
00367             pa_CORD_pos_advance(info->pos, mail_size);
00368
00369             const char* charset_name=info->charsets->mail().NAME().cstr();
00370
00371             // Subject: Re: parser3: =?koi8-r?Q?=D3=C5=CD=C9=CE=C1=D2?=
00372             bool to_quoted_printable=false;
00373
00374             bool email=false;
00375             uchar c;
00376             for(const char* src=mail_ptr; (c=(uchar)*src++); ) {
00377                 if(to_quoted_printable && (c==',' || c == '"' || addr_spec_soon(src-1/*position to 'c'*/))) {
00378                     email=c=='<';
00379                     to_string("?=");
00380                     to_quoted_printable=false;
00381                 }
00382                 //RFC   + An 'encoded-word' MUST NOT appear in any portion of an 'addr-spec'.
00383                 if(!email && (
00384                     !to_quoted_printable && (c & 0x80)  // starting quote-printable-encoding on first 8bit char
00385                     || to_quoted_printable && !mail_header_char_valid_within_Qencoded(c)
00386                     )) {
00387                     if(!to_quoted_printable) {
00388                         to_string("=?");
00389                         to_string(charset_name);
00390                         to_string("?Q?");
00391                         to_quoted_printable=true;
00392                     }
00393                     encode(mail_header_nonspace_char, '=', '_');
00394                 } else
00395                     to_char(c);
00396                 if(c=='>')
00397                     email=false;
00398             }
00399             if(to_quoted_printable) // close
00400                 to_string("?=");
00401
00402         } else
00403             ec_append(info->result, optimize, whitespace, info->pos, fragment_length);
00404         break;
00405     case String::L_SQL:
00406         // tainted, untaint language: sql
00407         if(info->connection) {
00408             const char *fragment_str=info->body->mid(info->fragment_begin, fragment_length).cstr();
00409             // skip source [we use recoded version]
00410             pa_CORD_pos_advance(info->pos, fragment_length);
00411
00412             to_string(info->connection->quote(fragment_str, fragment_length));
00413         } else
00414             throw Exception(0,
00415                 0,
00416                 "untaint in SQL language failed - no connection specified");
00417         break;
00418     case String::L_JS:
00419         escape(switch(c) {
00420             case '"': to_string("\\\"");  break;
00421             case '\'': to_string("\\'");  break;
00422             case '\n': to_string("\\n");  break;
00423             case '\\': to_string("\\\\");  break;
00424             case '\xFF': to_string("\\\xFF");  break;
00425             default: _default; break;
00426         });
00427         break;
00428     case String::L_XML:
00429         // [2]    Char    ::=    #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
00430         escape(switch(c) {
00431             case '\x9':
00432             case '\xA':
00433             case '\xD': // this is usually removed on input
00434                 _default;
00435                 break;
00436             case '&': to_string("&amp;");  break;
00437             case '>': to_string("&gt;");  break;
00438             case '<': to_string("&lt;");  break;
00439             case '"': to_string("&quot;");  break;
00440             case '\'': to_string("&apos;");  break;
00441             default:
00442                 if(((unsigned char)c)<0x20) {
00443                     // fixing it, so that libxml would not result
00444                     // in fatal error parsing text
00445                     // though it really violates standard.
00446                     // to indicate there were an error
00447                     // replace bad char not to it's code,
00448                     // which we can do,
00449                     // but rather to '!' to show that input were actually
00450                     // invalid.
00451                     // life: shows that MSIE can somehow garble form values
00452                     // so that they contain these chars.
00453                     to_char('!');
00454                 } else {
00455                     _default;
00456                 }
00457                 break;
00458         });
00459         break;
00460     case String::L_HTML:
00461         escape(switch(c) {
00462             case '&': to_string("&amp;");  break;
00463             case '>': to_string("&gt;");  break;
00464             case '<': to_string("&lt;");  break;
00465             case '"': to_string("&quot;");  break;
00466             default: _default; break;
00467         });
00468         break;
00469     case String::L_REGEX:
00470         // tainted, untaint language: regex
00471         escape(
00472             if(need_regex_escape(c))
00473                 to_char('\\')
00474             _default;
00475         );
00476         break;
00477     default:
00478         SAPI::abort("unknown untaint language #%d",
00479             static_cast<int>(to_lang)); // should never
00480         break; // never
00481     }
00482
00483     info->fragment_begin=fragment_end;
00484
00485     return 0; // 0=continue
00486 }
00487
00488
00489 String::Body String::cstr_to_string_body(Language lang,
00490           SQL_Connection* connection,
00491           const Request_charsets *charsets) const {
00492     if(is_empty())
00493         return String::Body();
00494
00495     Cstr_to_string_body_block_info info;
00496     // input
00497     info.lang=lang;
00498     info.connection=connection;
00499     info.charsets=charsets;
00500     info.body=&body;
00501     // output
00502     CORD_ec_init(info.result);
00503     // private
00504     body.set_pos(info.pos, 0);
00505     info.fragment_begin=0;
00506     info.whitespace=true;
00507
00508     langs.for_each(body, cstr_to_string_body_block, &info);
00509     return String::Body(CORD_ec_to_cord(info.result));
00510 }


value.dox File Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


void.C File Reference

Parser: VOID parser class. More...

Include dependency graph for void.C:

Include dependency graph

Go to the source code of this file.

Compounds

class | MVoid

Functions

DECLARE_CLASS_VAR (void, new MVoid, 0)
void | _length (Request &r, MethodParams &)
void | _pos (Request &r, MethodParams &params)
void | _int (Request &r, MethodParams &params)
void | _double (Request &r, MethodParams &params)
int | marshal_binds (HashStringValue &hash, SQL_Driver::Placeholder *&placeholders)
void | unmarshal_bind_updates (HashStringValue &hash, int placeholder_count, SQL_Driver::Placeholder *placeholders)
void | _sql (Request &r, MethodParams &params)
void | _left_right (Request &r, MethodParams &params)
void | _mid (Request &r, MethodParams &params)

Variables

const char *const | IDENT_VOID_C = "$Date: 2005/08/26 12:01:38 $"
String sql_bind_name

Detailed Description

Parser: VOID parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file void.C.

Function Documentation

DECLARE_CLASS_VAR | ( | void | ,
 |  | new | MVoid,
 |  | 0 |
 | ) |

void _length | ( | Request & | r,
 |  | MethodParams & |
 | ) | [static]

Definition at line 38 of file void.C.

References Request::write_no_lang().

Referenced by MVoid::MVoid().

void _pos | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 43 of file void.C.

References MethodParams::as_no_junction(), and Request::write_no_lang().

Referenced by MVoid::MVoid().

void _int | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 50 of file void.C.

References MethodParams::as_int(), VVoid::as_int(), Array< Value * >::count(), GET_SELF, and Request::write_no_lang().

Referenced by MVoid::MVoid().

void _double | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 56 of file void.C.

References MethodParams::as_double(), VVoid::as_double(), Array< Value * >::count(), GET_SELF, and Request::write_no_lang().

Referenced by MVoid::MVoid().

int marshal_binds | ( | HashStringValue & | hash,
 |  | SQL_Driver::Placeholder *& | placeholders
 | ) |

Definition at line 916 of file table.C.

References Hash< const String::Body, Value * >::count(), Hash< const String::Body, Value * >::for_each(), and marshal_bind().

Referenced by _sql(), and sql_result_string().

void unmarshal_bind_updates | ( | HashStringValue & | hash,
 |  | int | placeholder_count,
 |  | SQL_Driver::Placeholder * | placeholders
 | ) |

Definition at line 925 of file table.C.

References SQL_Driver::Placeholder::is_null, SQL_Driver::Placeholder::name, Hash< const String::Body, Value * >::put(), SQL_Driver::Placeholder::value, value, and SQL_Driver::Placeholder::were_updated.

Referenced by _sql(), and sql_result_string().

void _sql | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 84 of file void.C.

References MethodParams::as_junction(), MethodParams::as_no_junction(), Request::connection(), Hash< const String::Body, Value * >::count(), Array< Value * >::count(), String::cstr(), Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::is_defined(), Value::is_string(), String::L_SQL, String::L_UNSPECIFIED, marshal_binds(), Request::process_to_string(), SQL_Connection::query(), uint, and unmarshal_bind_updates().

Referenced by MVoid::MVoid().

void _left_right | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 128 of file void.C.

References MethodParams::as_int(), and ssize_t.

Referenced by MVoid::MVoid().

void _mid | ( | Request & | r,
 |  | MethodParams & | params
 | ) | [static]

Definition at line 138 of file void.C.

References MethodParams::as_int(), Array< Value * >::count(), and ssize_t.

Referenced by MVoid::MVoid().

Variable Documentation

const char* const IDENT_VOID_C = "$Date: 2005/08/26 12:01:38 $" [static]

Definition at line 8 of file void.C.

String sql_bind_name

Definition at line 21 of file void.C.


void.C Source File

void.C

Go to the documentation of this file.
00001
00008 static const char * const IDENT_VOID_C="$Date: 2005/08/26 12:01:38 $";
00009
00010 #include "classes.h"
00011 #include "pa_vmethod_frame.h"
00012
00013 #include "pa_request.h"
00014 #include "pa_vint.h"
00015 #include "pa_vdouble.h"
00016 #include "pa_vvoid.h"
00017 #include "pa_sql_connection.h"
00018
00019 // externs
00020
00021 extern String sql_bind_name;
00022
00023 // class
00024
00025 class MVoid: public Methoded {
00026 public:
00027     MVoid();
00028 public: // Methoded
00029     bool used_directly() { return true; }
00030 };
00031
00032 // global variable
00033
00034 DECLARE_CLASS_VAR(void, new MVoid, 0);
00035
00036 // methods
00037
00038 static void _length(Request& r, MethodParams&) {
00039     // always zero
00040     r.write_no_lang(*new VInt(0));
00041 }
00042
00043 static void _pos(Request& r, MethodParams& params) {
00044     // just checking for consistency
00045     params.as_no_junction(0, "substr must not be code");
00046     // never found
00047     r.write_no_lang(*new VInt(-1));
00048 }
00049
00050 static void _int(Request& r, MethodParams& params) {
00051     VVoid& vvoid=GET_SELF(r, VVoid);
00052     r.write_no_lang(*new VInt(
00053         params.count()==0?vvoid.as_int():params.as_int(0, "default must be int", r)));
00054 }
00055
00056 static void _double(Request& r, MethodParams& params) {
00057     VVoid& vvoid=GET_SELF(r, VVoid);
00058     r.write_no_lang(*new VDouble(
00059         params.count()==0?vvoid.as_double():params.as_double(0, "default must be double", r)));
00060 }
00061
00062 #ifndef DOXYGEN
00063 class Void_sql_event_handlers: public SQL_Driver_query_event_handlers {
00064     const String& statement_string;
00065 public:
00066     Void_sql_event_handlers(const String& astatement_string): statement_string(astatement_string) {}
00067     bool add_column(SQL_Error& /*error*/, const char* /*str*/, size_t /*length*/) { /* ignore */ return false; }
00068     bool before_rows(SQL_Error& error) {
00069         // there are some result rows, which is wrong
00070         error=SQL_Error("parser.runtime",
00071             /*statement_string,*/
00072             "must return nothing");
00073         return true;
00074     }
00075     bool add_row(SQL_Error& /*error*/) { /* never */ return false; }
00076     bool add_row_cell(SQL_Error& /*error*/, const char* /*str*/, size_t /*length*/) { /* never */ return false; }
00077
00078 };
00079 #endif
00080
00081 extern int marshal_binds(HashStringValue& hash, SQL_Driver::Placeholder*& placeholders);
00082 extern void unmarshal_bind_updates(HashStringValue& hash, int placeholder_count, SQL_Driver::Placeholder* placeholders);
00083
00084 static void _sql(Request& r, MethodParams& params) {
00085     Value& statement=params.as_junction(0, "statement must be code");
00086
00087     HashStringValue* bind=0;
00088     if(params.count()>1) {
00089         Value& voptions=params.as_no_junction(1, "options must be hash, not code");
00090         if(voptions.is_defined() && !voptions.is_string())
00091             if(HashStringValue* options=voptions.get_hash()) {
00092                 int valid_options=0;
00093                 if(Value* vbind=options->get(sql_bind_name)) {
00094                     valid_options++;
00095                     bind=vbind->get_hash();
00096                 }
00097                 if(valid_options!=options->count())
00098                     throw Exception("parser.runtime",
00099                         0,
00100                         "called with invalid option");
00101             } else
00102                 throw Exception("parser.runtime",
00103                     0,
00104                     "options must be hash");
00105     }
00106
00107     SQL_Driver::Placeholder* placeholders=0;
00108     uint placeholders_count=0;
00109     if(bind)
00110         placeholders_count=marshal_binds(*bind, placeholders);
00111
00112     Temp_lang temp_lang(r, String::L_SQL);
00113     const String& statement_string=r.process_to_string(statement);
00114     const char* statement_cstr=
00115         statement_string.cstr(String::L_UNSPECIFIED, r.connection());
00116     Void_sql_event_handlers handlers(statement_string);
00117     r.connection()->query(
00118         statement_cstr,
00119         placeholders_count, placeholders,
00120         0, 0,
00121         handlers,
00122         statement_string);
00123
00124     if(bind)
00125         unmarshal_bind_updates(*bind, placeholders_count, placeholders);
00126 }
00127
00128 static void _left_right(Request& r, MethodParams& params) {
00129     ssize_t sn=params.as_int(0, "n must be int", r);
00130     if(sn<0)
00131         throw Exception("parser.runtime",
00132             0,
00133             "n(%d) must be >=0", sn);
00134
00135     // return nothing
00136 }
00137
00138 static void _mid(Request& r, MethodParams& params) {
00139     ssize_t sbegin=params.as_int(0, "p must be int", r);
00140     if(sbegin<0)
00141         throw Exception("parser.runtime",
00142             0,
00143             "p(%d) must be >=0", sbegin);
00144
00145     if(params.count()>1) {
00146         ssize_t sn=params.as_int(1, "n must be int", r);
00147         if(sn<0)
00148             throw Exception("parser.runtime",
00149                 0,
00150                 "n(%d) must be >=0", sn);
00151     }
00152
00153     // return nothing
00154 }
00155
00156 // constructor
00157
00158 MVoid::MVoid(): Methoded("void") {
00159     // ^void.length[]
00160     add_native_method("length", Method::CT_DYNAMIC, _length, 0, 0);
00161
00162     // ^void.pos[substr]
00163     add_native_method("pos", Method::CT_DYNAMIC, _pos, 1, 1);
00164
00165     // ^void.int[]
00166     // ^void.int(default)
00167     add_native_method("int", Method::CT_DYNAMIC, _int, 0, 1);
00168
00169     // ^void.double[]
00170     // ^void.double(default)
00171     add_native_method("double", Method::CT_DYNAMIC, _double, 0, 1);
00172
00173     // ^sql[query]
00174     add_native_method("sql", Method::CT_STATIC, _sql, 1, 2);
00175
00176     // ^void.left() ^void.right()
00177     add_native_method("left", Method::CT_DYNAMIC, _left_right, 1, 1);
00178     add_native_method("right", Method::CT_DYNAMIC, _left_right, 1, 1);
00179
00180     // ^void.mid(p;n)
00181     add_native_method("mid", Method::CT_DYNAMIC, _mid, 1, 2);
00182 }


xdoc.C File Reference

Parser: xdoc parser class. More...

Include dependency graph for xdoc.C:

Include dependency graph

Go to the source code of this file.

Functions

DECLARE_CLASS_VAR (xdoc, 0, 0)

Detailed Description

Parser: xdoc parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file xdoc.C.

Function Documentation

DECLARE_CLASS_VAR | ( | xdoc | ,
 |  | 0 | ,
 |  | 0 |
 | ) |


xdoc.C Source File

xdoc.C

Go to the documentation of this file.
00001
00008 #include "pa_config_includes.h"
00009
00010 #ifdef XML
00011
00012 static const char * const IDENT_XDOC_C="$Date: 2005/12/16 10:15:12 $";
00013
00014 #include "libxml/tree.h"
00015 #include "libxml/HTMLtree.h"
00016 #include "libxslt/xsltInternals.h"
00017 #include "libxslt/transform.h"
00018 #include "libxslt/xsltutils.h"
00019 #include "libxslt/variables.h"
00020 #include "libxslt/imports.h"
00021
00022 #include "pa_vmethod_frame.h"
00023
00024 #include "pa_stylesheet_manager.h"
00025 #include "pa_request.h"
00026 #include "pa_vxdoc.h"
00027 #include "pa_charset.h"
00028 #include "pa_vfile.h"
00029 #include "pa_xml_exception.h"
00030 #include "xnode.h"
00031
00032 // defines
00033
00034 #define XDOC_CLASS_NAME "xdoc"
00035
00036 #define XDOC_OUTPUT_METHOD_OPTION_NAME "method"
00037 #define XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "xml"
00038 #define XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "html"
00039 #define XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "text"
00040
00041 // class
00042
00043 class MXdoc: public MXnode {
00044 public: // VStateless_class
00045     Value* create_new_value(Pool&, HashStringValue&) { return new VXdoc(); }
00046
00047 public:
00048     MXdoc();
00049
00050 };
00051
00052 // global variable
00053
00054 DECLARE_CLASS_VAR(xdoc, new MXdoc, 0);
00055
00056 // helper classes
00057
00058 class xmlOutputBuffer_auto_ptr {
00059 public:
00060     explicit xmlOutputBuffer_auto_ptr(xmlOutputBuffer *_APtr = 0)
00061         : _Owns(_APtr != 0), _Ptr(_APtr) {}
00062     xmlOutputBuffer_auto_ptr(const xmlOutputBuffer_auto_ptr& _Y)
00063         : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
00064     xmlOutputBuffer_auto_ptr& operator=(const xmlOutputBuffer_auto_ptr& _Y)
00065         {if (this != &_Y)
00066             {if (_Ptr != _Y.get())
00067                 {if (_Owns && _Ptr)
00068                     xmlOutputBufferClose(_Ptr);
00069                 _Owns = _Y._Owns; }
00070             else if (_Y._Owns)
00071                 _Owns = true;
00072             _Ptr = _Y.release(); }
00073         return (*this); }
00074     ~xmlOutputBuffer_auto_ptr()
00075         {if (_Owns && _Ptr)
00076             xmlOutputBufferClose(_Ptr); }
00077     xmlOutputBuffer& operator*() const
00078         {return (*get()); }
00079     xmlOutputBuffer *operator->() const
00080         {return (get()); }
00081     xmlOutputBuffer *get() const
00082         {return (_Ptr); }
00083     xmlOutputBuffer *release() const
00084         {((xmlOutputBuffer_auto_ptr *)this)->_Owns = false;
00085         return (_Ptr); }
00086 private:
00087     bool _Owns;
00088     xmlOutputBuffer *_Ptr;
00089 };
00090
00091 class xsltTransformContext_auto_ptr {
00092 public:
00093     explicit xsltTransformContext_auto_ptr(xsltTransformContext *_APtr = 0)
00094         : _Owns(_APtr != 0), _Ptr(_APtr) {}
00095     xsltTransformContext_auto_ptr(const xsltTransformContext_auto_ptr& _Y)
00096         : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
00097     xsltTransformContext_auto_ptr& operator=(const xsltTransformContext_auto_ptr& _Y)
00098         {if (this != &_Y)
00099             {if (_Ptr != _Y.get())
00100                 {if (_Owns && _Ptr)
00101                     xsltFreeTransformContext(_Ptr);
00102                 _Owns = _Y._Owns; }
00103             else if (_Y._Owns)
00104                 _Owns = true;
00105             _Ptr = _Y.release(); }
00106         return (*this); }
00107     ~xsltTransformContext_auto_ptr()
00108         {if (_Owns && _Ptr)
00109             xsltFreeTransformContext(_Ptr); }
00110     xsltTransformContext& operator*() const
00111         {return (*get()); }
00112     xsltTransformContext *operator->() const
00113         {return (get()); }
00114     xsltTransformContext *get() const
00115         {return (_Ptr); }
00116     xsltTransformContext *release() const
00117         {((xsltTransformContext_auto_ptr *)this)->_Owns = false;
00118         return (_Ptr); }
00119 private:
00120     bool _Owns;
00121     xsltTransformContext *_Ptr;
00122 };
00123
00124 class xsltStylesheet_auto_ptr {
00125 public:
00126     explicit xsltStylesheet_auto_ptr(xsltStylesheet *_APtr = 0)
00127         : _Owns(_APtr != 0), _Ptr(_APtr) {}
00128     xsltStylesheet_auto_ptr(const xsltStylesheet_auto_ptr& _Y)
00129         : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
00130     xsltStylesheet_auto_ptr& operator=(const xsltStylesheet_auto_ptr& _Y)
00131         {if (this != &_Y)
00132             {if (_Ptr != _Y.get())
00133                 {if (_Owns && _Ptr)
00134                     xsltFreeStylesheet(_Ptr);
00135                 _Owns = _Y._Owns; }
00136             else if (_Y._Owns)
00137                 _Owns = true;
00138             _Ptr = _Y.release(); }
00139         return (*this); }
00140     ~xsltStylesheet_auto_ptr()
00141         {if (_Owns && _Ptr)
00142             xsltFreeStylesheet(_Ptr); }
00143     xsltStylesheet& operator*() const
00144         {return (*get()); }
00145     xsltStylesheet *operator->() const
00146         {return (get()); }
00147     xsltStylesheet *get() const
00148         {return (_Ptr); }
00149     xsltStylesheet *release() const
00150         {((xsltStylesheet_auto_ptr *)this)->_Owns = false;
00151         return (_Ptr); }
00152 private:
00153     bool _Owns;
00154     xsltStylesheet *_Ptr;
00155 };
00156
00157 // methods
00158
00159 static void writeNode(Request& r, VXdoc& xdoc, xmlNode* node) {
00160     if(!node)
00161         throw Exception("parser.runtime",
00162             0,
00163             "error creating node"); // OOM, bad name, things like that
00164
00165     // write out result
00166     r.write_no_lang(xdoc.wrap(*node));
00167 }
00168
00169 struct IdsIteratorInfo {
00170     xmlChar *elementId;
00171     xmlNode *element;
00172 };
00173
00174 /* Hash Scanner function for pa_getElementById */
00175 extern "C" void // switching to calling convetion of libxml
00176 idsHashScanner (void *payload, void *data, xmlChar *name) {
00177     IdsIteratorInfo *priv = (IdsIteratorInfo *)data;
00178
00179     if (priv->element == NULL && xmlStrEqual (name, priv->elementId))
00180     {
00181         xmlNode* parent=((xmlID *)payload)->attr->parent;
00182         assert(parent);
00183         priv->element=parent;
00184     }
00185 }
00186
00187 static xmlNode*
00188 pa_getElementById(xmlDoc& xmldoc, xmlChar* elementId) {
00189     xmlHashTable *ids = (xmlHashTable *)xmldoc.ids;
00190     IdsIteratorInfo iter={elementId, NULL};
00191     xmlHashScan(ids, idsHashScanner, &iter);
00192     return iter.element;
00193 }
00194
00195 /*
00196 static xmlNode *
00197 pa_importNode (xmlDoc& xmldoc, xmlNode& importedNode, bool deep) {
00198     xmlNode *result = NULL;
00199
00200     switch (importedNode.type) {
00201     case XML_ATTRIBUTE_NODE:
00202         result = (xmlNode *)xmlCopyProp(xmldoc, (xmlAttr *)importedNode);
00203         result.parent=0; // no idea
00204         break;
00205     case XML_DOCUMENT_FRAG_NODE:
00206     case XML_ELEMENT_NODE:
00207     case XML_ENTITY_REF_NODE:
00208     case XML_PI_NODE:
00209     case XML_TEXT_NODE:
00210     case XML_CDATA_SECTION_NODE:
00211     case XML_COMMENT_NODE:
00212         result = xmlCopyNode (importedNode->n, deep);
00213         xmlSetTreeDoc (result, priv->n);
00214         break;
00215     default:
00216         *exc = GDOME_NOT_SUPPORTED_ERR;
00217     }
00218
00219     return result;
00220 }
00221 */
00222
00223 // Element createElement(in DOMString tagName) raises(DOMException);
00224 static void _createElement(Request& r, MethodParams& params) {
00225     VXdoc& vdoc=GET_SELF(r, VXdoc);
00226     xmlDoc& xmldoc=vdoc.get_xmldoc();
00227
00228     xmlChar* tagName=as_xmlchar(r, params, 0, "tagName must be string");
00229
00230     xmlNode *node=xmlNewDocNode(&xmldoc, NULL, tagName, NULL);
00231     writeNode(r, vdoc, node);
00232 }
00233
00234 // Element createElementNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
00235 static void _createElementNS(Request& r, MethodParams& params) {
00236     VXdoc& vdoc=GET_SELF(r, VXdoc);
00237     xmlDoc& xmldoc=vdoc.get_xmldoc();
00238
00239     // namespaceURI;localName
00240     xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00241     xmlChar* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string");
00242
00243     xmlChar* prefix=0;
00244     xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);
00245
00246     xmlNode *node;
00247     if(localName) {
00248         xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix);
00249         node=xmlNewDocNode(&xmldoc, &ns, localName, NULL);
00250     } else
00251         node=xmlNewDocNode(&xmldoc, NULL, qualifiedName/*unqualified, actually*/, NULL);
00252     writeNode(r, vdoc, node);
00253 }
00254
00255 // DocumentFragment createDocumentFragment()
00256 static void _createDocumentFragment(Request& r, MethodParams&) {
00257     VXdoc& vdoc=GET_SELF(r, VXdoc);
00258     xmlDoc& xmldoc=vdoc.get_xmldoc();
00259
00260     xmlNode *node=xmlNewDocFragment(&xmldoc);
00261     writeNode(r, vdoc, node);
00262 }
00263
00264 // Text createTextNode(in DOMString data);
00265 static void _createTextNode(Request& r, MethodParams& params) {
00266     VXdoc& vdoc=GET_SELF(r, VXdoc);
00267     xmlDoc& xmldoc=vdoc.get_xmldoc();
00268
00269     xmlChar* data=as_xmlchar(r, params, 0, "data must be string");
00270
00271     xmlNode *node=xmlNewDocText(&xmldoc, data);
00272     writeNode(r, vdoc, node);
00273 }
00274
00275 // Comment createComment(in DOMString data)
00276 static void _createComment(Request& r, MethodParams& params) {
00277     VXdoc& vdoc=GET_SELF(r, VXdoc);
00278
00279     xmlChar* data=as_xmlchar(r, params, 0, "data must be string");
00280
00281     xmlNode *node=xmlNewComment(data);
00282     writeNode(r, vdoc, node);
00283 }
00284
00285 // CDATASection createCDATASection(in DOMString data) raises(DOMException);
00286 static void _createCDATASection(Request& r, MethodParams& params) {
00287     VXdoc& vdoc=GET_SELF(r, VXdoc);
00288     xmlDoc& xmldoc=vdoc.get_xmldoc();
00289
00290     xmlChar* data=as_xmlchar(r, params, 0, "data must be string");
00291
00292     xmlNode *node=xmlNewCDataBlock(&xmldoc, data, strlen((const char*)data));
00293     writeNode(r, vdoc, node);
00294 }
00295
00296 // ProcessingInstruction createProcessingInstruction(in DOMString target,in DOMString data) raises(DOMException);
00297 static void _createProcessingInstruction(Request& r, MethodParams& params) {
00298     VXdoc& vdoc=GET_SELF(r, VXdoc);
00299     xmlDoc& xmldoc=vdoc.get_xmldoc();
00300
00301     xmlChar* target=as_xmlchar(r, params, 0, "data must be string");
00302     xmlChar* data=as_xmlchar(r, params, 1, "data must be string");
00303
00304     xmlNode *node=xmlNewDocPI(&xmldoc, target, data);
00305     writeNode(r, vdoc, node);
00306 }
00307
00308 // Attr createAttribute(in DOMString name) raises(DOMException);
00309 static void _createAttribute(Request& r, MethodParams& params) {
00310     VXdoc& vdoc=GET_SELF(r, VXdoc);
00311     xmlDoc& xmldoc=vdoc.get_xmldoc();
00312
00313     xmlChar* name=as_xmlchar(r, params, 0, "name must be string");
00314
00315     xmlNode *node=(xmlNode*)xmlNewDocProp(&xmldoc, name, 0);
00316     writeNode(r, vdoc, node);
00317 }
00318
00319 // Attr createAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
00320 static void _createAttributeNS(Request& r, MethodParams& params) {
00321     VXdoc& vdoc=GET_SELF(r, VXdoc);
00322     xmlDoc& xmldoc=vdoc.get_xmldoc();
00323
00324     xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00325     xmlChar* qualifiedName=as_xmlchar(r, params, 1, "name must be string");
00326
00327     xmlChar* prefix=0;
00328     xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);
00329
00330     xmlNode *node;
00331     if(localName) {
00332         xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix);
00333         node=(xmlNode*)xmlNewDocProp(&xmldoc, localName, NULL);
00334         xmlSetNs(node, &ns);
00335     } else
00336         node=(xmlNode*)xmlNewDocProp(&xmldoc, qualifiedName/*unqualified, actually*/, NULL);
00337     writeNode(r, vdoc, node);
00338 }
00339
00340 // EntityReference createEntityReference(in DOMString name) raises(DOMException);
00341 static void _createEntityReference(Request& r, MethodParams& params) {
00342     VXdoc& vdoc=GET_SELF(r, VXdoc);
00343     xmlDoc& xmldoc=vdoc.get_xmldoc();
00344
00345     xmlChar* name=as_xmlchar(r, params, 0, "name must be string");
00346
00347     xmlNode *node=xmlNewReference(&xmldoc, name);
00348     writeNode(r, vdoc, node);
00349 }
00350
00351
00352 static void _getElementById(Request& r, MethodParams& params) {
00353     VXdoc& vdoc=GET_SELF(r, VXdoc);
00354     xmlDoc& xmldoc=vdoc.get_xmldoc();
00355
00356     // elementId
00357     xmlChar* elementId=as_xmlchar(r, params, 0, "elementID must be string");
00358
00359     if(xmlNode *node=pa_getElementById(xmldoc, elementId)) {
00360         // write out result
00361         writeNode(r, vdoc, node);
00362     }
00363 }
00364
00365 static void _importNode(Request& r, MethodParams& params) {
00366     VXdoc& vdoc=GET_SELF(r, VXdoc);
00367     xmlDoc& xmldoc=vdoc.get_xmldoc();
00368
00369     xmlNode& importedNode=
00370         as_node(params, 0, "importedNode must be node");
00371     bool deep=
00372         params.as_bool(1, "deep must be bool", r);
00373
00374     xmlNode *node=xmlDocCopyNode(&importedNode, &xmldoc, deep?1: 0);
00375     // write out result
00376     writeNode(r, vdoc, node);
00377 }
00378 /*
00379 GdomeElement *gdome_doc_createElementNS (GdomeDocument *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeException *exc);
00380 GdomeAttr *gdome_doc_createAttributeNS (GdomeDocument *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeException *exc);
00381 */
00382
00383 static void _create(Request& r, MethodParams& params) {
00384     Charset& source_charset=r.charsets.source();
00385     VXdoc& vdoc=GET_SELF(r, VXdoc);
00386
00387     Value& param=params[params.count()-1];
00388     xmlDoc* xmldoc;
00389     bool set_encoding=false;
00390     if(param.get_junction()) { // {<?xml?>...}
00391         Temp_lang temp_lang(r, String::L_XML);
00392         const String& xml=r.process_to_string(param);
00393
00394         const char* cstr=xml.cstr(String::L_UNSPECIFIED, 0, &r.charsets);
00395         xmldoc=xmlParseMemory(cstr, strlen(cstr));
00396         //printf("document=0x%p\n", document);
00397         if(!xmldoc || xmlHaveGenericErrors())
00398             throw XmlException(0);
00399
00400         // must be last action in if, see after if}
00401     } else { // [localName]
00402         xmlChar* localName=r.transcode(param.as_string());
00403
00404 #if 0
00405         GdomeDocumentType *documentType=gdome_di_createDocumentType (
00406             docimpl,
00407             r.transcode(qualifiedName),
00408             0/*publicId*/,
00409             0/*systemId*/,
00410             &exc);
00411         if(!documentType || exc || xmlHaveGenericErrors())
00412             throw Exception(
00413                 method_name,
00414                 exc);
00416 #endif
00417         xmldoc=xmlNewDoc(0);
00418         if(!xmldoc || xmlHaveGenericErrors())
00419             throw XmlException(0);
00420         xmlNode* node=xmlNewChild((xmlNode*)xmldoc, NULL, localName, NULL);
00421         if(!node || xmlHaveGenericErrors())
00422             throw XmlException(0);
00423
00424         set_encoding=true;
00425         // must be last action in if, see after if}
00426     }
00427     // must be first action after if}
00428     // replace any previous parsed source
00429     vdoc.set_xmldoc(r.charsets, *xmldoc);
00430
00431     // URI
00432     const char* URI_cstr;
00433     if(params.count()>1) { // absolute(param)
00434         const String& URI=params.as_string(0, "URI must be string");
00435         URI_cstr=r.absolute(URI).cstr();
00436     } else // default = disk path to requested document
00437         URI_cstr=r.request_info.path_translated;
00438     if(URI_cstr)
00439         xmldoc->URL=source_charset.transcode_buf2xchar(URI_cstr, strlen(URI_cstr));
00440
00441     if(set_encoding) {
00442         const char* source_charset_name=source_charset.NAME().cstr();
00443         xmldoc->encoding=source_charset.transcode_buf2xchar(source_charset_name, strlen(source_charset_name));
00444     }
00445 }
00446
00447 static void _load(Request& r, MethodParams& params) {
00448     VXdoc& vdoc=GET_SELF(r, VXdoc);
00449
00450     // filespec
00451     const String* uri=&params.as_string(0, "uri must be string");
00452     const char* uri_cstr;
00453     if(uri->pos("://")==STRING_NOT_FOUND) // disk path
00454         uri_cstr=r.absolute(*uri).cstr(String::L_FILE_SPEC);
00455     else // xxx://
00456         uri_cstr=uri->cstr(String::L_AS_IS); // leave as-is for xmlParseFile to handle
00457
00459     xmlDoc* xmldoc=xmlParseFile(uri_cstr);
00460     if(!xmldoc || xmlHaveGenericErrors())
00461         throw XmlException(uri);
00462
00463     // must be first action after if}
00464     // replace any previous parsed source
00465     vdoc.set_xmldoc(r.charsets, *xmldoc);
00466 }
00467
00468 static void param_option_over_output_option(
00469                         HashStringValue& param_options, const char* option_name,
00470                         const String*& output_option) {
00471     if(Value* value=param_options.get(String::Body(option_name)))
00472         output_option=&value->as_string();
00473 }
00474 static void param_option_over_output_option(
00475                         HashStringValue& param_options, const char* option_name,
00476                         int& output_option) {
00477     if(Value* value=param_options.get(String::Body(option_name))) {
00478         const String& s=value->as_string();
00479         if(s=="yes")
00480             output_option=1;
00481         else if(s=="no")
00482             output_option=0;
00483         else
00484             throw Exception("parser.runtime",
00485                 &s,
00486                 "%s must be either 'yes' or 'no'", option_name);
00487     }
00488 }
00489
00491 static void prepare_output_options(Request& r,
00492                    MethodParams& params, size_t index,
00493                    VXdoc::Output_options& oo) {
00494 /*
00495 <xsl:output
00496   !method = "xml" | "html" | "text" | qname-but-not-ncname
00497   !version = nmtoken
00498   !encoding = string
00499   !omit-xml-declaration = "yes" | "no"
00500   !standalone = "yes" | "no"
00501   !doctype-public = string
00502   !doctype-system = string
00503   cdata-section-elements = qnames
00504   !indent = "yes" | "no"
00505   !media-type = string />
00506 */
00507
00508     // configuring with options from parameter...
00509     if(params.count()>index) {
00510         Value& voptions=params.as_no_junction(index, "options must be string");
00511         if(voptions.is_defined()) {
00512             if(HashStringValue *options=voptions.get_hash()) {
00513                 // $.method[xml|html|text]
00514                 if(Value* vmethod=options->get(String::Body(XDOC_OUTPUT_METHOD_OPTION_NAME)))
00515                     oo.method=&vmethod->as_string();
00516
00517                 // $.version[1.0]
00518                 param_option_over_output_option(*options, "version", oo.version);
00519                 // $.encoding[windows-1251|...]
00520                 param_option_over_output_option(*options, "encoding", oo.encoding);
00521                 // $.omit-xml-declaration[yes|no]
00522                 param_option_over_output_option(*options, "omit-xml-declaration", oo.omitXmlDeclaration);
00523                 // $.standalone[yes|no]
00524                 param_option_over_output_option(*options, "standalone", oo.standalone);
00525                 // $.indent[yes|no]
00526                 param_option_over_output_option(*options, "indent", oo.indent);
00527                 // $.media-type[text/{html|xml|plain}]
00528                 param_option_over_output_option(*options, "media-type", oo.mediaType);
00529             }
00530         }
00531     }
00532
00533     // default encoding from pool
00534     if(!oo.encoding)
00535         oo.encoding=new String(r.charsets.source().NAME(), String::L_TAINTED);
00536     // default method=xml
00537     if(!oo.method)
00538         oo.method=new String(XDOC_OUTPUT_METHOD_OPTION_VALUE_XML);
00539     // default mediaType = depending on method
00540     if(!oo.mediaType) {
00541         if(*oo.method==XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)
00542             oo.mediaType=new String("text/xml");
00543         else if(*oo.method==XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)
00544             oo.mediaType=new String("text/html");
00545         else // XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT & all others
00546             oo.mediaType=new String("text/plain");
00547     }
00548 }
00549
00550 struct Xdoc2buf_result {
00551     char* str;
00552     size_t length;
00553 };
00554 static Xdoc2buf_result xdoc2buf(Request& r, VXdoc& vdoc,
00555                      MethodParams& params, int index,
00556                      VXdoc::Output_options& oo,
00557                      const String* file_spec,
00558                      bool use_source_charset_to_render_and_client_charset_to_write_to_header=false) {
00559     Xdoc2buf_result result;
00560     prepare_output_options(r, params, index,
00561         oo);
00562
00563     const char* render_encoding;
00564     const char* header_encoding;
00565     if(use_source_charset_to_render_and_client_charset_to_write_to_header) {
00566         render_encoding=r.charsets.source().NAME_CSTR();
00567         header_encoding=r.charsets.client().NAME_CSTR();
00568     } else {
00569         header_encoding=render_encoding=oo.encoding->cstr();
00570     }
00571
00572     xmlCharEncodingHandler *renderer=xmlFindCharEncodingHandler(render_encoding);
00573     if(!renderer)
00574         throw Exception("parser.runtime",
00575             0,
00576             "encoding '%s' not supported", render_encoding);
00577     // UTF-8 renderer contains empty input/output converters,
00578     // which is wrong for xmlOutputBufferCreateIO
00579     // while zero renderer goes perfectly
00580     if(strcmp(render_encoding, "UTF-8")==0)
00581         renderer=0;
00582
00583     xmlOutputBuffer_auto_ptr outputBuffer(xmlAllocOutputBuffer(renderer));
00584
00585     xsltStylesheet_auto_ptr stylesheet(xsltNewStylesheet());
00586     if(!stylesheet.get())
00587         throw Exception(0,
00588             0,
00589             "xsltNewStylesheet failed");
00590
00591     #define OOSTRING2STYLE(name) \
00592         stylesheet->name=oo.name?BAD_CAST xmlMemStrdup((const char*)r.transcode(*oo.name)):0
00593     #define OOBOOL2STYLE(name) \
00594         if(oo.name>=0) stylesheet->name=oo.name
00595
00596     OOSTRING2STYLE(method);
00597     OOSTRING2STYLE(encoding);
00598     OOSTRING2STYLE(mediaType);
00599 //  OOSTRING2STYLE(doctypeSystem);
00600 //  OOSTRING2STYLE(doctypePublic);
00601     OOBOOL2STYLE(indent);
00602     OOSTRING2STYLE(version);
00603     OOBOOL2STYLE(standalone);
00604     OOBOOL2STYLE(omitXmlDeclaration);
00605
00606     xmlDoc& xmldoc=vdoc.get_xmldoc();
00607     xmldoc.encoding=BAD_CAST xmlMemStrdup(render_encoding);
00608     if(header_encoding)
00609         stylesheet->encoding=BAD_CAST xmlMemStrdup(header_encoding);
00610     if(xsltSaveResultTo(outputBuffer.get(), &xmldoc, stylesheet.get())<0
00611         || xmlHaveGenericErrors())
00612         throw XmlException(0);
00613
00614     // write out result
00615     char *gnome_str;  size_t gnome_length;
00616     if(outputBuffer->conv) {
00617         gnome_length=outputBuffer->conv->use;
00618         gnome_str=(char *)outputBuffer->conv->content;
00619     } else {
00620         gnome_length=outputBuffer->buffer->use;
00621         gnome_str=(char *)outputBuffer->buffer->content;
00622     }
00623
00624     if((result.length=gnome_length)) {
00625         result.str=pa_strdup(gnome_str, gnome_length);
00626     } else
00627         result.str=0;
00628
00629     if(file_spec)
00630         file_write(*file_spec,
00631             gnome_str, gnome_length,
00632             true/*as_text*/);
00633
00634     return result;
00635 }
00636
00637 static void _file(Request& r, MethodParams& params) {
00638     VXdoc& vdoc=GET_SELF(r, VXdoc);
00639     VXdoc::Output_options oo(vdoc.output_options);
00640     Xdoc2buf_result buf=xdoc2buf(r, vdoc, params, 0,
00641         oo,
00642         0/*not to file, to memory*/);
00643     // write out result
00644     r.write_no_lang(String(buf.str, buf.length));
00645
00646     // write out result
00647     VFile& vfile=*new VFile;
00648     VHash& vhcontent_type=*new VHash;
00649     vhcontent_type.hash().put(
00650         value_name,
00651         new VString(*oo.mediaType));
00652     vhcontent_type.hash().put(
00653         String::Body("charset"),
00654         new VString(*oo.encoding));
00655
00656     vfile.set(false/*tainted*/, buf.str?buf.str:""/*to distinguish from stat-ed file*/, buf.length,
00657         0/*file_name*/, &vhcontent_type);
00658     r.write_no_lang(vfile);
00659 }
00660
00661 static void _save(Request& r, MethodParams& params) {
00662     VXdoc& vdoc=GET_SELF(r, VXdoc);
00663
00664     const String& file_spec=r.absolute(params.as_string(0, "file name must be string"));
00665
00666     VXdoc::Output_options oo(vdoc.output_options);
00667     xdoc2buf(r, vdoc, params, 1,
00668         oo,
00669         &file_spec);
00670 }
00671
00672 static void _string(Request& r, MethodParams& params) {
00673     VXdoc& vdoc=GET_SELF(r, VXdoc);
00674     VXdoc::Output_options oo(vdoc.output_options);
00675     Xdoc2buf_result buf=xdoc2buf(r, vdoc, params, 0,
00676         oo,
00677         0/*not to file, to memory*/,
00678         true/*use source charset to render, client charset to put to header*/);
00679     // write out result
00680     r.write_no_lang(String(String::Body(buf.str), String::L_AS_IS));
00681 }
00682
00683 #ifndef DOXYGEN
00684 struct Add_xslt_param_info {
00685     Request* r;
00686     Array<const xmlChar*>* strings;
00687     const xmlChar** current_transform_param;
00688 };
00689 #endif
00690 static void add_xslt_param(
00691                HashStringValue::key_type attribute,
00692                HashStringValue::value_type meaning,
00693                Add_xslt_param_info* info) {
00694     xmlChar* s;
00695     *info->current_transform_param++=(s=info->r->transcode(attribute)); *info->strings+=s;
00696     *info->current_transform_param++=(s=info->r->transcode(meaning->as_string())); *info->strings+=s;
00697 }
00698
00699 static VXdoc& _transform(Request& r, const String* stylesheet_source,
00700                            VXdoc& vdoc, xsltStylesheetPtr stylesheet, const xmlChar** transform_params)
00701 {
00702     xmlDoc& xmldoc=vdoc.get_xmldoc();
00703
00704     xsltTransformContext_auto_ptr transformContext(
00705         xsltNewTransformContext(stylesheet, &xmldoc));
00706     // make params literal
00707     if (transformContext->globalVars == NULL) // strangly not initialized by xsltNewTransformContext
00708         transformContext->globalVars = xmlHashCreate(20);
00709     xsltQuoteUserParams(transformContext.get(), (const char**)transform_params);
00710     // do transform
00711     xmlDoc *transformed=xsltApplyStylesheetUser(
00712         stylesheet,
00713         &xmldoc,
00714         0/*already quoted-inserted  transform_params*/,
00715         0/*const char* output*/,
00716         0/*FILE *profile*/,
00717         transformContext.get());
00718     if(!transformed || xmlHaveGenericErrors())
00719         throw XmlException(stylesheet_source);
00720
00721     //gdome_xml_doc_mkref dislikes XML_HTML_DOCUMENT_NODE  type, fixing
00722     transformed->type=XML_DOCUMENT_NODE;
00723     // constructing result
00724     VXdoc& result=*new VXdoc(r.charsets, *transformed);
00725     /* grabbing options
00726
00727         <xsl:output
00728         !method = "xml" | "html" | "text"
00729             X| qname-but-not-ncname
00730         !version = nmtoken
00731         !encoding = string
00732         !omit-xml-declaration = "yes" | "no"
00733         !standalone = "yes" | "no"
00734         !doctype-public = string
00735         !doctype-system = string
00736         Xcdata-section-elements = qnames
00737         !indent = "yes" | "no"
00738         !media-type = string />
00739     */
00740     VXdoc::Output_options& oo=result.output_options;
00741
00742     oo.method=stylesheet->method?&r.transcode(stylesheet->method):0;
00743     oo.encoding=stylesheet->encoding?&r.transcode(stylesheet->encoding):0;
00744     oo.mediaType=stylesheet->mediaType?&r.transcode(stylesheet->mediaType):0;
00745     oo.indent=stylesheet->indent;
00746     oo.version=stylesheet->version?&r.transcode(stylesheet->version):0;
00747     oo.standalone=stylesheet->standalone;
00748     oo.omitXmlDeclaration=stylesheet->omitXmlDeclaration;
00749
00750     // return
00751     return result;
00752 }
00753 static void _transform(Request& r, MethodParams& params) {
00754     VXdoc& vdoc=GET_SELF(r, VXdoc);
00755
00756     // params
00757     Array<const xmlChar*> transform_strings;
00758     const xmlChar** transform_params=0;
00759     if(params.count()>1) {
00760         Value& vparams=params.as_no_junction(1, "transform parameters must be hash");
00761         if(!vparams.is_string())
00762             if(HashStringValue* hash=vparams.get_hash()) {
00763                 transform_params=new(UseGC) const xmlChar*[hash->count()*2+1];
00764                 Add_xslt_param_info info={
00765                     &r,
00766                     &transform_strings,
00767                     transform_params
00768                 };
00769                 hash->for_each(add_xslt_param, &info);
00770                 transform_params[hash->count()*2]=0;
00771             } else
00772                 throw Exception("parser.runtime",
00773                     0,
00774                     "transform parameters parameter must be hash");
00775     }
00776
00777     VXdoc* result;
00778     if(Value *vxdoc=params[0].as(VXDOC_TYPE, false)) { // stylesheet (xdoc)
00779         xmlDoc& stylesheetdoc=static_cast<VXdoc *>(vxdoc)->get_xmldoc();
00780         // compile xdoc stylesheet
00781         xsltStylesheet_auto_ptr stylesheet_ptr(xsltParseStylesheetDoc(&stylesheetdoc));
00782         if(xmlHaveGenericErrors())
00783             throw XmlException(0);
00784         if(!stylesheet_ptr.get())
00785             throw Exception("xml",
00786                 0,
00787                 "stylesheet failed to compile");
00788         // strange thing - xsltParseStylesheetDoc records document and destroys it in stylesheet destructor
00789         // we don't need that
00790         stylesheet_ptr->doc=0;
00791
00792         // transform!
00793         result=&_transform(r, 0,
00794             vdoc, stylesheet_ptr.get(),
00795             transform_params);
00796     } else { // stylesheet (file name)
00797         // extablish stylesheet connection
00798         const String& stylesheet_filespec=
00799             r.absolute(params.as_string(0, "stylesheet must be file name (string) or DOM document (xdoc)"));
00800         Stylesheet_connection_ptr connection=stylesheet_manager->get_connection(stylesheet_filespec);
00801
00802         // load and compile file to stylesheet [or get cached if any]
00803         // transform!
00804         result=&_transform(r, &stylesheet_filespec, vdoc, connection->stylesheet(),
00805             transform_params);
00806     }
00807
00808     // write out result
00809     r.write_no_lang(*result);
00810 }
00811
00812 // constructor
00813
00815 MXdoc::MXdoc(): MXnode(XDOC_CLASS_NAME, xnode_class) {
00817
00818     // Element createElement(in DOMString tagName) raises(DOMException);
00819     add_native_method("createElement", Method::CT_DYNAMIC, _createElement, 1, 1);
00820     // DocumentFragment createDocumentFragment();
00821     add_native_method("createDocumentFragment", Method::CT_DYNAMIC, _createDocumentFragment, 0, 0);
00822     // Text createTextNode(in DOMString data);
00823     add_native_method("createTextNode", Method::CT_DYNAMIC, _createTextNode, 1, 1);
00824     // Comment createComment(in DOMString data);
00825     add_native_method("createComment", Method::CT_DYNAMIC, _createComment, 1, 1);
00826     // CDATASection createCDATASection(in DOMString data) raises(DOMException);
00827     add_native_method("createCDATASection", Method::CT_DYNAMIC, _createCDATASection, 1, 1);
00828     // ProcessingInstruction createProcessingInstruction(in DOMString target, in DOMString data) raises(DOMException);
00829     add_native_method("createProcessingInstruction", Method::CT_DYNAMIC, _createProcessingInstruction, 2, 2);
00830     // Attr createAttribute(in DOMString name) raises(DOMException);
00831     add_native_method("createAttribute", Method::CT_DYNAMIC, _createAttribute, 1, 1);
00832     // EntityReference createEntityReference(in DOMString name) raises(DOMException);
00833     add_native_method("createEntityReference", Method::CT_DYNAMIC, _createEntityReference, 1, 1);
00834
00836
00837     // ^xdoc.getElementById[elementId]
00838     add_native_method("getElementById", Method::CT_DYNAMIC, _getElementById, 1, 1);
00839
00840     // Node (in Node importedNode, in boolean deep) raises(DOMException)
00841     add_native_method("importNode", Method::CT_DYNAMIC, _importNode, 2, 2);
00842
00843     // Attr createAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
00844     add_native_method("createAttributeNS", Method::CT_DYNAMIC, _createAttributeNS, 2, 2);
00845
00846     // Element createElementNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
00847     add_native_method("createElementNS", Method::CT_DYNAMIC, _createElementNS, 2, 2);
00848
00850
00851     // ^xdoc::create{qualifiedName}
00852     // ^xdoc::create[<some>xml</some>]
00853     // ^xdoc::create[URI][<some>xml</some>]
00854     add_native_method("create", Method::CT_DYNAMIC, _create, 1, 2);
00855     // for backward compatibility with <=v 1.82 2002/01/31 11:51:46 paf
00856     add_native_method("set", Method::CT_DYNAMIC, _create, 1, 1);
00857
00858     // ^xdoc::load[some.xml]
00859     add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
00860
00861     // ^xdoc.save[some.xml]
00862     // ^xdoc.save[some.xml;options hash]
00863     add_native_method("save", Method::CT_DYNAMIC, _save, 1, 2);
00864
00865     // ^xdoc.string[] <doc/>
00866     // ^xdoc.string[options hash] <doc/>
00867     add_native_method("string", Method::CT_DYNAMIC, _string, 0, 1);
00868
00869     // ^xdoc.file[] file with "<doc/>"
00870     // ^xdoc.file[options hash] file with "<doc/>"
00871     add_native_method("file", Method::CT_DYNAMIC, _file, 0, 1);
00872
00873     // ^xdoc.transform[stylesheet file_name/xdoc]
00874     // ^xdoc.transform[stylesheet file_name/xdoc;params hash]
00875     add_native_method("transform", Method::CT_DYNAMIC, _transform, 1, 2);
00876
00877 }
00878
00879 # else
00880
00881 #include "classes.h"
00882
00883 // global variable
00884
00885 DECLARE_CLASS_VAR(xdoc, 0, 0); // fictive
00886
00887 #endif


xnode.C File Reference

Parser: dom parser class. More...

Include dependency graph for xnode.C:

Include dependency graph

Go to the source code of this file.

Functions

DECLARE_CLASS_VAR (xnode, 0, 0)

Detailed Description

Parser: dom parser class.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file xnode.C.

Function Documentation

DECLARE_CLASS_VAR | ( | xnode | ,
 |  | 0 | ,
 |  | 0 |
 | ) |


xnode.C Source File

xnode.C

Go to the documentation of this file.
00001
00007 #include "classes.h"
00008 #ifdef XML
00009
00010 static const char * const IDENT_XNODE_C="$Date: 2005/12/19 11:54:57 $";
00011
00012 #include "pa_vmethod_frame.h"
00013
00014 #include "pa_charset.h"
00015 #include "pa_request.h"
00016 #include "pa_vxnode.h"
00017 #include "pa_vxdoc.h"
00018 #include "pa_vvoid.h"
00019 #include "pa_xml_exception.h"
00020
00021 #include "xnode.h"
00022 #include "libxml/xpath.h"
00023 #include "libxml/xpathInternals.h"
00024
00025 // global variable
00026
00027 DECLARE_CLASS_VAR(xnode, new MXnode, 0);
00028
00029 // classes
00030
00031 class xmlXPathObject_auto_ptr {
00032 public:
00033     explicit xmlXPathObject_auto_ptr(xmlXPathObject *_APtr = 0)
00034         : _Owns(_APtr != 0), _Ptr(_APtr) {}
00035     xmlXPathObject_auto_ptr(const xmlXPathObject_auto_ptr& _Y)
00036         : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
00037     xmlXPathObject_auto_ptr& operator=(const xmlXPathObject_auto_ptr& _Y)
00038         {if (this != &_Y)
00039             {if (_Ptr != _Y.get())
00040                 {if (_Owns && _Ptr)
00041                     xmlXPathFreeObject(_Ptr);
00042                 _Owns = _Y._Owns; }
00043             else if (_Y._Owns)
00044                 _Owns = true;
00045             _Ptr = _Y.release(); }
00046         return (*this); }
00047     ~xmlXPathObject_auto_ptr()
00048         {if (_Owns && _Ptr)
00049             xmlXPathFreeObject(_Ptr); }
00050     xmlXPathObject& operator*() const
00051         {return (*get()); }
00052     xmlXPathObject *operator->() const
00053         {return (get()); }
00054     xmlXPathObject *get() const
00055         {return (_Ptr); }
00056     xmlXPathObject *release() const
00057         {((xmlXPathObject_auto_ptr *)this)->_Owns = false;
00058         return (_Ptr); }
00059 private:
00060     bool _Owns;
00061     xmlXPathObject *_Ptr;
00062 };
00063
00064 class xmlXPathContext_auto_ptr {
00065 public:
00066     explicit xmlXPathContext_auto_ptr(xmlXPathContext *_APtr = 0)
00067         : _Owns(_APtr != 0), _Ptr(_APtr) {}
00068     xmlXPathContext_auto_ptr(const xmlXPathContext_auto_ptr& _Y)
00069         : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
00070     xmlXPathContext_auto_ptr& operator=(const xmlXPathContext_auto_ptr& _Y)
00071         {if (this != &_Y)
00072             {if (_Ptr != _Y.get())
00073                 {if (_Owns && _Ptr)
00074                     xmlXPathFreeContext(_Ptr);
00075                 _Owns = _Y._Owns; }
00076             else if (_Y._Owns)
00077                 _Owns = true;
00078             _Ptr = _Y.release(); }
00079         return (*this); }
00080     ~xmlXPathContext_auto_ptr()
00081         {if (_Owns && _Ptr)
00082             xmlXPathFreeContext(_Ptr); }
00083     xmlXPathContext& operator*() const
00084         {return (*get()); }
00085     xmlXPathContext *operator->() const
00086         {return (get()); }
00087     xmlXPathContext *get() const
00088         {return (_Ptr); }
00089     xmlXPathContext *release() const
00090         {((xmlXPathContext_auto_ptr *)this)->_Owns = false;
00091         return (_Ptr); }
00092 private:
00093     bool _Owns;
00094     xmlXPathContext *_Ptr;
00095 };
00096
00097 // helpers
00098
00099 xmlNode& as_node(MethodParams& params, int index, const char* msg) {
00100     Value& value=params.as_no_junction(index, msg);
00101     if(Value* vxnode=value.as(VXNODE_TYPE, false))
00102         return static_cast<VXnode*>(vxnode)->get_xmlnode();
00103     else
00104         throw Exception("parser.runtime",
00105             0,
00106             msg);
00107 }
00108
00109 xmlChar* as_xmlchar(Request& r, MethodParams& params, int index, const char* msg) {
00110     return r.transcode(params.as_string(index, msg));
00111 }
00112
00113 xmlAttr& as_attr(MethodParams& params, int index, const char* msg) {
00114     xmlNode& xmlnode=as_node(params, index, msg);
00115     if(xmlnode.type!=XML_ATTRIBUTE_NODE)
00116         throw Exception("parser.runtime",
00117             0,
00118             msg);
00119
00120     return *(xmlAttr*)&xmlnode;
00121 }
00122
00123 static void writeNode(Request& r, VXdoc& xdoc, xmlNode* node) {
00124     if(!node|| xmlHaveGenericErrors())
00125         throw XmlException(0); // OOM, bad name, things like that
00126
00127     // write out result
00128     r.write_no_lang(xdoc.wrap(*node));
00129 }
00130
00131 static xmlNode* pa_getAttributeNodeNS(xmlNode& selfNode,
00132                                       const xmlChar* localName,
00133                                       const xmlChar* namespaceURI)
00134 {
00135     for(xmlNode* currentNode=(xmlNode*)selfNode.properties;
00136         currentNode;
00137         currentNode=currentNode->next)
00138     {
00139         if(!namespaceURI || currentNode->ns && xmlStrEqual(currentNode->ns->href, namespaceURI))
00140             if(!localName || xmlStrEqual(currentNode->name, localName))
00141                 return currentNode;
00142     }
00143     return 0;
00144 }
00145
00146 xmlNs& pa_xmlMapNs(xmlDoc& doc, const xmlChar *href, const xmlChar *prefix) {
00147     assert(href);
00148     // prefix can be null
00149
00150     xmlNs *cur=doc.oldNs;
00151     while (cur != NULL &&
00152                  ((cur->prefix == NULL && prefix != NULL) ||
00153                     (cur->prefix != NULL && prefix == NULL) ||
00154                     !xmlStrEqual (cur->prefix, prefix)) &&
00155                  !xmlStrEqual (cur->href, href))
00156         cur = cur->next;
00157
00158     if (cur == NULL) {
00159         cur = xmlNewNs (NULL, href, prefix);
00160         if(!cur || xmlHaveGenericErrors())
00161             throw XmlException(0);
00162         cur->next = doc.oldNs;
00163         doc.oldNs = cur;
00164     }
00165
00166     return *cur;
00167 }
00168
00170 static void pa_addAttributeNode(xmlNode& selfNode, xmlAttr& attrNode)
00171 {
00172     if(attrNode.type!=XML_ATTRIBUTE_NODE)
00173         throw Exception("parser.runtime",
00174             0,
00175             "must be ATTRIBUTE_NODE");
00176
00177     /*
00178      * Add it at the end to preserve parsing order ...
00179      */
00180     if (selfNode.properties == NULL) {
00181         selfNode.properties = &attrNode;
00182     } else {
00183         xmlAttrPtr prev = selfNode.properties;
00184
00185         while (prev->next != NULL)
00186             prev = prev->next;
00187         prev->next = &attrNode;
00188         attrNode.prev = prev;
00189     }
00190
00191     if (xmlIsID(selfNode.doc, &selfNode, &attrNode) == 1)
00192         xmlAddID(NULL, selfNode.doc, xmlNodeGetContent((xmlNode*)&attrNode), &attrNode);
00193 }
00194
00195 static const xmlChar *
00196 pa_xmlGetNsURI(xmlNode *node) {
00197     if (node == NULL || node->ns == NULL)
00198         return NULL;
00199
00200     return node->ns->href;
00201 }
00202
00203 #ifndef DOXYGEN
00204 struct AccumulateFoundInfo
00205 {
00206     HashStringValue* hash;
00207     VXdoc* vdoc;
00208     int index;
00209 };
00210 #endif
00211 static void AccumulateFound(xmlNode& node, AccumulateFoundInfo* info)
00212 {
00213     info->hash->put(
00214         String::Body::Format(info->index++),
00215         &info->vdoc->wrap(node));
00216 }
00217 template<typename I> static void
00218 pa_xmlNamedPreorderTraversal (
00219                               xmlNode *root,
00220                               xmlChar *tagURI,
00221                               xmlChar *tagName,
00222                               void callback(xmlNode& node, I info),
00223                               I info)
00224 {
00225     for(xmlNode *iter=root->children; iter; iter = iter->next) {
00226         if(iter->type == XML_ELEMENT_NODE &&
00227             (xmlStrEqual(iter->name, tagName) ||
00228             xmlStrEqual(tagName, (const xmlChar*)"*"))) {
00229                 if(tagURI != NULL &&
00230                     (xmlStrEqual(pa_xmlGetNsURI(iter), tagURI) ||
00231                     xmlStrEqual(tagURI, (const xmlChar*)"*")))
00232                     callback(*iter, info);
00233                 else if(tagURI == NULL)
00234                     callback(*iter, info);
00235             }
00236             pa_xmlNamedPreorderTraversal(iter, tagURI, tagName, callback, info);
00237     }
00238
00239     return;
00240 }
00241
00242
00243 // methods
00244
00245 // DOM1 node
00246
00247 // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
00248 static void _insertBefore(Request& r, MethodParams& params) {
00249     VXnode& vnode=GET_SELF(r, VXnode);
00250     VXdoc& vxdoc=vnode.get_vxdoc();
00251
00252     //xmlNode& selfNode=vnode.get_xmlnode();
00253     xmlNode& newChild=as_node(params, 0, "newChild must be node");
00254     xmlNode& refChild=as_node(params, 1, "refChild must be node");
00255
00256     xmlNode* retNode=xmlAddPrevSibling(&refChild, &newChild);
00257     // write out result
00258     writeNode(r, vxdoc, retNode);
00259 }
00260
00261 // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
00262 static void _replaceChild(Request& r, MethodParams& params) {
00263     VXnode& vnode=GET_SELF(r, VXnode);
00264     VXdoc& vxdoc=vnode.get_vxdoc();
00265     xmlDoc& xmldoc=vxdoc.get_xmldoc();
00266     xmlNode& selfNode=vnode.get_xmlnode();
00267     xmlNode& newChild=as_node(params, 0, "newChild must be node");
00268     xmlNode& oldChild=as_node(params, 1, "oldChild must be node");
00269
00270     if(newChild.doc!=&xmldoc)
00271         throw Exception("xml.dom",
00272             0,
00273             "WRONG_DOCUMENT_ERR");
00274     if(oldChild.doc!=&xmldoc)
00275         throw Exception("xml.dom",
00276             0,
00277             "WRONG_DOCUMENT_ERR");
00278
00279     if(oldChild.parent!=&selfNode)
00280         throw Exception("xml.dom",
00281             0,
00282             "NOT_FOUND_ERR");
00283
00284     xmlNode* refChild=oldChild.next;
00285     xmlUnlinkNode(&oldChild);
00286     xmlNode* retNode;
00287     if(refChild)
00288         retNode=xmlAddPrevSibling(refChild, &newChild);
00289     else
00290         retNode=xmlAddChild(&selfNode, &newChild);
00291
00292     // write out result
00293     writeNode(r, vxdoc, retNode);
00294 }
00295
00296 // Node removeChild(in Node oldChild) raises(DOMException);
00297 static void _removeChild(Request& r, MethodParams& params) {
00298     VXnode& vnode=GET_SELF(r, VXnode);
00299     VXdoc& vxdoc=vnode.get_vxdoc();
00300     xmlDoc& xmldoc=vxdoc.get_xmldoc();
00301 //  xmlNode& selfNode=vnode.get_xmlnode();
00302     xmlNode& oldChild=as_node(params, 0, "refChild must be node");
00303
00304     if(oldChild.doc!=&xmldoc)
00305         throw Exception("xml.dom",
00306             0,
00307             "WRONG_DOCUMENT_ERR");
00308
00309     xmlUnlinkNode(&oldChild);
00310     // write out result
00311     writeNode(r, vxdoc, &oldChild);
00312 }
00313
00314 // Node appendChild(in Node newChild) raises(DOMException);
00315 static void _appendChild(Request& r, MethodParams& params) {
00316     VXnode& vnode=GET_SELF(r, VXnode);
00317     VXdoc& vxdoc=vnode.get_vxdoc();
00318     xmlNode& selfNode=vnode.get_xmlnode();
00319     xmlNode& newChild=as_node(params, 0, "newChild must be node");
00320
00321     xmlNode* retNode=xmlAddChild(&selfNode, &newChild);
00322     // write out result
00323     writeNode(r, vxdoc, retNode);
00324 }
00325
00326 // boolean hasChildNodes();
00327 static void _hasChildNodes(Request& r, MethodParams&) {
00328     VXnode& vnode=GET_SELF(r, VXnode);
00329     xmlNode& node=vnode.get_xmlnode();
00330
00331     // write out result
00332     bool result=node.children!=0;
00333     r.write_no_lang(*new VBool(result));
00334 }
00335
00336 // Node cloneNode(in boolean deep);
00337 static void _cloneNode(Request& r, MethodParams& params) {
00338     VXnode& vnode=GET_SELF(r, VXnode);
00339     xmlNode& selfNode=vnode.get_xmlnode();
00340     VXdoc& vxdoc=vnode.get_vxdoc();
00341     xmlDoc& xmldoc=vxdoc.get_xmldoc();
00342
00343     bool deep=params.as_bool(0, "deep must be bool", r);
00344
00345     xmlNode* retNode=xmlDocCopyNode(&selfNode, &xmldoc, deep?1: 0);
00346     // write out result
00347     writeNode(r, vxdoc, retNode);
00348 }
00349
00350 // DOM1 element
00351
00352 xmlNode& get_self_element(VXnode& vnode) {
00353     xmlNode& node=vnode.get_xmlnode();
00354
00355     if(node.type!=XML_ELEMENT_NODE)
00356         throw Exception("parser.runtime",
00357             0,
00358             "method can only be called on nodes of ELEMENT type");
00359
00360     return node;
00361 }
00362
00363
00364 static void _getAttribute(Request& r, MethodParams& params) {
00365     VXnode& vnode=GET_SELF(r, VXnode);
00366     xmlNode& element=get_self_element(vnode);
00367     const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");
00368
00369     // todo: when name="xmlns"
00370     xmlChar* attribute_value=xmlGetProp(&element, name);
00371     // write out result
00372     r.write_pass_lang(r.transcode(attribute_value));
00373 }
00374
00375 // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
00376 static void _setAttribute(Request& r, MethodParams& params) {
00377     VXnode& vnode=GET_SELF(r, VXnode);
00378     xmlNode& element=get_self_element(vnode);
00379     const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");
00380     const xmlChar* attribute_value=as_xmlchar(r, params, 1, "value must be string");
00381
00382     // todo: when name="xmlns"
00383     if(!xmlSetProp(&element, name,  attribute_value))
00384         throw XmlException(0);
00385 }
00386
00387 // void removeAttribute(in DOMString name) raises(DOMException);
00388 static void _removeAttribute(Request& r, MethodParams& params) {
00389     VXnode& vnode=GET_SELF(r, VXnode);
00390     xmlNode& element=get_self_element(vnode);
00391     const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");
00392
00393     // todo: when name="xmlns"
00394     xmlUnsetProp(&element, name);
00395 }
00396
00397 // Attr getAttributeNode(in DOMString name);
00398 static void _getAttributeNode(Request& r, MethodParams& params) {
00399     VXnode& vnode=GET_SELF(r, VXnode);
00400     VXdoc& vxdoc=vnode.get_vxdoc();
00401     xmlNode& element=get_self_element(vnode);
00402     const xmlChar* localName=as_xmlchar(r, params, 0, "name must be string");
00403
00404     if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, 0)){
00405         // write out result
00406         writeNode(r, vxdoc, retNode);
00407     }
00408 }
00409
00410 // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
00411 // Attr setAttributeNodeNS(in Attr newAttr) raises(DOMException);
00412 static void _setAttributeNode(Request& r, MethodParams& params) {
00413     VXnode& vnode=GET_SELF(r, VXnode);
00414     VXdoc& vxdoc=vnode.get_vxdoc();
00415     xmlNode& element=get_self_element(vnode);
00416     xmlDoc& xmldoc=vxdoc.get_xmldoc();
00417     xmlAttr& newAttr=as_attr(params, 0, "newAttr must be ATTRIBUTE node");
00418
00419     if(newAttr.doc!=&xmldoc)
00420         throw Exception("xml.dom",
00421             0,
00422             "WRONG_DOCUMENT_ERR");
00423
00424     if(newAttr.parent)
00425         throw Exception("xml.dom",
00426             0,
00427             "INUSE_ATTRIBUTE_ERR");
00428
00429     if(xmlNode* retNode=pa_getAttributeNodeNS(element, newAttr.name, pa_xmlGetNsURI((xmlNode*)&newAttr))) {
00430         // write out result
00431         writeNode(r, vxdoc, retNode);
00432         xmlUnlinkNode(retNode);
00433     }
00434
00435     pa_addAttributeNode(element, newAttr);
00436 }
00437
00438 // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
00439 static void _removeAttributeNode(Request& r, MethodParams& params) {
00440     VXnode& vnode=GET_SELF(r, VXnode);
00441     VXdoc& vxdoc=vnode.get_vxdoc();
00442     xmlNode& element=get_self_element(vnode);
00443     xmlAttr& oldAttr=as_attr(params, 0, "oldAttr must be ATTRIBUTE node");
00444
00445     if(oldAttr.parent!=&element)
00446         throw Exception("xml.dom",
00447             0,
00448             "NOT_FOUND_ERR");
00449
00450     xmlUnlinkNode((xmlNode*)&oldAttr);
00451
00452     // write out result
00453     writeNode(r, vxdoc, (xmlNode*)&oldAttr);
00454 }
00455
00456 // NodeList getElementsByTagName(in DOMString name);
00457 static void _getElementsByTagName(Request& r, MethodParams& params) {
00458     VXnode& vnode=GET_SELF(r, VXnode);
00459     VXdoc& vxdoc=vnode.get_vxdoc();
00460     xmlNode& xmlnode=vnode.get_xmlnode();
00461
00462     xmlChar* tagName=as_xmlchar(r, params, 0, "name must be string");
00463
00464     VHash& result=*new VHash;
00465     AccumulateFoundInfo info={&result.hash(), &vxdoc, 0};
00466     pa_xmlNamedPreorderTraversal(&xmlnode,
00467                               0,
00468                               tagName,
00469                               AccumulateFound,
00470                               &info);
00471
00472     // write out result
00473     r.write_no_lang(result);
00474 }
00475
00476 // DOM 2
00477
00478 // DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName);
00479 static void _getAttributeNS(Request& r, MethodParams& params) {
00480     VXnode& vnode=GET_SELF(r, VXnode);
00481     xmlNode& element=get_self_element(vnode);
00482
00483     xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00484     xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");
00485
00486     // todo: when name="xmlns"
00487     xmlChar* attribute_value=xmlGetNsProp(&element, localName, namespaceURI);
00488     // write out result
00489     r.write_pass_lang(r.transcode(attribute_value));
00490 }
00491
00492
00493 // void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException);
00494 static void _setAttributeNS(Request& r, MethodParams& params) {
00495     VXnode& vnode=GET_SELF(r, VXnode);
00496     xmlNode& element=get_self_element(vnode);
00497     VXdoc& vxdoc=vnode.get_vxdoc();
00498     xmlDoc& xmldoc=vxdoc.get_xmldoc();
00499     const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00500     const xmlChar* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string");
00501     const xmlChar* attribute_value=as_xmlchar(r, params, 2, "value must be string");
00502
00503     xmlChar* prefix=0;
00504     xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix);
00505
00506     // todo: name=xmlns
00507     xmlAttr* attrNode;
00508     if(localName) {
00509         xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, prefix);
00510
00511         attrNode=xmlSetNsProp(&element, &ns,
00512             localName,
00513             attribute_value);
00514     } else {
00515         attrNode=xmlSetProp(&element,
00516             qualifiedName/*unqualified, actually*/,
00517             attribute_value);
00518     }
00519
00520     if(!attrNode)
00521         throw XmlException(0);
00522 }
00523
00524 // void removeAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
00525 static void _removeAttributeNS(Request& r, MethodParams& params) {
00526     VXnode& vnode=GET_SELF(r, VXnode);
00527     xmlNode& element=get_self_element(vnode);
00528     VXdoc& vxdoc=vnode.get_vxdoc();
00529     xmlDoc& xmldoc=vxdoc.get_xmldoc();
00530     const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00531     const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");
00532
00533     // todo: when name="xmlns"
00534     xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, 0);
00535     xmlUnsetNsProp(&element, &ns, localName);
00536 }
00537
00538 // Attr getAttributeNodeNS(in DOMString namespaceURI, in DOMString localName);
00539 static void _getAttributeNodeNS(Request& r, MethodParams& params) {
00540     VXnode& vnode=GET_SELF(r, VXnode);
00541     VXdoc& vxdoc=vnode.get_vxdoc();
00542     xmlNode& element=get_self_element(vnode);
00543     const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00544     const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");
00545
00546     if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, namespaceURI)){
00547         // write out result
00548         writeNode(r, vxdoc, retNode);
00549     }
00550 }
00551
00552 // boolean hasAttribute(in DOMString name) raises(DOMException);
00553 static void _hasAttribute(Request& r, MethodParams& params) {
00554     VXnode& vnode=GET_SELF(r, VXnode);
00555     xmlNode& element=get_self_element(vnode);
00556
00557     const xmlChar* name=as_xmlchar(r, params, 0, "name must be string");
00558
00559     xmlChar* prop=xmlGetProp(&element, name);
00560     // todo: when name="xmlns"
00561     // write out result
00562     r.write_no_lang(*new VBool(prop!=0));
00563 }
00564
00565 // boolean hasAttributeNS(n DOMString namespaceURI, in DOMString localName) raises(DOMException);
00566 static void _hasAttributeNS(Request& r, MethodParams& params) {
00567     VXnode& vnode=GET_SELF(r, VXnode);
00568     xmlNode& element=get_self_element(vnode);
00569
00570     const xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00571     const xmlChar* localName=as_xmlchar(r, params, 1, "localName must be string");
00572
00573     xmlChar* prop=xmlGetNsProp(&element, localName, namespaceURI);
00574     // write out result
00575     r.write_no_lang(*new VBool(prop!=0));
00576 }
00577
00578 static void _getElementsByTagNameNS(Request& r, MethodParams& params) {
00579     VXnode& vnode=GET_SELF(r, VXnode);
00580     VXdoc& vdoc=vnode.get_vxdoc();
00581     xmlDoc& xmldoc=vdoc.get_xmldoc();
00582
00583     // namespaceURI;localName
00584     xmlChar* namespaceURI=as_xmlchar(r, params, 0, "namespaceURI must be string");
00585     xmlChar* localName=as_xmlchar(r, params, 1, "name must be string");
00586
00587     VHash& result=*new VHash;
00588     AccumulateFoundInfo info={&result.hash(), &vdoc, 0};
00589     pa_xmlNamedPreorderTraversal((xmlNode*)&xmldoc,
00590                               namespaceURI,
00591                               localName,
00592                               AccumulateFound,
00593                               &info);
00594
00595     // write out result
00596     r.write_no_lang(result);
00597 }
00598
00599
00600 // void normalize();
00601 static void _normalize(Request&, MethodParams&) {
00602 /*maybe someday
00603     VXnode& vnode=GET_SELF(r, VXnode);
00604     xmlNode& selfNode=vnode.get_xmlnode();
00605
00606     gdome_n_normalize(selfNode, &exc);
00607     if(exc)
00608         throw XmlException(0, exc);
00609 */
00610 }
00611
00612 #ifndef DOXYGEN
00613 struct Register_one_ns_info {
00614     Request* r;
00615     xmlXPathContextPtr ctxt;
00616 };
00617 #endif
00618 static void register_one_ns(
00619                                   HashStringValue::key_type key,
00620                                   HashStringValue::value_type value,
00621                                   Register_one_ns_info* info) {
00622     if(const String* svalue=value->get_string())
00623         xmlXPathRegisterNs(info->ctxt,
00624             info->r->transcode(key),
00625             info->r->transcode(*svalue));
00626     else
00627         throw Exception("parser.runtime",
00628             new String(key, String::L_TAINTED),
00629             "value is %s, must be string or number", value->type());
00630 }
00631 static void _selectX(Request& r, MethodParams& params,
00632                      void (*handler)(Request& r,
00633                               const String& expression,
00634                               xmlXPathObject_auto_ptr res,
00635                               VXdoc& xdoc,
00636                               Value*& result))
00637 {
00638     VXnode& vnode=GET_SELF(r, VXnode);
00639     xmlNode& xmlnode=vnode.get_xmlnode();
00640     VXdoc& vdoc=vnode.get_vxdoc();
00641     xmlDoc& xmldoc=vdoc.get_xmldoc();
00642
00643     // expression
00644     const String& expression=params.as_string(0, "expression must be string");
00645     xmlXPathContext_auto_ptr ctxt(xmlXPathNewContext(&xmldoc));
00646     {
00647         Register_one_ns_info info={&r, ctxt.get()};
00648         vdoc.search_namespaces.hash().for_each(register_one_ns, &info);
00649     }
00650     ctxt->node=&xmlnode;
00651     /*error to stderr for now*/
00652     xmlXPathObject_auto_ptr res(
00653         xmlXPathEvalExpression(r.transcode(expression), ctxt.get()));
00654
00655     if(xmlHaveGenericErrors())
00656         throw XmlException(0);
00657
00658     Value* result=0;
00659     if(res.get())
00660         handler(r, expression, res, vdoc, result);
00661     if(result)
00662         r.write_no_lang(*result);
00663 }
00664
00665 static void selectNodesHandler(Request&,
00666                    const String& expression,
00667                    xmlXPathObject_auto_ptr res,
00668                    VXdoc& xdoc,
00669                    Value*& result) {
00670     VHash& vhash=*new VHash;  result=&vhash;
00671     switch(res->type) {
00672     case XPATH_UNDEFINED:
00673         break;
00674     case XPATH_NODESET:
00675         if(res->nodesetval)
00676             if(int size=res->nodesetval->nodeNr) {
00677                 HashStringValue& hash=vhash.hash();
00678                 for(int i=0; i<size; i++)
00679                     hash.put(
00680                         String::Body::Format(i),
00681                         &xdoc.wrap(*res->nodesetval->nodeTab[i]));
00682             }
00683         break;
00684     default:
00685         throw Exception("parser.runtime",
00686             &expression,
00687             "wrong xmlXPathEvalExpression result type (%d)", res->type);
00688         break; // never
00689     }
00690 }
00691
00692 static void selectNodeHandler(Request& r,
00693                   const String& expression,
00694                   xmlXPathObject_auto_ptr res,
00695                   VXdoc& xdoc,
00696                   Value*& result) {
00697     switch(res->type) {
00698     case XPATH_UNDEFINED:
00699         break;
00700     case XPATH_NODESET:
00701         if(res->nodesetval && res->nodesetval->nodeNr) { // empty result strangly has NODESET  res->type
00702             if(res->nodesetval->nodeNr>1)
00703                 throw Exception("parser.runtime",
00704                     &expression,
00705                     "resulted not in a single node (%d)", res->nodesetval->nodeNr);
00706
00707             result=&xdoc.wrap(*res->nodesetval->nodeTab[0]);
00708         }
00709         break;
00710     case XPATH_BOOLEAN:
00711         result=new VBool(res->boolval!=0);
00712         break;
00713     case XPATH_NUMBER:
00714         result=new VDouble(res->floatval);
00715         break;
00716     case XPATH_STRING:
00717         result=new VString(r.transcode((xmlChar*)res->stringval));
00718         break;
00719     default:
00720         throw Exception("parser.runtime",
00721             &expression,
00722             "wrong xmlXPathEvalExpression result type (%d)", res->type);
00723     }
00724 }
00725
00726 static void selectBoolHandler(Request&,
00727                   const String& expression,
00728                   xmlXPathObject_auto_ptr res,
00729                   VXdoc& /*xdoc*/,
00730                   Value*& result) {
00731     switch(res->type) {
00732     case XPATH_BOOLEAN:
00733         result=new VBool(res->boolval!=0);
00734         break;
00735     case XPATH_NODESET:
00736         if(!(res->nodesetval && res->nodesetval->nodeNr))
00737             break;
00738         // else[nodeset] fall down to default
00739     default:
00740         throw Exception("parser.runtime",
00741             &expression,
00742             "wrong xmlXPathEvalExpression result type (%d)", res->type);
00743         break; // never
00744     }
00745 }
00746
00747 static void selectNumberHandler(Request&,
00748                 const String& expression,
00749                 xmlXPathObject_auto_ptr res,
00750                 VXdoc& /*xdoc*/,
00751                 Value*& result) {
00752     switch(res->type) {
00753     case XPATH_NUMBER:
00754         result=new VDouble(res->floatval);
00755         break;
00756     case XPATH_NODESET:
00757         if(!(res->nodesetval && res->nodesetval->nodeNr))
00758             break;
00759         // else[nodeset] fall down to default
00760     default:
00761         throw Exception("parser.runtime",
00762             &expression,
00763             "wrong xmlXPathEvalExpression result type (%d)", res->type);
00764         break; // never
00765     }
00766 }
00767
00768 static void selectStringHandler(Request& r,
00769                               const String& expression,
00770                               xmlXPathObject_auto_ptr res,
00771                               VXdoc& /*xdoc*/,
00772                               Value*& result) {
00773     switch(res->type) {
00774     case XPATH_UNDEFINED:
00775         break;
00776     case XPATH_STRING:
00777         result=new VString(r.transcode((xmlChar*)res->stringval));
00778         break;
00779     case XPATH_NODESET:
00780         if(!(res->nodesetval && res->nodesetval->nodeNr))
00781             break;
00782         // else[nodeset] fall down to default
00783     default:
00784         throw Exception("parser.runtime",
00785             &expression,
00786             "wrong xmlXPathEvalExpression result type (%d)", res->type);
00787         break; // never
00788     }
00789 }
00790
00791 static void _select(Request& r, MethodParams& params) {
00792     _selectX(r, params,
00793         selectNodesHandler);
00794 }
00795
00796 static void _selectSingle(Request& r, MethodParams& params) {
00797     _selectX(r, params,
00798         selectNodeHandler);
00799 }
00800
00801 static void _selectBool(Request& r, MethodParams& params) {
00802     _selectX(r, params,
00803         selectBoolHandler);
00804 }
00805
00806 static void _selectNumber(Request& r, MethodParams& params) {
00807     _selectX(r, params,
00808         selectNumberHandler);
00809 }
00810
00811 static void _selectString(Request& r, MethodParams& params) {
00812     _selectX(r, params,
00813         selectStringHandler);
00814 }
00815
00816 // constructor
00817
00819 MXnode::MXnode(const char* aname, VStateless_class *abase):
00820     Methoded(aname?aname:"xnode", abase)
00821 {
00823
00824     // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
00825     add_native_method("insertBefore", Method::CT_DYNAMIC, _insertBefore, 2, 2);
00826     // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
00827     add_native_method("replaceChild", Method::CT_DYNAMIC, _replaceChild, 2, 2);
00828     // Node removeChild(in Node oldChild) raises(DOMException);
00829     add_native_method("removeChild", Method::CT_DYNAMIC, _removeChild, 1, 1);
00830     // Node appendChild(in Node newChild) raises(DOMException);
00831     add_native_method("appendChild", Method::CT_DYNAMIC, _appendChild, 1, 1);
00832     // boolean hasChildNodes();
00833     add_native_method("hasChildNodes", Method::CT_DYNAMIC, _hasChildNodes, 0, 0);
00834     // Node cloneNode(in boolean deep);
00835     add_native_method("cloneNode", Method::CT_DYNAMIC, _cloneNode, 1, 1);
00836
00838
00839     // DOMString getAttribute(in DOMString name);
00840     add_native_method("getAttribute", Method::CT_DYNAMIC, _getAttribute, 1, 1);
00841     // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
00842     add_native_method("setAttribute", Method::CT_DYNAMIC, _setAttribute, 2, 2);
00843     // void removeAttribute(in DOMString name) raises(DOMException);
00844     add_native_method("removeAttribute", Method::CT_DYNAMIC, _removeAttribute, 1, 1);
00845     // Attr getAttributeNode(in DOMString name);
00846     add_native_method("getAttributeNode", Method::CT_DYNAMIC, _getAttributeNode, 1, 1);
00847     // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
00848     add_native_method("setAttributeNode", Method::CT_DYNAMIC, _setAttributeNode, 1, 1);
00849     // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
00850     add_native_method("removeAttributeNode", Method::CT_DYNAMIC, _removeAttributeNode, 1, 1);
00851     // NodeList getElementsByTagName(in DOMString name);
00852     add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1);
00853     // NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName);
00854     add_native_method("getElementsByTagNameNS", Method::CT_DYNAMIC, _getElementsByTagNameNS, 2, 2);
00855     // void normalize();
00856     add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0);
00857
00859
00860     // DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName);
00861     add_native_method("getAttributeNS", Method::CT_DYNAMIC, _getAttributeNS, 2, 2);
00862     // void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException);
00863     add_native_method("setAttributeNS", Method::CT_DYNAMIC, _setAttributeNS, 3, 3);
00864     // void removeAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
00865     add_native_method("removeAttributeNS", Method::CT_DYNAMIC, _removeAttributeNS, 2, 2);
00866     // Attr getAttributeNodeNS(in DOMString namespaceURI, in DOMString localName);
00867     add_native_method("getAttributeNodeNS", Method::CT_DYNAMIC, _getAttributeNodeNS, 2, 2);
00868     // Attr setAttributeNodeNS(in Attr newAttr) raises(DOMException);
00869     add_native_method("setAttributeNodeNS", Method::CT_DYNAMIC, _setAttributeNode, 1, 1);
00870     // boolean hasAttribute(in DOMString name) raises(DOMException);
00871     add_native_method("hasAttribute", Method::CT_DYNAMIC, _hasAttribute, 1, 1);
00872     // boolean hasAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
00873     add_native_method("hasAttributeNS", Method::CT_DYNAMIC, _hasAttributeNS, 2, 2);
00874
00876     // ^node.select[/some/xpath/query] = hash $.#[dnode]
00877     add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1);
00878
00879     // ^node.selectSingle[/some/xpath/query] = first node [if any]
00880     add_native_method("selectSingle", Method::CT_DYNAMIC, _selectSingle, 1, 1);
00881     // ^node.selectBool[/some/xpath/query] = bool value [if any]
00882     add_native_method("selectBool", Method::CT_DYNAMIC, _selectBool, 1, 1);
00883     // ^node.selectNumber[/some/xpath/query] = double value [if any]
00884     add_native_method("selectNumber", Method::CT_DYNAMIC, _selectNumber, 1, 1);
00885     // ^node.selectString[/some/xpath/query] = strinv value [if any]
00886     add_native_method("selectString", Method::CT_DYNAMIC, _selectString, 1, 1);
00887
00888     // consts
00889
00890 #define CONST(name) \
00891     consts.put(String::Body(#name), new VInt(XML_##name))
00892 #define CONST2(name, value) \
00893     consts.put(String::Body(#name), new VInt(value))
00894
00895     CONST(ELEMENT_NODE);
00896     CONST(ATTRIBUTE_NODE);
00897     CONST(TEXT_NODE);
00898     CONST(CDATA_SECTION_NODE);
00899     CONST2(ENTITY_REFERENCE_NODE, XML_ENTITY_REF_NODE);
00900     CONST(ENTITY_NODE);
00901     CONST2(PROCESSING_INSTRUCTION_NODE, XML_PI_NODE);
00902     CONST(COMMENT_NODE);
00903     CONST(DOCUMENT_NODE);
00904     CONST(DOCUMENT_TYPE_NODE);
00905     CONST2(DOCUMENT_FRAGMENT_NODE, XML_DOCUMENT_FRAG_NODE);
00906     CONST(NOTATION_NODE);
00907 }
00908
00909 #else
00910
00911 // global variable
00912
00913 DECLARE_CLASS_VAR(xnode, 0, 0); // fictive
00914
00915 #endif


xnode.h File Reference

Parser: dnode methods class - MDnode class decl. More...

Go to the source code of this file.

Compounds

class | MXnode

Functions

xmlNode & | as_node (MethodParams &params, int index, const char *msg)
xmlChar * | as_xmlchar (Request &r, MethodParams &params, int index, const char *msg)
xmlNs & | pa_xmlMapNs (xmlDoc &doc, const xmlChar *href, const xmlChar *prefix)

Variables

const char *const | IDENT_XNODE_H = "$Date: 2005/12/16 10:15:12 $"

Detailed Description

Parser: dnode methods class - MDnode class decl.

Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)

Definition in file xnode.h.

Function Documentation

xmlNode& as_node | ( | MethodParams & | params,
 |  | int | index,
 |  | const char * | msg
 | ) |

xmlChar* as_xmlchar | ( | Request & | r,
 |  | MethodParams & | params,
 |  | int | index,
 |  | const char * | msg
 | ) |

xmlNs& pa_xmlMapNs | ( | xmlDoc & | doc,
 |  | const xmlChar * | href,
 |  | const xmlChar * | prefix
 | ) |

Variable Documentation

const char* const IDENT_XNODE_H = "$Date: 2005/12/16 10:15:12 $" [static]

Definition at line 11 of file xnode.h.


xnode.h Source File

xnode.h

Go to the documentation of this file.
00001
00008 #ifndef XNODE_H
00009 #define XNODE_H
00010
00011 static const char * const IDENT_XNODE_H="$Date: 2005/12/16 10:15:12 $";
00012
00013 class MXnode: public Methoded {
00014 public: // Value
00015
00017     Value* get_element(const String& aname, Value& aself, bool looking_up) {
00018         // $method
00019         if(Value* result=Methoded::get_element(aname, aself, looking_up))
00020             return result;
00021
00022         // $const
00023         if(Value* result=consts.get(aname))
00024             return result;
00025
00026         return 0;
00027     }
00028
00029
00030 public: // VStateless_class
00031     Value* create_new_value(Pool&, HashStringValue&) {
00032         throw Exception("parser.runtime",
00033             0,
00034             "no constructors available, use CreateXXX DOM methods to create nodes instead");
00035     }
00036
00037 public:
00038     MXnode(const char* aname=0, VStateless_class* abase=0);
00039
00040 public: // Methoded
00041     bool used_directly() { return true; }
00042
00043 private:
00044
00045     HashStringValue consts;
00046 };
00047
00048 xmlNode& as_node(MethodParams& params, int index, const char* msg);
00049 xmlChar* as_xmlchar(Request& r, MethodParams& params, int index, const char* msg);
00050 xmlNs& pa_xmlMapNs(xmlDoc& doc, const xmlChar* href, const xmlChar* prefix);
00051
00052 #endif


Annotated Index

Parser3 Source Code Compound List

Here are the classes, structs, unions and interfaces with brief descriptions:
_IO_COUNTERS_
apr_file_t
apr_finfo_t
apr_sdbm_datum_t | Structure for referencing the datum record within an sdbm
apr_sdbm_t
Array< T > | Simple Array
Array< T >::Action_options
Array_iterator< T > Array iterator, usage:
AutoSYNCHRONIZED | Helper to ensure paired Mutex::acquire() and Mutex::release()
cache_line
Cache_manager | Can return status and can expire it contents
Cache_managers | Maintains name=>Cache_manager association, can expire its contents
Charset | Charset holds name & transcode tables registers libxml transcoders
Charset::Tables
Charset::Tables::Rec
Charset::UTF8CaseTable
Charset::UTF8CaseTable::Rec
Charsets | Convention: use UPPERCASE keys
chr_data
compile_data
CORD_ec_struct
CORD_fill_data
CORD_pe
CORD_Pos
CordRep
CordRep::Concatenation
CordRep::Function
CordRep::Generic
Date_calendar_table_template_columns
Dictionary | Simple dictionary, speding up lookups on contained two columned table
Dictionary::Subst
dirent
Exception
EXIF_tag_value2name | Value of exif tag -> it's value
ffblk | Win32/unix unified directory entry structure name for findfirst/next/close interface
File_read_result
Font | Simple gdImage-based font storage & text output
ForestElement
FT
gdBuf
gdGifEncoder | Used by gdImage::Gif to produce buffer with bytes in GIF format
gdGrowingBuf
gdImage | Image type
gdImage::Point | Point type for use in polygon drawing
GIF_Header | GIF file header
Hash< K, V > | Simple hash
Hash< K, V >::Pair | Pair storage
Hashfile_value_serialized_prolog
JPG_Exif_IFD_begin
JPG_Exif_IFD_entry
JPG_Exif_segment_begin | JPEG frame header
JPG_Exif_TIFF_header | JPEG Exif TIFF Header
JPG_Segment_head | JPEG record head
JPG_Size_segment_body | JPEG frame header
Junction | junction is some code joined with context of it's evaluation
lf_state
lsplit_result
lt_dlhandle_struct
lt_dlinfo
lt_dlloader
lt_dlsymlist
lt_dlsymlists_t
lt_user_dlloader
match_data
MDate
MDouble
Method | Class method
Methoded | Pure virtual base for configurable Methoded descendants
Methoded_array | All Methoded registered here in autogenerated classes.C
MethodParams | method parameters passed in this array
MFile
MForm
MHash
MHashfile
MImage
MInt
MMail
MMath
MMemory
MResponse
MString
MTable
Mutex | Simple semaphore object
MVoid
MXnode
Operation | Parser source code got compiled into intermediate form of Operation-s, which are executed afterwards
Operation::Origin
PA_Allocated | Memory allocation/dallocation goes via pa_malloc/pa_free
PA_Cleaned | Those who want their destructor called during finalization, must derive from this class [also]
PA_exec_result
PA_MD5_CTX
pa_request_rec_tag
Parse_control | Compiler status
Parser_module_config_tag | Apache parser module configuration [httpd.conf + .htaccess-es]
PNG_Header | PNG file header
Pool | Pool mechanizm allows users not to free up allocated objects, leaving that problem to 'pools'
Pool::Cleanup
Pooled | Base for all classes that are allocated in 'pools'
Pos
Property | junction is getter and setter methods
Random_provider
real_pcre
real_pcre_extra
refill_data
Request | Main workhorse
Request::Exception_details
Request::Exception_trace
Request::Execute_nonvirtual_method_result
Request::StackItem
Request::Trace
Request_charsets
Request_context_saver | Auto-object used to save request context across ^try body
Request_info | Some information from web server
SAPI | Target web-Server API
SAPI_Info | SAPI func decl
SMTP | SIMPLE MAIL TRANSPORT PROTOCOL Win32 realization
SQL_Connection | SQL connection. handy wrapper around low level SQL_Driver
SQL_Driver | SQL driver API
SQL_Driver::Placeholder | To pass IN and OUT int/double NOT in string format
SQL_Driver_manager | Sql driver manager
SQL_Driver_query_event_handlers | Events, occuring when SQL_Driver::query()-ing
SQL_Driver_services | Service functions for SQL driver to use
SQL_Driver_services_impl | SQL_Driver_services Pooled implementation
SQL_Error | Fields are freed elsewhere
Stack< T > | Simple stack based on Array
String | String which knows the lang of all it's langs
String::Body
String::C
String::Cm
String::Languages
String_match_table_template_columns
StringOrValue
Stylesheet_connection | Connection with stylesheet: remembers time and can figure out that it needs recompilation
Stylesheet_connection_ptr | Auto-object used to track Stylesheet_connection usage
Stylesheet_manager | XSLT stylesheet driver manager maintains stylesheet cache expiring unused stylesheets
substr_args
Table | VTable backend
TableSeparators
Temp_client_charset
Temp_connection | Auto-object used for temporary changing Request::fconnection
Temp_derived
Temp_hash_value< K, V > | Auto-object used to temporarily substituting/removing hash values
Temp_lang | Auto-object used for temporary changing Request::flang
Temp_method | Auto-object used for temporarily substituting/removing class method
Temp_method_frame_self | Auto-object used for temporary changing VMethod_frame::fself
Temp_value_element | Auto-object used for temporarily substituting/removing elements
Untaint_lang_name2enum
uuid | To hell with extra bytes on 64bit platforms
Value | Grandfather of all values in Parser
VBool | VBool
VClass | Stores - static fields: VClass::ffields
VClass::Prevent_info
VClassMAIN
VCodeFrame | Specialized write wrapper, completely transparent, but intercepting string writes
VConsole | Console class
VCookie | Cookie class
VDate | Value of type 'date'. implemented with time_t
VDouble | Value of type 'double'. implemented with double
VEnv | Env class
VFile | Holds received from user or read from disk file
VForm | Derivates from VStateless_class so that :CLASS element referred to this
VHash | Value of type 'hash', implemented with Hash
VHash_lock
VHashfile | Value of type 'hashfile', implemented with SDBM library bundled in ../libs/sdbm
VImage | Holds img attributes and [image itself]
VInt | Value of type 'int'. implemented with int
VJunction | Junction is method+self+context, implemented with Junction
VMail | $mail:received letter
VMath
VMemory
VMethodFrame | Method frame write context accepts values written by method code also handles method parameters and local variables
VObject | Parser class instance, stores - class VObject::fclass; - fields VObject::ffields (dynamic, not static, which are stored in class)
VObject::Prevent_append_if_exists_in_static_or_base_info
VProperty | Property two methods
VRequest | Request class
VResponse | Value of type 'response'
VStateless_class | Object' class
VStateless_object | The object of some class
VStatus | Status class
VString | Value of type 'string'. implemented with String
VTable | Value of type 'table'. implemented with Table
VVoid | Value of type 'void'. ex: usually $sjfklsjfksjdfk has this type
VXdoc | Value of type 'xdoc'. implemented with libxml & co
VXdoc::Output_options
VXnode | Value of type 'xnode'. implemented with xmlNode
WContext | Write context they do different write()s here, later picking up the result
WWrapper | Specialized write context, adds to WContext VHash autocreation ability


_IO_COUNTERS_ Struct Reference

List of all members.

Public Attributes

ULONGLONG | ReadOperationCount
ULONGLONG | WriteOperationCount
ULONGLONG | OtherOperationCount
ULONGLONG | ReadTransferCount
ULONGLONG | WriteTransferCount
ULONGLONG | OtherTransferCount

Member Data Documentation

ULONGLONG _IO_COUNTERS_::ReadOperationCount

Definition at line 29 of file pa_vstatus.C.

Referenced by rusage_element().

ULONGLONG _IO_COUNTERS_::WriteOperationCount

Definition at line 30 of file pa_vstatus.C.

Referenced by rusage_element().

ULONGLONG _IO_COUNTERS_::OtherOperationCount

Definition at line 31 of file pa_vstatus.C.

Referenced by rusage_element().

ULONGLONG _IO_COUNTERS_::ReadTransferCount

Definition at line 32 of file pa_vstatus.C.

Referenced by rusage_element().

ULONGLONG _IO_COUNTERS_::WriteTransferCount

Definition at line 33 of file pa_vstatus.C.

Referenced by rusage_element().

ULONGLONG _IO_COUNTERS_::OtherTransferCount

Definition at line 34 of file pa_vstatus.C.

Referenced by rusage_element().

The documentation for this struct was generated from the following file:
  • pa_vstatus.C


Member List

_IO_COUNTERS_ Member List

This is the complete list of members for _IO_COUNTERS_, including all inherited members.
OtherOperationCount | _IO_COUNTERS_
OtherTransferCount | _IO_COUNTERS_
ReadOperationCount | _IO_COUNTERS_
ReadTransferCount | _IO_COUNTERS_
WriteOperationCount | _IO_COUNTERS_
WriteTransferCount | _IO_COUNTERS_


apr_file_t Struct Reference

List of all members.

Public Attributes

int handle

Member Data Documentation

int apr_file_t::handle

Definition at line 16 of file apr_file_io.C.

The documentation for this struct was generated from the following file:
  • apr_file_io.C


Member List

apr_file_t Member List

This is the complete list of members for apr_file_t, including all inherited members.
handle apr_file_t


apr_finfo_t Struct Reference
[Stat Functions]

List of all members.

Public Attributes

apr_off_t size
The size of the file. More...

Member Data Documentation

apr_off_t apr_finfo_t::size

The size of the file.

Definition at line 138 of file apr_file_info.h.

The documentation for this struct was generated from the following file:
  • apr_file_info.h


Member List

apr_finfo_t Member List

This is the complete list of members for apr_finfo_t, including all inherited members.
size apr_finfo_t


apr_sdbm_datum_t Struct Reference
[SDBM library]

Structure for referencing the datum record within an sdbm. More...

List of all members.

Public Attributes

char * | dptr
pointer to the data stored/retrieved. More...

int | dsize
size of data. More...

Detailed Description

Structure for referencing the datum record within an sdbm.

Definition at line 92 of file apr_sdbm.h.

Member Data Documentation

char* apr_sdbm_datum_t::dptr

pointer to the data stored/retrieved.

Definition at line 94 of file apr_sdbm.h.

Referenced by VHashfile::deserialize_value(), VHashfile::for_each(), for_each_string_callback(), VHashfile::get_field(), VHashfile::put_field(), VHashfile::remove(), and VHashfile::serialize_value().

int apr_sdbm_datum_t::dsize

size of data.

Definition at line 96 of file apr_sdbm.h.

Referenced by VHashfile::deserialize_value(), VHashfile::for_each(), for_each_string_callback(), VHashfile::get_field(), VHashfile::put_field(), VHashfile::remove(), and VHashfile::serialize_value().

The documentation for this struct was generated from the following file:
  • apr_sdbm.h


Member List

apr_sdbm_datum_t Member List

This is the complete list of members for apr_sdbm_datum_t, including all inherited members.
dptr | apr_sdbm_datum_t
dsize | apr_sdbm_datum_t


apr_sdbm_t Struct Reference

Collaboration diagram for apr_sdbm_t:

[legend]
List of all members.

Public Attributes

apr_pool_t * pool
apr_file_t * dirf
apr_file_t * pagf
apr_int32_t flags
long | maxbno
long | curbit
long | hmask
long | blkptr
int | keyptr
long | blkno
long | pagbno
char | pagbuf [PBLKSIZ]
long | dirbno
char | dirbuf [DBLKSIZ]
int | lckcnt

Member Data Documentation

apr_pool_t* apr_sdbm_t::pool

Definition at line 88 of file sdbm_private.h.

Referenced by prep().

apr_file_t* apr_sdbm_t::dirf

Definition at line 89 of file sdbm_private.h.

Referenced by database_cleanup(), and prep().

apr_file_t* apr_sdbm_t::pagf

Definition at line 90 of file sdbm_private.h.

Referenced by database_cleanup(), and prep().

apr_int32_t apr_sdbm_t::flags

Definition at line 91 of file sdbm_private.h.

Referenced by database_cleanup(), and prep().

long apr_sdbm_t::maxbno

Definition at line 92 of file sdbm_private.h.

long apr_sdbm_t::curbit

Definition at line 93 of file sdbm_private.h.

long apr_sdbm_t::hmask

Definition at line 94 of file sdbm_private.h.

long apr_sdbm_t::blkptr

Definition at line 95 of file sdbm_private.h.

int apr_sdbm_t::keyptr

Definition at line 96 of file sdbm_private.h.

long apr_sdbm_t::blkno

Definition at line 97 of file sdbm_private.h.

long apr_sdbm_t::pagbno

Definition at line 98 of file sdbm_private.h.

char apr_sdbm_t::pagbuf[PBLKSIZ]

Definition at line 99 of file sdbm_private.h.

long apr_sdbm_t::dirbno

Definition at line 100 of file sdbm_private.h.

char apr_sdbm_t::dirbuf[DBLKSIZ]

Definition at line 101 of file sdbm_private.h.

int apr_sdbm_t::lckcnt

Definition at line 102 of file sdbm_private.h.

The documentation for this struct was generated from the following file:
  • sdbm_private.h


Member List

apr_sdbm_t Member List

This is the complete list of members for apr_sdbm_t, including all inherited members.
blkno | apr_sdbm_t
blkptr | apr_sdbm_t
curbit | apr_sdbm_t
dirbno | apr_sdbm_t
dirbuf | apr_sdbm_t
dirf | apr_sdbm_t
flags | apr_sdbm_t
hmask | apr_sdbm_t
keyptr | apr_sdbm_t
lckcnt | apr_sdbm_t
maxbno | apr_sdbm_t
pagbno | apr_sdbm_t
pagbuf | apr_sdbm_t
pagf | apr_sdbm_t
pool | apr_sdbm_t


TemplateArray class Reference

Array< T > Class Template Reference

Simple Array. More...

Inheritance diagram for Array:

[legend]
Collaboration diagram for Array< T >:

[legend]
List of all members.

Public Types

typedef T | element_type

Public Methods

Array (size_t initial=3)
size_t | count () const
how many items are in Array. More...

Array & | operator+= (T src)
append to array. More...

Array & | append (const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false)
append other Array portion to this one. starting from offset. More...

T | get (size_t index) const
get index-element. More...

T & | get_ref (size_t index) const
ref version of get. More...

void | put (size_t index, T element)
put index-element. More...

T | operator[] (size_t index) const
template<typename I> void | for_each (void(*callback)(T, I), I info) const
iterate over all elements. More...

template<typename I> void | for_each_ref (void(*callback)(T &, I), I info)
iterate over all elements. More...

template<typename I> T | first_that (bool(*callback)(T, I), I info) const
iterate over all elements until condition becomes true, return that element. More...

Protected Methods

bool | is_full ()
void | expand (size_t delta)

Protected Attributes

T * | felements
elements[growing size] here. More...

size_t | fallocated
size_t | fused

Private Methods

Array (const Array &)
Array & | operator= (const Array &)

Friends

class | Array_iterator< T >

Detailed Description

template<typename T>
class Array< T >

Simple Array.

Definition at line 27 of file pa_array.h.

Member Typedef Documentation

template<typename T>
typedef T Array< T >::element_type

Definition at line 78 of file pa_array.h.

Constructor & Destructor Documentation

template<typename T>
Array< T >::Array ( size_t initial = 3 ) [inline]

Definition at line 80 of file pa_array.h.

template<typename T>
Array< T >::Array ( const Array< T > & ) [inline, private]

Definition at line 198 of file pa_array.h.

Member Function Documentation

template<typename T>
size_t Array< T >::count ( ) const [inline]

how many items are in Array.

Definition at line 88 of file pa_array.h.

Referenced by Array< Operation >::append(), Array_iterator< T >::Array_iterator(), Array< Operation >::get(), Array< Operation >::get_ref(), output_pieces(), Stack< StackItem >::push(), and Array< Operation >::put().

template<typename T>
Array& Array< T >::operator+= ( T src ) [inline]

append to array.

Definition at line 90 of file pa_array.h.

template<typename T>
Array& Array< T >::append | ( | const Array< T > & | src,
 |  | size_t | offset = 0,
 |  | size_t | limit = ARRAY_OPTION_LIMIT_ALL,
 |  | bool | reverse = false
 | ) | [inline]

append other Array portion to this one. starting from offset.

Definition at line 100 of file pa_array.h.

template<typename T>
T Array< T >::get ( size_t index ) const [inline]

get index-element.

Definition at line 141 of file pa_array.h.

Referenced by Array< Operation >::operator[](), Stack< StackItem >::pop(), and Stack< StackItem >::top_value().

template<typename T>
T& Array< T >::get_ref ( size_t index ) const [inline]

ref version of get.

Definition at line 147 of file pa_array.h.

Referenced by output_pieces().

template<typename T>
void Array< T >::put | ( | size_t | index,
 |  | T | element
 | ) | [inline]

put index-element.

Definition at line 153 of file pa_array.h.

Referenced by Stack< StackItem >::push().

template<typename T>
T Array< T >::operator[] ( size_t index ) const [inline]

Definition at line 158 of file pa_array.h.

template<typename T>
template<typename I>
void Array< T >::for_each | ( | void(* | callback)(T, I),
 |  | I | info
 | ) | const [inline]

iterate over all elements.

Definition at line 161 of file pa_array.h.

Referenced by VHashfile::for_each().

template<typename T>
template<typename I>
void Array< T >::for_each_ref | ( | void(* | callback)(T &, I),
 |  | I | info
 | ) | [inline]

iterate over all elements.

Definition at line 168 of file pa_array.h.

template<typename T>
template<typename I>
T Array< T >::first_that | ( | bool(* | callback)(T, I),
 |  | I | info
 | ) | const [inline]

iterate over all elements until condition becomes true, return that element.

Definition at line 175 of file pa_array.h.

template<typename T>
bool Array< T >::is_full ( ) [inline, protected]

Definition at line 186 of file pa_array.h.

Referenced by Array< Operation >::operator+=().

template<typename T>
void Array< T >::expand ( size_t delta ) [inline, protected]

Definition at line 189 of file pa_array.h.

Referenced by Array< Operation >::append(), and Array< Operation >::operator+=().

template<typename T>
Array& Array< T >::operator= ( const Array< T > & ) [inline, private]

Definition at line 199 of file pa_array.h.

Friends And Related Function Documentation

template<typename T>
friend class Array_iterator< T > [friend]

Definition at line 29 of file pa_array.h.

Member Data Documentation

template<typename T>
T* Array< T >::felements [protected]

elements[growing size] here.

Definition at line 34 of file pa_array.h.

Referenced by Array< Operation >::append(), Array< Operation >::Array(), Array_iterator< T >::Array_iterator(), Array< Operation >::expand(), Array< Operation >::first_that(), Array< Operation >::for_each(), Array< Operation >::for_each_ref(), Array< Operation >::get(), Array< Operation >::get_ref(), Array< Operation >::operator+=(), and Array< Operation >::put().

template<typename T>
size_t Array< T >::fallocated [protected]

Definition at line 37 of file pa_array.h.

Referenced by Array< Operation >::append(), Array< Operation >::Array(), Array< Operation >::expand(), and Array< Operation >::is_full().

template<typename T>
size_t Array< T >::fused [protected]

Definition at line 40 of file pa_array.h.

Referenced by Array< Operation >::append(), Array< Operation >::Array(), Array< Operation >::count(), Array< Operation >::first_that(), Array< Operation >::for_each(), Array< Operation >::for_each_ref(), Array< Operation >::is_full(), Array< Operation >::operator+=(), and Stack< StackItem >::wipe_unused().

The documentation for this class was generated from the following file:
  • pa_array.h


Member List

Array< T > Member List

This is the complete list of members for Array< T >, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< T > | [inline]
Array(size_t initial=3) | Array< T > | [inline]
Array(const Array &) | Array< T > | [inline, private]
Array_iterator< T > class | Array< T > | [friend]
count() const | Array< T > | [inline]
element_type typedef | Array< T > |
expand(size_t delta) | Array< T > | [inline, protected]
fallocated | Array< T > | [protected]
felements | Array< T > | [protected]
first_that(bool(*callback)(T, I), I info) const | Array< T > | [inline]
for_each(void(*callback)(T, I), I info) const | Array< T > | [inline]
for_each_ref(void(*callback)(T &, I), I info) | Array< T > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fused | Array< T > | [protected]
get(size_t index) const | Array< T > | [inline]
get_ref(size_t index) const | Array< T > | [inline]
is_full() | Array< T > | [inline, protected]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(T src) | Array< T > | [inline]
operator=(const Array &) | Array< T > | [inline, private]
operator[](size_t index) const | Array< T > | [inline]
put(size_t index, T element) | Array< T > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


TemplateArray::Action_options struct Reference

Array< T >::Action_options Struct Template Reference

List of all members.

Public Methods

Action_options (size_t aoffset=0, size_t alimit=ARRAY_OPTION_LIMIT_ALL, bool areverse=false)
bool | adjust (size_t count)

Public Attributes

size_t | offset
size_t | limit
bool | reverse
bool | defined

template<typename T>
struct Array< T >::Action_options

Constructor & Destructor Documentation

template<typename T>
Array< T >::Action_options::Action_options | ( | size_t | aoffset = 0,
 |  | size_t | alimit = ARRAY_OPTION_LIMIT_ALL,
 |  | bool | areverse = false
 | ) | [inline]

Definition at line 49 of file pa_array.h.

References ARRAY_OPTION_LIMIT_ALL, Array< T >::Action_options::defined, Array< T >::Action_options::limit, Array< T >::Action_options::offset, and Array< T >::Action_options::reverse.

Member Function Documentation

template<typename T>
bool Array< T >::Action_options::adjust ( size_t count ) [inline]

Definition at line 56 of file pa_array.h.

References ARRAY_OPTION_LIMIT_ALL, Array< T >::Action_options::limit, Array< T >::Action_options::offset, and Array< T >::Action_options::reverse.

Member Data Documentation

template<typename T>
size_t Array< T >::Action_options::offset

Definition at line 44 of file pa_array.h.

Referenced by Array< T >::Action_options::Action_options(), and Array< T >::Action_options::adjust().

template<typename T>
size_t Array< T >::Action_options::limit

Definition at line 45 of file pa_array.h.

Referenced by Array< T >::Action_options::Action_options(), and Array< T >::Action_options::adjust().

template<typename T>
bool Array< T >::Action_options::reverse

Definition at line 46 of file pa_array.h.

Referenced by Array< T >::Action_options::Action_options(), and Array< T >::Action_options::adjust().

template<typename T>
bool Array< T >::Action_options::defined

Definition at line 47 of file pa_array.h.

Referenced by Array< T >::Action_options::Action_options().

The documentation for this struct was generated from the following file:
  • pa_array.h


Member List

Array< T >::Action_options Member List

This is the complete list of members for Array< T >::Action_options, including all inherited members.
Action_options(size_t aoffset=0, size_t alimit=ARRAY_OPTION_LIMIT_ALL, bool areverse=false) | Array< T >::Action_options | [inline]
adjust(size_t count) | Array< T >::Action_options | [inline]
defined | Array< T >::Action_options |
limit | Array< T >::Action_options |
offset | Array< T >::Action_options |
reverse | Array< T >::Action_options |


TemplateArray_iterator class Reference

Array_iterator< T > Class Template Reference

Array iterator, usage:
    // Array<T> a;
    for(Array_iterator<T> i(a); i.has_next(); ) {
        T& element=i.next();
        ...
    }
. More...

Collaboration diagram for Array_iterator< T >:

[legend]
List of all members.

Public Methods

Array_iterator (const Array< T > &aarray)
bool | has_next ()
there are still elements. More...

const T | next ()
quickly extracts next Array element. More...

Private Attributes

const Array< T > & | farray
T * | fcurrent
T * | flast

Detailed Description

template<typename T>
class Array_iterator< T >

Array iterator, usage:
    // Array<T> a;
    for(Array_iterator<T> i(a); i.has_next(); ) {
        T& element=i.next();
        ...
    }
.

Definition at line 212 of file pa_array.h.

Constructor & Destructor Documentation

template<typename T>
Array_iterator< T >::Array_iterator ( const Array< T > & aarray ) [inline]

Definition at line 220 of file pa_array.h.

References Array< T >::count(), Array_iterator< T >::fcurrent, Array< T >::felements, and Array_iterator< T >::flast.

Member Function Documentation

template<typename T>
bool Array_iterator< T >::has_next ( ) [inline]

there are still elements.

Definition at line 226 of file pa_array.h.

References Array_iterator< T >::fcurrent, and Array_iterator< T >::flast.

Referenced by _columns(), _create(), _hash(), _save(), add_connections_to_status_cache_table(), WContext::detach_junctions(), Request::execute(), split_horizontal(), split_vertical(), Table::Table(), table_row_to_hash(), and VMethodFrame::VMethodFrame().

template<typename T>
const T Array_iterator< T >::next ( ) [inline]

quickly extracts next Array element.

Definition at line 231 of file pa_array.h.

References Array_iterator< T >::fcurrent.

Referenced by _columns(), _create(), _hash(), _save(), add_connections_to_status_cache_table(), WContext::detach_junctions(), Request::execute(), split_horizontal(), split_vertical(), Table::Table(), table_row_to_hash(), and VMethodFrame::VMethodFrame().

Member Data Documentation

template<typename T>
const Array<T>& Array_iterator< T >::farray [private]

Definition at line 214 of file pa_array.h.

template<typename T>
T* Array_iterator< T >::fcurrent [private]

Definition at line 215 of file pa_array.h.

Referenced by Array_iterator< T >::Array_iterator(), Array_iterator< T >::has_next(), and Array_iterator< T >::next().

template<typename T>
T* Array_iterator< T >::flast [private]

Definition at line 216 of file pa_array.h.

Referenced by Array_iterator< T >::Array_iterator(), and Array_iterator< T >::has_next().

The documentation for this class was generated from the following file:
  • pa_array.h


Member List

Array_iterator< T > Member List

This is the complete list of members for Array_iterator< T >, including all inherited members.
Array_iterator(const Array< T > &aarray) | Array_iterator< T > | [inline]
farray | Array_iterator< T > | [private]
fcurrent | Array_iterator< T > | [private]
flast | Array_iterator< T > | [private]
has_next() | Array_iterator< T > | [inline]
next() | Array_iterator< T > | [inline]


AutoSYNCHRONIZED Class Reference

Helper to ensure paired Mutex::acquire() and Mutex::release(). More...

List of all members.

Public Methods

AutoSYNCHRONIZED ()
~AutoSYNCHRONIZED ()

Detailed Description

Helper to ensure paired Mutex::acquire() and Mutex::release().

Use it with SYNCHRONIZED macro

Definition at line 45 of file pa_threads.h.

Constructor & Destructor Documentation

AutoSYNCHRONIZED::AutoSYNCHRONIZED ( ) [inline]

Definition at line 47 of file pa_threads.h.

References Mutex::acquire().

AutoSYNCHRONIZED::~AutoSYNCHRONIZED ( ) [inline]

Definition at line 48 of file pa_threads.h.

References Mutex::release().

The documentation for this class was generated from the following file:
  • pa_threads.h


Member List

AutoSYNCHRONIZED Member List

This is the complete list of members for AutoSYNCHRONIZED, including all inherited members.
AutoSYNCHRONIZED() | AutoSYNCHRONIZED | [inline]
~AutoSYNCHRONIZED() | AutoSYNCHRONIZED | [inline]


cache_line Struct Reference

List of all members.

Public Attributes

size_t | tag
char | data [LINE_SZ]

Member Data Documentation

size_t cache_line::tag

Definition at line 485 of file cordxtra.c.

char cache_line::data[LINE_SZ]

Definition at line 486 of file cordxtra.c.

The documentation for this struct was generated from the following file:
  • cordxtra.c


Member List

cache_line Member List

This is the complete list of members for cache_line, including all inherited members.
data | cache_line
tag | cache_line


Cache_manager Class Reference

can return status and can expire it contents. More...

Inheritance diagram for Cache_manager:

[legend]
Collaboration diagram for Cache_manager:

[legend]
List of all members.

Public Methods

virtual Value * | get_status ()=0
if filter_server_id not null, returns status only Cachable -s with matching cacheable_item_server_id(). More...

virtual void | maybe_expire_cache ()
virtual | ~Cache_manager ()

Detailed Description

can return status and can expire it contents.

Definition at line 21 of file pa_cache_managers.h.

Constructor & Destructor Documentation

virtual Cache_manager::~Cache_manager ( ) [inline, virtual]

Definition at line 26 of file pa_cache_managers.h.

Member Function Documentation

virtual Value* Cache_manager::get_status ( ) [pure virtual]

if filter_server_id not null, returns status only Cachable -s with matching cacheable_item_server_id().

Implemented in SQL_Driver_manager, and Stylesheet_manager.

Referenced by VStatus::get_element().

virtual void Cache_manager::maybe_expire_cache ( ) [inline, virtual]

Reimplemented in SQL_Driver_manager, and Stylesheet_manager.

Definition at line 25 of file pa_cache_managers.h.

The documentation for this class was generated from the following file:
  • pa_cache_managers.h


Member List

Cache_manager Member List

This is the complete list of members for Cache_manager, including all inherited members.
free(void *ptr) | PA_Allocated | [inline, static]
get_status()=0 | Cache_manager | [pure virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_expire_cache() | Cache_manager | [inline, virtual]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
~Cache_manager() | Cache_manager | [inline, virtual]


Cache_managers Class Reference

maintains name=>Cache_manager association, can expire its contents. More...

Inheritance diagram for Cache_managers:

[legend]
Collaboration diagram for Cache_managers:

[legend]
List of all members.

Public Methods

Cache_managers ()
virtual | ~Cache_managers ()
void | maybe_expire ()
maybe-expires all caches it contains, each cache manager desides it itself. More...

Detailed Description

maintains name=>Cache_manager association, can expire its contents.

Definition at line 30 of file pa_cache_managers.h.

Constructor & Destructor Documentation

Cache_managers::Cache_managers ( )

Definition at line 21 of file pa_cache_managers.C.

References Hash< const String::Body, Cache_manager * >::put(), and stylesheet_manager.

Cache_managers::~Cache_managers ( ) [virtual]

Definition at line 32 of file pa_cache_managers.C.

References delete_one(), and Hash< const String::Body, Cache_manager * >::for_each().

Member Function Documentation

void Cache_managers::maybe_expire ( )

maybe-expires all caches it contains, each cache manager desides it itself.

Definition at line 42 of file pa_cache_managers.C.

References Hash< const String::Body, Cache_manager * >::for_each(), and maybe_expire_one().

The documentation for this class was generated from the following files:
  • pa_cache_managers.h
  • pa_cache_managers.C


Member List

Cache_managers Member List

This is the complete list of members for Cache_managers, including all inherited members.
Cache_managers() | Cache_managers |
clear() | Hash< const String::Body, Cache_manager * > | [inline]
count() const | Hash< const String::Body, Cache_manager * > | [inline]
first_that(bool callback(const String::Body, Cache_manager *, I), I info) const | Hash< const String::Body, Cache_manager * > | [inline]
for_each(void callback(const String::Body, Cache_manager *, I), I info) const | Hash< const String::Body, Cache_manager * > | [inline]
for_each_ref(void callback(const String::Body, Cache_manager *&, I), I info) const | Hash< const String::Body, Cache_manager * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
get(const String::Body key) const | Hash< const String::Body, Cache_manager * > | [inline]
Hash() | Hash< const String::Body, Cache_manager * > | [inline]
Hash(const Hash &source) | Hash< const String::Body, Cache_manager * > | [inline]
key_type typedef | Hash< const String::Body, Cache_manager * > |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_expire() | Cache_managers |
maybe_put_replaced(const String::Body key, Cache_manager *value, F prevent) | Hash< const String::Body, Cache_manager * > | [inline]
maybe_replace_maybe_append(const String::Body key, Cache_manager *value, F1 prevent_replace, F2 prevent_append, I info) | Hash< const String::Body, Cache_manager * > | [inline]
maybe_replace_never_append(const String::Body key, Cache_manager *value, F1 prevent_replace, I info) | Hash< const String::Body, Cache_manager * > | [inline]
merge_dont_replace(const Hash &src) | Hash< const String::Body, Cache_manager * > | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put(const String::Body key, Cache_manager *value) | Hash< const String::Body, Cache_manager * > | [inline]
put_dont_replace(const String::Body key, Cache_manager *value) | Hash< const String::Body, Cache_manager * > | [inline]
put_replaced(const String::Body key, Cache_manager *value) | Hash< const String::Body, Cache_manager * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
remove(const String::Body key) | Hash< const String::Body, Cache_manager * > | [inline]
replace_maybe_append(const String::Body key, Cache_manager *value, F prevent, I info) | Hash< const String::Body, Cache_manager * > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
value_type typedef | Hash< const String::Body, Cache_manager * > |
~Cache_managers() | Cache_managers | [virtual]


Charset Class Reference

charset holds name & transcode tables registers libxml transcoders. More...

Inheritance diagram for Charset:

[legend]
Collaboration diagram for Charset:

[legend]
List of all members.

Public Methods

Charset (Request_charsets *charsets, const String::Body ANAME, const String *afile_spec)
const String::Body | NAME () const
const char * | NAME_CSTR () const
bool | isUTF8 () const
xmlCharEncodingHandler & | transcoder (const String::Body NAME)
String::C | transcode_cstr (const xmlChar *s)
converts xmlChar* null-terminated string to char*. More...

const String & | transcode (const xmlChar *s)
converts xmlChar* null-terminated string to parser String. More...

xmlChar * | transcode_buf2xchar (const char *buf, size_t buf_size)
converts sized char* to xmlChar*. More...

xmlChar * | transcode (const String &s)
converts parser String to xmlChar*. More...

xmlChar * | transcode (const String::Body s)
converts parser String::Body to xmlChar*. More...

Static Public Methods

String::C | transcode (const String::C src, const Charset &source_transcoder, const Charset &dest_transcoder)
String & | transcode (const String &src, const Charset &source_transcoder, const Charset &dest_transcoder)
String::Body | transcode (const String::Body src, const Charset &source_transcoder, const Charset &dest_transcoder)
void | transcode (ArrayString &src, const Charset &source_transcoder, const Charset &dest_transcoder)
void | transcode (HashStringString &src, const Charset &source_transcoder, const Charset &dest_transcoder)

Public Attributes

unsigned char | pcre_tables [tables_length]

Private Methods

void | load_definition (Request_charsets &charsets, const String &afile_spec)
void | sort_ToTable ()
const String::C | transcodeToUTF8 (const String::C src) const
const String::C | transcodeFromUTF8 (const String::C src) const
const String::C | transcodeToCharset (const String::C src, const Charset &dest_transcoder) const
transcode using both charsets. More...

void | addEncoding (char *name_cstr)
void | initTranscoder (const String::Body name, const char *name_cstr)

Private Attributes

const String::Body | FNAME
char * | FNAME_CSTR
bool | fisUTF8
Tables tables
xmlCharEncodingHandler * | ftranscoder

Detailed Description

charset holds name & transcode tables registers libxml transcoders.

Definition at line 49 of file pa_charset.h.

Constructor & Destructor Documentation

Charset::Charset | ( | Request_charsets * | charsets,
 |  | const String::Body | ANAME,
 |  | const String * | afile_spec
 | ) |

Definition at line 448 of file pa_charset.C.

Member Function Documentation

const String::Body Charset::NAME ( ) const [inline]

Definition at line 54 of file pa_charset.h.

References FNAME.

Referenced by _connect(), Charsets::Charsets(), VResponse::get_element(), and VRequest::get_element().

const char* Charset::NAME_CSTR ( ) const [inline]

Definition at line 55 of file pa_charset.h.

References FNAME_CSTR.

bool Charset::isUTF8 ( ) const [inline]

Definition at line 57 of file pa_charset.h.

References fisUTF8.

Referenced by String::change_case().

String::C Charset::transcode | ( | const String::C | src,
 |  | const Charset & | source_transcoder,
 |  | const Charset & | dest_transcoder
 | ) | [static]

Definition at line 570 of file pa_charset.C.

Referenced by _exec_cgi(), cstr_to_string_body_block(), output_sole_piece(), pa_internal_file_read_http(), store_message_element(), text_value_to_string(), VForm::transcode(), and SQL_Driver_services_impl::transcode().

String & Charset::transcode | ( | const String & | src,
 |  | const Charset & | source_transcoder,
 |  | const Charset & | dest_transcoder
 | ) | [static]

Definition at line 1190 of file pa_charset.C.

String::Body Charset::transcode | ( | const String::Body | src,
 |  | const Charset & | source_transcoder,
 |  | const Charset & | dest_transcoder
 | ) | [static]

Definition at line 1176 of file pa_charset.C.

void Charset::transcode | ( | ArrayString & | src,
 |  | const Charset & | source_transcoder,
 |  | const Charset & | dest_transcoder
 | ) | [static]

Definition at line 1199 of file pa_charset.C.

void Charset::transcode | ( | HashStringString & | src,
 |  | const Charset & | source_transcoder,
 |  | const Charset & | dest_transcoder
 | ) | [static]

Definition at line 1219 of file pa_charset.C.

xmlCharEncodingHandler& Charset::transcoder ( const String::Body NAME )

void Charset::load_definition | ( | Request_charsets & | charsets,
 |  | const String & | afile_spec
 | ) | [private]

Definition at line 469 of file pa_charset.C.

void Charset::sort_ToTable ( ) [private]

Definition at line 541 of file pa_charset.C.

const String::C Charset::transcodeToUTF8 ( const String::C src ) const [private]

Todo:
not so memory-hungry with prescan

Definition at line 793 of file pa_charset.C.

const String::C Charset::transcodeFromUTF8 ( const String::C src ) const [private]

Definition at line 943 of file pa_charset.C.

const String::C Charset::transcodeToCharset | ( | const String::C | src,
 |  | const Charset & | dest_transcoder
 | ) | const [private]

transcode using both charsets.

Definition at line 964 of file pa_charset.C.

void Charset::addEncoding ( char * name_cstr ) [private]

void Charset::initTranscoder | ( | const String::Body | name,
 |  | const char * | name_cstr
 | ) | [private]

String::C Charset::transcode_cstr ( const xmlChar * s )

converts xmlChar* null-terminated string to char*.

const String& Charset::transcode ( const xmlChar * s )

converts xmlChar* null-terminated string to parser String.

xmlChar* Charset::transcode_buf2xchar | ( | const char * | buf,
 |  | size_t | buf_size
 | ) |

converts sized char* to xmlChar*.

Returns:
xmlChar* WHICH CALLER SHOULD FREE

xmlChar* Charset::transcode ( const String & s )

converts parser String to xmlChar*.

xmlChar* Charset::transcode ( const String::Body s )

converts parser String::Body to xmlChar*.

Member Data Documentation

unsigned char Charset::pcre_tables[tables_length]

Definition at line 86 of file pa_charset.h.

Referenced by _list(), String::change_case(), and String::match().

const String::Body Charset::FNAME [private]

Definition at line 123 of file pa_charset.h.

Referenced by NAME().

char* Charset::FNAME_CSTR [private]

Definition at line 124 of file pa_charset.h.

Referenced by NAME_CSTR().

bool Charset::fisUTF8 [private]

Definition at line 125 of file pa_charset.h.

Referenced by isUTF8().

Tables Charset::tables [private]

Definition at line 126 of file pa_charset.h.

xmlCharEncodingHandler* Charset::ftranscoder [private]

Definition at line 151 of file pa_charset.h.

The documentation for this class was generated from the following files:
  • pa_charset.h
  • pa_charset.C


Member List

Charset Member List

This is the complete list of members for Charset, including all inherited members.
addEncoding(char *name_cstr) | Charset | [private]
Charset(Request_charsets *charsets, const String::Body ANAME, const String *afile_spec) | Charset |
fisUTF8 | Charset | [private]
FNAME | Charset | [private]
FNAME_CSTR | Charset | [private]
free(void *ptr) | PA_Allocated | [inline, static]
ftranscoder | Charset | [private]
initTranscoder(const String::Body name, const char *name_cstr) | Charset | [private]
isUTF8() const | Charset | [inline]
load_definition(Request_charsets &charsets, const String &afile_spec) | Charset | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
NAME() const | Charset | [inline]
NAME_CSTR() const | Charset | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
pcre_tables | Charset |
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
sort_ToTable() | Charset | [private]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
tables | Charset | [private]
transcode(const String::C src, const Charset &source_transcoder, const Charset &dest_transcoder) | Charset | [static]
transcode(const String &src, const Charset &source_transcoder, const Charset &dest_transcoder) | Charset | [static]
transcode(const String::Body src, const Charset &source_transcoder, const Charset &dest_transcoder) | Charset | [static]
transcode(ArrayString &src, const Charset &source_transcoder, const Charset &dest_transcoder) | Charset | [static]
transcode(HashStringString &src, const Charset &source_transcoder, const Charset &dest_transcoder) | Charset | [static]
transcode(const xmlChar *s) | Charset |
transcode(const String &s) | Charset |
transcode(const String::Body s) | Charset |
transcode_buf2xchar(const char *buf, size_t buf_size) | Charset |
transcode_cstr(const xmlChar *s) | Charset |
transcodeFromUTF8(const String::C src) const | Charset | [private]
transcoder(const String::Body NAME) | Charset |
transcodeToCharset(const String::C src, const Charset &dest_transcoder) const | Charset | [private]
transcodeToUTF8(const String::C src) const | Charset | [private]


Charset::Tables Struct Reference

Collaboration diagram for Charset::Tables:

[legend]
List of all members.

Public Attributes

XMLCh | fromTable [0x100]
Rec | toTable [MAX_CHARSET_UNI_CODES]
uint toTableSize

Member Data Documentation

XMLCh Charset::Tables::fromTable[0x100]

Definition at line 107 of file pa_charset.h.

Rec Charset::Tables::toTable[MAX_CHARSET_UNI_CODES]

Definition at line 108 of file pa_charset.h.

uint Charset::Tables::toTableSize

Definition at line 109 of file pa_charset.h.

The documentation for this struct was generated from the following file:
  • pa_charset.h


Member List

Charset::Tables Member List

This is the complete list of members for Charset::Tables, including all inherited members.
fromTable | Charset::Tables
toTable | Charset::Tables
toTableSize | Charset::Tables


Charset::Tables::Rec Struct Reference

List of all members.

Public Attributes

XMLCh intCh
XMLByte extCh

Member Data Documentation

XMLCh Charset::Tables::Rec::intCh

Definition at line 103 of file pa_charset.h.

XMLByte Charset::Tables::Rec::extCh

Definition at line 104 of file pa_charset.h.

The documentation for this struct was generated from the following file:
  • pa_charset.h


Member List

Charset::Tables::Rec Member List

This is the complete list of members for Charset::Tables::Rec, including all inherited members.
extCh | Charset::Tables::Rec
intCh | Charset::Tables::Rec


Charset::UTF8CaseTable Struct Reference

Collaboration diagram for Charset::UTF8CaseTable:

[legend]
List of all members.

Public Attributes

uint size
Rec * records

Member Data Documentation

uint Charset::UTF8CaseTable::size

Definition at line 117 of file pa_charset.h.

Rec* Charset::UTF8CaseTable::records

Definition at line 118 of file pa_charset.h.

The documentation for this struct was generated from the following file:
  • pa_charset.h


Member List

Charset::UTF8CaseTable Member List

This is the complete list of members for Charset::UTF8CaseTable, including all inherited members.
records | Charset::UTF8CaseTable
size | Charset::UTF8CaseTable


Charset::UTF8CaseTable::Rec Struct Reference

List of all members.

Public Attributes

XMLCh from
XMLCh to

Member Data Documentation

XMLCh Charset::UTF8CaseTable::Rec::from

Definition at line 114 of file pa_charset.h.

XMLCh Charset::UTF8CaseTable::Rec::to

Definition at line 114 of file pa_charset.h.

The documentation for this struct was generated from the following file:
  • pa_charset.h


Member List

Charset::UTF8CaseTable::Rec Member List

This is the complete list of members for Charset::UTF8CaseTable::Rec, including all inherited members.
from | Charset::UTF8CaseTable::Rec
to | Charset::UTF8CaseTable::Rec


Charsets Class Reference

convention: use UPPERCASE keys. More...

Inheritance diagram for Charsets:

[legend]
Collaboration diagram for Charsets:

[legend]
List of all members.

Public Methods

Charsets ()
Charset & | get (const String::Body ANAME)
void | load_charset (Request_charsets &charsets, const String::Body ANAME, const String &afile_spec)

Detailed Description

convention: use UPPERCASE keys.

Definition at line 20 of file pa_charsets.h.

Constructor & Destructor Documentation

Charsets::Charsets ( )

Definition at line 24 of file pa_charsets.C.

References Charset::NAME(), and Hash< const String::Body, Charset * >::put().

Member Function Documentation

Charset & Charsets::get ( const String::Body ANAME )

Definition at line 28 of file pa_charsets.C.

References Hash< K, V >::get(), String::L_TAINTED, and result.

void Charsets::load_charset | ( | Request_charsets & | charsets,
 |  | const String::Body | ANAME,
 |  | const String & | afile_spec
 | ) |

Definition at line 37 of file pa_charsets.C.

References Hash< K, V >::get(), and Hash< const String::Body, Charset * >::put().

The documentation for this class was generated from the following files:
  • pa_charsets.h
  • pa_charsets.C


Member List

Charsets Member List

This is the complete list of members for Charsets, including all inherited members.
Charsets() | Charsets |
clear() | Hash< const String::Body, Charset * > | [inline]
count() const | Hash< const String::Body, Charset * > | [inline]
first_that(bool callback(const String::Body, Charset *, I), I info) const | Hash< const String::Body, Charset * > | [inline]
for_each(void callback(const String::Body, Charset *, I), I info) const | Hash< const String::Body, Charset * > | [inline]
for_each_ref(void callback(const String::Body, Charset *&, I), I info) const | Hash< const String::Body, Charset * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
get(const String::Body ANAME) | Charsets |
Hash< const String::Body, Charset * >::get(const String::Body key) const | Hash< const String::Body, Charset * > | [inline]
Hash() | Hash< const String::Body, Charset * > | [inline]
Hash(const Hash &source) | Hash< const String::Body, Charset * > | [inline]
key_type typedef | Hash< const String::Body, Charset * > |
load_charset(Request_charsets &charsets, const String::Body ANAME, const String &afile_spec) | Charsets |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_put_replaced(const String::Body key, Charset *value, F prevent) | Hash< const String::Body, Charset * > | [inline]
maybe_replace_maybe_append(const String::Body key, Charset *value, F1 prevent_replace, F2 prevent_append, I info) | Hash< const String::Body, Charset * > | [inline]
maybe_replace_never_append(const String::Body key, Charset *value, F1 prevent_replace, I info) | Hash< const String::Body, Charset * > | [inline]
merge_dont_replace(const Hash &src) | Hash< const String::Body, Charset * > | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put(const String::Body key, Charset *value) | Hash< const String::Body, Charset * > | [inline]
put_dont_replace(const String::Body key, Charset *value) | Hash< const String::Body, Charset * > | [inline]
put_replaced(const String::Body key, Charset *value) | Hash< const String::Body, Charset * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
remove(const String::Body key) | Hash< const String::Body, Charset * > | [inline]
replace_maybe_append(const String::Body key, Charset *value, F prevent, I info) | Hash< const String::Body, Charset * > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
value_type typedef | Hash< const String::Body, Charset * > |


chr_data Struct Reference

List of all members.

Public Attributes

size_t | pos
char | target

Member Data Documentation

size_t chr_data::pos

Definition at line 290 of file cordxtra.c.

Referenced by CORD_chr(), and CORD_rchr().

char chr_data::target

Definition at line 291 of file cordxtra.c.

Referenced by CORD_chr(), CORD_range_contains_chr_greater_then(), and CORD_rchr().

The documentation for this struct was generated from the following file:
  • cordxtra.c


Member List

chr_data Member List

This is the complete list of members for chr_data, including all inherited members.
pos | chr_data
target | chr_data


compile_data Struct Reference

List of all members.

Public Attributes

const uschar * | lcc
const uschar * | fcc
const uschar * | cbits
const uschar * | ctypes

Member Data Documentation

const uschar* compile_data::lcc

Definition at line 299 of file internal.h.

Referenced by check_escape(), pcre_compile(), and pcre_study().

const uschar* compile_data::fcc

Definition at line 300 of file internal.h.

Referenced by check_escape(), compile_branch(), pcre_compile(), pcre_study(), and set_bit().

const uschar* compile_data::cbits

Definition at line 301 of file internal.h.

Referenced by compile_branch(), pcre_compile(), pcre_study(), and set_start_bits().

const uschar* compile_data::ctypes

Definition at line 302 of file internal.h.

Referenced by check_escape(), compile_branch(), is_counted_repeat(), pcre_compile(), pcre_study(), read_repeat_counts(), and set_bit().

The documentation for this struct was generated from the following file:
  • internal.h


Member List

compile_data Member List

This is the complete list of members for compile_data, including all inherited members.
cbits | compile_data
ctypes | compile_data
fcc | compile_data
lcc | compile_data


CORD_ec_struct Struct Reference

List of all members.

Public Attributes

CORD ec_cord
char * | ec_bufptr
char | ec_buf [CORD_BUFSZ+1]

Member Data Documentation

CORD CORD_ec_struct::ec_cord

Definition at line 38 of file ec.h.

Referenced by CORD_ec_append_cord(), CORD_ec_flush_buf(), and CORD_from_file_eager().

char* CORD_ec_struct::ec_bufptr

Definition at line 39 of file ec.h.

Referenced by CORD_ec_flush_buf(), CORD_vsprintf(), and ec_len().

char CORD_ec_struct::ec_buf[CORD_BUFSZ+1]

Definition at line 40 of file ec.h.

Referenced by CORD_ec_flush_buf(), CORD_vsprintf(), and ec_len().

The documentation for this struct was generated from the following file:
  • ec.h


Member List

CORD_ec_struct Member List

This is the complete list of members for CORD_ec_struct, including all inherited members.
ec_buf | CORD_ec_struct
ec_bufptr | CORD_ec_struct
ec_cord | CORD_ec_struct


CORD_fill_data Struct Reference

List of all members.

Public Attributes

size_t | len
size_t | count
char * | buf

Member Data Documentation

size_t CORD_fill_data::len

Definition at line 87 of file cordxtra.c.

Referenced by CORD_fill_buf().

size_t CORD_fill_data::count

Definition at line 88 of file cordxtra.c.

Referenced by CORD_fill_buf().

char* CORD_fill_data::buf

Definition at line 89 of file cordxtra.c.

Referenced by CORD_fill_buf().

The documentation for this struct was generated from the following file:
  • cordxtra.c


Member List

CORD_fill_data Member List

This is the complete list of members for CORD_fill_data, including all inherited members.
buf | CORD_fill_data
count | CORD_fill_data
len | CORD_fill_data


CORD_pe Struct Reference

List of all members.

Public Attributes

CORD pe_cord
size_t pe_start_pos

Member Data Documentation

CORD CORD_pe::pe_cord

Definition at line 26 of file cord_pos.h.

Referenced by CORD_pos_to_cord(), and CORD_set_pos().

size_t CORD_pe::pe_start_pos

Definition at line 27 of file cord_pos.h.

Referenced by CORD__next(), CORD__prev(), and CORD_set_pos().

The documentation for this struct was generated from the following file:
  • cord_pos.h


Member List

CORD_pe Member List

This is the complete list of members for CORD_pe, including all inherited members.
pe_cord | CORD_pe
pe_start_pos | CORD_pe


CORD_Pos Struct Reference

Collaboration diagram for CORD_Pos:

[legend]
List of all members.

Public Attributes

size_t | cur_pos
int | path_len
const char * | cur_leaf
size_t | cur_start
size_t | cur_end
CORD_pe | path [MAX_DEPTH+1]
char | function_buf [FUNCTION_BUF_SZ]

Member Data Documentation

size_t CORD_Pos::cur_pos

Definition at line 33 of file cord_pos.h.

Referenced by CORD_next(), CORD_pos_to_index(), CORD_prev(), and CORD_set_pos().

int CORD_Pos::path_len

Definition at line 34 of file cord_pos.h.

Referenced by CORD_pos_valid(), and CORD_set_pos().

const char* CORD_Pos::cur_leaf

Definition at line 37 of file cord_pos.h.

size_t CORD_Pos::cur_start

Definition at line 44 of file cord_pos.h.

Referenced by CORD_prev().

size_t CORD_Pos::cur_end

Definition at line 45 of file cord_pos.h.

Referenced by CORD_next(), and CORD_prev().

struct CORD_pe CORD_Pos::path[MAX_DEPTH + 1]

Definition at line 47 of file cord_pos.h.

Referenced by CORD_pos_to_cord(), and CORD_set_pos().

char CORD_Pos::function_buf[FUNCTION_BUF_SZ]

Definition at line 51 of file cord_pos.h.

The documentation for this struct was generated from the following file:
  • cord_pos.h


Member List

CORD_Pos Member List

This is the complete list of members for CORD_Pos, including all inherited members.
cur_end | CORD_Pos
cur_leaf | CORD_Pos
cur_pos | CORD_Pos
cur_start | CORD_Pos
function_buf | CORD_Pos
path | CORD_Pos
path_len | CORD_Pos


CordRep Union Reference

Collaboration diagram for CordRep:

[legend]
List of all members.

Public Attributes

CordRep::Concatenation concatenation
CordRep::Function function
CordRep::Generic generic
char string [1]

Member Data Documentation

struct CordRep::Concatenation CordRep::concatenation

struct CordRep::Function CordRep::function

Referenced by CORD_apply_access_fn(), and CORD_block_iter().

struct CordRep::Generic CordRep::generic

char CordRep::string[1]

Definition at line 70 of file cordbscs.c.

The documentation for this union was generated from the following file:
  • cordbscs.c


Member List

CordRep Member List

This is the complete list of members for CordRep, including all inherited members.
concatenation | CordRep
function | CordRep
generic | CordRep
string | CordRep


CordRep::Concatenation Struct Reference

List of all members.

Public Attributes

char | null
char | header
char | depth
unsigned char | left_len
word len
CORD left
CORD right

Member Data Documentation

char CordRep::Concatenation::null

Definition at line 43 of file cordbscs.c.

char CordRep::Concatenation::header

Definition at line 44 of file cordbscs.c.

char CordRep::Concatenation::depth

Definition at line 45 of file cordbscs.c.

unsigned char CordRep::Concatenation::left_len

Definition at line 46 of file cordbscs.c.

word CordRep::Concatenation::len

Definition at line 50 of file cordbscs.c.

CORD CordRep::Concatenation::left

Definition at line 51 of file cordbscs.c.

CORD CordRep::Concatenation::right

Definition at line 52 of file cordbscs.c.

The documentation for this struct was generated from the following file:
  • cordbscs.c


Member List

CordRep::Concatenation Member List

This is the complete list of members for CordRep::Concatenation, including all inherited members.
depth | CordRep::Concatenation
header | CordRep::Concatenation
left | CordRep::Concatenation
left_len | CordRep::Concatenation
len | CordRep::Concatenation
null | CordRep::Concatenation
right | CordRep::Concatenation


CordRep::Function Struct Reference

List of all members.

Public Attributes

char | null
char | header
char | depth
char | left_len
word len
CORD_fn fn
void * | client_data

Member Data Documentation

char CordRep::Function::null

Definition at line 55 of file cordbscs.c.

char CordRep::Function::header

Definition at line 56 of file cordbscs.c.

char CordRep::Function::depth

Definition at line 57 of file cordbscs.c.

char CordRep::Function::left_len

Definition at line 58 of file cordbscs.c.

word CordRep::Function::len

Definition at line 59 of file cordbscs.c.

CORD_fn CordRep::Function::fn

Definition at line 60 of file cordbscs.c.

void* CordRep::Function::client_data

Definition at line 61 of file cordbscs.c.

The documentation for this struct was generated from the following file:
  • cordbscs.c


Member List

CordRep::Function Member List

This is the complete list of members for CordRep::Function, including all inherited members.
client_data | CordRep::Function
depth | CordRep::Function
fn | CordRep::Function
header | CordRep::Function
left_len | CordRep::Function
len | CordRep::Function
null | CordRep::Function


CordRep::Generic Struct Reference

List of all members.

Public Attributes

char | null
char | header
char | depth
char | left_len
word len

Member Data Documentation

char CordRep::Generic::null

Definition at line 64 of file cordbscs.c.

char CordRep::Generic::header

Definition at line 65 of file cordbscs.c.

char CordRep::Generic::depth

Definition at line 66 of file cordbscs.c.

char CordRep::Generic::left_len

Definition at line 67 of file cordbscs.c.

word CordRep::Generic::len

Definition at line 68 of file cordbscs.c.

The documentation for this struct was generated from the following file:
  • cordbscs.c


Member List

CordRep::Generic Member List

This is the complete list of members for CordRep::Generic, including all inherited members.
depth | CordRep::Generic
header | CordRep::Generic
left_len | CordRep::Generic
len | CordRep::Generic
null | CordRep::Generic


Date_calendar_table_template_columns Class Reference

Inheritance diagram for Date_calendar_table_template_columns:

[legend]
Collaboration diagram for Date_calendar_table_template_columns:

[legend]
List of all members.

Public Methods

Date_calendar_table_template_columns ()

Constructor & Destructor Documentation

Date_calendar_table_template_columns::Date_calendar_table_template_columns ( ) [inline]

Definition at line 38 of file date.C.

The documentation for this class was generated from the following file:
  • date.C


Member List

Date_calendar_table_template_columns Member List

This is the complete list of members for Date_calendar_table_template_columns, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< const String * > | [inline]
Array(size_t initial=3) | Array< const String * > | [inline]
count() const | Array< const String * > | [inline]
Date_calendar_table_template_columns() | Date_calendar_table_template_columns | [inline]
element_type typedef | Array< const String * > |
expand(size_t delta) | Array< const String * > | [inline, protected]
fallocated | Array< const String * > | [protected]
felements | Array< const String * > | [protected]
first_that(bool(*callback)(const String *, I), I info) const | Array< const String * > | [inline]
for_each(void(*callback)(const String *, I), I info) const | Array< const String * > | [inline]
for_each_ref(void(*callback)(const String *&, I), I info) | Array< const String * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fused | Array< const String * > | [protected]
get(size_t index) const | Array< const String * > | [inline]
get_ref(size_t index) const | Array< const String * > | [inline]
is_full() | Array< const String * > | [inline, protected]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(const String *src) | Array< const String * > | [inline]
operator[](size_t index) const | Array< const String * > | [inline]
put(size_t index, const String *element) | Array< const String * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


Dictionary Class Reference

simple dictionary, speding up lookups on contained two columned table. More...

Inheritance diagram for Dictionary:

[legend]
Collaboration diagram for Dictionary:

[legend]
List of all members.

Public Methods

Dictionary (Table &atable)
construct wrapper, grabbing first letters of first column into first. More...

Subst | first_that_begins (const char *str) const
find first row that contains string in first column which starts src. More...

Private Attributes

Array< Subst > substs
int | starting_line_of [0x100]
int | constructor_line

Friends

void | pa_dictionary_add_first (Table::element_type row, Dictionary *self)

Detailed Description

simple dictionary, speding up lookups on contained two columned table.

Definition at line 16 of file pa_dictionary.h.

Constructor & Destructor Documentation

Dictionary::Dictionary ( Table & atable )

construct wrapper, grabbing first letters of first column into first.

Definition at line 40 of file pa_dictionary.C.

References constructor_line, pa_dictionary_add_first, and starting_line_of.

Member Function Documentation

Dictionary::Subst Dictionary::first_that_begins ( const char * str ) const

find first row that contains string in first column which starts src.

Definition at line 62 of file pa_dictionary.C.

References Array< Subst >::first_that(), starting_line_of, starts(), str, and substs.

Referenced by String::replace().

Friends And Related Function Documentation

void pa_dictionary_add_first | ( | Table::element_type | row,
 |  | Dictionary * | self
 | ) | [friend]

Definition at line 14 of file pa_dictionary.C.

Referenced by Dictionary().

Member Data Documentation

Array<Subst> Dictionary::substs [private]

Definition at line 38 of file pa_dictionary.h.

Referenced by first_that_begins(), and pa_dictionary_add_first().

int Dictionary::starting_line_of[0x100] [private]

Definition at line 44 of file pa_dictionary.h.

Referenced by Dictionary(), first_that_begins(), and pa_dictionary_add_first().

int Dictionary::constructor_line [private]

Definition at line 44 of file pa_dictionary.h.

Referenced by Dictionary(), and pa_dictionary_add_first().

The documentation for this class was generated from the following files:
  • pa_dictionary.h
  • pa_dictionary.C


Member List

Dictionary Member List

This is the complete list of members for Dictionary, including all inherited members.
constructor_line | Dictionary | [private]
Dictionary(Table &atable) | Dictionary |
first_that_begins(const char *str) const | Dictionary |
free(void *ptr) | PA_Allocated | [inline, static]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
pa_dictionary_add_first(Table::element_type row, Dictionary *self) | Dictionary | [friend]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
starting_line_of | Dictionary | [private]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
substs | Dictionary | [private]


Dictionary::Subst Struct Reference

Collaboration diagram for Dictionary::Subst:

[legend]
List of all members.

Public Methods

Subst (int)
Subst (const char *afrom, const String *ato)
operator bool ()

Public Attributes

const char * | from
size_t | from_length
const String * | to

Constructor & Destructor Documentation

Dictionary::Subst::Subst ( int ) [inline]

Definition at line 23 of file pa_dictionary.h.

References from.

Dictionary::Subst::Subst | ( | const char * | afrom,
 |  | const String * | ato
 | ) | [inline]

Definition at line 24 of file pa_dictionary.h.

References from, and from_length.

Member Function Documentation

Dictionary::Subst::operator bool ( ) [inline]

Definition at line 27 of file pa_dictionary.h.

References from.

Member Data Documentation

const char* Dictionary::Subst::from

Definition at line 20 of file pa_dictionary.h.

Referenced by operator bool(), starts(), and Subst().

size_t Dictionary::Subst::from_length

Definition at line 20 of file pa_dictionary.h.

Referenced by String::replace(), starts(), and Subst().

const String* Dictionary::Subst::to

Definition at line 21 of file pa_dictionary.h.

Referenced by String::replace().

The documentation for this struct was generated from the following file:
  • pa_dictionary.h


Member List

Dictionary::Subst Member List

This is the complete list of members for Dictionary::Subst, including all inherited members.
from | Dictionary::Subst |
from_length | Dictionary::Subst |
operator bool() | Dictionary::Subst | [inline]
Subst(int) | Dictionary::Subst | [inline]
Subst(const char *afrom, const String *ato) | Dictionary::Subst | [inline]
to | Dictionary::Subst |


dirent Struct Reference

List of all members.

Public Attributes

char * d_name

Member Data Documentation

char* dirent::d_name

Definition at line 37 of file config_fixed.h.

The documentation for this struct was generated from the following file:
  • config_fixed.h


Member List

dirent Member List

This is the complete list of members for dirent, including all inherited members.
d_name dirent


Exception Class Reference

Collaboration diagram for Exception:

[legend]
List of all members.

Public Methods

Exception ()
Exception (const char *atype, const String *aproblem_source, const char *comment_fmt,...)
Exception (const Exception &src)
operator bool ()
Exception & | operator= (const Exception &src)
const char * | type (bool can_be_empty=false) const
extracts exception type. More...

const String * | problem_source () const
extracts exception problem_source. More...

const char * | comment (bool can_be_empty=false) const
extracts exception comment. More...

Protected Attributes

const char * | ftype
const String * | fproblem_source
char * | fcomment

Constructor & Destructor Documentation

Exception::Exception ( )

Definition at line 18 of file pa_exception.C.

Exception::Exception | ( | const char * | atype,
 |  | const String * | aproblem_source,
 |  | const char * | comment_fmt,
 |  | ... |
 | ) |

Definition at line 31 of file pa_exception.C.

References fcomment, fproblem_source, ftype, MAX_STRING, and vsnprintf.

Exception::Exception ( const Exception & src )

Definition at line 19 of file pa_exception.C.

Member Function Documentation

Exception::operator bool ( ) [inline]

Definition at line 32 of file pa_exception.h.

References fcomment, fproblem_source, and ftype.

Exception & Exception::operator= ( const Exception & src )

Definition at line 24 of file pa_exception.C.

References fcomment, fproblem_source, and ftype.

const char* Exception::type ( bool can_be_empty = false ) const [inline]

extracts exception type.

Definition at line 36 of file pa_exception.h.

References ftype.

Referenced by Request::get_details(), and Request::get_exception_cstr().

const String * Exception::problem_source ( ) const

extracts exception problem_source.

Definition at line 48 of file pa_exception.C.

References fproblem_source, and String::length().

Referenced by Request::get_details().

const char* Exception::comment ( bool can_be_empty = false ) const [inline]

extracts exception comment.

Definition at line 45 of file pa_exception.h.

References fcomment, and result.

Referenced by Request::get_details(), and Request::get_exception_cstr().

Member Data Documentation

const char* Exception::ftype [protected]

Definition at line 55 of file pa_exception.h.

Referenced by Exception(), operator bool(), operator=(), and type().

const String* Exception::fproblem_source [protected]

Definition at line 56 of file pa_exception.h.

Referenced by Exception(), operator bool(), operator=(), and problem_source().

char* Exception::fcomment [protected]

Definition at line 57 of file pa_exception.h.

Referenced by comment(), Exception(), operator bool(), and operator=().

The documentation for this class was generated from the following files:
  • pa_exception.h
  • pa_exception.C


Member List

Exception Member List

This is the complete list of members for Exception, including all inherited members.
comment(bool can_be_empty=false) const | Exception | [inline]
Exception() | Exception |
Exception(const char *atype, const String *aproblem_source, const char *comment_fmt,...) | Exception |
Exception(const Exception &src) | Exception |
fcomment | Exception | [protected]
fproblem_source | Exception | [protected]
ftype | Exception | [protected]
operator bool() | Exception | [inline]
operator=(const Exception &src) | Exception |
problem_source() const | Exception |
type(bool can_be_empty=false) const | Exception | [inline]


EXIF_tag_value2name Class Reference

value of exif tag -> it's value. More...

Inheritance diagram for EXIF_tag_value2name:

[legend]
Collaboration diagram for EXIF_tag_value2name:

[legend]
List of all members.

Public Methods

EXIF_tag_value2name ()

Detailed Description

value of exif tag -> it's value.

Definition at line 53 of file image.C.

Constructor & Destructor Documentation

EXIF_tag_value2name::EXIF_tag_value2name ( ) [inline]

Definition at line 55 of file image.C.

The documentation for this class was generated from the following file:
  • image.C


Member List

EXIF_tag_value2name Member List

This is the complete list of members for EXIF_tag_value2name, including all inherited members.
clear() | Hash< int, const char * > | [inline]
count() const | Hash< int, const char * > | [inline]
EXIF_tag_value2name() | EXIF_tag_value2name | [inline]
first_that(bool callback(int, const char *, I), I info) const | Hash< int, const char * > | [inline]
for_each(void callback(int, const char *, I), I info) const | Hash< int, const char * > | [inline]
for_each_ref(void callback(int, const char *&, I), I info) const | Hash< int, const char * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
get(int key) const | Hash< int, const char * > | [inline]
Hash() | Hash< int, const char * > | [inline]
Hash(const Hash &source) | Hash< int, const char * > | [inline]
key_type typedef | Hash< int, const char * > |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_put_replaced(int key, const char *value, F prevent) | Hash< int, const char * > | [inline]
maybe_replace_maybe_append(int key, const char *value, F1 prevent_replace, F2 prevent_append, I info) | Hash< int, const char * > | [inline]
maybe_replace_never_append(int key, const char *value, F1 prevent_replace, I info) | Hash< int, const char * > | [inline]
merge_dont_replace(const Hash &src) | Hash< int, const char * > | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put(int key, const char *value) | Hash< int, const char * > | [inline]
put_dont_replace(int key, const char *value) | Hash< int, const char * > | [inline]
put_replaced(int key, const char *value) | Hash< int, const char * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
remove(int key) | Hash< int, const char * > | [inline]
replace_maybe_append(int key, const char *value, F prevent, I info) | Hash< int, const char * > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
value_type typedef | Hash< int, const char * > |


ffblk Struct Reference

win32/unix unified directory entry structure name for findfirst/next/close interface. More...

List of all members.

Public Attributes

DWORD | ff_attrib
FILETIME | ftCreationTime
FILETIME | ftLastAccessTime
FILETIME | ftLastWriteTime
DWORD | nFileSizeHigh
DWORD | nFileSizeLow
DWORD | dwReserved0
DWORD | dwReserved1
CHAR | ff_name [MAX_PATH]
CHAR | cAlternateFileName [14]
HANDLE | handle

Detailed Description

win32/unix unified directory entry structure name for findfirst/next/close interface.

Definition at line 27 of file pa_dir.h.

Member Data Documentation

DWORD ffblk::ff_attrib

Definition at line 28 of file pa_dir.h.

FILETIME ffblk::ftCreationTime

Definition at line 29 of file pa_dir.h.

FILETIME ffblk::ftLastAccessTime

Definition at line 30 of file pa_dir.h.

FILETIME ffblk::ftLastWriteTime

Definition at line 31 of file pa_dir.h.

DWORD ffblk::nFileSizeHigh

Definition at line 32 of file pa_dir.h.

DWORD ffblk::nFileSizeLow

Definition at line 33 of file pa_dir.h.

DWORD ffblk::dwReserved0

Definition at line 34 of file pa_dir.h.

DWORD ffblk::dwReserved1

Definition at line 35 of file pa_dir.h.

CHAR ffblk::ff_name[ MAX_PATH ]

Definition at line 36 of file pa_dir.h.

CHAR ffblk::cAlternateFileName[ 14 ]

Definition at line 37 of file pa_dir.h.

HANDLE ffblk::handle

Definition at line 39 of file pa_dir.h.

Referenced by findclose(), findfirst(), and findnext().

The documentation for this struct was generated from the following file:
  • pa_dir.h


Member List

ffblk Member List

This is the complete list of members for ffblk, including all inherited members.
cAlternateFileName | ffblk
dwReserved0 | ffblk
dwReserved1 | ffblk
ff_attrib | ffblk
ff_name | ffblk
ftCreationTime | ffblk
ftLastAccessTime | ffblk
ftLastWriteTime | ffblk
handle | ffblk
nFileSizeHigh | ffblk
nFileSizeLow | ffblk


File_read_result Struct Reference

Collaboration diagram for File_read_result:

[legend]
List of all members.

Public Attributes

bool | success
char * | str
size_t | length
HashStringValue * headers

Member Data Documentation

bool File_read_result::success

Definition at line 105 of file pa_common.h.

Referenced by cache_get(), file_read(), and file_read_text().

char* File_read_result::str

Definition at line 106 of file pa_common.h.

Referenced by _load(), cache_get(), file_read(), file_read_text(), and output_pieces().

size_t File_read_result::length

Definition at line 106 of file pa_common.h.

Referenced by _load(), cache_get(), file_read(), and output_pieces().

HashStringValue* File_read_result::headers

Definition at line 107 of file pa_common.h.

Referenced by _load(), and file_read().

The documentation for this struct was generated from the following file:
  • pa_common.h


Member List

File_read_result Member List

This is the complete list of members for File_read_result, including all inherited members.
headers | File_read_result
length | File_read_result
str | File_read_result
success | File_read_result


Font Class Reference

simple gdImage-based font storage & text output. More...

Inheritance diagram for Font:

[legend]
Collaboration diagram for Font:

[legend]
List of all members.

Public Methods

Font (const String &aalphabet, gdImage *aifont, int aheight, int amonospace, int aspacebarspace)
int | string_width (const String &s)
counts trailing letter_spacing, consider this OK. useful for contiuations. More...

void | string_display (gdImage &image, int x, int y, const String &s)
size_t | index_of (char ch)
******************************** char **********************************. More...

int | index_width (size_t index)
******************************** char **********************************. More...

void | index_display (gdImage &image, int x, int y, size_t index)
******************************** char **********************************. More...

int | step_width (int index)
******************************* string *********************************. More...

Public Attributes

int | height
Font heigth. More...

int | monospace
Default char width. More...

int | spacebarspace
spacebar width. More...

gdImage * ifont
const String & | alphabet

Static Public Attributes

const int | letter_spacing = 1

Detailed Description

simple gdImage-based font storage & text output.

Definition at line 27 of file pa_vimage.h.

Constructor & Destructor Documentation

Font::Font | ( | const String & | aalphabet,
 |  | gdImage * | aifont,
 |  | int | aheight,
 |  | int | amonospace,
 |  | int | aspacebarspace
 | ) |

Definition at line 962 of file image.C.

Member Function Documentation

size_t Font::index_of ( char ch )

******************************** char **********************************.

Definition at line 972 of file image.C.

References alphabet, String::pos(), and STRING_NOT_FOUND.

Referenced by string_display(), and string_width().

int Font::index_width ( size_t index )

******************************** char **********************************.

Definition at line 977 of file image.C.

References gdImage::GetPixel(), gdImage::GetTransparent(), height, ifont, spacebarspace, STRING_NOT_FOUND, gdImage::SX(), and Y.

Referenced by index_display(), and step_width().

void Font::index_display | ( | gdImage & | image,
 |  | int | x,
 |  | int | y,
 |  | size_t | index
 | ) |

******************************** char **********************************.

Definition at line 989 of file image.C.

References gdImage::Copy(), height, ifont, index_width(), STRING_NOT_FOUND, and Y.

Referenced by string_display().

int Font::step_width ( int index )

******************************* string *********************************.

Definition at line 996 of file image.C.

References index_width(), letter_spacing, and monospace.

Referenced by string_display(), and string_width().

int Font::string_width ( const String & s )

counts trailing letter_spacing, consider this OK. useful for contiuations.

Definition at line 1001 of file image.C.

References String::cstr(), index_of(), result, and step_width().

Referenced by _length().

void Font::string_display | ( | gdImage & | image,
 |  | int | x,
 |  | int | y,
 |  | const String & | s
 | ) |

Definition at line 1009 of file image.C.

References String::cstr(), index_display(), index_of(), and step_width().

Referenced by _text().

Member Data Documentation

const int Font::letter_spacing = 1 [static]

Definition at line 960 of file image.C.

Referenced by step_width().

int Font::height

Font heigth.

Definition at line 31 of file pa_vimage.h.

Referenced by index_display(), and index_width().

int Font::monospace

Default char width.

Definition at line 32 of file pa_vimage.h.

Referenced by step_width().

int Font::spacebarspace

spacebar width.

Definition at line 33 of file pa_vimage.h.

Referenced by index_width().

gdImage* Font::ifont

Definition at line 34 of file pa_vimage.h.

Referenced by index_display(), and index_width().

const String& Font::alphabet

Definition at line 35 of file pa_vimage.h.

Referenced by index_of().

The documentation for this class was generated from the following files:
  • pa_vimage.h
  • image.C


Member List

Font Member List

This is the complete list of members for Font, including all inherited members.
alphabet | Font |
Font(const String &aalphabet, gdImage *aifont, int aheight, int amonospace, int aspacebarspace) | Font |
free(void *ptr) | PA_Allocated | [inline, static]
height | Font |
ifont | Font |
index_display(gdImage &image, int x, int y, size_t index) | Font |
index_of(char ch) | Font |
index_width(size_t index) | Font |
letter_spacing | Font | [static]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
monospace | Font |
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
spacebarspace | Font |
step_width(int index) | Font |
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
string_display(gdImage &image, int x, int y, const String &s) | Font |
string_width(const String &s) | Font |


ForestElement Struct Reference

List of all members.

Public Attributes

CORD c
size_t len

Member Data Documentation

CORD ForestElement::c

Definition at line 648 of file cordbscs.c.

Referenced by CORD_add_forest(), CORD_concat_forest(), and CORD_init_forest().

size_t ForestElement::len

Definition at line 649 of file cordbscs.c.

Referenced by CORD_add_forest(), and CORD_concat_forest().

The documentation for this struct was generated from the following file:
  • cordbscs.c


Member List

ForestElement Member List

This is the complete list of members for ForestElement, including all inherited members.
c | ForestElement
len | ForestElement


FT Union Reference

List of all members.

Public Attributes

unsigned __int64 | ft_scalar
FILETIME | ft_struct

Member Data Documentation

unsigned __int64 FT::ft_scalar

Definition at line 56 of file pa_vstatus.C.

Referenced by rusage_element().

FILETIME FT::ft_struct

Definition at line 57 of file pa_vstatus.C.

Referenced by rusage_element().

The documentation for this union was generated from the following file:
  • pa_vstatus.C


Member List

FT Member List

This is the complete list of members for FT, including all inherited members.
ft_scalar | FT
ft_struct | FT


gdBuf Struct Reference

List of all members.

Public Methods

gdBuf (void *aptr, size_t asize)

Public Attributes

void * | ptr
size_t | size

Constructor & Destructor Documentation

gdBuf::gdBuf | ( | void * | aptr,
 |  | size_t | asize
 | ) | [inline]

Definition at line 35 of file gif.h.

References ptr, and size.

Member Data Documentation

void* gdBuf::ptr

Definition at line 32 of file gif.h.

Referenced by _gif(), and gdBuf().

size_t gdBuf::size

Definition at line 33 of file gif.h.

Referenced by _gif(), and gdBuf().

The documentation for this struct was generated from the following file:
  • gif.h


Member List

gdBuf Member List

This is the complete list of members for gdBuf, including all inherited members.
gdBuf(void *aptr, size_t asize) | gdBuf | [inline]
ptr | gdBuf |
size | gdBuf |


gdGifEncoder Class Reference

used by gdImage::Gif to produce buffer with bytes in GIF format. More...

Inheritance diagram for gdGifEncoder:

[legend]
Collaboration diagram for gdGifEncoder:

[legend]
List of all members.

Public Methods

gdGifEncoder (gdImage &aim)
gdBuf | encode (int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue)

Private Types

typedef int | code_int
a code_int must be able to hold 2**GIFBITS values of type int, and also -1. More...

typedef long int | count_int

Private Methods

void | Putbyte (unsigned char c)
void | Putword (int w)
void | Write (void *buf, size_t size)
void | prepare_encoder (void)
void | BumpPixel (void)
int | GIFNextPixel ()
void | compress (int init_bits)
void | output (code_int code)
void | cl_block (void)
void | cl_hash (count_int hsize)
void | char_init (void)
void | char_out (int c)
void | flush_char (void)

Private Attributes

gdImage & im
gdGrowingBuf buf
int | Width
int | Height
int | curx
int | cury
long | CountDown
int | Pass
int | Interlace
int | g_init_bits
int | ClearCode
int | EOFCode
int | n_bits
int | maxbits
code_int maxcode
code_int maxmaxcode
count_int | htab [HSIZE]
unsigned short | codetab [HSIZE]
code_int hsize
code_int free_ent
int | clear_flg
int | offset
long int | in_count
long int | out_count
unsigned long | cur_accum
int | cur_bits
int | a_count
char | accum [256]

Detailed Description

used by gdImage::Gif to produce buffer with bytes in GIF format.

Definition at line 163 of file gif.h.

Member Typedef Documentation

typedef int gdGifEncoder::code_int [private]

a code_int must be able to hold 2**GIFBITS values of type int, and also -1.

Definition at line 177 of file gif.h.

Referenced by compress(), and output().

typedef long int gdGifEncoder::count_int [private]

Definition at line 182 of file gif.h.

Referenced by compress().

Constructor & Destructor Documentation

gdGifEncoder::gdGifEncoder ( gdImage & aim )

Definition at line 683 of file gifio.C.

References a_count, clear_flg, ClearCode, CountDown, cur_accum, cur_bits, curx, cury, EOFCode, free_ent, g_init_bits, GIFBITS, Height, HSIZE, hsize, in_count, Interlace, maxbits, maxcode, maxmaxcode, n_bits, offset, out_count, Pass, and Width.

Member Function Documentation

gdBuf gdGifEncoder::encode | ( | int | GWidth,
 |  | int | GHeight,
 |  | int | GInterlace,
 |  | int | Background,
 |  | int | Transparent,
 |  | int | BitsPerPixel,
 |  | int * | Red,
 |  | int * | Green,
 |  | int * | Blue
 | ) |

Definition at line 174 of file gifio.C.

References buf, compress(), CountDown, curx, cury, Height, Interlace, Pass, Putbyte(), Putword(), and Width.

Referenced by gdImage::Gif().

void gdGifEncoder::Putbyte ( unsigned char c ) [private]

Definition at line 333 of file gifio.C.

References gdGrowingBuf::append(), and buf.

Referenced by encode(), and flush_char().

void gdGifEncoder::Putword ( int w ) [private]

Definition at line 340 of file gifio.C.

References gdGrowingBuf::append(), and buf.

Referenced by encode().

void gdGifEncoder::Write | ( | void * | buf,
 |  | size_t | size
 | ) | [private]

Definition at line 348 of file gifio.C.

References gdGrowingBuf::append(), buf, and size.

Referenced by flush_char().

void gdGifEncoder::prepare_encoder ( void ) [private]

void gdGifEncoder::BumpPixel ( void ) [private]

Definition at line 99 of file gifio.C.

References curx, cury, Height, Interlace, Pass, and Width.

Referenced by GIFNextPixel().

int gdGifEncoder::GIFNextPixel ( ) [private]

Definition at line 155 of file gifio.C.

References BumpPixel(), CountDown, curx, cury, gdImage::GetPixel(), and im.

Referenced by compress().

void gdGifEncoder::compress ( int init_bits ) [private]

Definition at line 425 of file gifio.C.

References char_init(), cl_block(), cl_hash(), clear_flg, ClearCode, code_int, CodeTabOf, count_int, EOFCode, free_ent, g_init_bits, GIFNextPixel(), HashTabOf, hsize, in_count, maxbits, MAXCODE, maxcode, maxmaxcode, n_bits, offset, out_count, and output().

Referenced by encode().

void gdGifEncoder::output ( code_int code ) [private]

Definition at line 542 of file gifio.C.

References char_out(), clear_flg, code_int, cur_accum, cur_bits, EOFCode, flush_char(), free_ent, g_init_bits, masks, maxbits, MAXCODE, maxcode, maxmaxcode, and n_bits.

Referenced by compress().

void gdGifEncoder::cl_block ( void ) [private]

Definition at line 598 of file gifio.C.

Referenced by compress().

void gdGifEncoder::cl_hash ( count_int hsize ) [private]

Definition at line 609 of file gifio.C.

Referenced by compress().

void gdGifEncoder::char_init ( void ) [private]

Definition at line 653 of file gifio.C.

References a_count.

Referenced by compress().

void gdGifEncoder::char_out ( int c ) [private]

Definition at line 663 of file gifio.C.

References a_count, accum, and flush_char().

Referenced by output().

void gdGifEncoder::flush_char ( void ) [private]

Definition at line 674 of file gifio.C.

References a_count, accum, Putbyte(), and Write().

Referenced by char_out(), and output().

Member Data Documentation

gdImage& gdGifEncoder::im [private]

Definition at line 204 of file gif.h.

Referenced by GIFNextPixel().

gdGrowingBuf gdGifEncoder::buf [private]

Definition at line 205 of file gif.h.

Referenced by encode(), Putbyte(), Putword(), and Write().

int gdGifEncoder::Width [private]

Definition at line 207 of file gif.h.

Referenced by BumpPixel(), encode(), and gdGifEncoder().

int gdGifEncoder::Height [private]

Definition at line 207 of file gif.h.

Referenced by BumpPixel(), encode(), and gdGifEncoder().

int gdGifEncoder::curx [private]

Definition at line 208 of file gif.h.

Referenced by BumpPixel(), encode(), gdGifEncoder(), and GIFNextPixel().

int gdGifEncoder::cury [private]

Definition at line 208 of file gif.h.

Referenced by BumpPixel(), encode(), gdGifEncoder(), and GIFNextPixel().

long gdGifEncoder::CountDown [private]

Definition at line 209 of file gif.h.

Referenced by encode(), gdGifEncoder(), and GIFNextPixel().

int gdGifEncoder::Pass [private]

Definition at line 210 of file gif.h.

Referenced by BumpPixel(), encode(), and gdGifEncoder().

int gdGifEncoder::Interlace [private]

Definition at line 211 of file gif.h.

Referenced by BumpPixel(), encode(), and gdGifEncoder().

int gdGifEncoder::g_init_bits [private]

Definition at line 213 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

int gdGifEncoder::ClearCode [private]

Definition at line 215 of file gif.h.

Referenced by compress(), and gdGifEncoder().

int gdGifEncoder::EOFCode [private]

Definition at line 216 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

int gdGifEncoder::n_bits [private]

Definition at line 218 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

int gdGifEncoder::maxbits [private]

Definition at line 219 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

code_int gdGifEncoder::maxcode [private]

Definition at line 221 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

code_int gdGifEncoder::maxmaxcode [private]

Definition at line 222 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

count_int gdGifEncoder::htab[HSIZE] [private]

Definition at line 224 of file gif.h.

unsigned short gdGifEncoder::codetab[HSIZE] [private]

Definition at line 225 of file gif.h.

code_int gdGifEncoder::hsize [private]

Definition at line 226 of file gif.h.

Referenced by compress(), and gdGifEncoder().

code_int gdGifEncoder::free_ent [private]

Definition at line 228 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

int gdGifEncoder::clear_flg [private]

Definition at line 234 of file gif.h.

Referenced by compress(), gdGifEncoder(), and output().

int gdGifEncoder::offset [private]

Definition at line 236 of file gif.h.

Referenced by compress(), and gdGifEncoder().

long int gdGifEncoder::in_count [private]

Definition at line 237 of file gif.h.

Referenced by compress(), and gdGifEncoder().

long int gdGifEncoder::out_count [private]

Definition at line 238 of file gif.h.

Referenced by compress(), and gdGifEncoder().

unsigned long gdGifEncoder::cur_accum [private]

Definition at line 240 of file gif.h.

Referenced by gdGifEncoder(), and output().

int gdGifEncoder::cur_bits [private]

Definition at line 241 of file gif.h.

Referenced by gdGifEncoder(), and output().

int gdGifEncoder::a_count [private]

Definition at line 246 of file gif.h.

Referenced by char_init(), char_out(), flush_char(), and gdGifEncoder().

char gdGifEncoder::accum[ 256 ] [private]

Definition at line 251 of file gif.h.

Referenced by char_out(), and flush_char().

The documentation for this class was generated from the following files:
  • gif.h
  • gifio.C


Member List

gdGifEncoder Member List

This is the complete list of members for gdGifEncoder, including all inherited members.
a_count | gdGifEncoder | [private]
accum | gdGifEncoder | [private]
buf | gdGifEncoder | [private]
BumpPixel(void) | gdGifEncoder | [private]
char_init(void) | gdGifEncoder | [private]
char_out(int c) | gdGifEncoder | [private]
cl_block(void) | gdGifEncoder | [private]
cl_hash(count_int hsize) | gdGifEncoder | [private]
clear_flg | gdGifEncoder | [private]
ClearCode | gdGifEncoder | [private]
code_int typedef | gdGifEncoder | [private]
codetab | gdGifEncoder | [private]
compress(int init_bits) | gdGifEncoder | [private]
count_int typedef | gdGifEncoder | [private]
CountDown | gdGifEncoder | [private]
cur_accum | gdGifEncoder | [private]
cur_bits | gdGifEncoder | [private]
curx | gdGifEncoder | [private]
cury | gdGifEncoder | [private]
encode(int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue) | gdGifEncoder |
EOFCode | gdGifEncoder | [private]
flush_char(void) | gdGifEncoder | [private]
free(void *ptr) | PA_Allocated | [inline, static]
free_ent | gdGifEncoder | [private]
g_init_bits | gdGifEncoder | [private]
gdGifEncoder(gdImage &aim) | gdGifEncoder |
GIFNextPixel() | gdGifEncoder | [private]
Height | gdGifEncoder | [private]
hsize | gdGifEncoder | [private]
htab | gdGifEncoder | [private]
im | gdGifEncoder | [private]
in_count | gdGifEncoder | [private]
Interlace | gdGifEncoder | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maxbits | gdGifEncoder | [private]
maxcode | gdGifEncoder | [private]
maxmaxcode | gdGifEncoder | [private]
n_bits | gdGifEncoder | [private]
offset | gdGifEncoder | [private]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
out_count | gdGifEncoder | [private]
output(code_int code) | gdGifEncoder | [private]
Pass | gdGifEncoder | [private]
prepare_encoder(void) | gdGifEncoder | [private]
Putbyte(unsigned char c) | gdGifEncoder | [private]
Putword(int w) | gdGifEncoder | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
Width | gdGifEncoder | [private]
Write(void *buf, size_t size) | gdGifEncoder | [private]


gdGrowingBuf Class Reference

Inheritance diagram for gdGrowingBuf:

[legend]
Collaboration diagram for gdGrowingBuf:

[legend]
List of all members.

Public Methods

operator gdBuf ()
gdGrowingBuf ()
void | append (unsigned char *abuf, size_t asize)

Private Methods

void | expand (size_t delta)

Private Attributes

unsigned char * | fptr
size_t | fallocated
size_t | fused

Constructor & Destructor Documentation

gdGrowingBuf::gdGrowingBuf ( ) [inline]

Definition at line 51 of file gif.h.

References fallocated, fptr, and fused.

Member Function Documentation

void gdGrowingBuf::expand ( size_t delta ) [inline, private]

Definition at line 43 of file gif.h.

References fallocated, fptr, and PA_Allocated::realloc().

Referenced by append().

gdGrowingBuf::operator gdBuf ( ) [inline]

Definition at line 49 of file gif.h.

References fptr, and fused.

void gdGrowingBuf::append | ( | unsigned char * | abuf,
 |  | size_t | asize
 | ) | [inline]

Definition at line 53 of file gif.h.

References expand(), fallocated, fptr, fused, and ssize_t.

Referenced by gdGifEncoder::Putbyte(), gdGifEncoder::Putword(), and gdGifEncoder::Write().

Member Data Documentation

unsigned char* gdGrowingBuf::fptr [private]

Definition at line 39 of file gif.h.

Referenced by append(), expand(), gdGrowingBuf(), and operator gdBuf().

size_t gdGrowingBuf::fallocated [private]

Definition at line 40 of file gif.h.

Referenced by append(), expand(), and gdGrowingBuf().

size_t gdGrowingBuf::fused [private]

Definition at line 41 of file gif.h.

Referenced by append(), gdGrowingBuf(), and operator gdBuf().

The documentation for this class was generated from the following file:
  • gif.h


Member List

gdGrowingBuf Member List

This is the complete list of members for gdGrowingBuf, including all inherited members.
append(unsigned char *abuf, size_t asize) | gdGrowingBuf | [inline]
expand(size_t delta) | gdGrowingBuf | [inline, private]
fallocated | gdGrowingBuf | [private]
fptr | gdGrowingBuf | [private]
free(void *ptr) | PA_Allocated | [inline, private, static]
fused | gdGrowingBuf | [private]
gdGrowingBuf() | gdGrowingBuf | [inline]
malloc(size_t size) | PA_Allocated | [inline, private, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, private, static]
operator delete(void *ptr) | PA_Allocated | [inline, private, static]
operator gdBuf() | gdGrowingBuf | [inline]
operator new(size_t size) | PA_Allocated | [inline, private, static]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, private, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, private, static]


gdImage Class Reference

Image type. More...

Inheritance diagram for gdImage:

[legend]
Collaboration diagram for gdImage:

[legend]
List of all members.

Public Methods

void | Polygon (Point *p, int n, int c, bool closed=true)
void | FilledPolygon (Point *p, int n, int c)
void | FilledPolygonReplaceColor (Point *p, int n, int a, int b)
int | ColorAllocate (int r, int g, int b)
int | ColorClosest (int r, int g, int b, int tolerance=0)
int | ColorExact (int r, int g, int b)
int | ColorRGB (int r, int g, int b)
int | Color (unsigned int rgb)
unsigned int | DecodeColor (int color)
void | ColorDeallocate (int color)
void | SetColorTransparent (int color)
int | BoundsSafe (int x, int y)
void | DoSetPixel (int x, int y, int color)
gdBuf Gif ()
void | Arc (int cx, int cy, int w, int h, int s, int e, int color)
void | Sector (int cx, int cy, int w, int h, int s, int e, int color)
void | FillToBorder (int x, int y, int border, int color)
void | Fill (int x, int y, int color)
void | Copy (gdImage &dst, int dstX, int dstY, int srcX, int srcY, int w, int h)
void | CopyResampled (gdImage &dst, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH, int tolerance)
void | SetLineWidth (int width)
void | SetLineStyle (const char *aLineStyle)
void | SetInterlace (int interlaceArg)
Functions to manipulate images
void | Create (int asx, int asy)
bool | CreateFromGif (FILE *fd)
void | SetPixel (int x, int y, int color)
int | GetPixel (int x, int y)
void | Line (int x1, int y1, int x2, int y2, int color)
void | StyledLine (int x1, int y1, int x2, int y2, int color, const char *lineStyle)
void | Rectangle (int x1, int y1, int x2, int y2, int color)
void | LineReplaceColor (int x1, int y1, int x2, int y2, int a, int b)
void | FilledRectangle (int x1, int y1, int x2, int y2, int color)
information about image. READ ONLY
int | SX ()
int | SY ()
int | ColorsTotal ()
int | Red (int c)
int | Green (int c)
int | Blue (int c)
int | GetTransparent ()
int | GetInterlaced ()

Private Methods

int | GetDataBlock (FILE *fd, unsigned char *buf)
int | LWZReadByte (FILE *fd, int flag, int input_code_size)
void | ReadImage (FILE *fd, int len, int height, unsigned char(*cmap)[256], int interlace, int ignore)
int | DoExtension (FILE *fd, int label, int *Transparent)
int | GetCode (FILE *fd, int code_size, int flag)

Private Attributes

unsigned char ** | pixels
int | sx
int | sy
int | colorsTotal
int | red [gdMaxColors]
int | green [gdMaxColors]
int | blue [gdMaxColors]
int | open [gdMaxColors]
int | transparent
int * | polyInts
int | polyAllocated
int | lineWidth
const char * | lineStyle
int | interlace
int | ZeroDataBlock

Detailed Description

Image type.

See functions below; you will not need to change the elements directly. Use the provided macros to access sx, sy, the color table, and colorsTotal for read-only purposes.

Definition at line 69 of file gif.h.

Member Function Documentation

void gdImage::Create | ( | int | asx,
 |  | int | asy
 | ) |

Definition at line 27 of file gif.C.

References colorsTotal, interlace, lineWidth, PA_Allocated::malloc(), PA_Allocated::malloc_atomic(), pixels, polyAllocated, polyInts, sx, sy, and transparent.

Referenced by _create(), and CreateFromGif().

bool gdImage::CreateFromGif ( FILE * fd )

Definition at line 773 of file gifio.C.

References BitSet, colorsTotal, Create(), DoExtension(), FALSE, INTERLACE, interlace, LM_to_uint, LOCALCOLORMAP, MAXCOLORMAPSIZE, open, ReadColorMap(), ReadImage(), ReadOK, SetColorTransparent(), and ZeroDataBlock.

Referenced by load().

void gdImage::SetPixel | ( | int | x,
 |  | int | y,
 |  | int | color
 | ) |

Definition at line 133 of file gif.C.

References DoSetPixel().

Referenced by _pixel(), Arc(), Copy(), CopyResampled(), FilledRectangle(), FillToBorder(), and ReadImage().

int gdImage::GetPixel | ( | int | x,
 |  | int | y
 | ) |

Definition at line 160 of file gif.C.

References BoundsSafe(), and pixels.

Referenced by _pixel(), Copy(), CopyResampled(), Fill(), FillToBorder(), gdGifEncoder::GIFNextPixel(), and Font::index_width().

void gdImage::Line | ( | int | x1,
 |  | int | y1,
 |  | int | x2,
 |  | int | y2,
 |  | int | color
 | ) |

Definition at line 181 of file gif.C.

References styledSet.

Referenced by _line(), Arc(), FilledPolygon(), Polygon(), Rectangle(), and Sector().

void gdImage::StyledLine | ( | int | x1,
 |  | int | y1,
 |  | int | x2,
 |  | int | y2,
 |  | int | color,
 |  | const char * | lineStyle
 | ) |

void gdImage::Rectangle | ( | int | x1,
 |  | int | y1,
 |  | int | x2,
 |  | int | y2,
 |  | int | color
 | ) |

Definition at line 575 of file gif.C.

References Line().

Referenced by _rectangle().

void gdImage::LineReplaceColor | ( | int | x1,
 |  | int | y1,
 |  | int | x2,
 |  | int | y2,
 |  | int | a,
 |  | int | b
 | ) |

Definition at line 927 of file gif.C.

References BoundsSafe(), and pixels.

Referenced by FilledPolygonReplaceColor().

void gdImage::FilledRectangle | ( | int | x1,
 |  | int | y1,
 |  | int | x2,
 |  | int | y2,
 |  | int | color
 | ) |

Definition at line 583 of file gif.C.

References SetPixel().

Referenced by _bar(), and _create().

void gdImage::Polygon | ( | Point * | p,
 |  | int | n,
 |  | int | c,
 |  | bool | closed = true
 | ) |

Definition at line 787 of file gif.C.

References Line(), p, gdImage::Point::x, and gdImage::Point::y.

Referenced by _polygon(), and _polyline().

void gdImage::FilledPolygon | ( | Point * | p,
 |  | int | n,
 |  | int | c
 | ) |

Definition at line 813 of file gif.C.

References dir, gdCompareInt(), Line(), PA_Allocated::malloc(), p, polyAllocated, polyInts, PA_Allocated::realloc(), gdImage::Point::x, and gdImage::Point::y.

Referenced by _polybar().

void gdImage::FilledPolygonReplaceColor | ( | Point * | p,
 |  | int | n,
 |  | int | a,
 |  | int | b
 | ) |

Definition at line 939 of file gif.C.

References dir, gdCompareInt(), LineReplaceColor(), PA_Allocated::malloc(), p, polyAllocated, polyInts, PA_Allocated::realloc(), gdImage::Point::x, and gdImage::Point::y.

Referenced by _replace().

int gdImage::ColorAllocate | ( | int | r,
 |  | int | g,
 |  | int | b
 | ) |

Definition at line 82 of file gif.C.

References blue, colorsTotal, gdMaxColors, green, open, and red.

Referenced by ColorRGB(), Copy(), and CopyResampled().

int gdImage::ColorClosest | ( | int | r,
 |  | int | g,
 |  | int | b,
 |  | int | tolerance = 0
 | ) |

Definition at line 43 of file gif.C.

References blue, green, open, and red.

Referenced by Copy(), and CopyResampled().

int gdImage::ColorExact | ( | int | r,
 |  | int | g,
 |  | int | b
 | ) |

Definition at line 66 of file gif.C.

References blue, green, open, and red.

Referenced by ColorRGB(), Copy(), and CopyResampled().

int gdImage::ColorRGB | ( | int | r,
 |  | int | g,
 |  | int | b
 | ) |

Definition at line 106 of file gif.C.

References ColorAllocate(), and ColorExact().

Referenced by Color().

int gdImage::Color ( unsigned int rgb )

Definition at line 111 of file gif.C.

References ColorRGB().

Referenced by _arc(), _bar(), _circle(), _create(), _fill(), _line(), _pixel(), _polybar(), _polygon(), _polyline(), _rectangle(), _replace(), and _sector().

unsigned int gdImage::DecodeColor ( int color )

Definition at line 115 of file gif.C.

References blue, green, and red.

Referenced by _pixel().

void gdImage::ColorDeallocate ( int color )

Definition at line 121 of file gif.C.

References open.

void gdImage::SetColorTransparent ( int color )

Definition at line 127 of file gif.C.

References transparent.

Referenced by CreateFromGif().

int gdImage::BoundsSafe | ( | int | x,
 |  | int | y
 | ) | [inline]

Definition at line 255 of file gif.h.

References sx, and sy.

Referenced by DoSetPixel(), Fill(), FillToBorder(), GetPixel(), and LineReplaceColor().

void gdImage::DoSetPixel | ( | int | x,
 |  | int | y,
 |  | int | color
 | ) | [inline]

Definition at line 259 of file gif.h.

References BoundsSafe(), and pixels.

Referenced by Fill(), and SetPixel().

gdBuf gdImage::Gif ( )

Definition at line 44 of file gifio.C.

References blue, colorstobpp(), colorsTotal, gdGifEncoder::encode(), green, interlace, red, sx, sy, and transparent.

Referenced by _gif().

void gdImage::Arc | ( | int | cx,
 |  | int | cy,
 |  | int | w,
 |  | int | h,
 |  | int | s,
 |  | int | e,
 |  | int | color
 | ) |

Definition at line 279 of file gif.C.

References cost, costScale, Line(), SetPixel(), sint, and sintScale.

Referenced by _arc(), and _circle().

void gdImage::Sector | ( | int | cx,
 |  | int | cy,
 |  | int | w,
 |  | int | h,
 |  | int | s,
 |  | int | e,
 |  | int | color
 | ) |

Definition at line 406 of file gif.C.

References cost, costScale, Line(), sint, and sintScale.

Referenced by _sector().

void gdImage::FillToBorder | ( | int | x,
 |  | int | y,
 |  | int | border,
 |  | int | color
 | ) |

Definition at line 435 of file gif.C.

References BoundsSafe(), GetPixel(), SetPixel(), and sx.

void gdImage::Fill | ( | int | x,
 |  | int | y,
 |  | int | color
 | ) |

Definition at line 505 of file gif.C.

References BoundsSafe(), DoSetPixel(), GetPixel(), and sx.

Referenced by _fill().

void gdImage::Copy | ( | gdImage & | dst,
 |  | int | dstX,
 |  | int | dstY,
 |  | int | srcX,
 |  | int | srcY,
 |  | int | w,
 |  | int | h
 | ) |

Definition at line 602 of file gif.C.

References blue, ColorAllocate(), ColorClosest(), ColorExact(), gdMaxColors, GetPixel(), GetTransparent(), green, red, and SetPixel().

Referenced by _copy(), and Font::index_display().

void gdImage::CopyResampled | ( | gdImage & | dst,
 |  | int | dstX,
 |  | int | dstY,
 |  | int | srcX,
 |  | int | srcY,
 |  | int | dstW,
 |  | int | dstH,
 |  | int | srcW,
 |  | int | srcH,
 |  | int | tolerance
 | ) |

Definition at line 656 of file gif.C.

References Blue(), blue, ColorAllocate(), ColorClosest(), ColorExact(), GetPixel(), GetTransparent(), Green(), green, p, Red(), red, SetPixel(), sx, sy, and transparent.

Referenced by _copy().

void gdImage::SetLineWidth ( int width )

Definition at line 1059 of file gif.C.

References lineWidth.

Referenced by VImage::put_element().

void gdImage::SetLineStyle ( const char * aLineStyle )

Definition at line 1064 of file gif.C.

References lineStyle.

Referenced by VImage::put_element().

void gdImage::SetInterlace ( int interlaceArg )

Definition at line 1054 of file gif.C.

References interlace.

int gdImage::SX ( ) [inline]

Definition at line 122 of file gif.h.

References sx.

Referenced by _font(), _load(), and Font::index_width().

int gdImage::SY ( ) [inline]

Definition at line 123 of file gif.h.

References sy.

Referenced by _font(), and _load().

int gdImage::ColorsTotal ( ) [inline]

Definition at line 124 of file gif.h.

References colorsTotal.

int gdImage::Red ( int c ) [inline]

Definition at line 125 of file gif.h.

References red.

Referenced by CopyResampled().

int gdImage::Green ( int c ) [inline]

Definition at line 126 of file gif.h.

References green.

Referenced by CopyResampled().

int gdImage::Blue ( int c ) [inline]

Definition at line 127 of file gif.h.

References blue.

Referenced by CopyResampled().

int gdImage::GetTransparent ( ) [inline]

Definition at line 128 of file gif.h.

References transparent.

Referenced by Copy(), CopyResampled(), and Font::index_width().

int gdImage::GetInterlaced ( ) [inline]

Definition at line 129 of file gif.h.

References interlace.

int gdImage::GetDataBlock | ( | FILE * | fd,
 |  | unsigned char * | buf
 | ) | [private]

Definition at line 933 of file gifio.C.

References ReadOK, and ZeroDataBlock.

Referenced by DoExtension(), GetCode(), and LWZReadByte().

int gdImage::LWZReadByte | ( | FILE * | fd,
 |  | int | flag,
 |  | int | input_code_size
 | ) | [private]

Definition at line 991 of file gifio.C.

References FALSE, GetCode(), GetDataBlock(), MAX_LWZ_BITS, and TRUE.

Referenced by ReadImage().

void gdImage::ReadImage | ( | FILE * | fd,
 |  | int | len,
 |  | int | height,
 |  | unsigned char * | cmap[256],
 |  | int | interlace,
 |  | int | ignore
 | ) | [private]

Definition at line 1102 of file gifio.C.

References blue, CM_BLUE, CM_GREEN, CM_RED, colorsTotal, FALSE, gdMaxColors, green, LWZReadByte(), open, ReadOK, red, SetPixel(), TRUE, and v.

Referenced by CreateFromGif().

int gdImage::DoExtension | ( | FILE * | fd,
 |  | int | label,
 |  | int * | Transparent
 | ) | [private]

Definition at line 905 of file gifio.C.

References FALSE, GetDataBlock(), and LM_to_uint.

Referenced by CreateFromGif().

int gdImage::GetCode | ( | FILE * | fd,
 |  | int | code_size,
 |  | int | flag
 | ) | [private]

Definition at line 950 of file gifio.C.

References FALSE, GetDataBlock(), and TRUE.

Referenced by LWZReadByte().

Member Data Documentation

unsigned char** gdImage::pixels [private]

Definition at line 134 of file gif.h.

Referenced by Create(), DoSetPixel(), GetPixel(), and LineReplaceColor().

int gdImage::sx [private]

Definition at line 135 of file gif.h.

Referenced by BoundsSafe(), CopyResampled(), Create(), Fill(), FillToBorder(), Gif(), and SX().

int gdImage::sy [private]

Definition at line 136 of file gif.h.

Referenced by BoundsSafe(), CopyResampled(), Create(), Gif(), and SY().

int gdImage::colorsTotal [private]

Definition at line 137 of file gif.h.

Referenced by ColorAllocate(), ColorsTotal(), Create(), CreateFromGif(), Gif(), and ReadImage().

int gdImage::red[gdMaxColors] [private]

Definition at line 138 of file gif.h.

Referenced by ColorAllocate(), ColorClosest(), ColorExact(), Copy(), CopyResampled(), DecodeColor(), Gif(), ReadImage(), and Red().

int gdImage::green[gdMaxColors] [private]

Definition at line 139 of file gif.h.

Referenced by ColorAllocate(), ColorClosest(), ColorExact(), Copy(), CopyResampled(), DecodeColor(), Gif(), Green(), and ReadImage().

int gdImage::blue[gdMaxColors] [private]

Definition at line 140 of file gif.h.

Referenced by Blue(), ColorAllocate(), ColorClosest(), ColorExact(), Copy(), CopyResampled(), DecodeColor(), Gif(), and ReadImage().

int gdImage::open[gdMaxColors] [private]

Definition at line 141 of file gif.h.

Referenced by ColorAllocate(), ColorClosest(), ColorDeallocate(), ColorExact(), CreateFromGif(), and ReadImage().

int gdImage::transparent [private]

Definition at line 142 of file gif.h.

Referenced by CopyResampled(), Create(), GetTransparent(), Gif(), and SetColorTransparent().

int* gdImage::polyInts [private]

Definition at line 143 of file gif.h.

Referenced by Create(), FilledPolygon(), and FilledPolygonReplaceColor().

int gdImage::polyAllocated [private]

Definition at line 144 of file gif.h.

Referenced by Create(), FilledPolygon(), and FilledPolygonReplaceColor().

int gdImage::lineWidth [private]

Definition at line 145 of file gif.h.

Referenced by Create(), and SetLineWidth().

const char* gdImage::lineStyle [private]

Definition at line 145 of file gif.h.

Referenced by SetLineStyle().

int gdImage::interlace [private]

Definition at line 146 of file gif.h.

Referenced by Create(), CreateFromGif(), GetInterlaced(), Gif(), and SetInterlace().

int gdImage::ZeroDataBlock [private]

Definition at line 158 of file gif.h.

Referenced by CreateFromGif(), and GetDataBlock().

The documentation for this class was generated from the following files:
  • gif.h
  • gif.C
  • gifio.C


Member List

gdImage Member List

This is the complete list of members for gdImage, including all inherited members.
Arc(int cx, int cy, int w, int h, int s, int e, int color) | gdImage |
blue | gdImage | [private]
Blue(int c) | gdImage | [inline]
BoundsSafe(int x, int y) | gdImage | [inline]
Color(unsigned int rgb) | gdImage |
ColorAllocate(int r, int g, int b) | gdImage |
ColorClosest(int r, int g, int b, int tolerance=0) | gdImage |
ColorDeallocate(int color) | gdImage |
ColorExact(int r, int g, int b) | gdImage |
ColorRGB(int r, int g, int b) | gdImage |
ColorsTotal() | gdImage | [inline]
colorsTotal | gdImage | [private]
Copy(gdImage &dst, int dstX, int dstY, int srcX, int srcY, int w, int h) | gdImage |
CopyResampled(gdImage &dst, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH, int tolerance) | gdImage |
Create(int asx, int asy) | gdImage |
CreateFromGif(FILE *fd) | gdImage |
DecodeColor(int color) | gdImage |
DoExtension(FILE *fd, int label, int *Transparent) | gdImage | [private]
DoSetPixel(int x, int y, int color) | gdImage | [inline]
Fill(int x, int y, int color) | gdImage |
FilledPolygon(Point *p, int n, int c) | gdImage |
FilledPolygonReplaceColor(Point *p, int n, int a, int b) | gdImage |
FilledRectangle(int x1, int y1, int x2, int y2, int color) | gdImage |
FillToBorder(int x, int y, int border, int color) | gdImage |
free(void *ptr) | PA_Allocated | [inline, static]
GetCode(FILE *fd, int code_size, int flag) | gdImage | [private]
GetDataBlock(FILE *fd, unsigned char *buf) | gdImage | [private]
GetInterlaced() | gdImage | [inline]
GetPixel(int x, int y) | gdImage |
GetTransparent() | gdImage | [inline]
Gif() | gdImage |
Green(int c) | gdImage | [inline]
green | gdImage | [private]
interlace | gdImage | [private]
Line(int x1, int y1, int x2, int y2, int color) | gdImage |
LineReplaceColor(int x1, int y1, int x2, int y2, int a, int b) | gdImage |
lineStyle | gdImage | [private]
lineWidth | gdImage | [private]
LWZReadByte(FILE *fd, int flag, int input_code_size) | gdImage | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
open | gdImage | [private]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
pixels | gdImage | [private]
polyAllocated | gdImage | [private]
Polygon(Point *p, int n, int c, bool closed=true) | gdImage |
polyInts | gdImage | [private]
ReadImage(FILE *fd, int len, int height, unsigned char(*cmap)[256], int interlace, int ignore) | gdImage | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
Rectangle(int x1, int y1, int x2, int y2, int color) | gdImage |
red | gdImage | [private]
Red(int c) | gdImage | [inline]
Sector(int cx, int cy, int w, int h, int s, int e, int color) | gdImage |
SetColorTransparent(int color) | gdImage |
SetInterlace(int interlaceArg) | gdImage |
SetLineStyle(const char *aLineStyle) | gdImage |
SetLineWidth(int width) | gdImage |
SetPixel(int x, int y, int color) | gdImage |
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
StyledLine(int x1, int y1, int x2, int y2, int color, const char *lineStyle) | gdImage |
sx | gdImage | [private]
SX() | gdImage | [inline]
SY() | gdImage | [inline]
sy | gdImage | [private]
transparent | gdImage | [private]
ZeroDataBlock | gdImage | [private]


gdImage::Point Struct Reference

Point type for use in polygon drawing. More...

List of all members.

Public Attributes

int | x
int | y

Detailed Description

Point type for use in polygon drawing.

Definition at line 87 of file gif.h.

Member Data Documentation

int gdImage::Point::x

Definition at line 88 of file gif.h.

Referenced by gdImage::FilledPolygon(), gdImage::FilledPolygonReplaceColor(), and gdImage::Polygon().

int gdImage::Point::y

Definition at line 88 of file gif.h.

Referenced by gdImage::FilledPolygon(), gdImage::FilledPolygonReplaceColor(), and gdImage::Polygon().

The documentation for this struct was generated from the following file:
  • gif.h


Member List

gdImage::Point Member List

This is the complete list of members for gdImage::Point, including all inherited members.
x | gdImage::Point
y | gdImage::Point


GIF_Header Struct Reference

GIF file header. More...

List of all members.

Public Attributes

char | signature [3]
char | version [3]
uchar | width [2]
uchar | height [2]
char | dif
char | fonColor
char | nulls

Detailed Description

GIF file header.

Definition at line 255 of file image.C.

Member Data Documentation

char GIF_Header::signature[3]

Definition at line 256 of file image.C.

Referenced by measure_gif().

char GIF_Header::version[3]

Definition at line 257 of file image.C.

uchar GIF_Header::width[2]

Definition at line 258 of file image.C.

Referenced by measure_gif().

uchar GIF_Header::height[2]

Definition at line 259 of file image.C.

Referenced by measure_gif().

char GIF_Header::dif

Definition at line 260 of file image.C.

char GIF_Header::fonColor

Definition at line 261 of file image.C.

char GIF_Header::nulls

Definition at line 262 of file image.C.

The documentation for this struct was generated from the following file:
  • image.C


Member List

GIF_Header Member List

This is the complete list of members for GIF_Header, including all inherited members.
dif | GIF_Header
fonColor | GIF_Header
height | GIF_Header
nulls | GIF_Header
signature | GIF_Header
version | GIF_Header
width | GIF_Header


TemplateHash class Reference

Hash< K, V > Class Template Reference

Simple hash. More...

Inheritance diagram for Hash:

[legend]
Collaboration diagram for Hash< K, V >:

[legend]
List of all members.

Public Types

typedef K | key_type
typedef V | value_type

Public Methods

Hash ()
Hash (const Hash &source)
bool | put (K key, V value)
put a [value] under the [key]
Returns:
existed or not.
 More...

template<typename R, typename F, typename I> R | replace_maybe_append (K key, V value, F prevent, I info)
put a [value] under the [key]
Returns:
existed or not.
 More...

template<typename R, typename F1, typename F2, typename I> R | maybe_replace_maybe_append (K key, V value, F1 prevent_replace, F2 prevent_append, I info)
put a [value] under the [key]
Returns:
existed or not.
 More...

template<typename R, typename F1, typename I> R | maybe_replace_never_append (K key, V value, F1 prevent_replace, I info)
put a [value] under the [key]
Returns:
existed or not.
 More...

bool | remove (K key)
remove the [key]
Returns:
existed or not.
 More...

V | get (K key) const
get associated [value] by the [key]. More...

bool | put_replaced (K key, V value)
put a [value] under the [key] if that [key] existed
Returns:
existed or not.
 More...

template<typename R, typename F> R | maybe_put_replaced (K key, V value, F prevent)
put a [value] under the [key] if that [key] existed
Returns:
existed or not.
 More...

bool | put_dont_replace (K key, V value)
put a [value] under the [key] if that [key] NOT existed
Returns:
existed or not.
 More...

void | merge_dont_replace (const Hash &src)
put all 'src' values if NO with same key existed. More...

int | count () const
number of elements in hash. More...

template<typename I> void | for_each (void callback(K, V, I), I info) const
iterate over all pairs. More...

template<typename I> void | for_each_ref (void callback(K, V &, I), I info) const
iterate over all pairs. More...

template<typename I> V | first_that (bool callback(K, V, I), I info) const
iterate over all pairs until condition becomes true, return that element. More...

void | clear ()
remove all elements. More...

Private Types

enum | { THRESHOLD_PERCENT = 75 }
expand when these %% of allocated exausted. More...

Private Methods

bool | is_full ()
filled to threshold: needs expanding. More...

void | expand ()
allocate larger buffer & rehash. More...

Hash & | operator= (const Hash &)

Private Attributes

int | allocates_index
the index of [allocated] in [Hash_allocates]. More...

int | allocated
number of allocated pairs. More...

int | threshold
helper: expanding when fused_refs == threshold. More...

int | fused_refs
used pairs. More...

int | fpairs_count
stored pairs total (including those by links). More...

Hash::Pair ** refs
pair storage. More...

Detailed Description

template<typename K, typename V>
class Hash< K, V >

Simple hash.

Automatically rehashed when almost is_full. Contains no 0 values. get returning 0 means there were no such. "put value 0" means "remove"

Definition at line 45 of file pa_hash.h.

Member Typedef Documentation

template<typename K, typename V>
typedef K Hash< K, V >::key_type

Definition at line 48 of file pa_hash.h.

template<typename K, typename V>
typedef V Hash< K, V >::value_type

Definition at line 49 of file pa_hash.h.

Member Enumeration Documentation

template<typename K, typename V>
anonymous enum [private]

expand when these %% of allocated exausted.

Enumeration values:
THRESHOLD_PERCENT

Definition at line 362 of file pa_hash.h.

Constructor & Destructor Documentation

template<typename K, typename V>
Hash< K, V >::Hash ( ) [inline]

Definition at line 51 of file pa_hash.h.

template<typename K, typename V>
Hash< K, V >::Hash ( const Hash< K, V > & source ) [inline]

Definition at line 58 of file pa_hash.h.

Member Function Documentation

template<typename K, typename V>
bool Hash< K, V >::put | ( | K | key,
 |  | V | value
 | ) | [inline]

put a [value] under the [key]

Returns:
existed or not.

Definition at line 80 of file pa_hash.h.

Referenced by _exec_cgi(), pa_register_thread_request(), Temp_hash_value< K, V >::Temp_hash_value(), and Temp_hash_value< K, V >::~Temp_hash_value().

template<typename K, typename V>
template<typename R, typename F, typename I>
R Hash< K, V >::replace_maybe_append | ( | K | key,
 |  | V | value,
 |  | F | prevent,
 |  | I | info
 | ) | [inline]

put a [value] under the [key]

Returns:
existed or not.

Definition at line 107 of file pa_hash.h.

template<typename K, typename V>
template<typename R, typename F1, typename F2, typename I>
R Hash< K, V >::maybe_replace_maybe_append | ( | K | key,
 |  | V | value,
 |  | F1 | prevent_replace,
 |  | F2 | prevent_append,
 |  | I | info
 | ) | [inline]

put a [value] under the [key]

Returns:
existed or not.

Definition at line 143 of file pa_hash.h.

template<typename K, typename V>
template<typename R, typename F1, typename I>
R Hash< K, V >::maybe_replace_never_append | ( | K | key,
 |  | V | value,
 |  | F1 | prevent_replace,
 |  | I | info
 | ) | [inline]

put a [value] under the [key]

Returns:
existed or not.

Definition at line 185 of file pa_hash.h.

template<typename K, typename V>
bool Hash< K, V >::remove ( K key ) [inline]

remove the [key]

Returns:
existed or not.

Definition at line 216 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Hash< const String::Body, void * >::put_replaced(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
V Hash< K, V >::get ( K key ) const [inline]

get associated [value] by the [key].

Definition at line 233 of file pa_hash.h.

Referenced by Charsets::get(), VStateless_class::get_method(), Charsets::load_charset(), and pa_thread_request().

template<typename K, typename V>
bool Hash< K, V >::put_replaced | ( | K | key,
 |  | V | value
 | ) | [inline]

put a [value] under the [key] if that [key] existed

Returns:
existed or not.

Definition at line 244 of file pa_hash.h.

template<typename K, typename V>
template<typename R, typename F>
R Hash< K, V >::maybe_put_replaced | ( | K | key,
 |  | V | value,
 |  | F | prevent
 | ) | [inline]

put a [value] under the [key] if that [key] existed

Returns:
existed or not.

Definition at line 263 of file pa_hash.h.

template<typename K, typename V>
bool Hash< K, V >::put_dont_replace | ( | K | key,
 |  | V | value
 | ) | [inline]

put a [value] under the [key] if that [key] NOT existed

Returns:
existed or not.

Definition at line 289 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::merge_dont_replace().

template<typename K, typename V>
void Hash< K, V >::merge_dont_replace ( const Hash< K, V > & src ) [inline]

put all 'src' values if NO with same key existed.

Todo:
optimize this.allocated==src.allocated case

Definition at line 317 of file pa_hash.h.

template<typename K, typename V>
int Hash< K, V >::count ( ) const [inline]

number of elements in hash.

Definition at line 324 of file pa_hash.h.

Referenced by pa_exec().

template<typename K, typename V>
template<typename I>
void Hash< K, V >::for_each | ( | void callback(K, V, I) | ,
 |  | I | info
 | ) | const [inline]

iterate over all pairs.

Definition at line 327 of file pa_hash.h.

Referenced by pa_exec().

template<typename K, typename V>
template<typename I>
void Hash< K, V >::for_each_ref | ( | void callback(K, V &, I) | ,
 |  | I | info
 | ) | const [inline]

iterate over all pairs.

Definition at line 335 of file pa_hash.h.

template<typename K, typename V>
template<typename I>
V Hash< K, V >::first_that | ( | bool callback(K, V, I) | ,
 |  | I | info
 | ) | const [inline]

iterate over all pairs until condition becomes true, return that element.

Definition at line 343 of file pa_hash.h.

template<typename K, typename V>
void Hash< K, V >::clear ( ) [inline]

remove all elements.

Definition at line 354 of file pa_hash.h.

template<typename K, typename V>
bool Hash< K, V >::is_full ( ) [inline, private]

filled to threshold: needs expanding.

Definition at line 397 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
void Hash< K, V >::expand ( ) [inline, private]

allocate larger buffer & rehash.

Definition at line 400 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
Hash& Hash< K, V >::operator= ( const Hash< K, V > & ) [inline, private]

Definition at line 429 of file pa_hash.h.

Member Data Documentation

template<typename K, typename V>
int Hash< K, V >::allocates_index [private]

the index of [allocated] in [Hash_allocates].

Definition at line 367 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::expand(), and Hash< const String::Body, void * >::Hash().

template<typename K, typename V>
int Hash< K, V >::allocated [private]

number of allocated pairs.

Definition at line 370 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::clear(), Hash< const String::Body, void * >::expand(), Hash< const String::Body, void * >::first_that(), Hash< const String::Body, void * >::for_each(), Hash< const String::Body, void * >::for_each_ref(), Hash< const String::Body, void * >::get(), Hash< const String::Body, void * >::Hash(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::merge_dont_replace(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Hash< const String::Body, void * >::put_replaced(), Hash< const String::Body, void * >::remove(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
int Hash< K, V >::threshold [private]

helper: expanding when fused_refs == threshold.

Definition at line 373 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::expand(), Hash< const String::Body, void * >::Hash(), and Hash< const String::Body, void * >::is_full().

template<typename K, typename V>
int Hash< K, V >::fused_refs [private]

used pairs.

Definition at line 376 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::clear(), Hash< const String::Body, void * >::Hash(), Hash< const String::Body, void * >::is_full(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
int Hash< K, V >::fpairs_count [private]

stored pairs total (including those by links).

Definition at line 379 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::clear(), Hash< const String::Body, void * >::count(), Hash< const String::Body, void * >::Hash(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Hash< const String::Body, void * >::remove(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
Hash::Pair ** Hash< K, V >::refs [private]

pair storage.

Referenced by Hash< const String::Body, void * >::clear(), Hash< const String::Body, void * >::expand(), Hash< const String::Body, void * >::first_that(), Hash< const String::Body, void * >::for_each(), Hash< const String::Body, void * >::for_each_ref(), Hash< const String::Body, void * >::get(), Hash< const String::Body, void * >::Hash(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), Hash< const String::Body, void * >::merge_dont_replace(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Hash< const String::Body, void * >::put_replaced(), Hash< const String::Body, void * >::remove(), and Hash< const String::Body, void * >::replace_maybe_append().

The documentation for this class was generated from the following file:
  • pa_hash.h


Member List

Hash< K, V > Member List

This is the complete list of members for Hash< K, V >, including all inherited members.
allocated | Hash< K, V > | [private]
allocates_index | Hash< K, V > | [private]
clear() | Hash< K, V > | [inline]
count() const | Hash< K, V > | [inline]
expand() | Hash< K, V > | [inline, private]
first_that(bool callback(K, V, I), I info) const | Hash< K, V > | [inline]
for_each(void callback(K, V, I), I info) const | Hash< K, V > | [inline]
for_each_ref(void callback(K, V &, I), I info) const | Hash< K, V > | [inline]
fpairs_count | Hash< K, V > | [private]
free(void *ptr) | PA_Allocated | [inline, static]
fused_refs | Hash< K, V > | [private]
get(K key) const | Hash< K, V > | [inline]
Hash() | Hash< K, V > | [inline]
Hash(const Hash &source) | Hash< K, V > | [inline]
is_full() | Hash< K, V > | [inline, private]
key_type typedef | Hash< K, V > |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_put_replaced(K key, V value, F prevent) | Hash< K, V > | [inline]
maybe_replace_maybe_append(K key, V value, F1 prevent_replace, F2 prevent_append, I info) | Hash< K, V > | [inline]
maybe_replace_never_append(K key, V value, F1 prevent_replace, I info) | Hash< K, V > | [inline]
merge_dont_replace(const Hash &src) | Hash< K, V > | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator=(const Hash &) | Hash< K, V > | [inline, private]
put(K key, V value) | Hash< K, V > | [inline]
put_dont_replace(K key, V value) | Hash< K, V > | [inline]
put_replaced(K key, V value) | Hash< K, V > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
refs | Hash< K, V > | [private]
remove(K key) | Hash< K, V > | [inline]
replace_maybe_append(K key, V value, F prevent, I info) | Hash< K, V > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
threshold | Hash< K, V > | [private]
THRESHOLD_PERCENT enum value | Hash< K, V > | [private]
value_type typedef | Hash< K, V > |


TemplateHash::Pair class Reference

Hash< K, V >::Pair Class Template Reference

pair storage. More...

Inheritance diagram for Hash::Pair:

[legend]
Collaboration diagram for Hash< K, V >::Pair:

[legend]
List of all members.

Public Methods

Pair (uint acode, K akey, V avalue, Pair *alink)

Public Attributes

uint code
K | key
V | value
Pair * | link

Detailed Description

template<typename K, typename V>
class Hash< K, V >::Pair

pair storage.

Definition at line 382 of file pa_hash.h.

Constructor & Destructor Documentation

template<typename K, typename V>
Hash< K, V >::Pair::Pair | ( | uint | acode,
 |  | K | akey,
 |  | V | avalue,
 |  | Pair * | alink
 | ) | [inline]

Definition at line 389 of file pa_hash.h.

References Hash< K, V >::Pair::code, Hash< K, V >::Pair::key, uint, and Hash< K, V >::Pair::value.

Member Data Documentation

template<typename K, typename V>
uint Hash< K, V >::Pair::code

Definition at line 384 of file pa_hash.h.

Referenced by Hash< K, V >::Pair::Pair().

template<typename K, typename V>
K Hash< K, V >::Pair::key

Definition at line 385 of file pa_hash.h.

Referenced by Hash< K, V >::Pair::Pair().

template<typename K, typename V>
V Hash< K, V >::Pair::value

Definition at line 386 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::first_that(), Hash< K, V >::Pair::Pair(), Hash< const String::Body, void * >::put(), and Hash< const String::Body, void * >::replace_maybe_append().

template<typename K, typename V>
Pair* Hash< K, V >::Pair::link

Definition at line 387 of file pa_hash.h.

Referenced by Hash< const String::Body, void * >::expand(), Hash< const String::Body, void * >::get(), Hash< const String::Body, void * >::Hash(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::merge_dont_replace(), Hash< const String::Body, void * >::put_replaced(), and Hash< const String::Body, void * >::remove().

The documentation for this class was generated from the following file:
  • pa_hash.h


Member List

Hash< K, V >::Pair Member List

This is the complete list of members for Hash< K, V >::Pair, including all inherited members.
code | Hash< K, V >::Pair |
free(void *ptr) | PA_Allocated | [inline, static]
key | Hash< K, V >::Pair |
link | Hash< K, V >::Pair |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
Pair(uint acode, K akey, V avalue, Pair *alink) | Hash< K, V >::Pair | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
value | Hash< K, V >::Pair |


Hashfile_value_serialized_prolog Struct Reference

List of all members.

Public Attributes

uint version
time_t time_to_die

Member Data Documentation

uint Hashfile_value_serialized_prolog::version

Definition at line 85 of file pa_vhashfile.C.

Referenced by VHashfile::deserialize_value(), and VHashfile::serialize_value().

time_t Hashfile_value_serialized_prolog::time_to_die

Definition at line 86 of file pa_vhashfile.C.

Referenced by VHashfile::deserialize_value(), and VHashfile::serialize_value().

The documentation for this struct was generated from the following file:
  • pa_vhashfile.C


Member List

Hashfile_value_serialized_prolog Member List

This is the complete list of members for Hashfile_value_serialized_prolog, including all inherited members.
time_to_die | Hashfile_value_serialized_prolog
version | Hashfile_value_serialized_prolog


JPG_Exif_IFD_begin Struct Reference

List of all members.

Public Attributes

uchar directory_entry_count [2]

Member Data Documentation

uchar JPG_Exif_IFD_begin::directory_entry_count[2]

Definition at line 293 of file image.C.

Referenced by parse_IFD().

The documentation for this struct was generated from the following file:
  • image.C


Member List

JPG_Exif_IFD_begin Member List

This is the complete list of members for JPG_Exif_IFD_begin, including all inherited members.
directory_entry_count JPG_Exif_IFD_begin


JPG_Exif_IFD_entry Struct Reference

List of all members.

Public Attributes

uchar | tag [2]
uchar | format [2]
uchar | components_count [4]
uchar | value_or_offset_to_it [4]

Member Data Documentation

uchar JPG_Exif_IFD_entry::tag[2]

Definition at line 298 of file image.C.

Referenced by parse_IFD_entry().

uchar JPG_Exif_IFD_entry::format[2]

Definition at line 299 of file image.C.

Referenced by parse_IFD_entry_value().

uchar JPG_Exif_IFD_entry::components_count[4]

Definition at line 300 of file image.C.

Referenced by parse_IFD_entry_value().

uchar JPG_Exif_IFD_entry::value_or_offset_to_it[4]

Definition at line 301 of file image.C.

Referenced by parse_IFD_entry(), and parse_IFD_entry_value().

The documentation for this struct was generated from the following file:
  • image.C


Member List

JPG_Exif_IFD_entry Member List

This is the complete list of members for JPG_Exif_IFD_entry, including all inherited members.
components_count | JPG_Exif_IFD_entry
format | JPG_Exif_IFD_entry
tag | JPG_Exif_IFD_entry
value_or_offset_to_it | JPG_Exif_IFD_entry


JPG_Exif_segment_begin Struct Reference

JPEG frame header. More...

List of all members.

Public Attributes

char signature [6]

Detailed Description

JPEG frame header.

Definition at line 280 of file image.C.

Member Data Documentation

char JPG_Exif_segment_begin::signature[6]

Definition at line 281 of file image.C.

Referenced by parse_exif().

The documentation for this struct was generated from the following file:
  • image.C


Member List

JPG_Exif_segment_begin Member List

This is the complete list of members for JPG_Exif_segment_begin, including all inherited members.
signature JPG_Exif_segment_begin


JPG_Exif_TIFF_header Struct Reference

JPEG Exif TIFF Header. More...

List of all members.

Public Attributes

uchar | byte_align_identifier [2]
char | dummy [2]
uchar | first_IFD_offset [4]

Detailed Description

JPEG Exif TIFF Header.

Definition at line 285 of file image.C.

Member Data Documentation

uchar JPG_Exif_TIFF_header::byte_align_identifier[2]

Definition at line 286 of file image.C.

Referenced by parse_exif().

char JPG_Exif_TIFF_header::dummy[2]

Definition at line 287 of file image.C.

uchar JPG_Exif_TIFF_header::first_IFD_offset[4]

Definition at line 288 of file image.C.

Referenced by parse_exif().

The documentation for this struct was generated from the following file:
  • image.C


Member List

JPG_Exif_TIFF_header Member List

This is the complete list of members for JPG_Exif_TIFF_header, including all inherited members.
byte_align_identifier | JPG_Exif_TIFF_header
dummy | JPG_Exif_TIFF_header
first_IFD_offset | JPG_Exif_TIFF_header


JPG_Segment_head Struct Reference

JPEG record head. More...

List of all members.

Public Attributes

uchar marker
uchar code
uchar length [2]

Detailed Description

JPEG record head.

Definition at line 266 of file image.C.

Member Data Documentation

uchar JPG_Segment_head::marker

Definition at line 267 of file image.C.

Referenced by measure_jpeg().

uchar JPG_Segment_head::code

Definition at line 268 of file image.C.

Referenced by measure_jpeg().

uchar JPG_Segment_head::length[2]

Definition at line 269 of file image.C.

Referenced by measure_jpeg().

The documentation for this struct was generated from the following file:
  • image.C


Member List

JPG_Segment_head Member List

This is the complete list of members for JPG_Segment_head, including all inherited members.
code | JPG_Segment_head
length | JPG_Segment_head
marker | JPG_Segment_head


JPG_Size_segment_body Struct Reference

JPEG frame header. More...

List of all members.

Public Attributes

char | data
uchar | height [2]
uchar | width [2]
char | numComponents

Detailed Description

JPEG frame header.

Definition at line 272 of file image.C.

Member Data Documentation

char JPG_Size_segment_body::data

Definition at line 273 of file image.C.

uchar JPG_Size_segment_body::height[2]

Definition at line 274 of file image.C.

Referenced by measure_jpeg().

uchar JPG_Size_segment_body::width[2]

Definition at line 275 of file image.C.

Referenced by measure_jpeg().

char JPG_Size_segment_body::numComponents

Definition at line 276 of file image.C.

The documentation for this struct was generated from the following file:
  • image.C


Member List

JPG_Size_segment_body Member List

This is the complete list of members for JPG_Size_segment_body, including all inherited members.
data | JPG_Size_segment_body
height | JPG_Size_segment_body
numComponents | JPG_Size_segment_body
width | JPG_Size_segment_body


Junction Class Reference

junction is some code joined with context of it's evaluation. More...

Collaboration diagram for Junction:

[legend]
List of all members.

Public Methods

Junction (Value &aself, const Method *amethod, VMethodFrame *amethod_frame, Value *arcontext, WContext *awcontext, ArrayOperation *acode)
Code-Junction constructor. More...

Junction (Value &aself, const Method *amethod, bool ais_getter=false)
Method-Junction or Getter-Junction constructor. More...

void | reattach (WContext *new_wcontext)

Public Attributes

Value & self
always present. More...

either these // so called 'method-junction'
const Method * | method
or these are present // so called 'code-junction'
VMethodFrame * method_frame
Value * rcontext
WContext * wcontext
ArrayOperation * code
bool | is_getter

Detailed Description

junction is some code joined with context of it's evaluation.

there are code-junctions and method-junctions

  • code-junctions are used when some parameter passed in cury brackets
  • method-junctions used in ^method[] calls or $method references
Junctions register themselves in method_frame [if any] for consequent invalidation. This prevents evaluation of junctions in outdated context

To stop situations like this:

    @main[]
    ^method1[]
    ^method2[]

    @method1[]
    $junction{
        some code
    }

    @method2[]
    ^junction[]

On wcontext[most dynamic context of all] scope exit (WContext::~WContext()) got cleaned - Junction::wcontext becomes WContext.fparent (if any), or Junction::method_frame becomes 0 (if no parent), which later in Request::process triggers exception

parent changing helps ^switch implementation to remain simple

Definition at line 50 of file pa_junction.h.

Constructor & Destructor Documentation

Junction::Junction | ( | Value & | aself,
 |  | const Method * | amethod,
 |  | VMethodFrame * | amethod_frame,
 |  | Value * | arcontext,
 |  | WContext * | awcontext,
 |  | ArrayOperation * | acode
 | ) |

Code-Junction constructor.

Definition at line 57 of file pa_value.C.

References WContext::attach_junction(), and wcontext.

Junction::Junction | ( | Value & | aself,
 |  | const Method * | amethod,
 |  | bool | ais_getter = false
 | ) | [inline]

Method-Junction or Getter-Junction constructor.

Definition at line 62 of file pa_junction.h.

References is_getter, method, and self.

Member Function Documentation

void Junction::reattach ( WContext * new_wcontext )

Definition at line 72 of file pa_value.C.

References assert, WContext::attach_junction(), method_frame, rcontext, and wcontext.

Member Data Documentation

Value& Junction::self

always present.

Definition at line 72 of file pa_junction.h.

Referenced by Request::execute(), Request::get_element(), Junction(), Request::process(), Request::put_element(), and VMethodFrame::store_param().

const Method* Junction::method

Definition at line 75 of file pa_junction.h.

Referenced by VMethodFrame::can_store_param(), Request::core(), Request::execute(), Request::execute_virtual_method(), VMethodFrame::fill_unspecified_params(), Junction(), Request::process(), Request::put_element(), VMethodFrame::store_param(), and VMethodFrame::VMethodFrame().

VMethodFrame* Junction::method_frame

Definition at line 79 of file pa_junction.h.

Referenced by _match(), Request::process(), reattach(), and try_catch().

Value* Junction::rcontext

Definition at line 80 of file pa_junction.h.

Referenced by Request::process(), and reattach().

WContext* Junction::wcontext

Definition at line 81 of file pa_junction.h.

Referenced by Junction(), Request::process(), and reattach().

ArrayOperation* Junction::code

Definition at line 82 of file pa_junction.h.

Referenced by Request::process().

bool Junction::is_getter

Definition at line 85 of file pa_junction.h.

Referenced by Junction(), and Request::process().

The documentation for this class was generated from the following files:
  • pa_junction.h
  • pa_value.C


Member List

Junction Member List

This is the complete list of members for Junction, including all inherited members.
code | Junction |
is_getter | Junction |
Junction(Value &aself, const Method *amethod, VMethodFrame *amethod_frame, Value *arcontext, WContext *awcontext, ArrayOperation *acode) | Junction |
Junction(Value &aself, const Method *amethod, bool ais_getter=false) | Junction | [inline]
method | Junction |
method_frame | Junction |
rcontext | Junction |
reattach(WContext *new_wcontext) | Junction |
self | Junction |
wcontext | Junction |


lf_state Struct Reference

Collaboration diagram for lf_state:

[legend]
List of all members.

Public Attributes

FILE * | lf_file
size_t | lf_current
cache_line *volatile | lf_cache [CACHE_SZ/LINE_SZ]

Member Data Documentation

FILE* lf_state::lf_file

Definition at line 491 of file cordxtra.c.

size_t lf_state::lf_current

Definition at line 492 of file cordxtra.c.

cache_line* volatile lf_state::lf_cache[CACHE_SZ/LINE_SZ]

Definition at line 493 of file cordxtra.c.

The documentation for this struct was generated from the following file:
  • cordxtra.c


Member List

lf_state Member List

This is the complete list of members for lf_state, including all inherited members.
lf_cache | lf_state
lf_current | lf_state
lf_file | lf_state


lsplit_result Struct Reference

List of all members.

Public Methods

operator bool ()

Public Attributes

char * | piece
char | delim

Member Function Documentation

lsplit_result::operator bool ( ) [inline]

Definition at line 184 of file table.C.

References piece.

Member Data Documentation

char* lsplit_result::piece

Definition at line 181 of file table.C.

Referenced by _load(), lsplit(), and operator bool().

char lsplit_result::delim

Definition at line 182 of file table.C.

Referenced by _load(), and lsplit().

The documentation for this struct was generated from the following file:
  • table.C


Member List

lsplit_result Member List

This is the complete list of members for lsplit_result, including all inherited members.
delim | lsplit_result |
operator bool() | lsplit_result | [inline]
piece | lsplit_result |


lt_dlhandle_struct Struct Reference

Collaboration diagram for lt_dlhandle_struct:

[legend]
List of all members.

Public Attributes

lt_dlhandle_struct * | next
lt_dlloader * loader
lt_dlinfo info
int | depcount
lt_dlhandle * deplibs
lt_module module
lt_ptr | system
lt_caller_data * | caller_data
int | flags

Member Data Documentation

struct lt_dlhandle_struct* lt_dlhandle_struct::next

Definition at line 699 of file ltdl.c.

lt_dlloader* lt_dlhandle_struct::loader

Definition at line 700 of file ltdl.c.

lt_dlinfo lt_dlhandle_struct::info

Definition at line 701 of file ltdl.c.

int lt_dlhandle_struct::depcount

Definition at line 702 of file ltdl.c.

lt_dlhandle* lt_dlhandle_struct::deplibs

Definition at line 703 of file ltdl.c.

lt_module lt_dlhandle_struct::module

Definition at line 704 of file ltdl.c.

lt_ptr lt_dlhandle_struct::system

Definition at line 705 of file ltdl.c.

lt_caller_data* lt_dlhandle_struct::caller_data

Definition at line 706 of file ltdl.c.

int lt_dlhandle_struct::flags

Definition at line 707 of file ltdl.c.

The documentation for this struct was generated from the following file:
  • ltdl.c


Member List

lt_dlhandle_struct Member List

This is the complete list of members for lt_dlhandle_struct, including all inherited members.
caller_data | lt_dlhandle_struct
depcount | lt_dlhandle_struct
deplibs | lt_dlhandle_struct
flags | lt_dlhandle_struct
info | lt_dlhandle_struct
loader | lt_dlhandle_struct
module | lt_dlhandle_struct
next | lt_dlhandle_struct
system | lt_dlhandle_struct


lt_dlinfo Struct Reference

List of all members.

Public Attributes

char * | filename
char * | name
int | ref_count

Member Data Documentation

char* lt_dlinfo::filename

Definition at line 238 of file ltdl.h.

char* lt_dlinfo::name

Definition at line 239 of file ltdl.h.

int lt_dlinfo::ref_count

Definition at line 240 of file ltdl.h.

The documentation for this struct was generated from the following file:
  • ltdl.h


Member List

lt_dlinfo Member List

This is the complete list of members for lt_dlinfo, including all inherited members.
filename | lt_dlinfo
name | lt_dlinfo
ref_count | lt_dlinfo


lt_dlloader Struct Reference

Collaboration diagram for lt_dlloader:

[legend]
List of all members.

Public Attributes

lt_dlloader * | next
const char * | loader_name
const char * | sym_prefix
lt_module_open * | module_open
lt_module_close * | module_close
lt_find_sym * | find_sym
lt_dlloader_exit * | dlloader_exit
lt_user_data dlloader_data

Member Data Documentation

struct lt_dlloader* lt_dlloader::next

Definition at line 688 of file ltdl.c.

const char* lt_dlloader::loader_name

Definition at line 689 of file ltdl.c.

const char* lt_dlloader::sym_prefix

Definition at line 690 of file ltdl.c.

lt_module_open* lt_dlloader::module_open

Definition at line 691 of file ltdl.c.

lt_module_close* lt_dlloader::module_close

Definition at line 692 of file ltdl.c.

lt_find_sym* lt_dlloader::find_sym

Definition at line 693 of file ltdl.c.

lt_dlloader_exit* lt_dlloader::dlloader_exit

Definition at line 694 of file ltdl.c.

lt_user_data lt_dlloader::dlloader_data

Definition at line 695 of file ltdl.c.

The documentation for this struct was generated from the following file:
  • ltdl.c


Member List

lt_dlloader Member List

This is the complete list of members for lt_dlloader, including all inherited members.
dlloader_data | lt_dlloader
dlloader_exit | lt_dlloader
find_sym | lt_dlloader
loader_name | lt_dlloader
module_close | lt_dlloader
module_open | lt_dlloader
next | lt_dlloader
sym_prefix | lt_dlloader


lt_dlsymlist Struct Reference

List of all members.

Public Attributes

const char * | name
lt_ptr | address

Member Data Documentation

const char* lt_dlsymlist::name

Definition at line 217 of file ltdl.h.

lt_ptr lt_dlsymlist::address

Definition at line 218 of file ltdl.h.

The documentation for this struct was generated from the following file:
  • ltdl.h


Member List

lt_dlsymlist Member List

This is the complete list of members for lt_dlsymlist, including all inherited members.
address | lt_dlsymlist
name | lt_dlsymlist


lt_dlsymlists_t Struct Reference

Collaboration diagram for lt_dlsymlists_t:

[legend]
List of all members.

Public Attributes

lt_dlsymlists_t * | next
const lt_dlsymlist * | syms

Member Data Documentation

struct lt_dlsymlists_t* lt_dlsymlists_t::next

Definition at line 1460 of file ltdl.c.

const lt_dlsymlist* lt_dlsymlists_t::syms

Definition at line 1461 of file ltdl.c.

The documentation for this struct was generated from the following file:
  • ltdl.c


Member List

lt_dlsymlists_t Member List

This is the complete list of members for lt_dlsymlists_t, including all inherited members.
next | lt_dlsymlists_t
syms | lt_dlsymlists_t


lt_user_dlloader Struct Reference

List of all members.

Public Attributes

const char * | sym_prefix
lt_module_open * | module_open
lt_module_close * | module_close
lt_find_sym * | find_sym
lt_dlloader_exit * | dlloader_exit
lt_user_data dlloader_data

Member Data Documentation

const char* lt_user_dlloader::sym_prefix

Definition at line 280 of file ltdl.h.

lt_module_open* lt_user_dlloader::module_open

Definition at line 281 of file ltdl.h.

lt_module_close* lt_user_dlloader::module_close

Definition at line 282 of file ltdl.h.

lt_find_sym* lt_user_dlloader::find_sym

Definition at line 283 of file ltdl.h.

lt_dlloader_exit* lt_user_dlloader::dlloader_exit

Definition at line 284 of file ltdl.h.

lt_user_data lt_user_dlloader::dlloader_data

Definition at line 285 of file ltdl.h.

Referenced by lt_dlinit().

The documentation for this struct was generated from the following file:
  • ltdl.h


Member List

lt_user_dlloader Member List

This is the complete list of members for lt_user_dlloader, including all inherited members.
dlloader_data | lt_user_dlloader
dlloader_exit | lt_user_dlloader
find_sym | lt_user_dlloader
module_close | lt_user_dlloader
module_open | lt_user_dlloader
sym_prefix | lt_user_dlloader


match_data Struct Reference

List of all members.

Public Attributes

int | errorcode
int * | offset_vector
int | offset_end
int | offset_max
const uschar * | lcc
const uschar * | ctypes
BOOL offset_overflow
BOOL notbol
BOOL noteol
BOOL endonly
BOOL notempty
const uschar * | start_subject
const uschar * | end_subject
const uschar * | start_match
const uschar * | end_match_ptr
int | end_offset_top

Member Data Documentation

int match_data::errorcode

Definition at line 309 of file internal.h.

Referenced by match(), and pcre_exec().

int* match_data::offset_vector

Definition at line 310 of file internal.h.

Referenced by match(), match_ref(), and pcre_exec().

int match_data::offset_end

Definition at line 311 of file internal.h.

Referenced by match(), and pcre_exec().

int match_data::offset_max

Definition at line 312 of file internal.h.

Referenced by match(), and pcre_exec().

const uschar* match_data::lcc

Definition at line 313 of file internal.h.

Referenced by match(), match_ref(), and pcre_exec().

const uschar* match_data::ctypes

Definition at line 314 of file internal.h.

Referenced by match(), and pcre_exec().

BOOL match_data::offset_overflow

Definition at line 315 of file internal.h.

Referenced by match(), and pcre_exec().

BOOL match_data::notbol

Definition at line 316 of file internal.h.

Referenced by match(), and pcre_exec().

BOOL match_data::noteol

Definition at line 317 of file internal.h.

Referenced by match(), and pcre_exec().

BOOL match_data::endonly

Definition at line 318 of file internal.h.

Referenced by match(), and pcre_exec().

BOOL match_data::notempty

Definition at line 319 of file internal.h.

Referenced by match(), and pcre_exec().

const uschar* match_data::start_subject

Definition at line 320 of file internal.h.

Referenced by match(), match_ref(), and pcre_exec().

const uschar* match_data::end_subject

Definition at line 321 of file internal.h.

Referenced by match(), match_ref(), and pcre_exec().

const uschar* match_data::start_match

Definition at line 322 of file internal.h.

Referenced by match(), and pcre_exec().

const uschar* match_data::end_match_ptr

Definition at line 323 of file internal.h.

Referenced by match(), and pcre_exec().

int match_data::end_offset_top

Definition at line 324 of file internal.h.

Referenced by match(), and pcre_exec().

The documentation for this struct was generated from the following file:
  • internal.h


Member List

match_data Member List

This is the complete list of members for match_data, including all inherited members.
ctypes | match_data
end_match_ptr | match_data
end_offset_top | match_data
end_subject | match_data
endonly | match_data
errorcode | match_data
lcc | match_data
notbol | match_data
notempty | match_data
noteol | match_data
offset_end | match_data
offset_max | match_data
offset_overflow | match_data
offset_vector | match_data
start_match | match_data
start_subject | match_data


MDate Class Reference

Inheritance diagram for MDate:

[legend]
Collaboration diagram for MDate:

[legend]
List of all members.

Public Methods

Value * create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

MDate ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MDate::MDate ( )

Definition at line 404 of file date.C.

References _calendar(), _create(), _now(), _roll(), _sql_string(), _unix_timestamp(), VStateless_class::add_native_method(), Method::CT_DYNAMIC, and Method::CT_STATIC.

Member Function Documentation

Value* MDate::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 22 of file date.C.

bool MDate::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 27 of file date.C.

The documentation for this class was generated from the following file:
  • date.C


Member List

MDate Member List

This is the complete list of members for MDate, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | MDate | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
MDate() | MDate |
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MDate | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MDouble Class Reference

Inheritance diagram for MDouble:

[legend]
Collaboration diagram for MDouble:

[legend]
List of all members.

Public Methods

MDouble ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MDouble::MDouble ( )

Definition at line 100 of file double.C.

References _dec(), _div(), _double(), _inc(), _int(), _mod(), _mul(), _sql(), VStateless_class::add_native_method(), Method::CT_DYNAMIC, and Method::CT_STATIC.

Member Function Documentation

bool MDouble::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 27 of file double.C.

The documentation for this class was generated from the following file:
  • double.C


Member List

MDouble Member List

This is the complete list of members for MDouble, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
MDouble() | MDouble |
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MDouble | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


Method Class Reference

class method. More...

Inheritance diagram for Method:

[legend]
Collaboration diagram for Method:

[legend]
List of all members.

Public Types

enum | Call_type { CT_ANY, CT_STATIC, CT_DYNAMIC }
allowed method call types. More...

Public Methods

Method::Method (Call_type call_type, int amin_numbered_params_count, int amax_numbered_params_count, ArrayString *aparams_names, ArrayString *alocals_names, ArrayOperation *aparser_code, NativeCodePtr anative_code)
void | check_actual_numbered_params (Value &self, MethodParams *actual_numbered_params) const
call this before invoking to ensure proper actual numbered params count. More...

Public Attributes

Call_type call_type
either numbered params // for native-code methods = operators
int | min_numbered_params_count
int | max_numbered_params_count
or named params&locals // for parser-code methods
ArrayString * params_names
ArrayString * locals_names
the Code
ArrayOperation * parser_code
NativeCodePtr native_code

Detailed Description

class method.

methods can have

  • named or
  • numbered parameters
methods can be
  • parser or
  • native onces
holds
  • parameter names or number limits
  • local names
  • code [parser or native]

Definition at line 45 of file pa_method.h.

Member Enumeration Documentation

enum Method::Call_type

allowed method call types.

Enumeration values:
CT_ANY | method can be called either statically or dynamically.
CT_STATIC | method can be called only statically.
CT_DYNAMIC | method can be called only dynamically.

Definition at line 49 of file pa_method.h.

Referenced by VStateless_class::add_native_method(), Request::execute(), and Method::Method().

Member Function Documentation

Method::Method::Method | ( | Call_type | call_type,
 |  | int | amin_numbered_params_count,
 |  | int | amax_numbered_params_count,
 |  | ArrayString * | aparams_names,
 |  | ArrayString * | alocals_names,
 |  | ArrayOperation * | aparser_code,
 |  | NativeCodePtr | anative_code
 | ) | [inline]

Definition at line 72 of file pa_method.h.

References call_type, Call_type, locals_names, max_numbered_params_count, Method::Method(), min_numbered_params_count, native_code, NativeCodePtr, params_names, and parser_code.

Referenced by Method::Method().

void Method::check_actual_numbered_params | ( | Value & | self,
 |  | MethodParams * | actual_numbered_params
 | ) | const

call this before invoking to ensure proper actual numbered params count.

Definition at line 42 of file pa_value.C.

References Array< Value * >::count(), Value::get_class(), min_numbered_params_count, VStateless_class::name_cstr(), and Value::type().

Referenced by Request::execute().

Member Data Documentation

Call_type Method::call_type

Definition at line 58 of file pa_method.h.

Referenced by Request::execute(), and Method::Method().

int Method::min_numbered_params_count

Definition at line 61 of file pa_method.h.

Referenced by check_actual_numbered_params(), and Method::Method().

int Method::max_numbered_params_count

Definition at line 61 of file pa_method.h.

Referenced by Method::Method(), VMethodFrame::store_param(), and VMethodFrame::VMethodFrame().

ArrayString* Method::params_names

Definition at line 65 of file pa_method.h.

Referenced by VMethodFrame::can_store_param(), VMethodFrame::fill_unspecified_params(), Method::Method(), Request::process(), Request::put_element(), and VMethodFrame::store_param().

ArrayString* Method::locals_names

Definition at line 65 of file pa_method.h.

Referenced by Method::Method(), and VMethodFrame::VMethodFrame().

ArrayOperation* Method::parser_code

Definition at line 69 of file pa_method.h.

Referenced by _process(), Request::execute(), Request::execute_method(), Method::Method(), Request::process(), and Request::put_element().

NativeCodePtr Method::native_code

Definition at line 69 of file pa_method.h.

Referenced by Request::execute(), and Method::Method().

The documentation for this class was generated from the following files:
  • pa_method.h
  • pa_value.C


Member List

Method Member List

This is the complete list of members for Method, including all inherited members.
call_type | Method |
Call_type enum name | Method |
check_actual_numbered_params(Value &self, MethodParams *actual_numbered_params) const | Method |
CT_ANY enum value | Method |
CT_DYNAMIC enum value | Method |
CT_STATIC enum value | Method |
free(void *ptr) | PA_Allocated | [inline, static]
locals_names | Method |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
max_numbered_params_count | Method |
Method::Method(Call_type call_type, int amin_numbered_params_count, int amax_numbered_params_count, ArrayString *aparams_names, ArrayString *alocals_names, ArrayOperation *aparser_code, NativeCodePtr anative_code) | Method | [inline]
min_numbered_params_count | Method |
native_code | Method |
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
params_names | Method |
parser_code | Method |
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


Methoded Class Reference

Pure virtual base for configurable Methoded descendants. More...

Inheritance diagram for Methoded:

[legend]
Collaboration diagram for Methoded:

[legend]
List of all members.

Public Methods

override const VJunction * | put_element (Value &, const String &, Value *)
virtual bool | used_directly ()=0
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

virtual void | configure_admin (Request &)
use this method to read parameters from root "auto.p"; access r.main_class. More...

virtual void | configure_user (Request &)
use this method to read parameters from 'MAIN' class; access r.main_class. More...

virtual void | construct_statics ()
use it to construct static variables. check some static so that would be only ONCE! More...

Methoded (const char *aname, VStateless_class *abase=0)
void | register_directly_used (Request &r)

Detailed Description

Pure virtual base for configurable Methoded descendants.

See also:
Methoded_array

Definition at line 21 of file classes.h.

Constructor & Destructor Documentation

Methoded::Methoded | ( | const char * | aname,
 |  | VStateless_class * | abase = 0
 | ) | [inline]

Definition at line 45 of file classes.h.

References new.

Member Function Documentation

override const VJunction* Methoded::put_element | ( | Value & | ,
 |  | const String & | ,
 |  | Value * |
 | ) | [inline]

Definition at line 24 of file classes.h.

References override.

virtual bool Methoded::used_directly ( ) [pure virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implemented in MDate, MDouble, MFile, MForm, MHash, MHashfile, MImage, MInt, MMail, MMath, MMemory, MResponse, MString, MTable, MVoid, and MXnode.

Referenced by register_directly_used().

virtual void Methoded::configure_admin ( Request & ) [inline, virtual]

use this method to read parameters from root "auto.p"; access r.main_class.

Reimplemented in MForm.

Definition at line 37 of file classes.h.

virtual void Methoded::configure_user ( Request & ) [inline, virtual]

use this method to read parameters from 'MAIN' class; access r.main_class.

Reimplemented in MMail.

Definition at line 39 of file classes.h.

virtual void Methoded::construct_statics ( ) [inline, virtual]

use it to construct static variables. check some static so that would be only ONCE!

Definition at line 41 of file classes.h.

void Methoded::register_directly_used ( Request & r )

Definition at line 15 of file classes.C.

References Request::classes(), VStateless_class::lock(), VStateless_class::name(), Hash< const String::Body, Value * >::put(), and used_directly().

The documentation for this class was generated from the following files:
  • classes.h
  • classes.C


Member List

Methoded Member List

This is the complete list of members for Methoded, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly()=0 | Methoded | [pure virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


Methoded_array Class Reference

all Methoded registered here in autogenerated classes.C. More...

Inheritance diagram for Methoded_array:

[legend]
Collaboration diagram for Methoded_array:

[legend]
List of all members.

Public Methods

Methoded_array ()
void | configure_admin (Request &r)
See also:
Methoded::configure_admin.
 More...

void | configure_user (Request &r)
See also:
Methoded::configure_user.
 More...

void | register_directly_used (Request &r)
See also:
Methoded::register_directly_used.
 More...

Detailed Description

all Methoded registered here in autogenerated classes.C.

Definition at line 54 of file classes.h.

Constructor & Destructor Documentation

Methoded_array::Methoded_array ( )

Definition at line 39 of file classes.C.

Member Function Documentation

void Methoded_array::configure_admin ( Request & r )

See also:
Methoded::configure_admin.

Definition at line 65 of file classes.C.

Referenced by Request::configure_admin().

void Methoded_array::configure_user ( Request & r )

See also:
Methoded::configure_user.

Definition at line 73 of file classes.C.

Referenced by Request::configure().

void Methoded_array::register_directly_used ( Request & r )

See also:
Methoded::register_directly_used.

Definition at line 81 of file classes.C.

Referenced by Request::Request().

The documentation for this class was generated from the following files:
  • classes.h
  • classes.C


Member List

Methoded_array Member List

This is the complete list of members for Methoded_array, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< Methoded * > | [inline]
Array(size_t initial=3) | Array< Methoded * > | [inline]
configure_admin(Request &r) | Methoded_array |
configure_user(Request &r) | Methoded_array |
count() const | Array< Methoded * > | [inline]
element_type typedef | Array< Methoded * > |
expand(size_t delta) | Array< Methoded * > | [inline, protected]
fallocated | Array< Methoded * > | [protected]
felements | Array< Methoded * > | [protected]
first_that(bool(*callback)(Methoded *, I), I info) const | Array< Methoded * > | [inline]
for_each(void(*callback)(Methoded *, I), I info) const | Array< Methoded * > | [inline]
for_each_ref(void(*callback)(Methoded *&, I), I info) | Array< Methoded * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fused | Array< Methoded * > | [protected]
get(size_t index) const | Array< Methoded * > | [inline]
get_ref(size_t index) const | Array< Methoded * > | [inline]
is_full() | Array< Methoded * > | [inline, protected]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded_array() | Methoded_array |
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(Methoded *src) | Array< Methoded * > | [inline]
operator[](size_t index) const | Array< Methoded * > | [inline]
put(size_t index, Methoded *element) | Array< Methoded * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded_array |
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


MethodParams Class Reference

method parameters passed in this array. More...

Inheritance diagram for MethodParams:

[legend]
Collaboration diagram for MethodParams:

[legend]
List of all members.

Public Methods

Value & | operator[] (size_t index)
Value & last ()
Value & | as_junction (int index, const char *msg)
handy is-value-a-junction ensurer. More...

Value & | as_junction (Value *value, const char *msg, int index)
handy is-value-a-junction ensurer. More...

Value & | as_no_junction (int index, const char *msg)
handy value-is-not-a-junction ensurer. More...

Value & | as_no_junction (Value *value, const char *msg, int index)
handy value-is-not-a-junction ensurer. More...

double | as_double (int index, const char *msg, Request &r)
handy expression auto-processing to double. More...

int | as_int (int index, const char *msg, Request &r)
handy expression auto-processing to int. More...

bool | as_bool (int index, const char *msg, Request &r)
handy expression auto-processing to bool. More...

const String & | as_string (int index, const char *msg)
handy string ensurer. More...

Private Methods

Value & | get_as (Value *value, bool as_junction, const char *msg, int index)
handy value-is/not-a-junction ensurer. More...

Value & | get_processed (Value *value, const char *msg, int index, Request &r)

Detailed Description

method parameters passed in this array.

contains handy typecast ad junction/not junction ensurers

Definition at line 32 of file pa_vmethod_frame.h.

Member Function Documentation

Value& MethodParams::operator[] ( size_t index ) [inline]

Definition at line 34 of file pa_vmethod_frame.h.

References Array< Value * >::get().

Value& MethodParams::last ( ) [inline]

Definition at line 36 of file pa_vmethod_frame.h.

References Array< Value * >::count(), and Array< Value * >::get().

Referenced by get_action_options().

Value& MethodParams::as_junction | ( | int | index,
 |  | const char * | msg
 | ) | [inline]

handy is-value-a-junction ensurer.

Definition at line 39 of file pa_vmethod_frame.h.

References Array< Value * >::get(), and value.

Referenced by _append(), _cache(), _case(), _connect(), _eval(), _find(), _for(), _foreach(), _locate_expression(), _lock(), _match(), _menu(), _rem(), _select(), _sort(), _sql(), _switch(), _try_operator(), _untaint(), _while(), get_processed(), and sql_result_string().

Value& MethodParams::as_junction | ( | Value * | value,
 |  | const char * | msg,
 |  | int | index
 | ) | [inline]

handy is-value-a-junction ensurer.

Definition at line 44 of file pa_vmethod_frame.h.

References get_as(), and value.

Value& MethodParams::as_no_junction | ( | int | index,
 |  | const char * | msg
 | ) | [inline]

handy value-is-not-a-junction ensurer.

Definition at line 48 of file pa_vmethod_frame.h.

References Array< Value * >::get(), and value.

Referenced by _connect(), _create(), _create_or_add(), _delete(), _eval(), _exec_cgi(), _find(), _hash(), _intersection(), _intersects(), _join(), _list(), _load(), _match(), _measure(), _move(), _polybar(), _polygon(), _polyline(), _pos(), _replace(), _save(), _send(), _sort(), _sql(), _stat(), _sub(), _taint(), _union(), _use(), as_image(), as_string(), split_list(), and sql_result_string().

Value& MethodParams::as_no_junction | ( | Value * | value,
 |  | const char * | msg,
 |  | int | index
 | ) | [inline]

handy value-is-not-a-junction ensurer.

Definition at line 53 of file pa_vmethod_frame.h.

References get_as(), and value.

double MethodParams::as_double | ( | int | index,
 |  | const char * | msg,
 |  | Request & | r
 | ) | [inline]

handy expression auto-processing to double.

Definition at line 57 of file pa_vmethod_frame.h.

References Value::as_double(), Array< Value * >::get(), get_processed(), Value::is_evaluated_expr(), and value.

Referenced by _double(), _now(), _random(), _sleep_operator(), math1(), math2(), vdouble_op(), and vint_op().

int MethodParams::as_int | ( | int | index,
 |  | const char * | msg,
 |  | Request & | r
 | ) | [inline]

handy expression auto-processing to int.

Definition at line 64 of file pa_vmethod_frame.h.

References Value::as_int(), Array< Value * >::get(), get_processed(), Value::is_evaluated_expr(), and value.

Referenced by _arc(), _bar(), _circle(), _copy(), _create(), _fill(), _font(), _for(), _int(), _left(), _left_right(), _line(), _mid(), _offset(), _pixel(), _polybar(), _polygon(), _polyline(), _rectangle(), _replace(), _right(), _roll(), _sector(), _text(), _unix_timestamp(), fill_month_days(), and fill_week_days().

bool MethodParams::as_bool | ( | int | index,
 |  | const char * | msg,
 |  | Request & | r
 | ) | [inline]

handy expression auto-processing to bool.

Definition at line 71 of file pa_vmethod_frame.h.

References Value::as_bool(), Array< Value * >::get(), get_processed(), Value::is_evaluated_expr(), and value.

Referenced by _if().

const String& MethodParams::as_string | ( | int | index,
 |  | const char * | msg
 | ) | [inline]

handy string ensurer.

Definition at line 78 of file pa_vmethod_frame.h.

References as_no_junction(), and Value::as_string().

Referenced by _append(), _base64(), _basename(), _cache(), _calendar(), _create(), _crypt(), _delete(), _dirname(), _exec_cgi(), _font(), _for(), _foreach(), _fullpath(), _gif(), _justext(), _justname(), _keys(), _length(), _load(), _locate_name_value(), _lock(), _md5(), _offset(), _open(), _roll(), _save(), _taint(), _text(), _throw_operator(), _trim(), _untaint(), as_file_spec(), and split_with_options().

Value& MethodParams::get_as | ( | Value * | value,
 |  | bool | as_junction,
 |  | const char * | msg,
 |  | int | index
 | ) | [inline, private]

handy value-is/not-a-junction ensurer.

Definition at line 85 of file pa_vmethod_frame.h.

References Value::get_junction(), and value.

Referenced by as_junction(), and as_no_junction().

Value & MethodParams::get_processed | ( | Value * | value,
 |  | const char * | msg,
 |  | int | index,
 |  | Request & | r
 | ) | [private]

Definition at line 19 of file pa_vmethod_frame.C.

References as_junction(), Request::process_to_value(), and value.

Referenced by as_bool(), as_double(), and as_int().

The documentation for this class was generated from the following files:
  • pa_vmethod_frame.h
  • pa_vmethod_frame.C


Member List

MethodParams Member List

This is the complete list of members for MethodParams, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< Value * > | [inline]
Array(size_t initial=3) | Array< Value * > | [inline]
as_bool(int index, const char *msg, Request &r) | MethodParams | [inline]
as_double(int index, const char *msg, Request &r) | MethodParams | [inline]
as_int(int index, const char *msg, Request &r) | MethodParams | [inline]
as_junction(int index, const char *msg) | MethodParams | [inline]
as_junction(Value *value, const char *msg, int index) | MethodParams | [inline]
as_no_junction(int index, const char *msg) | MethodParams | [inline]
as_no_junction(Value *value, const char *msg, int index) | MethodParams | [inline]
as_string(int index, const char *msg) | MethodParams | [inline]
count() const | Array< Value * > | [inline]
element_type typedef | Array< Value * > |
expand(size_t delta) | Array< Value * > | [inline, protected]
fallocated | Array< Value * > | [protected]
felements | Array< Value * > | [protected]
first_that(bool(*callback)(Value *, I), I info) const | Array< Value * > | [inline]
for_each(void(*callback)(Value *, I), I info) const | Array< Value * > | [inline]
for_each_ref(void(*callback)(Value *&, I), I info) | Array< Value * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fused | Array< Value * > | [protected]
get(size_t index) const | Array< Value * > | [inline]
get_as(Value *value, bool as_junction, const char *msg, int index) | MethodParams | [inline, private]
get_processed(Value *value, const char *msg, int index, Request &r) | MethodParams | [private]
get_ref(size_t index) const | Array< Value * > | [inline]
is_full() | Array< Value * > | [inline, protected]
last() | MethodParams | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(Value *src) | Array< Value * > | [inline]
operator[](size_t index) | MethodParams | [inline]
Array< Value * >::operator[](size_t index) const | Array< Value * > | [inline]
put(size_t index, Value *element) | Array< Value * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


MFile Class Reference

Inheritance diagram for MFile:

[legend]
Collaboration diagram for MFile:

[legend]
List of all members.

Public Methods

Value * create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

MFile ()

Constructor & Destructor Documentation

MFile::MFile ( )

Definition at line 809 of file file.C.

References _base64(), _basename(), _cgi(), _create(), _delete(), _dirname(), _exec(), _find(), _fullpath(), _justext(), _justname(), _list(), _load(), _lock(), _move(), _save(), _sql(), _sql_string(), _stat(), VStateless_class::add_native_method(), Method::CT_DYNAMIC, Method::CT_STATIC, and file.

Member Function Documentation

Value* MFile::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 48 of file file.C.

bool MFile::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 51 of file file.C.

The documentation for this class was generated from the following file:
  • file.C


Member List

MFile Member List

This is the complete list of members for MFile, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | MFile | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MFile() | MFile |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MFile | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MForm Class Reference

Inheritance diagram for MForm:

[legend]
Collaboration diagram for MForm:

[legend]
List of all members.

Public Methods

bool | used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

void | configure_admin (Request &r)
use this method to read parameters from root "auto.p"; access r.main_class. More...

MForm ()

Constructor & Destructor Documentation

MForm::MForm ( ) [inline]

Definition at line 29 of file form.C.

Member Function Documentation

bool MForm::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 24 of file form.C.

void MForm::configure_admin ( Request & r ) [virtual]

use this method to read parameters from root "auto.p"; access r.main_class.

Reimplemented from Methoded.

Definition at line 51 of file form.C.

References Value::as_double(), Request_info::content_length, Value::get_element(), VStateless_class::get_element(), LIMITS_NAME, Request::main_class, MAX_POST_SIZE_DEFAULT, MAX_POST_SIZE_NAME, Request_info::method, Request_info::post_data, Request_info::post_size, SAPI::read_post(), Request::request_info, Request::sapi_info, StrEqNc(), and value.

The documentation for this class was generated from the following file:
  • form.C


Member List

MForm Member List

This is the complete list of members for MForm, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &r) | MForm | [virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MForm() | MForm | [inline]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MForm | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MHash Class Reference

Inheritance diagram for MHash:

[legend]
Collaboration diagram for MHash:

[legend]
List of all members.

Public Methods

Value * create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

MHash ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MHash::MHash ( )

Definition at line 373 of file hash.C.

References _count(), _create_or_add(), _delete(), _foreach(), _intersection(), _intersects(), _keys(), _sql(), _sub(), _union(), VStateless_class::add_native_method(), and Method::CT_DYNAMIC.

Member Function Documentation

Value* MHash::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 25 of file hash.C.

bool MHash::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 30 of file hash.C.

The documentation for this class was generated from the following file:
  • hash.C


Member List

MHash Member List

This is the complete list of members for MHash, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | MHash | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MHash() | MHash |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MHash | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MHashfile Class Reference

Inheritance diagram for MHashfile:

[legend]
Collaboration diagram for MHashfile:

[legend]
List of all members.

Public Methods

Value * | create_new_value (Pool &apool, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

MHashfile ()
bool | used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MHashfile::MHashfile ( )

Definition at line 139 of file hashfile.C.

References _clear(), _delete(), _foreach(), _hash(), _open(), VStateless_class::add_native_method(), and Method::CT_DYNAMIC.

Member Function Documentation

Value* MHashfile::create_new_value | ( | Pool & | apool,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 22 of file hashfile.C.

bool MHashfile::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 27 of file hashfile.C.

The documentation for this class was generated from the following file:
  • hashfile.C


Member List

MHashfile Member List

This is the complete list of members for MHashfile, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &apool, HashStringValue &) | MHashfile | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MHashfile() | MHashfile |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MHashfile | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MImage Class Reference

Inheritance diagram for MImage:

[legend]
Collaboration diagram for MImage:

[legend]
List of all members.

Public Methods

Value * create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

MImage ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MImage::MImage ( )

Definition at line 1156 of file image.C.

References _arc(), _bar(), _circle(), _copy(), _create(), _fill(), _font(), _gif(), _html(), _length(), _line(), _load(), _measure(), _pixel(), _polybar(), _polygon(), _polyline(), _rectangle(), _replace(), _sector(), _text(), VStateless_class::add_native_method(), and Method::CT_DYNAMIC.

Member Function Documentation

Value* MImage::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 36 of file image.C.

bool MImage::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 42 of file image.C.

The documentation for this class was generated from the following file:
  • image.C


Member List

MImage Member List

This is the complete list of members for MImage, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | MImage | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MImage() | MImage |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MImage | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MInt Class Reference

Inheritance diagram for MInt:

[legend]
Collaboration diagram for MInt:

[legend]
List of all members.

Public Methods

MInt ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MInt::MInt ( )

Definition at line 98 of file int.C.

References _dec(), _div(), _double(), _inc(), _int(), _mod(), _mul(), _sql(), VStateless_class::add_native_method(), Method::CT_DYNAMIC, and Method::CT_STATIC.

Member Function Documentation

bool MInt::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 27 of file int.C.

The documentation for this class was generated from the following file:
  • int.C


Member List

MInt Member List

This is the complete list of members for MInt, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MInt() | MInt |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MInt | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MMail Class Reference

Inheritance diagram for MMail:

[legend]
Collaboration diagram for MMail:

[legend]
List of all members.

Public Methods

bool | used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

void | configure_user (Request &r)
use this method to read parameters from 'MAIN' class; access r.main_class. More...

MMail ()

Constructor & Destructor Documentation

MMail::MMail ( )

Definition at line 231 of file mail.C.

References _send(), VStateless_class::add_native_method(), Method::CT_STATIC, and MAIL_CLASS_NAME.

Member Function Documentation

bool MMail::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 41 of file mail.C.

void MMail::configure_user ( Request & r ) [virtual]

use this method to read parameters from 'MAIN' class; access r.main_class.

Reimplemented from Methoded.

Definition at line 236 of file mail.C.

References Request::classes_conf, VStateless_class::get_element(), Value::get_hash(), Value::is_string(), MAIL_CLASS_NAME, MAIL_NAME, Request::main_class, VStateless_class::name(), and Hash< const String::Body, void * >::put().

The documentation for this class was generated from the following file:
  • mail.C


Member List

MMail Member List

This is the complete list of members for MMail, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &r) | MMail | [virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MMail() | MMail |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MMail | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MMath Class Reference

Inheritance diagram for MMath:

[legend]
Collaboration diagram for MMath:

[legend]
List of all members.

Public Methods

MMath ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MMath::MMath ( )

Definition at line 367 of file math.C.

References crypt(), degrees(), frac(), radians(), and random().

Member Function Documentation

bool MMath::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 46 of file math.C.

The documentation for this class was generated from the following file:
  • math.C


Member List

MMath Member List

This is the complete list of members for MMath, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MMath() | MMath |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MMath | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MMemory Class Reference

Inheritance diagram for MMemory:

[legend]
Collaboration diagram for MMemory:

[legend]
List of all members.

Public Methods

MMemory ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MMemory::MMemory ( )

Definition at line 50 of file memory.C.

References _compact(), VStateless_class::add_native_method(), and Method::CT_STATIC.

Member Function Documentation

bool MMemory::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 19 of file memory.C.

The documentation for this class was generated from the following file:
  • memory.C


Member List

MMemory Member List

This is the complete list of members for MMemory, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MMemory() | MMemory |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MMemory | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MResponse Class Reference

Inheritance diagram for MResponse:

[legend]
Collaboration diagram for MResponse:

[legend]
List of all members.

Public Methods

MResponse ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MResponse::MResponse ( )

Definition at line 37 of file response.C.

References _clear(), VStateless_class::add_native_method(), and Method::CT_DYNAMIC.

Member Function Documentation

bool MResponse::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 22 of file response.C.

The documentation for this class was generated from the following file:
  • response.C


Member List

MResponse Member List

This is the complete list of members for MResponse, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MResponse() | MResponse |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MResponse | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MString Class Reference

Inheritance diagram for MString:

[legend]
Collaboration diagram for MString:

[legend]
List of all members.

Public Methods

MString ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MString::MString ( )

Definition at line 606 of file string.C.

References _append(), _base64(), _double(), _int(), _left(), _length(), _lower(), _lsplit(), _match(), _mid(), _normalize(), _pos(), _replace(), _right(), _rsplit(), _save(), _split(), _sql(), _string_format(), _trim(), _upper(), VStateless_class::add_native_method(), Method::CT_ANY, Method::CT_DYNAMIC, and Method::CT_STATIC.

Member Function Documentation

bool MString::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 29 of file string.C.

The documentation for this class was generated from the following file:
  • string.C


Member List

MString Member List

This is the complete list of members for MString, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MString() | MString |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MString | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MTable Class Reference

Inheritance diagram for MTable:

[legend]
Collaboration diagram for MTable:

[legend]
List of all members.

Public Methods

Value * create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

MTable ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MTable::MTable ( )

Definition at line 1060 of file table.C.

References _append(), _columns(), _count(), _create(), _flip(), _hash(), _join(), _line(), _load(), _locate(), _menu(), _offset(), _save(), _select(), _sort(), _sql(), VStateless_class::add_native_method(), and Method::CT_DYNAMIC.

Member Function Documentation

Value* MTable::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 23 of file table.C.

bool MTable::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 29 of file table.C.

The documentation for this class was generated from the following file:
  • table.C


Member List

MTable Member List

This is the complete list of members for MTable, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | MTable | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MTable() | MTable |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MTable | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


Mutex Class Reference

simple semaphore object. More...

List of all members.

Public Methods

Mutex ()
~Mutex ()

Private Methods

void | acquire ()
void | release ()

Private Attributes

uint handle

Friends

class | AutoSYNCHRONIZED

Detailed Description

simple semaphore object.

Definition at line 25 of file pa_threads.h.

Constructor & Destructor Documentation

Mutex::Mutex ( )

Definition at line 24 of file apache13core/pa_threads.C.

References handle, and uint.

Mutex::~Mutex ( )

Definition at line 28 of file apache13core/pa_threads.C.

References handle.

Member Function Documentation

void Mutex::acquire ( ) [private]

Definition at line 32 of file apache13core/pa_threads.C.

References handle.

Referenced by AutoSYNCHRONIZED::AutoSYNCHRONIZED().

void Mutex::release ( ) [private]

Definition at line 36 of file apache13core/pa_threads.C.

References handle.

Referenced by AutoSYNCHRONIZED::~AutoSYNCHRONIZED().

Friends And Related Function Documentation

friend class AutoSYNCHRONIZED [friend]

Definition at line 26 of file pa_threads.h.

Member Data Documentation

uint Mutex::handle [private]

Definition at line 28 of file pa_threads.h.

Referenced by acquire(), release(), and ~Mutex().

The documentation for this class was generated from the following files:
  • pa_threads.h
  • apache13core/pa_threads.C
  • cgi/pa_threads.C
  • isapi/pa_threads.C


Member List

Mutex Member List

This is the complete list of members for Mutex, including all inherited members.
acquire() | Mutex | [private]
AutoSYNCHRONIZED class | Mutex | [friend]
handle | Mutex | [private]
Mutex() | Mutex |
release() | Mutex | [private]
~Mutex() | Mutex |


MVoid Class Reference

Inheritance diagram for MVoid:

[legend]
Collaboration diagram for MVoid:

[legend]
List of all members.

Public Methods

MVoid ()
bool used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Constructor & Destructor Documentation

MVoid::MVoid ( )

Definition at line 158 of file void.C.

References _double(), _int(), _left_right(), _length(), _mid(), _pos(), _sql(), VStateless_class::add_native_method(), Method::CT_DYNAMIC, and Method::CT_STATIC.

Member Function Documentation

bool MVoid::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 29 of file void.C.

The documentation for this class was generated from the following file:
  • void.C


Member List

MVoid Member List

This is the complete list of members for MVoid, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MVoid() | MVoid |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MVoid | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


MXnode Class Reference

Inheritance diagram for MXnode:

[legend]
Collaboration diagram for MXnode:

[legend]
List of all members.

Public Methods

Value * | get_element (const String &aname, Value &aself, bool looking_up)
MXnode: +$const. More...

Value * create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

MXnode (const char *aname=0, VStateless_class *abase=0)
bool | used_directly ()
should Methoded_array::register_directly_used register this class in Request::classes() or not. More...

Private Attributes

HashStringValue consts

Constructor & Destructor Documentation

MXnode::MXnode | ( | const char * | aname = 0,
 |  | VStateless_class * | abase = 0
 | ) |

Member Function Documentation

Value* MXnode::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

MXnode: +$const.

Reimplemented from VStateless_class.

Definition at line 17 of file xnode.h.

References consts, Hash< const String::Body, Value * >::get(), VStateless_class::get_element(), and result.

Value* MXnode::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented from VStateless_class.

Definition at line 31 of file xnode.h.

bool MXnode::used_directly ( ) [inline, virtual]

should Methoded_array::register_directly_used register this class in Request::classes() or not.

if not - global variable with Methoded descendant is used in VStateless_class parameter

Implements Methoded.

Definition at line 41 of file xnode.h.

Member Data Documentation

HashStringValue MXnode::consts [private]

Definition at line 45 of file xnode.h.

Referenced by get_element().

The documentation for this class was generated from the following file:
  • xnode.h


Member List

MXnode Member List

This is the complete list of members for MXnode, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
configure_admin(Request &) | Methoded | [inline, virtual]
configure_user(Request &) | Methoded | [inline, virtual]
construct_statics() | Methoded | [inline, virtual]
consts | MXnode | [private]
create_new_value(Pool &, HashStringValue &) | MXnode | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | MXnode | [inline, virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
Methoded(const char *aname, VStateless_class *abase=0) | Methoded | [inline]
MXnode(const char *aname=0, VStateless_class *abase=0) | MXnode |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &, Value *) | Methoded | [inline]
VStateless_class::put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
register_directly_used(Request &r) | Methoded |
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStateless_class | [inline, virtual]
used_directly() | MXnode | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


Operation Union Reference

Parser source code got compiled into intermediate form of Operation-s, which are executed afterwards. More...

Collaboration diagram for Operation:

[legend]
List of all members.

Public Methods

Operation ()
needed to fill unused Array entries. More...

Operation (OPCODE acode)
Operation (uint afile_no, uint aline, uint acol)
Operation (Value *avalue)
Operation (ArrayOperation *aops)

Public Attributes

OPCODE code
operation code. More...

Origin origin
not an operation, but rather debug information: [OP_VALUE; debug_info; Value*]. More...

Value * value
not an operation, but rather value stored after argumented op. More...

ArrayOperation * ops
not an operation, but rather code array stored after argumented op. More...

Detailed Description

Parser source code got compiled into intermediate form of Operation-s, which are executed afterwards.

It is compiled into Array of Operation-s. Each Operation can be either OPCODE or data pointer, following the literal-instruction.

  • OP_VALUE followed by Origin, followed by Value*
  • OP_CURLY_CODE__STORE_PARAM followed by ArrayOperation*
  • OP_EXPR_CODE__STORE_PARAM followed by ArrayOperation*
  • OP_NESTED_CODE followed by ArrayOperation*

Definition at line 35 of file pa_operation.h.

Constructor & Destructor Documentation

Operation::Operation ( ) [inline]

needed to fill unused Array entries.

Definition at line 53 of file pa_operation.h.

Operation::Operation ( OPCODE acode ) [inline]

Definition at line 54 of file pa_operation.h.

References code, and OPCODE.

Operation::Operation | ( | uint | afile_no,
 |  | uint | aline,
 |  | uint | acol
 | ) | [inline]

Definition at line 55 of file pa_operation.h.

References uint.

Operation::Operation ( Value * avalue ) [inline]

Definition at line 57 of file pa_operation.h.

Operation::Operation ( ArrayOperation * aops ) [inline]

Definition at line 58 of file pa_operation.h.

Member Data Documentation

OPCODE Operation::code

operation code.

Definition at line 47 of file pa_operation.h.

Referenced by changetail_or_append(), and Operation().

Origin Operation::origin

not an operation, but rather debug information: [OP_VALUE; debug_info; Value*].

Definition at line 48 of file pa_operation.h.

Value* Operation::value

not an operation, but rather value stored after argumented op.

Definition at line 49 of file pa_operation.h.

ArrayOperation* Operation::ops

not an operation, but rather code array stored after argumented op.

Definition at line 50 of file pa_operation.h.

The documentation for this union was generated from the following file:
  • pa_operation.h


Member List

Operation Member List

This is the complete list of members for Operation, including all inherited members.
code | Operation |
Operation() | Operation | [inline]
Operation(OPCODE acode) | Operation | [inline]
Operation(uint afile_no, uint aline, uint acol) | Operation | [inline]
Operation(Value *avalue) | Operation | [inline]
Operation(ArrayOperation *aops) | Operation | [inline]
ops | Operation |
origin | Operation |
value | Operation |


Operation::Origin Struct Reference

List of all members.

Static Public Methods

Origin | create (uint afile_no, uint aline, uint acol)

Public Attributes

uint | file_no:8
file number (max: 255): index in Request::file_list. More...

uint | line:8+8
line number (max: 64535). More...

uint | col:8
column number (max: 255). More...

Member Function Documentation

Origin Operation::Origin::create | ( | uint | afile_no,
 |  | uint | aline,
 |  | uint | acol
 | ) | [inline, static]

Definition at line 41 of file pa_operation.h.

References result, and uint.

Member Data Documentation

uint Operation::Origin::file_no

file number (max: 255): index in Request::file_list.

Definition at line 37 of file pa_operation.h.

Referenced by Request::core(), Request::get_details(), and Request::get_exception_cstr().

uint Operation::Origin::line

line number (max: 64535).

Definition at line 38 of file pa_operation.h.

Referenced by Request::core(), Request::get_details(), and Request::get_exception_cstr().

uint Operation::Origin::col

column number (max: 255).

Definition at line 39 of file pa_operation.h.

Referenced by Request::core(), Request::get_details(), and Request::get_exception_cstr().

The documentation for this struct was generated from the following file:
  • pa_operation.h


Member List

Operation::Origin Member List

This is the complete list of members for Operation::Origin, including all inherited members.
col | Operation::Origin |
create(uint afile_no, uint aline, uint acol) | Operation::Origin | [inline, static]
file_no | Operation::Origin |
line | Operation::Origin |


PA_Allocated Class Reference

memory allocation/dallocation goes via pa_malloc/pa_free. More...

Inheritance diagram for PA_Allocated:

[legend]
List of all members.

Static Public Methods

void * | operator new (size_t size)
the sole: instances allocated using our functions. More...

void | operator delete (void *ptr)
void * | malloc (size_t size)
void * | malloc_atomic (size_t size)
char * | strdup (const char *auto_variable_never_null, size_t helper_length=0)
void | free (void *ptr)
void * | realloc (void *ptr, size_t size)

Static Private Methods

void * | calloc (size_t size)
use malloc/malloc_atomic instead [GC clears result of those]. More...

Detailed Description

memory allocation/dallocation goes via pa_malloc/pa_free.

Definition at line 113 of file pa_memory.h.

Member Function Documentation

void* PA_Allocated::operator new ( size_t size ) [inline, static]

the sole: instances allocated using our functions.

Definition at line 116 of file pa_memory.h.

References pa_malloc(), and size.

void PA_Allocated::operator delete ( void * ptr ) [inline, static]

Definition at line 119 of file pa_memory.h.

References pa_free().

void* PA_Allocated::malloc ( size_t size ) [inline, static]

Definition at line 122 of file pa_memory.h.

References pa_malloc(), and size.

Referenced by Array< Operation >::Array(), gdImage::Create(), gdImage::FilledPolygon(), gdImage::FilledPolygonReplaceColor(), SMTP::SMTP(), and String::v().

void* PA_Allocated::malloc_atomic ( size_t size ) [inline, static]

Definition at line 125 of file pa_memory.h.

References pa_malloc_atomic(), and size.

Referenced by gdImage::Create().

char* PA_Allocated::strdup | ( | const char * | auto_variable_never_null,
 |  | size_t | helper_length = 0
 | ) | [inline, static]

Definition at line 128 of file pa_memory.h.

References pa_strdup().

Referenced by Request::absolute(), VForm::AppendFormEntry(), VCookie::fill_fields(), VEnv::get_element(), VConsole::get_element(), VInt::get_string(), VDouble::get_string(), VForm::refill_fields_and_tables(), Request::relative(), VFile::set(), and VForm::transcode().

void PA_Allocated::free ( void * ptr ) [inline, static]

Definition at line 131 of file pa_memory.h.

References pa_free().

Referenced by Request::~Request(), and SMTP::~SMTP().

void* PA_Allocated::realloc | ( | void * | ptr,
 |  | size_t | size
 | ) | [inline, static]

Definition at line 134 of file pa_memory.h.

References pa_realloc(), and size.

Referenced by Array< Operation >::expand(), gdGrowingBuf::expand(), gdImage::FilledPolygon(), and gdImage::FilledPolygonReplaceColor().

void* PA_Allocated::calloc ( size_t size ) [static, private]

use malloc/malloc_atomic instead [GC clears result of those].

The documentation for this class was generated from the following file:
  • pa_memory.h


Member List

PA_Allocated Member List

This is the complete list of members for PA_Allocated, including all inherited members.
calloc(size_t size) | PA_Allocated | [private, static]
free(void *ptr) | PA_Allocated | [inline, static]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


PA_Cleaned Class Reference

Those who want their destructor called during finalization, must derive from this class [also]. More...

List of all members.

Public Methods

PA_Cleaned ()
virtual | ~PA_Cleaned ()

Static Private Methods

void | cleanup (void *obj, void *displ)

Detailed Description

Those who want their destructor called during finalization, must derive from this class [also].

Definition at line 146 of file pa_memory.h.

Constructor & Destructor Documentation

PA_Cleaned::PA_Cleaned ( ) [inline]

Definition at line 153 of file pa_memory.h.

References cleanup().

virtual PA_Cleaned::~PA_Cleaned ( ) [inline, virtual]

Definition at line 168 of file pa_memory.h.

References GC_REGISTER_FINALIZER_IGNORE_SELF.

Member Function Documentation

void PA_Cleaned::cleanup | ( | void * | obj,
 |  | void * | displ
 | ) | [inline, static, private]

Definition at line 148 of file pa_memory.h.

Referenced by PA_Cleaned().

The documentation for this class was generated from the following file:
  • pa_memory.h


Member List

PA_Cleaned Member List

This is the complete list of members for PA_Cleaned, including all inherited members.
cleanup(void *obj, void *displ) | PA_Cleaned | [inline, private, static]
PA_Cleaned() | PA_Cleaned | [inline]
~PA_Cleaned() | PA_Cleaned | [inline, virtual]


PA_exec_result Struct Reference

Collaboration diagram for PA_exec_result:

[legend]
List of all members.

Public Methods

PA_exec_result ()

Public Attributes

int status
exit code. More...

String & out
String & err

Constructor & Destructor Documentation

PA_exec_result::PA_exec_result ( ) [inline]

Definition at line 24 of file pa_exec.h.

References new, and status.

Member Data Documentation

int PA_exec_result::status

exit code.

Definition at line 20 of file pa_exec.h.

Referenced by _exec_cgi(), pa_exec(), PA_exec_result(), and sendmail().

String& PA_exec_result::out

Definition at line 21 of file pa_exec.h.

Referenced by _exec_cgi(), and pa_exec().

String& PA_exec_result::err

Definition at line 22 of file pa_exec.h.

Referenced by _exec_cgi(), pa_exec(), and sendmail().

The documentation for this struct was generated from the following file:
  • pa_exec.h


Member List

PA_exec_result Member List

This is the complete list of members for PA_exec_result, including all inherited members.
err | PA_exec_result |
out | PA_exec_result |
PA_exec_result() | PA_exec_result | [inline]
status | PA_exec_result |


PA_MD5_CTX Struct Reference

List of all members.

Public Attributes

UINT4 | state [4]
UINT4 | count [2]
unsigned char | buffer [64]

Member Data Documentation

UINT4 PA_MD5_CTX::state[4]

Definition at line 120 of file pa_md5.h.

UINT4 PA_MD5_CTX::count[2]

Definition at line 121 of file pa_md5.h.

unsigned char PA_MD5_CTX::buffer[64]

Definition at line 122 of file pa_md5.h.

The documentation for this struct was generated from the following file:
  • pa_md5.h


Member List

PA_MD5_CTX Member List

This is the complete list of members for PA_MD5_CTX, including all inherited members.
buffer | PA_MD5_CTX
count | PA_MD5_CTX
state | PA_MD5_CTX


pa_request_rec_tag Struct Reference

List of all members.

Public Attributes

void * | real_request_rec
pa_pool * pool
int | header_only
int * | status
const char * | method
pa_table * headers_out
void * | subprocess_env
const char ** | content_type
char * | uri
char * | filename
char * | path_info
char * | args
stat * | finfo

Member Data Documentation

void* pa_request_rec_tag::real_request_rec

Definition at line 24 of file pa_httpd.h.

Referenced by pa_ap_add_cgi_vars(), pa_ap_add_common_vars(), pa_ap_get_client_block(), pa_ap_hard_timeout(), pa_ap_kill_timeout(), pa_ap_log_rerror(), pa_ap_reset_timeout(), pa_ap_rwrite(), pa_ap_send_http_header(), pa_ap_setup_client_block(), and pa_ap_should_client_block().

pa_pool* pa_request_rec_tag::pool

Definition at line 26 of file pa_httpd.h.

Referenced by SAPI::add_header_attribute().

int pa_request_rec_tag::header_only

Definition at line 27 of file pa_httpd.h.

Referenced by pa_parser_handler(), and real_parser_handler().

int* pa_request_rec_tag::status

Definition at line 28 of file pa_httpd.h.

Referenced by SAPI::add_header_attribute().

const char* pa_request_rec_tag::method

Definition at line 29 of file pa_httpd.h.

Referenced by real_parser_handler().

pa_table* pa_request_rec_tag::headers_out

Definition at line 31 of file pa_httpd.h.

Referenced by SAPI::add_header_attribute().

void* pa_request_rec_tag::subprocess_env

Definition at line 32 of file pa_httpd.h.

Referenced by SAPI::environment(), and SAPI::get_env().

const char** pa_request_rec_tag::content_type

Definition at line 33 of file pa_httpd.h.

Referenced by SAPI::add_header_attribute().

char* pa_request_rec_tag::uri

Definition at line 35 of file pa_httpd.h.

char* pa_request_rec_tag::filename

Definition at line 36 of file pa_httpd.h.

Referenced by real_parser_handler().

char* pa_request_rec_tag::path_info

Definition at line 37 of file pa_httpd.h.

char* pa_request_rec_tag::args

Definition at line 38 of file pa_httpd.h.

Referenced by real_parser_handler().

struct stat* pa_request_rec_tag::finfo

Definition at line 39 of file pa_httpd.h.

Referenced by pa_parser_handler().

The documentation for this struct was generated from the following file:
  • pa_httpd.h


Member List

pa_request_rec_tag Member List

This is the complete list of members for pa_request_rec_tag, including all inherited members.
args | pa_request_rec_tag
content_type | pa_request_rec_tag
filename | pa_request_rec_tag
finfo | pa_request_rec_tag
header_only | pa_request_rec_tag
headers_out | pa_request_rec_tag
method | pa_request_rec_tag
path_info | pa_request_rec_tag
pool | pa_request_rec_tag
real_request_rec | pa_request_rec_tag
status | pa_request_rec_tag
subprocess_env | pa_request_rec_tag
uri | pa_request_rec_tag


Parse_control Class Reference

compiler status. More...

Collaboration diagram for Parse_control:

[legend]
List of all members.

Public Methods

const String & | alias_method (const String &name)
Parse_control (Request &arequest, VStateless_class *aclass, const char *asource, const String *amain_alias, uint afile_no, int line_no_offset)
void | pos_next_line ()
void | pos_next_c (int c)
void | pos_prev_c ()
not precise in case of \t in the middle of the text. More...

void | ungetc ()

Public Attributes

char | error [MAX_STRING]
output: filled input 'methods' and 'error' if any. More...

input
Request & request
VStateless_class * cclass
const char * | source
uint file_no
Pos pos
state; initially
bool | trim_bof
int | pending_state
i=0. More...

String::Body string
lexical string accumulator. More...

Pos string_start
enum lexical_state | ls
=LS_USER;. More...

int | ls_sp
=0. More...

enum lexical_state | ls_stack [MAX_LEXICAL_STATES]
int | brackets_nestages [MAX_LEXICAL_STATES]
brackets nestage on each state. More...

bool | in_call_value
bool | explicit_result

Private Attributes

const String * | main_alias
uint last_line_end_col

Detailed Description

compiler status.

Definition at line 56 of file compile_tools.h.

Constructor & Destructor Documentation

Parse_control::Parse_control | ( | Request & | arequest,
 |  | VStateless_class * | aclass,
 |  | const char * | asource,
 |  | const String * | amain_alias,
 |  | uint | afile_no,
 |  | int | line_no_offset
 | ) | [inline]

Definition at line 89 of file compile_tools.h.

References explicit_result, file_no, in_call_value, last_line_end_col, ls, ls_sp, LS_USER, pending_state, source, trim_bof, and uint.

Member Function Documentation

const String & Parse_control::alias_method ( const String & name )

Definition at line 65 of file compile_tools.C.

References main_alias.

void Parse_control::pos_next_line ( ) [inline]

Definition at line 113 of file compile_tools.h.

References Pos::col, last_line_end_col, and Pos::line.

void Parse_control::pos_next_c ( int c ) [inline]

Definition at line 118 of file compile_tools.h.

References Pos::col, and TAB_SIZE.

void Parse_control::pos_prev_c ( ) [inline]

not precise in case of \t in the middle of the text.

Definition at line 125 of file compile_tools.h.

References Pos::col, last_line_end_col, and Pos::line.

Referenced by Request::compile(), and ungetc().

void Parse_control::ungetc ( ) [inline]

Definition at line 131 of file compile_tools.h.

References pos_prev_c(), and source.

Member Data Documentation

const String* Parse_control::main_alias [private]

Definition at line 57 of file compile_tools.h.

Referenced by alias_method().

uint Parse_control::last_line_end_col [private]

Definition at line 58 of file compile_tools.h.

Referenced by Parse_control(), pos_next_line(), and pos_prev_c().

Request& Parse_control::request

Definition at line 63 of file compile_tools.h.

VStateless_class* Parse_control::cclass

Definition at line 64 of file compile_tools.h.

Referenced by Request::compile().

const char* Parse_control::source

Definition at line 65 of file compile_tools.h.

Referenced by Parse_control(), and ungetc().

uint Parse_control::file_no

Definition at line 66 of file compile_tools.h.

Referenced by Parse_control().

Pos Parse_control::pos

Definition at line 67 of file compile_tools.h.

Referenced by Request::compile().

bool Parse_control::trim_bof

Definition at line 71 of file compile_tools.h.

Referenced by Parse_control().

int Parse_control::pending_state

i=0.

Definition at line 72 of file compile_tools.h.

Referenced by Parse_control().

String::Body Parse_control::string

lexical string accumulator.

Definition at line 73 of file compile_tools.h.

Pos Parse_control::string_start

Definition at line 74 of file compile_tools.h.

enum lexical_state Parse_control::ls

=LS_USER;.

Definition at line 77 of file compile_tools.h.

Referenced by Parse_control(), pop_LS(), and push_LS().

int Parse_control::ls_sp

=0.

Definition at line 78 of file compile_tools.h.

Referenced by Parse_control(), pop_LS(), and push_LS().

enum lexical_state Parse_control::ls_stack[MAX_LEXICAL_STATES]

Definition at line 79 of file compile_tools.h.

Referenced by pop_LS(), and push_LS().

int Parse_control::brackets_nestages[MAX_LEXICAL_STATES]

brackets nestage on each state.

Definition at line 80 of file compile_tools.h.

bool Parse_control::in_call_value

Definition at line 82 of file compile_tools.h.

Referenced by Parse_control().

bool Parse_control::explicit_result

Definition at line 83 of file compile_tools.h.

Referenced by Request::compile(), and Parse_control().

char Parse_control::error[MAX_STRING]

output: filled input 'methods' and 'error' if any.

Definition at line 87 of file compile_tools.h.

Referenced by Request::compile().

The documentation for this class was generated from the following files:
  • compile_tools.h
  • compile_tools.C


Member List

Parse_control Member List

This is the complete list of members for Parse_control, including all inherited members.
alias_method(const String &name) | Parse_control |
brackets_nestages | Parse_control |
cclass | Parse_control |
error | Parse_control |
explicit_result | Parse_control |
file_no | Parse_control |
in_call_value | Parse_control |
last_line_end_col | Parse_control | [private]
ls | Parse_control |
ls_sp | Parse_control |
ls_stack | Parse_control |
main_alias | Parse_control | [private]
Parse_control(Request &arequest, VStateless_class *aclass, const char *asource, const String *amain_alias, uint afile_no, int line_no_offset) | Parse_control | [inline]
pending_state | Parse_control |
pos | Parse_control |
pos_next_c(int c) | Parse_control | [inline]
pos_next_line() | Parse_control | [inline]
pos_prev_c() | Parse_control | [inline]
request | Parse_control |
source | Parse_control |
string | Parse_control |
string_start | Parse_control |
trim_bof | Parse_control |
ungetc() | Parse_control | [inline]


Parser_module_config_tag Struct Reference

apache parser module configuration [httpd.conf + .htaccess-es]. More...

List of all members.

Public Attributes

const char * | parser_config_filespec
filespec of site's config file. More...

int | parser_status_allowed

Detailed Description

apache parser module configuration [httpd.conf + .htaccess-es].

Definition at line 43 of file pa_httpd.h.

Member Data Documentation

const char* Parser_module_config_tag::parser_config_filespec

filespec of site's config file.

Definition at line 44 of file pa_httpd.h.

Referenced by cmd_parser_config(), parser_merge_dir_config(), parser_merge_server_config(), and real_parser_handler().

int Parser_module_config_tag::parser_status_allowed

Definition at line 45 of file pa_httpd.h.

Referenced by cmd_parser_status_allowed(), parser_merge_dir_config(), parser_merge_server_config(), and real_parser_handler().

The documentation for this struct was generated from the following file:
  • pa_httpd.h


Member List

Parser_module_config_tag Member List

This is the complete list of members for Parser_module_config_tag, including all inherited members.
parser_config_filespec | Parser_module_config_tag
parser_status_allowed | Parser_module_config_tag


PNG_Header Struct Reference

PNG file header. More...

List of all members.

Public Attributes

char | dummy [12]
char | signature [4]
uchar | high_width [2]
uchar | width [2]
uchar | high_height [2]
uchar | height [4]

Detailed Description

PNG file header.

Definition at line 245 of file image.C.

Member Data Documentation

char PNG_Header::dummy[12]

Definition at line 246 of file image.C.

char PNG_Header::signature[4]

Definition at line 247 of file image.C.

Referenced by measure_png().

uchar PNG_Header::high_width[2]

Definition at line 248 of file image.C.

uchar PNG_Header::width[2]

Definition at line 249 of file image.C.

Referenced by measure_png().

uchar PNG_Header::high_height[2]

Definition at line 250 of file image.C.

uchar PNG_Header::height[4]

Definition at line 251 of file image.C.

Referenced by measure_png().

The documentation for this struct was generated from the following file:
  • image.C


Member List

PNG_Header Member List

This is the complete list of members for PNG_Header, including all inherited members.
dummy | PNG_Header
height | PNG_Header
high_height | PNG_Header
high_width | PNG_Header
signature | PNG_Header
width | PNG_Header


Pool Class Reference

Pool mechanizm allows users not to free up allocated objects, leaving that problem to 'pools'. More...

Collaboration diagram for Pool:

[legend]
List of all members.

Public Methods

Pool ()
~Pool ()
void | register_cleanup (void(*cleanup)(void *), void *data)
registers a routine to clean up non-pooled allocations. More...

void | unregister_cleanup (void *cleanup_data)
unregister it, looking it up by it's data. More...

Private Methods

bool | real_register_cleanup (void(*cleanup)(void *), void *data)
void | fail_register_cleanup () const
throws register cleanup exception. More...

Pool (const Pool &)
Pool & | operator= (const Pool &)

Private Attributes

Array< Cleanup > cleanups

Detailed Description

Pool mechanizm allows users not to free up allocated objects, leaving that problem to 'pools'.

See also:
Pooled

Definition at line 24 of file pa_pool.h.

Constructor & Destructor Documentation

Pool::Pool ( )

Definition at line 18 of file pa_pool.C.

Pool::~Pool ( )

Definition at line 24 of file pa_pool.C.

References cleanup(), cleanups, and Array< Cleanup >::for_each().

Pool::Pool ( const Pool & ) [private]

Member Function Documentation

void Pool::register_cleanup | ( | void(* | cleanup)(void *),
 |  | void * | data
 | ) |

registers a routine to clean up non-pooled allocations.

Definition at line 32 of file pa_pool.C.

References cleanup(), cleanups, and data.

Referenced by Pooled::Pooled().

void Pool::unregister_cleanup ( void * cleanup_data )

unregister it, looking it up by it's data.

Definition at line 40 of file pa_pool.C.

References cleanups, Array< Cleanup >::for_each_ref(), and unregister_cleanup().

Referenced by unregister_cleanup(), and Pooled::~Pooled().

bool Pool::real_register_cleanup | ( | void(* | cleanup)(void *),
 |  | void * | data
 | ) | [private]

void Pool::fail_register_cleanup ( ) const [private]

throws register cleanup exception.

Pool& Pool::operator= ( const Pool & ) [private]

Member Data Documentation

Array<Cleanup> Pool::cleanups [private]

Definition at line 44 of file pa_pool.h.

Referenced by register_cleanup(), unregister_cleanup(), and ~Pool().

The documentation for this class was generated from the following files:
  • pa_pool.h
  • pa_pool.C


Member List

Pool Member List

This is the complete list of members for Pool, including all inherited members.
cleanups | Pool | [private]
fail_register_cleanup() const | Pool | [private]
operator=(const Pool &) | Pool | [private]
Pool() | Pool |
Pool(const Pool &) | Pool | [private]
real_register_cleanup(void(*cleanup)(void *), void *data) | Pool | [private]
register_cleanup(void(*cleanup)(void *), void *data) | Pool |
unregister_cleanup(void *cleanup_data) | Pool |
~Pool() | Pool |


Pool::Cleanup Struct Reference

List of all members.

Public Methods

Cleanup (void(*acleanup)(void *), void *adata)

Public Attributes

void(* | cleanup )(void *)
void * | data

Constructor & Destructor Documentation

Pool::Cleanup::Cleanup | ( | void(* | acleanup)(void *),
 |  | void * | adata
 | ) | [inline]

Definition at line 31 of file pa_pool.h.

References cleanup, and data.

Member Data Documentation

void(* Pool::Cleanup::cleanup)(void *)

Referenced by Cleanup(), cleanup(), and unregister_cleanup().

void* Pool::Cleanup::data

Definition at line 29 of file pa_pool.h.

Referenced by Cleanup(), cleanup(), and unregister_cleanup().

The documentation for this struct was generated from the following file:
  • pa_pool.h


Member List

Pool::Cleanup Member List

This is the complete list of members for Pool::Cleanup, including all inherited members.
cleanup | Pool::Cleanup |
Cleanup(void(*acleanup)(void *), void *adata) | Pool::Cleanup | [inline]
data | Pool::Cleanup |


Pooled Class Reference

Base for all classes that are allocated in 'pools'. More...

Inheritance diagram for Pooled:

[legend]
Collaboration diagram for Pooled:

[legend]
List of all members.

Public Methods

Pooled (Pool &apool)
virtual ~Pooled ()
Sole: this got called automatically from Pool::~Pool(). More...

Private Attributes

Pool & fpool

Detailed Description

Base for all classes that are allocated in 'pools'.

Holds Pool object.

Definition at line 68 of file pa_pool.h.

Constructor & Destructor Documentation

Pooled::Pooled ( Pool & apool )

Definition at line 50 of file pa_pool.C.

References cleanup(), fpool, and Pool::register_cleanup().

Pooled::~Pooled ( ) [virtual]

Sole: this got called automatically from Pool::~Pool().

Definition at line 55 of file pa_pool.C.

References fpool, and Pool::unregister_cleanup().

Member Data Documentation

Pool& Pooled::fpool [private]

Definition at line 70 of file pa_pool.h.

Referenced by Pooled(), and ~Pooled().

The documentation for this class was generated from the following files:
  • pa_pool.h
  • pa_pool.C


Member List

Pooled Member List

This is the complete list of members for Pooled, including all inherited members.
fpool | Pooled | [private]
Pooled(Pool &apool) | Pooled |
~Pooled() | Pooled | [virtual]


Pos Struct Reference

List of all members.

Public Methods

Pos (int aline, int acol)
Pos ()
void | clear ()
operator bool ()

Public Attributes

int | line
int | col

Constructor & Destructor Documentation

Pos::Pos | ( | int | aline,
 |  | int | acol
 | ) | [inline]

Definition at line 48 of file compile_tools.h.

References col, and line.

Pos::Pos ( ) [inline]

Definition at line 49 of file compile_tools.h.

References col, and line.

Member Function Documentation

void Pos::clear ( ) [inline]

Definition at line 51 of file compile_tools.h.

References col, and line.

Pos::operator bool ( ) [inline]

Definition at line 52 of file compile_tools.h.

References col.

Member Data Documentation

int Pos::line

Definition at line 46 of file compile_tools.h.

Referenced by clear(), Request::compile(), Pos(), Parse_control::pos_next_line(), and Parse_control::pos_prev_c().

int Pos::col

Definition at line 47 of file compile_tools.h.

Referenced by clear(), Request::compile(), operator bool(), Pos(), Parse_control::pos_next_c(), Parse_control::pos_next_line(), and Parse_control::pos_prev_c().

The documentation for this struct was generated from the following file:
  • compile_tools.h


Member List

Pos Member List

This is the complete list of members for Pos, including all inherited members.
clear() | Pos | [inline]
col | Pos |
line | Pos |
operator bool() | Pos | [inline]
Pos(int aline, int acol) | Pos | [inline]
Pos() | Pos | [inline]


Property Class Reference

junction is getter and setter methods. More...

Inheritance diagram for Property:

[legend]
Collaboration diagram for Property:

[legend]
List of all members.

Public Attributes

Method * getter
Method * setter

Detailed Description

junction is getter and setter methods.

it is used to cache our knowledge that some element is in fact property and to save us one hash lookup and one name construction (element--get_element/set_leement)

Definition at line 20 of file pa_property.h.

Member Data Documentation

Method* Property::getter

Definition at line 22 of file pa_property.h.

Referenced by VClass::add_method(), and VClass::get_element().

Method* Property::setter

Definition at line 23 of file pa_property.h.

Referenced by VClass::add_method(), and VClass::prevent_overwrite_property().

The documentation for this class was generated from the following file:
  • pa_property.h


Member List

Property Member List

This is the complete list of members for Property, including all inherited members.
free(void *ptr) | PA_Allocated | [inline, static]
getter | Property |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
setter | Property |
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]


Random_provider Class Reference

List of all members.

Public Methods

Random_provider ()
~Random_provider ()
void | generate (void *buffer, size_t size)

Private Methods

void | acquire ()
void | release ()

Private Attributes

HCRYPTPROV | fhProv

Constructor & Destructor Documentation

Random_provider::Random_provider ( ) [inline]

Definition at line 74 of file math.C.

References fhProv.

Random_provider::~Random_provider ( ) [inline]

Definition at line 75 of file math.C.

References release().

Member Function Documentation

void Random_provider::acquire ( ) [inline, private]

Definition at line 57 of file math.C.

References fhProv, and SYNCHRONIZED.

Referenced by generate().

void Random_provider::release ( ) [inline, private]

Definition at line 68 of file math.C.

References fhProv.

Referenced by ~Random_provider().

void Random_provider::generate | ( | void * | buffer,
 |  | size_t | size
 | ) | [inline]

Definition at line 76 of file math.C.

References acquire(), fhProv, and size.

Referenced by random().

Member Data Documentation

HCRYPTPROV Random_provider::fhProv [private]

Definition at line 55 of file math.C.

Referenced by acquire(), generate(), Random_provider(), and release().

The documentation for this class was generated from the following file:
  • math.C


Member List

Random_provider Member List

This is the complete list of members for Random_provider, including all inherited members.
acquire() | Random_provider | [inline, private]
fhProv | Random_provider | [private]
generate(void *buffer, size_t size) | Random_provider | [inline]
Random_provider() | Random_provider | [inline]
release() | Random_provider | [inline, private]
~Random_provider() | Random_provider | [inline]


real_pcre Struct Reference

List of all members.

Public Attributes

unsigned long int | magic_number
const unsigned char * | tables
unsigned long int | options
uschar top_bracket
uschar top_backref
uschar first_char
uschar req_char
uschar | code [1]

Member Data Documentation

unsigned long int real_pcre::magic_number

Definition at line 277 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), pcre_info(), and pcre_study().

const unsigned char* real_pcre::tables

Definition at line 278 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), and pcre_study().

unsigned long int real_pcre::options

Definition at line 279 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), pcre_info(), and pcre_study().

uschar real_pcre::top_bracket

Definition at line 280 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), and pcre_info().

uschar real_pcre::top_backref

Definition at line 281 of file internal.h.

Referenced by pcre_compile(), and pcre_exec().

uschar real_pcre::first_char

Definition at line 282 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), and pcre_info().

uschar real_pcre::req_char

Definition at line 283 of file internal.h.

Referenced by pcre_compile(), and pcre_exec().

uschar real_pcre::code[1]

Definition at line 284 of file internal.h.

Referenced by pcre_compile(), pcre_exec(), and pcre_study().

The documentation for this struct was generated from the following file:
  • internal.h


Member List

real_pcre Member List

This is the complete list of members for real_pcre, including all inherited members.
code | real_pcre
first_char | real_pcre
magic_number | real_pcre
options | real_pcre
req_char | real_pcre
tables | real_pcre
top_backref | real_pcre
top_bracket | real_pcre


real_pcre_extra Struct Reference

List of all members.

Public Attributes

uschar options
uschar start_bits [32]

Member Data Documentation

uschar real_pcre_extra::options

Definition at line 290 of file internal.h.

Referenced by pcre_exec(), and pcre_study().

uschar real_pcre_extra::start_bits[32]

Definition at line 291 of file internal.h.

Referenced by pcre_exec(), and pcre_study().

The documentation for this struct was generated from the following file:
  • internal.h


Member List

real_pcre_extra Member List

This is the complete list of members for real_pcre_extra, including all inherited members.
options | real_pcre_extra
start_bits | real_pcre_extra


refill_data Struct Reference

Collaboration diagram for refill_data:

[legend]
List of all members.

Public Attributes

lf_state * state
size_t file_pos
cache_line * new_cache

Member Data Documentation

lf_state* refill_data::state

Definition at line 503 of file cordxtra.c.

size_t refill_data::file_pos

Definition at line 504 of file cordxtra.c.

cache_line* refill_data::new_cache

Definition at line 505 of file cordxtra.c.

The documentation for this struct was generated from the following file:
  • cordxtra.c


Member List

refill_data Member List

This is the complete list of members for refill_data, including all inherited members.
file_pos | refill_data
new_cache | refill_data
state | refill_data


Request Class Reference

Main workhorse. More...

Inheritance diagram for Request:

[legend]
Collaboration diagram for Request:

[legend]
List of all members.

Public Methods

Pool & pool ()
uint | register_file (String::Body file_spec)
Exception_details | get_details (const Exception &e)
const char * | get_exception_cstr (const Exception &e, Exception_details &details)
void | wipe_unused_execution_stack ()
See also:
Stack::wipe_unused.
 More...

Request (SAPI_Info &asapi_info, Request_info &arequest_info, String::Language adefault_lang, bool status_allowed)
~Request ()
HashStringValue & classes ()
global classes. More...

void | core (const char *config_filespec, bool config_fail_on_read_problem, bool header_only)
core request processing. More...

void | execute (ArrayOperation &ops)
executes ops. More...

void | recoursion_checked_execute (ArrayOperation &ops)
execute ops with anti-recoursion check. More...

void | use_file (VStateless_class &aclass, const String &file_name, const String *main_alias=0, bool ignore_class_path=false, bool fail_on_read_problem=true, bool fail_on_file_absence=true)
compiles the file, maybe forcing it's class name and base_class. More...

void | use_buf (VStateless_class &aclass, const char *source, const String *main_alias, uint file_no, int line_no_offset=0)
compiles a source buffer. More...

StringOrValue | process (Value &input_value, bool intercept_string=true)
processes any code-junction there may be inside of value. More...

void | write_no_lang (const String &astring)
appending, sure of clean string inside. More...

void | write_no_lang (Value &avalue)
appending sure value, that would be converted to clean string. More...

void | write_pass_lang (const String &astring)
appending string, passing language built into string being written. More...

void | write_pass_lang (Value &avalue)
appending possible string, passing language built into string being written. More...

void | write_assign_lang (Value &avalue)
appending possible string, assigning untaint language. More...

void | write_assign_lang (const String &astring)
appending string, assigning untaint language. More...

const String & | relative (const char *apath, const String &relative_name)
returns relative to path path to file. More...

const String & | absolute (const String &relative_name)
returns an absolute path to relative name. More...

const String & | mime_type_of (const char *user_file_name_cstr)
returns the mime type of 'user_file_name_cstr'. More...

SQL_Connection * | connection (bool fail_on_error=true)
returns current SQL connection if any. More...

void | set_interrupted (bool ainterrupted)
bool | get_interrupted ()
VMethodFrame * get_method_frame ()
Value & get_self ()
const String * | execute_virtual_method (Value &aself, const String &method_name)
for @main[]. More...

StringOrValue | execute_method (VMethodFrame &amethodFrame, const Method &method)
for @postprocess[body]. More...

const String * | execute_method (Value &aself, const Method &method, VString *optional_param, bool do_return_string)
Execute_nonvirtual_method_result | execute_nonvirtual_method (VStateless_class &aclass, const String &method_name, VString *optional_param, bool do_return_string)
xmlChar * | transcode (const String &s)
See also:
Charset::transcode.
 More...

xmlChar * | transcode (const String::Body s)
See also:
Charset::transcode.
 More...

const String & | transcode (const xmlChar *s)
See also:
Charset::transcode.
 More...

const String & | process_to_string (Value &input_value)
convinient helpers. More...

Value & | process_to_value (Value &input_value, bool intercept_string=true)
convinient helpers. More...

Public Attributes

bool | finterrupted
interrupted flag, raised on signals [SIGPIPE]. More...

Request_info & request_info
info from web server. More...

SAPI_Info & sapi_info
info about ServerAPI. More...

Request_charsets charsets
source, client, mail charsets. More...

VStateless_class & main_class
'MAIN' class conglomerat & operators are methods of this class. More...

VForm & form
$form:elements. More...

VMail & mail
$mail. More...

VResponse & response
$response:elements. More...

VCookie & cookie
$cookie:elements. More...

Hash< const String::Body,
void * > 		classes_conf
classes configured data. More...

VMethodFrame * method_frame
request processing status contexts. More...

Value * rcontext
request processing status contexts. More...

WContext * wcontext
request processing status contexts. More...

String::Language flang
current language. More...

SQL_Connection * fconnection
current connection. More...

Private Methods

void | configure_admin (VStateless_class &conf_class)
void | configure ()
VStateless_class & | compile (VStateless_class *aclass, const char *source, const String *main_alias, uint file_no, int line_no_offset)
void | put_element (Value &ncontext, const String &name, Value &value)
Value & | get_element (Value &ncontext, const String &name, bool can_call_operator)
String::Language | set_lang (String::Language alang)
void | restore_lang (String::Language alang)
SQL_Connection * | set_connection (SQL_Connection *aconnection)
void | restore_connection (SQL_Connection *aconnection)
void | output_result (VFile *body_file, bool header_only, bool as_attachment)

Private Attributes

Pool fpool
Stack< StackItem > stack
execution stack. More...

Exception_trace exception_trace
exception stack trace. More...

bool | configure_admin_done
already executed some @conf method. More...

const String::Language | fdefault_lang
Table * mime_types
$MAIN:MIME-TYPES. More...

implementation defined
HashStringValue fclasses
core data classes. More...

Hash< const String::Body,
bool > 		used_files
already used files to avoid cyclic uses. More...

Array< String::Body > file_list
list of all used files, Operation::file_no = index to it. More...

uint anti_endless_execute_recoursion
endless execute(execute(... More...

Friends

class | Temp_lang
class | Temp_connection
class | Request_context_saver
class | Temp_request_self
class | Exception_trace

Detailed Description

Main workhorse.

Definition at line 43 of file pa_request.h.

Constructor & Destructor Documentation

Request::Request | ( | SAPI_Info & | asapi_info,
 |  | Request_info & | arequest_info,
 |  | String::Language | adefault_lang,
 |  | bool | status_allowed
 | ) |

Parameters:
adefault_lang | all tainted data default untainting lang
status_allowed | status class allowed

Definition at line 99 of file pa_request.C.

References VStateless_class::base_class(), charsets, classes(), CONSOLE_CLASS_NAME, cookie, COOKIE_CLASS_NAME, ENV_CLASS_NAME, file_list, form, Value::get_class(), VStateless_class::get_class(), VResponse::get_class(), String::Language, mail, main_class, methoded_array(), VStateless_class::name(), new, pa_register_thread_request(), Hash< const String::Body, Value * >::put(), Methoded_array::register_directly_used(), REQUEST_CLASS_NAME, request_info, response, and STATUS_CLASS_NAME.

Request::~Request ( )

Definition at line 187 of file pa_request.C.

References PA_Allocated::free(), SAPI::log(), and sapi_info.

Member Function Documentation

Pool& Request::pool ( ) [inline]

Definition at line 69 of file pa_request.h.

uint Request::register_file ( String::Body file_spec )

Definition at line 539 of file pa_request.C.

References Array< String::Body >::count(), file_list, and uint.

Referenced by _process(), and use_file().

Request::Exception_details Request::get_details ( const Exception & e )

Definition at line 951 of file pa_request.C.

References String::append(), Operation::Origin::col, Exception::comment(), exception_trace, Request::Exception_trace::extract_origin(), file_list, Operation::Origin::file_no, VHash::hash(), String::L_TAINTED, Operation::Origin::line, Request::Trace::origin(), Exception::problem_source(), Hash< const String::Body, Value * >::put(), and Exception::type().

Referenced by core(), and try_catch().

const char * Request::get_exception_cstr | ( | const Exception & | e,
 |  | Exception_details & | details
 | ) |

Definition at line 235 of file pa_request.C.

References Operation::Origin::col, Exception::comment(), String::cstr(), file_list, Operation::Origin::file_no, Operation::Origin::line, MAX_STRING, Request::Trace::origin(), Request::Exception_details::problem_source, request_info, result, snprintf, Request::Exception_details::trace, Exception::type(), and Request_info::uri.

Referenced by core().

void Request::wipe_unused_execution_stack ( ) [inline]

See also:
Stack::wipe_unused.

Definition at line 165 of file pa_request.h.

References Stack< T >::wipe_unused().

Referenced by _compact().

HashStringValue& Request::classes ( ) [inline]

global classes.

Definition at line 182 of file pa_request.h.

Referenced by execute(), Methoded::register_directly_used(), and Request().

void Request::core | ( | const char * | config_filespec,
 |  | bool | config_fail_on_read_problem,
 |  | bool | header_only
 | ) |

core request processing.

BEWARE: may throw exception to you: catch it!

Parameters:
config_filespec | system config filespec
config_fail_on_read_problem | fail if system config file not found

Definition at line 299 of file pa_request.C.

References String::append(), String::append_help_length(), String::append_strdup(), Value::as_bool(), StringOrValue::as_string(), StringOrValue::as_value(), VString::as_vfile(), Value::as_vfile(), AUTO_FILE_NAME, before, Request::Exception_trace::bottom_index(), charsets, Request::Exception_trace::clear(), Hash< const String::Body, Value * >::clear(), Operation::Origin::col, Table::columns_type, configure(), cookie, Request_info::document_root, Array< ArrayString * >::element_type, exception_trace, execute_method(), execute_virtual_method(), fdefault_lang, VResponse::fields(), file_list, Operation::Origin::file_no, VCookie::fill_fields(), VMail::fill_received(), flang, String::Body::Format(), Array< Trace >::get(), Hash< const String::Body, Value * >::get(), get_details(), VStateless_class::get_element(), get_exception_cstr(), Value::get_junction(), Value::get_string(), VHash::hash(), Request::Exception_trace::is_empty(), Value::is_string(), String::L_CLEAN, String::L_TAINTED, String::L_UNSPECIFIED, Operation::Origin::line, SAPI::log(), mail, main_class, MAIN_METHOD_NAME, Junction::method, Request::Trace::name(), Request::Trace::origin(), output_result(), Request_info::path_translated, Hash< const String::Body, Value * >::put(), request_info, response, rethrow, sapi_info, VMethodFrame::set_self(), VMethodFrame::store_param(), Stack< Trace >::top_index(), UNHANDLED_EXCEPTION_CONTENT_TYPE, UNHANDLED_EXCEPTION_METHOD_NAME, Request_info::uri, use_file(), value, and Request::Exception_details::vhash.

Referenced by real_parser_handler().

void Request::execute ( ArrayOperation & ops )

executes ops.

Definition at line 105 of file execute.C.

References absolute(), Value::as_bool(), Value::as_double(), Value::as_expr_result(), Value::as_int(), Value::as_string(), StringOrValue::as_value(), Method::Call_type, Method::call_type, Method::check_actual_numbered_params(), classes(), Array< Operation >::count(), VStateless_class::create_new_value(), String::cstr(), Method::CT_ANY, Method::CT_DYNAMIC, Method::CT_STATIC, dir_exists(), exception_trace, file_exist(), VMethodFrame::fill_unspecified_params(), flang, fpool, Hash< const String::Body, Value * >::get(), Value::get_class(), WContext::get_constructing(), get_element(), WContext::get_in_expression(), get_interrupted(), Value::get_junction(), get_self(), WContext::get_string(), Value::get_string(), Array_iterator< T >::has_next(), HashStringValue, Value::is(), Value::is_defined(), VMethodFrame::junction, String::L_CLEAN, String::L_PASS_APPENDED, String::Language, Junction::method, method_frame, VStateless_class::name(), Method::native_code, Array_iterator< T >::next(), VMethodFrame::numbered_params(), OP_ADD, OP_BIN_AND, OP_BIN_OR, OP_BIN_SL, OP_BIN_SR, OP_BIN_XOR, OP_CALL, OP_CALL__WRITE, OP_CONSTRUCT_EXPR, OP_CONSTRUCT_VALUE, OP_CURLY_CODE__CONSTRUCT, OP_CURLY_CODE__STORE_PARAM, OP_DEF, OP_DEXISTS, OP_DIV, OP_EXPR_CODE__STORE_PARAM, OP_FEXISTS, OP_GET_CLASS, OP_GET_ELEMENT, OP_GET_ELEMENT__WRITE, OP_GET_ELEMENT_OR_OPERATOR, OP_IN, OP_INTDIV, OP_INV, OP_IS, OP_LOG_AND, OP_LOG_OR, OP_LOG_XOR, OP_MOD, OP_MUL, OP_NEG, OP_NESTED_CODE, OP_NUM_EQ, OP_NUM_GE, OP_NUM_GT, OP_NUM_LE, OP_NUM_LT, OP_NUM_NE, OP_OBJECT_POOL, OP_PREPARE_TO_CONSTRUCT_OBJECT, OP_PREPARE_TO_EXPRESSION, OP_STORE_PARAM, OP_STR_EQ, OP_STR_GE, OP_STR_GT, OP_STR_LE, OP_STR_LT, OP_STR_NE, OP_STRING__WRITE, OP_STRING_POOL, OP_SUB, OP_VALUE, OP_WITH_READ, OP_WITH_ROOT, OP_WITH_SELF, OP_WITH_WRITE, OP_WRITE_EXPR_RESULT, OP_WRITE_VALUE, OPCODE, Method::parser_code, Stack< T >::pop(), Stack< Trace >::push(), Stack< T >::push(), Value::put_element(), put_element(), PUT_ELEMENT_REPLACED_ELEMENT, rcontext, recoursion_checked_execute(), request_info, result, WContext::result(), rethrow, sapi_info, Junction::self, WContext::set_constructing(), WContext::set_in_expression(), set_interrupted(), VMethodFrame::set_self(), WContext::set_somebody_entered_some_class(), stack, VMethodFrame::store_param(), String::this_starts(), Stack< T >::top_index(), Stack< T >::top_value(), Value::type(), Request_info::uri, value, wcontext, VMethodFrame::write(), write_assign_lang(), and write_no_lang().

Referenced by _process(), and execute_method().

void Request::recoursion_checked_execute ( ArrayOperation & ops ) [inline]

execute ops with anti-recoursion check.

Definition at line 197 of file pa_request.h.

References ANTI_ENDLESS_EXECUTE_RECOURSION, and anti_endless_execute_recoursion.

Referenced by execute(), process(), and put_element().

void Request::use_file | ( | VStateless_class & | aclass,
 |  | const String & | file_name,
 |  | const String * | main_alias = 0,
 |  | bool | ignore_class_path = false,
 |  | bool | fail_on_read_problem = true,
 |  | bool | fail_on_file_absence = true
 | ) |

compiles the file, maybe forcing it's class name and base_class.

Definition at line 544 of file pa_request.C.

References absolute(), Value::as_string(), charsets, CLASS_PATH_NAME, Array< ArrayString * >::count(), entry_exists(), file_exist(), file_read_text(), String::first_char(), Array< ArrayString * >::get(), Hash< const String::Body, bool >::get(), VStateless_class::get_element(), Value::get_table(), Value::is_string(), main_class, MAIN_CLASS_NAME, Hash< const String::Body, bool >::put(), register_file(), size, use_buf(), and used_files.

Referenced by _use(), and core().

void Request::use_buf | ( | VStateless_class & | aclass,
 |  | const char * | source,
 |  | const String * | main_alias,
 |  | uint | file_no,
 |  | int | line_no_offset = 0
 | ) |

compiles a source buffer.

Definition at line 595 of file pa_request.C.

References compile(), configure_admin(), execute_nonvirtual_method(), file_list, String::L_TAINTED, Request::Execute_nonvirtual_method_result::method, and uint.

Referenced by _process(), and use_file().

StringOrValue Request::process | ( | Value & | input_value,
 |  | bool | intercept_string = true
 | ) |

processes any code-junction there may be inside of value.

Parameters:
intercept_string - true: they want result=string value, possible object result goes to wcontext
  • false: they want any result[string|object] nothing goes to wcontext. used in (expression) params evaluation
using the fact it's either string_ or value_ result requested to speed up checkes

Definition at line 923 of file execute.C.

References Junction::code, Value::get_junction(), WContext::get_string(), Junction::is_getter, VMethodFrame::junction, Junction::method, Junction::method_frame, method_frame, Method::params_names, Method::parser_code, Junction::rcontext, rcontext, recoursion_checked_execute(), WContext::result(), result, sapi_info, Junction::self, VMethodFrame::set_self(), StringOrValue::set_string(), Junction::wcontext, and wcontext.

Referenced by _connect(), _find(), _for(), _if(), _menu(), _switch(), _untaint(), _while(), process_try_body_code(), and try_catch().

const String& Request::process_to_string ( Value & input_value ) [inline]

convinient helpers.

Definition at line 226 of file pa_request.h.

Referenced by _append(), _cache(), _create(), _match(), _process(), _sql(), _string_format(), process_cache_body_code(), sql_result_string(), and text_value_to_string().

Value& Request::process_to_value | ( | Value & | input_value,
 |  | bool | intercept_string = true
 | ) | [inline]

convinient helpers.

Definition at line 229 of file pa_request.h.

References StringOrValue::as_value().

Referenced by _case(), _eval(), _hash(), _html(), _load(), _select(), _sort(), _sql(), _switch(), _while(), get_action_options(), get_element(), MethodParams::get_processed(), and sql_result_string().

void Request::write_no_lang ( const String & astring ) [inline]

appending, sure of clean string inside.

Definition at line 244 of file pa_request.h.

References String::L_CLEAN, String::L_OPTIMIZE_BIT, and String::Language.

Referenced by _cache(), _calendar(), _columns(), _count(), _double(), _eval(), _flip(), _gif(), _hash(), _int(), _intersection(), _intersects(), _keys(), _length(), _line(), _list(), _locate(), _offset(), _pixel(), _pos(), _random(), _select(), _sql(), _string_format(), _union(), _unix_timestamp(), execute(), math1(), math2(), and split_with_options().

void Request::write_no_lang ( Value & avalue ) [inline]

appending sure value, that would be converted to clean string.

Definition at line 249 of file pa_request.h.

References String::L_CLEAN, String::L_OPTIMIZE_BIT, and String::Language.

void Request::write_pass_lang ( const String & astring ) [inline]

appending string, passing language built into string being written.

Definition at line 258 of file pa_request.h.

References String::L_PASS_APPENDED.

Referenced by _crypt(), _find(), _for(), _html(), _if(), _md5(), _menu(), _send(), _switch(), _taint(), _try_operator(), _uid64(), _untaint(), _uuid(), and _while().

void Request::write_pass_lang ( Value & avalue ) [inline]

appending possible string, passing language built into string being written.

Definition at line 262 of file pa_request.h.

References String::L_PASS_APPENDED.

void Request::write_assign_lang ( Value & avalue ) [inline]

appending possible string, assigning untaint language.

Definition at line 268 of file pa_request.h.

Referenced by _base64(), _basename(), _cache(), _connect(), _dirname(), _find(), _fullpath(), _justext(), _justname(), _left(), _match(), _mid(), _normalize(), _pos(), _replace(), _right(), _sql(), _sql_string(), _trim(), change_case(), and execute().

void Request::write_assign_lang ( const String & astring ) [inline]

appending string, assigning untaint language.

Definition at line 272 of file pa_request.h.

const String & Request::relative | ( | const char * | apath,
 |  | const String & | relative_name
 | ) |

returns relative to path path to file.

Definition at line 622 of file pa_request.C.

References result, rsplit(), and PA_Allocated::strdup().

Referenced by _find(), and absolute().

const String & Request::absolute ( const String & relative_name )

returns an absolute path to relative name.

Definition at line 631 of file pa_request.C.

References Request_info::document_root, String::first_char(), Request_info::path_translated, String::pos(), relative(), request_info, result, String::starts_with(), PA_Allocated::strdup(), and STRING_NOT_FOUND.

Referenced by _cache(), _create(), _delete(), _exec_cgi(), _find(), _fullpath(), _list(), _load(), _lock(), _measure(), _move(), _open(), _process(), _save(), _stat(), as_file_spec(), execute(), load(), output_pieces(), output_result(), and use_file().

const String & Request::mime_type_of ( const char * user_file_name_cstr )

returns the mime type of 'user_file_name_cstr'.

Definition at line 900 of file pa_request.C.

References String::CC_LOWER, String::change_case(), charsets, Table::item(), Table::locate(), mime_types, MIME_TYPES_NAME, result, and Request_charsets::source().

Referenced by _create(), _load(), _sql(), _stat(), file_value_to_string(), and output_result().

SQL_Connection* Request::connection ( bool fail_on_error = true ) [inline]

returns current SQL connection if any.

Definition at line 287 of file pa_request.h.

Referenced by _process(), _save(), _sql(), _sql_string(), and sql_result_string().

void Request::set_interrupted ( bool ainterrupted ) [inline]

Definition at line 296 of file pa_request.h.

Referenced by execute().

bool Request::get_interrupted ( ) [inline]

Definition at line 297 of file pa_request.h.

Referenced by execute().

VMethodFrame* Request::get_method_frame ( ) [inline]

Definition at line 326 of file pa_request.h.

Referenced by _for(), and _process().

Value & Request::get_self ( )

Definition at line 197 of file pa_request.C.

References method_frame, and VMethodFrame::self().

Referenced by _string_format(), execute(), and get_element().

const String * Request::execute_virtual_method | ( | Value & | aself,
 |  | const String & | method_name
 | ) |

for @main[].

Definition at line 1087 of file execute.C.

References execute_method(), Value::get_element(), Value::get_junction(), Junction::method, and value.

Referenced by core().

StringOrValue Request::execute_method | ( | VMethodFrame & | amethodFrame,
 |  | const Method & | method
 | ) |

for @postprocess[body].

Definition at line 1018 of file execute.C.

References execute(), method_frame, Method::parser_code, rcontext, WContext::result(), result, and wcontext.

Referenced by core(), execute_nonvirtual_method(), and execute_virtual_method().

const String * Request::execute_method | ( | Value & | aself,
 |  | const Method & | method,
 |  | VString * | optional_param,
 |  | bool | do_return_string
 | ) |

Definition at line 1040 of file execute.C.

References StringOrValue::as_string(), VMethodFrame::can_store_param(), execute(), VMethodFrame::fill_unspecified_params(), method_frame, Method::parser_code, rcontext, WContext::result(), result, VMethodFrame::set_self(), VMethodFrame::store_param(), wcontext, and WContext::write().

Request::Execute_nonvirtual_method_result Request::execute_nonvirtual_method | ( | VStateless_class & | aclass,
 |  | const String & | method_name,
 |  | VString * | optional_param,
 |  | bool | do_return_string
 | ) |

Definition at line 1076 of file execute.C.

References execute_method(), VStateless_class::get_method(), Request::Execute_nonvirtual_method_result::method, result, and Request::Execute_nonvirtual_method_result::string.

Referenced by use_buf().

xmlChar* Request::transcode ( const String & s )

See also:
Charset::transcode.

xmlChar* Request::transcode ( const String::Body s )

See also:
Charset::transcode.

const String& Request::transcode ( const xmlChar * s )

See also:
Charset::transcode.

void Request::configure_admin ( VStateless_class & conf_class ) [private]

Definition at line 205 of file pa_request.C.

References charsets, CHARSETS_NAME, Methoded_array::configure_admin(), configure_admin_done, Hash< const String::Body, Value * >::for_each(), VStateless_class::get_element(), Value::get_hash(), Value::is_string(), load_charset(), MAIN_CLASS_NAME, and methoded_array().

Referenced by configure(), and use_buf().

void Request::configure ( ) [private]

Definition at line 275 of file pa_request.C.

References configure_admin(), configure_admin_done, Methoded_array::configure_user(), VStateless_class::get_element(), Value::get_table(), main_class, methoded_array(), and mime_types.

Referenced by core().

VStateless_class & Request::compile | ( | VStateless_class * | aclass,
 |  | const char * | source,
 |  | const String * | main_alias,
 |  | uint | file_no,
 |  | int | line_no_offset
 | ) | [private]

Definition at line 17 of file compile.C.

References Parse_control::cclass, Pos::col, Parse_control::error, Parse_control::explicit_result, file_list, Pos::line, Parse_control::pos, Parse_control::pos_prev_c(), uint, and yyparse().

Referenced by use_buf().

void Request::put_element | ( | Value & | ncontext,
 |  | const String & | name,
 |  | Value & | value
 | ) | [private]

Definition at line 875 of file execute.C.

References Array< const String * >::count(), VMethodFrame::junction, VJunction::junction(), Junction::method, method_frame, Method::params_names, Method::parser_code, Value::put_element(), PUT_ELEMENT_REPLACED_ELEMENT, rcontext, recoursion_checked_execute(), Junction::self, VMethodFrame::set_self(), VMethodFrame::store_param(), value, wcontext, and WContext::write().

Referenced by execute().

Value & Request::get_element | ( | Value & | ncontext,
 |  | const String & | name,
 |  | bool | can_call_operator
 | ) | [private]

Todo:
cache|prepare junctions
Bug:
^superbase:method would dynamically call ^base:method if there is any

Definition at line 836 of file execute.C.

References Value::base(), VStateless_class::derived_from(), Value::get_class(), WContext::get_constructing(), Value::get_element(), Value::get_junction(), VStateless_class::get_method(), get_self(), WContext::get_somebody_entered_some_class(), main_class, VStateless_class::name_cstr(), process_to_value(), rcontext, Junction::self, value, and wcontext.

Referenced by execute().

String::Language Request::set_lang ( String::Language alang ) [inline, private]

Definition at line 401 of file pa_request.h.

References String::Language, and result.

void Request::restore_lang ( String::Language alang ) [inline, private]

Definition at line 406 of file pa_request.h.

References String::Language.

Referenced by Temp_lang::~Temp_lang().

SQL_Connection* Request::set_connection ( SQL_Connection * aconnection ) [inline, private]

Definition at line 412 of file pa_request.h.

References result.

void Request::restore_connection ( SQL_Connection * aconnection ) [inline, private]

Definition at line 417 of file pa_request.h.

Referenced by Temp_connection::~Temp_connection().

void Request::output_result | ( | VFile * | body_file,
 |  | bool | header_only,
 |  | bool | as_attachment
 | ) | [private]

Definition at line 813 of file pa_request.C.

References absolute(), add_header_attribute(), Value::as(), Value::as_string(), cookie, String::cstr(), String::cstrm(), DEFAULT_CONTENT_TYPE, VResponse::fields(), VFile::fields(), file_stat(), Hash< const String::Body, Value * >::for_each(), Hash< const String::Body, Value * >::get(), Value::get_hash(), VHash::hash(), mime_type_of(), NONAME_DAT, output_pieces(), VCookie::output_result(), output_sole_piece(), Hash< const String::Body, Value * >::put(), Hash< const String::Body, Value * >::put_dont_replace(), response, rsplit(), sapi_info, v, and VDATE_TYPE.

Referenced by core().

Friends And Related Function Documentation

friend class Temp_lang [friend]

Definition at line 44 of file pa_request.h.

friend class Temp_connection [friend]

Definition at line 45 of file pa_request.h.

friend class Request_context_saver [friend]

Definition at line 46 of file pa_request.h.

friend class Temp_request_self [friend]

Definition at line 47 of file pa_request.h.

friend class Exception_trace [friend]

Definition at line 48 of file pa_request.h.

Member Data Documentation

Pool Request::fpool [private]

Definition at line 67 of file pa_request.h.

Referenced by execute().

HashStringValue Request::fclasses [private]

core data classes.

Definition at line 114 of file pa_request.h.

Hash<const String::Body, bool> Request::used_files [private]

already used files to avoid cyclic uses.

Definition at line 117 of file pa_request.h.

Referenced by use_file().

Array<String::Body> Request::file_list [private]

list of all used files, Operation::file_no = index to it.

Definition at line 119 of file pa_request.h.

Referenced by compile(), core(), get_details(), get_exception_cstr(), register_file(), Request(), and use_buf().

uint Request::anti_endless_execute_recoursion [private]

endless execute(execute(...

preventing counter

See also:
ANTI_ENDLESS_EXECUTE_RECOURSION

Definition at line 124 of file pa_request.h.

Referenced by recoursion_checked_execute(), and Request_context_saver::restore().

Stack<StackItem> Request::stack [private]

execution stack.

Definition at line 129 of file pa_request.h.

Referenced by execute(), and Request_context_saver::restore().

Exception_trace Request::exception_trace [private]

exception stack trace.

Definition at line 132 of file pa_request.h.

Referenced by core(), execute(), get_details(), and Request_context_saver::restore().

VMethodFrame* Request::method_frame

request processing status contexts.

Definition at line 137 of file pa_request.h.

Referenced by execute(), execute_method(), get_self(), process(), put_element(), and Request_context_saver::restore().

Value* Request::rcontext

request processing status contexts.

Definition at line 138 of file pa_request.h.

Referenced by execute(), execute_method(), get_element(), process(), put_element(), and Request_context_saver::restore().

WContext* Request::wcontext

request processing status contexts.

Definition at line 139 of file pa_request.h.

Referenced by execute(), execute_method(), get_element(), process(), put_element(), and Request_context_saver::restore().

String::Language Request::flang

current language.

Definition at line 141 of file pa_request.h.

Referenced by core(), execute(), and Request_context_saver::restore().

SQL_Connection* Request::fconnection

current connection.

Definition at line 143 of file pa_request.h.

Referenced by Request_context_saver::restore().

bool Request::finterrupted

interrupted flag, raised on signals [SIGPIPE].

Definition at line 146 of file pa_request.h.

Request_info& Request::request_info

info from web server.

Definition at line 302 of file pa_request.h.

Referenced by _exec_cgi(), _find(), _fullpath(), absolute(), MForm::configure_admin(), core(), execute(), VMail::fill_received(), and get_exception_cstr().

SAPI_Info& Request::sapi_info

info about ServerAPI.

Definition at line 305 of file pa_request.h.

Referenced by _exec_cgi(), MForm::configure_admin(), core(), execute(), output_pieces(), output_result(), output_sole_piece(), process(), and ~Request().

Request_charsets Request::charsets

source, client, mail charsets.

Definition at line 308 of file pa_request.h.

Referenced by _cache(), _connect(), _exec_cgi(), _list(), _load(), _match(), change_case(), configure_admin(), core(), file_value_to_string(), VMail::fill_received(), VMail::message_hash_to_string(), mime_type_of(), output_pieces(), output_sole_piece(), Request(), text_value_to_string(), and use_file().

VStateless_class& Request::main_class

'MAIN' class conglomerat & operators are methods of this class.

Definition at line 311 of file pa_request.h.

Referenced by _connect(), _use(), configure(), MForm::configure_admin(), MMail::configure_user(), core(), get_element(), Request(), and use_file().

VForm& Request::form

$form:elements.

Definition at line 313 of file pa_request.h.

Referenced by Request().

VMail& Request::mail

$mail.

Definition at line 315 of file pa_request.h.

Referenced by core(), and Request().

VResponse& Request::response

$response:elements.

Definition at line 317 of file pa_request.h.

Referenced by core(), output_result(), and Request().

VCookie& Request::cookie

$cookie:elements.

Definition at line 319 of file pa_request.h.

Referenced by core(), output_result(), and Request().

Hash<const String::Body, void*> Request::classes_conf

classes configured data.

Definition at line 322 of file pa_request.h.

Referenced by _cache(), _case(), _open(), _send(), _switch(), and MMail::configure_user().

bool Request::configure_admin_done [private]

already executed some @conf method.

Definition at line 372 of file pa_request.h.

Referenced by configure(), and configure_admin().

const String::Language Request::fdefault_lang [private]

Definition at line 392 of file pa_request.h.

Referenced by core().

Table* Request::mime_types [private]

$MAIN:MIME-TYPES.

Definition at line 397 of file pa_request.h.

Referenced by configure(), and mime_type_of().

The documentation for this class was generated from the following files:
  • pa_request.h
  • compile.C
  • execute.C
  • pa_request.C


Member List

Request Member List

This is the complete list of members for Request, including all inherited members.
absolute(const String &relative_name) | Request |
anti_endless_execute_recoursion | Request | [private]
charsets | Request |
classes() | Request | [inline]
classes_conf | Request |
compile(VStateless_class *aclass, const char *source, const String *main_alias, uint file_no, int line_no_offset) | Request | [private]
configure() | Request | [private]
configure_admin(VStateless_class &conf_class) | Request | [private]
configure_admin_done | Request | [private]
connection(bool fail_on_error=true) | Request | [inline]
cookie | Request |
core(const char *config_filespec, bool config_fail_on_read_problem, bool header_only) | Request |
Exception_trace class | Request | [friend]
exception_trace | Request | [private]
execute(ArrayOperation &ops) | Request |
execute_method(VMethodFrame &amethodFrame, const Method &method) | Request |
execute_method(Value &aself, const Method &method, VString *optional_param, bool do_return_string) | Request |
execute_nonvirtual_method(VStateless_class &aclass, const String &method_name, VString *optional_param, bool do_return_string) | Request |
execute_virtual_method(Value &aself, const String &method_name) | Request |
fclasses | Request | [private]
fconnection | Request |
fdefault_lang | Request | [private]
file_list | Request | [private]
finterrupted | Request |
flang | Request |
form | Request |
fpool | Request | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_details(const Exception &e) | Request |
get_element(Value &ncontext, const String &name, bool can_call_operator) | Request | [private]
get_exception_cstr(const Exception &e, Exception_details &details) | Request |
get_interrupted() | Request | [inline]
get_method_frame() | Request | [inline]
get_self() | Request |
mail | Request |
main_class | Request |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
method_frame | Request |
mime_type_of(const char *user_file_name_cstr) | Request |
mime_types | Request | [private]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
output_result(VFile *body_file, bool header_only, bool as_attachment) | Request | [private]
pool() | Request | [inline]
process(Value &input_value, bool intercept_string=true) | Request |
process_to_string(Value &input_value) | Request | [inline]
process_to_value(Value &input_value, bool intercept_string=true) | Request | [inline]
put_element(Value &ncontext, const String &name, Value &value) | Request | [private]
rcontext | Request |
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
recoursion_checked_execute(ArrayOperation &ops) | Request | [inline]
register_file(String::Body file_spec) | Request |
relative(const char *apath, const String &relative_name) | Request |
Request(SAPI_Info &asapi_info, Request_info &arequest_info, String::Language adefault_lang, bool status_allowed) | Request |
Request_context_saver class | Request | [friend]
request_info | Request |
response | Request |
restore_connection(SQL_Connection *aconnection) | Request | [inline, private]
restore_lang(String::Language alang) | Request | [inline, private]
sapi_info | Request |
set_connection(SQL_Connection *aconnection) | Request | [inline, private]
set_interrupted(bool ainterrupted) | Request | [inline]
set_lang(String::Language alang) | Request | [inline, private]
stack | Request | [private]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
Temp_connection class | Request | [friend]
Temp_lang class | Request | [friend]
Temp_request_self class | Request | [friend]
transcode(const String &s) | Request |
transcode(const String::Body s) | Request |
transcode(const xmlChar *s) | Request |
use_buf(VStateless_class &aclass, const char *source, const String *main_alias, uint file_no, int line_no_offset=0) | Request |
use_file(VStateless_class &aclass, const String &file_name, const String *main_alias=0, bool ignore_class_path=false, bool fail_on_read_problem=true, bool fail_on_file_absence=true) | Request |
used_files | Request | [private]
wcontext | Request |
wipe_unused_execution_stack() | Request | [inline]
write_assign_lang(Value &avalue) | Request | [inline]
write_assign_lang(const String &astring) | Request | [inline]
write_no_lang(const String &astring) | Request | [inline]
write_no_lang(Value &avalue) | Request | [inline]
write_pass_lang(const String &astring) | Request | [inline]
write_pass_lang(Value &avalue) | Request | [inline]
~Request() | Request |


Request::Exception_details Struct Reference

Collaboration diagram for Request::Exception_details:

[legend]
List of all members.

Public Methods

Exception_details (const Trace atrace, const String *aproblem_source, VHash &avhash)

Public Attributes

const Trace | trace
const String * | problem_source
VHash & vhash

Constructor & Destructor Documentation

Request::Exception_details::Exception_details | ( | const Trace | atrace,
 |  | const String * | aproblem_source,
 |  | VHash & | avhash
 | ) | [inline]

Definition at line 156 of file pa_request.h.

Member Data Documentation

const Trace Request::Exception_details::trace

Definition at line 152 of file pa_request.h.

Referenced by Request::get_exception_cstr().

const String* Request::Exception_details::problem_source

Definition at line 153 of file pa_request.h.

Referenced by Request::get_exception_cstr().

VHash& Request::Exception_details::vhash

Definition at line 154 of file pa_request.h.

Referenced by Request::core(), and try_catch().

The documentation for this struct was generated from the following file:
  • pa_request.h


Member List

Request::Exception_details Member List

This is the complete list of members for Request::Exception_details, including all inherited members.
Exception_details(const Trace atrace, const String *aproblem_source, VHash &avhash) | Request::Exception_details | [inline]
problem_source | Request::Exception_details |
trace | Request::Exception_details |
vhash | Request::Exception_details |


Request::Exception_trace Class Reference

Inheritance diagram for Request::Exception_trace:

[legend]
Collaboration diagram for Request::Exception_trace:

[legend]
List of all members.

Public Methods

Exception_trace ()
size_t | bottom_index ()
void | set_bottom_index (size_t abottom)
element_type bottom_value ()
void | clear ()
bool | is_empty ()
const element_type | extract_origin (const String *&problem_source)

Private Attributes

size_t | fbottom

Constructor & Destructor Documentation

Request::Exception_trace::Exception_trace ( ) [inline]

Definition at line 94 of file pa_request.h.

References fbottom.

Member Function Documentation

size_t Request::Exception_trace::bottom_index ( ) [inline]

Definition at line 96 of file pa_request.h.

References fbottom.

Referenced by bottom_value(), and Request::core().

void Request::Exception_trace::set_bottom_index ( size_t abottom ) [inline]

Definition at line 97 of file pa_request.h.

References fbottom.

element_type Request::Exception_trace::bottom_value ( ) [inline]

Definition at line 98 of file pa_request.h.

References bottom_index(), Array< Trace >::element_type, and Array< Trace >::get().

Referenced by extract_origin().

void Request::Exception_trace::clear ( ) [inline]

Definition at line 100 of file pa_request.h.

References fbottom, and Stack< Trace >::ftop.

Referenced by Request::core().

bool Request::Exception_trace::is_empty ( ) [inline]

Reimplemented from Stack< Trace >.

Definition at line 104 of file pa_request.h.

References fbottom, and Stack< Trace >::ftop.

Referenced by Request::core(), and extract_origin().

const Request::Trace Request::Exception_trace::extract_origin ( const String *& problem_source )

Definition at line 932 of file pa_request.C.

References bottom_value(), fbottom, is_empty(), Request::Trace::name(), and result.

Referenced by Request::get_details().

Member Data Documentation

size_t Request::Exception_trace::fbottom [private]

Definition at line 92 of file pa_request.h.

Referenced by bottom_index(), clear(), Exception_trace(), extract_origin(), is_empty(), and set_bottom_index().

The documentation for this class was generated from the following files:
  • pa_request.h
  • pa_request.C


Member List

Request::Exception_trace Member List

This is the complete list of members for Request::Exception_trace, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< Trace > | [inline]
Array(size_t initial=3) | Array< Trace > | [inline]
bottom_index() | Request::Exception_trace | [inline]
bottom_value() | Request::Exception_trace | [inline]
clear() | Request::Exception_trace | [inline]
count() const | Array< Trace > | [inline]
element_type typedef | Array< Trace > |
Exception_trace() | Request::Exception_trace | [inline]
expand(size_t delta) | Array< Trace > | [inline, protected]
extract_origin(const String *&problem_source) | Request::Exception_trace |
fallocated | Array< Trace > | [protected]
fbottom | Request::Exception_trace | [private]
felements | Array< Trace > | [protected]
first_that(bool(*callback)(Trace, I), I info) const | Array< Trace > | [inline]
for_each(void(*callback)(Trace, I), I info) const | Array< Trace > | [inline]
for_each_ref(void(*callback)(Trace &, I), I info) | Array< Trace > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
ftop | Stack< Trace > | [protected]
fused | Array< Trace > | [protected]
get(size_t index) const | Array< Trace > | [inline]
get_ref(size_t index) const | Array< Trace > | [inline]
is_empty() | Request::Exception_trace | [inline]
is_full() | Array< Trace > | [inline, protected]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(Trace src) | Array< Trace > | [inline]
operator[](size_t index) const | Array< Trace > | [inline]
pop() | Stack< Trace > | [inline]
push(Trace item) | Stack< Trace > | [inline]
put(size_t index, Trace element) | Array< Trace > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_bottom_index(size_t abottom) | Request::Exception_trace | [inline]
set_top_index(size_t atop) | Stack< Trace > | [inline]
Stack() | Stack< Trace > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
top_index() | Stack< Trace > | [inline]
top_value() | Stack< Trace > | [inline]
wipe_unused() | Stack< Trace > | [inline]


Request::Execute_nonvirtual_method_result Struct Reference

Collaboration diagram for Request::Execute_nonvirtual_method_result:

[legend]
List of all members.

Public Methods

Execute_nonvirtual_method_result ()

Public Attributes

const String * string
Method * method

Constructor & Destructor Documentation

Request::Execute_nonvirtual_method_result::Execute_nonvirtual_method_result ( ) [inline]

Definition at line 350 of file pa_request.h.

Member Data Documentation

const String* Request::Execute_nonvirtual_method_result::string

Definition at line 348 of file pa_request.h.

Referenced by Request::execute_nonvirtual_method().

Method* Request::Execute_nonvirtual_method_result::method

Definition at line 349 of file pa_request.h.

Referenced by Request::execute_nonvirtual_method(), and Request::use_buf().

The documentation for this struct was generated from the following file:
  • pa_request.h


Member List

Request::Execute_nonvirtual_method_result Member List

This is the complete list of members for Request::Execute_nonvirtual_method_result, including all inherited members.
Execute_nonvirtual_method_result() | Request::Execute_nonvirtual_method_result | [inline]
method | Request::Execute_nonvirtual_method_result |
string | Request::Execute_nonvirtual_method_result |


Request::StackItem Union Reference

Collaboration diagram for Request::StackItem:

[legend]
List of all members.

Public Methods

Value & | value () const
const String & | string () const
ArrayOperation & | ops () const
VMethodFrame & | method_frame () const
StackItem ()
needed to fill unused Array entries. More...

StackItem (Value &avalue)
StackItem (ArrayOperation &aops)
StackItem (VMethodFrame &amethod_frame)

Public Attributes

Value * fvalue
ArrayOperation * fops
VMethodFrame * fmethod_frame

Constructor & Destructor Documentation

Request::StackItem::StackItem ( ) [inline]

needed to fill unused Array entries.

Definition at line 85 of file pa_request.h.

Request::StackItem::StackItem ( Value & avalue ) [inline]

Definition at line 86 of file pa_request.h.

Request::StackItem::StackItem ( ArrayOperation & aops ) [inline]

Definition at line 87 of file pa_request.h.

Request::StackItem::StackItem ( VMethodFrame & amethod_frame ) [inline]

Definition at line 88 of file pa_request.h.

Member Function Documentation

Value& Request::StackItem::value ( ) const [inline]

Definition at line 77 of file pa_request.h.

const String& Request::StackItem::string ( ) const [inline]

Definition at line 78 of file pa_request.h.

References Value::as_string().

ArrayOperation& Request::StackItem::ops ( ) const [inline]

Definition at line 81 of file pa_request.h.

VMethodFrame& Request::StackItem::method_frame ( ) const [inline]

Definition at line 82 of file pa_request.h.

Member Data Documentation

Value* Request::StackItem::fvalue

Definition at line 73 of file pa_request.h.

ArrayOperation* Request::StackItem::fops

Definition at line 74 of file pa_request.h.

VMethodFrame* Request::StackItem::fmethod_frame

Definition at line 75 of file pa_request.h.

The documentation for this union was generated from the following file:
  • pa_request.h


Member List

Request::StackItem Member List

This is the complete list of members for Request::StackItem, including all inherited members.
fmethod_frame | Request::StackItem |
fops | Request::StackItem |
fvalue | Request::StackItem |
method_frame() const | Request::StackItem | [inline]
ops() const | Request::StackItem | [inline]
StackItem() | Request::StackItem | [inline]
StackItem(Value &avalue) | Request::StackItem | [inline]
StackItem(ArrayOperation &aops) | Request::StackItem | [inline]
StackItem(VMethodFrame &amethod_frame) | Request::StackItem | [inline]
string() const | Request::StackItem | [inline]
value() const | Request::StackItem | [inline]


Request::Trace Class Reference

Collaboration diagram for Request::Trace:

[legend]
List of all members.

Public Methods

Trace ()
void | clear ()
operator bool () const
Trace (const String *aname, const Operation::Origin aorigin)
const String * | name () const
const Operation::Origin | origin () const

Private Attributes

const String * | fname
Operation::Origin forigin

Constructor & Destructor Documentation

Request::Trace::Trace ( ) [inline]

Definition at line 55 of file pa_request.h.

Request::Trace::Trace | ( | const String * | aname,
 |  | const Operation::Origin | aorigin
 | ) | [inline]

Definition at line 59 of file pa_request.h.

Member Function Documentation

void Request::Trace::clear ( ) [inline]

Definition at line 56 of file pa_request.h.

Request::Trace::operator bool ( ) const [inline]

Definition at line 57 of file pa_request.h.

const String* Request::Trace::name ( ) const [inline]

Definition at line 62 of file pa_request.h.

Referenced by Request::core(), and Request::Exception_trace::extract_origin().

const Operation::Origin Request::Trace::origin ( ) const [inline]

Definition at line 63 of file pa_request.h.

Referenced by Request::core(), Request::get_details(), and Request::get_exception_cstr().

Member Data Documentation

const String* Request::Trace::fname [private]

Definition at line 52 of file pa_request.h.

Operation::Origin Request::Trace::forigin [private]

Definition at line 53 of file pa_request.h.

The documentation for this class was generated from the following file:
  • pa_request.h


Member List

Request::Trace Member List

This is the complete list of members for Request::Trace, including all inherited members.
clear() | Request::Trace | [inline]
fname | Request::Trace | [private]
forigin | Request::Trace | [private]
name() const | Request::Trace | [inline]
operator bool() const | Request::Trace | [inline]
origin() const | Request::Trace | [inline]
Trace() | Request::Trace | [inline]
Trace(const String *aname, const Operation::Origin aorigin) | Request::Trace | [inline]


Request_charsets Class Reference

Collaboration diagram for Request_charsets:

[legend]
List of all members.

Public Methods

Request_charsets (Charset &asource, Charset &aclient, Charset &amail)
Charset & | source () const
void | set_source (Charset &asource)
Charset & | client () const
void | set_client (Charset &aclient)
Charset & | mail () const
void | set_mail (Charset &amail)

Private Attributes

Charset * fsource
Charset * fclient
Charset * fmail

Friends

class | Temp_client_charset

Constructor & Destructor Documentation

Request_charsets::Request_charsets | ( | Charset & | asource,
 |  | Charset & | aclient,
 |  | Charset & | amail
 | ) | [inline]

Definition at line 20 of file pa_request_charsets.h.

Member Function Documentation

Charset& Request_charsets::source ( ) const [inline]

Definition at line 28 of file pa_request_charsets.h.

Referenced by _connect(), _exec_cgi(), _list(), _match(), change_case(), VMail::fill_received(), VResponse::get_element(), VRequest::get_element(), load_charset(), VMail::message_hash_to_string(), Request::mime_type_of(), output_sole_piece(), pa_internal_file_read_http(), VResponse::put_element(), VForm::refill_fields_and_tables(), VForm::should_refill_fields_and_tables(), text_value_to_string(), and VForm::transcode().

void Request_charsets::set_source ( Charset & asource ) [inline]

Definition at line 28 of file pa_request_charsets.h.

Referenced by VRequest::put_element().

Charset& Request_charsets::client ( ) const [inline]

Definition at line 29 of file pa_request_charsets.h.

Referenced by VResponse::get_element(), output_sole_piece(), VForm::refill_fields_and_tables(), VForm::should_refill_fields_and_tables(), and VForm::transcode().

void Request_charsets::set_client ( Charset & aclient ) [inline]

Definition at line 29 of file pa_request_charsets.h.

Referenced by VResponse::put_element(), Temp_client_charset::Temp_client_charset(), and Temp_client_charset::~Temp_client_charset().

Charset& Request_charsets::mail ( ) const [inline]

Definition at line 30 of file pa_request_charsets.h.

Referenced by text_value_to_string().

void Request_charsets::set_mail ( Charset & amail ) [inline]

Definition at line 30 of file pa_request_charsets.h.

Referenced by VMail::message_hash_to_string().

Friends And Related Function Documentation

friend class Temp_client_charset [friend]

Definition at line 14 of file pa_request_charsets.h.

Member Data Documentation

Charset* Request_charsets::fsource [private]

Definition at line 16 of file pa_request_charsets.h.

Charset* Request_charsets::fclient [private]

Definition at line 17 of file pa_request_charsets.h.

Charset* Request_charsets::fmail [private]

Definition at line 18 of file pa_request_charsets.h.

The documentation for this class was generated from the following file:
  • pa_request_charsets.h


Member List

Request_charsets Member List

This is the complete list of members for Request_charsets, including all inherited members.
client() const | Request_charsets | [inline]
fclient | Request_charsets | [private]
fmail | Request_charsets | [private]
fsource | Request_charsets | [private]
mail() const | Request_charsets | [inline]
Request_charsets(Charset &asource, Charset &aclient, Charset &amail) | Request_charsets | [inline]
set_client(Charset &aclient) | Request_charsets | [inline]
set_mail(Charset &amail) | Request_charsets | [inline]
set_source(Charset &asource) | Request_charsets | [inline]
source() const | Request_charsets | [inline]
Temp_client_charset class | Request_charsets | [friend]


Request_context_saver Class Reference

Auto-object used to save request context across ^try body. More...

Collaboration diagram for Request_context_saver:

[legend]
List of all members.

Public Methods

Request_context_saver (Request &ar)
void | restore ()

Private Attributes

Request & fr
size_t | exception_trace_top
exception stack trace. More...

size_t | exception_trace_bottom
size_t | stack
execution stack. More...

uint anti_endless_execute_recoursion
VMethodFrame * method_frame
contexts. More...

Value * rcontext
WContext * wcontext
String::Language flang
current language. More...

SQL_Connection * fconnection
current connection. More...

Detailed Description

Auto-object used to save request context across ^try body.

Definition at line 427 of file pa_request.h.

Constructor & Destructor Documentation

Request_context_saver::Request_context_saver ( Request & ar ) [inline]

Definition at line 446 of file pa_request.h.

References anti_endless_execute_recoursion, exception_trace_bottom, exception_trace_top, flang, and stack.

Member Function Documentation

void Request_context_saver::restore ( ) [inline]

Definition at line 457 of file pa_request.h.

References anti_endless_execute_recoursion, Request::anti_endless_execute_recoursion, Request::exception_trace, exception_trace_bottom, exception_trace_top, Request::fconnection, flang, Request::flang, Request::method_frame, Request::rcontext, Stack< StackItem >::set_top_index(), stack, Request::stack, and Request::wcontext.

Referenced by try_catch().

Member Data Documentation

Request& Request_context_saver::fr [private]

Definition at line 428 of file pa_request.h.

size_t Request_context_saver::exception_trace_top [private]

exception stack trace.

Definition at line 431 of file pa_request.h.

Referenced by Request_context_saver(), and restore().

size_t Request_context_saver::exception_trace_bottom [private]

Definition at line 432 of file pa_request.h.

Referenced by Request_context_saver(), and restore().

size_t Request_context_saver::stack [private]

execution stack.

Definition at line 434 of file pa_request.h.

Referenced by Request_context_saver(), and restore().

uint Request_context_saver::anti_endless_execute_recoursion [private]

Definition at line 435 of file pa_request.h.

Referenced by Request_context_saver(), and restore().

VMethodFrame* Request_context_saver::method_frame [private]

contexts.

Definition at line 437 of file pa_request.h.

Value* Request_context_saver::rcontext [private]

Definition at line 438 of file pa_request.h.

WContext* Request_context_saver::wcontext [private]

Definition at line 439 of file pa_request.h.

String::Language Request_context_saver::flang [private]

current language.

Definition at line 441 of file pa_request.h.

Referenced by Request_context_saver(), and restore().

SQL_Connection* Request_context_saver::fconnection [private]

current connection.

Definition at line 443 of file pa_request.h.

The documentation for this class was generated from the following file:
  • pa_request.h


Member List

Request_context_saver Member List

This is the complete list of members for Request_context_saver, including all inherited members.
anti_endless_execute_recoursion | Request_context_saver | [private]
exception_trace_bottom | Request_context_saver | [private]
exception_trace_top | Request_context_saver | [private]
fconnection | Request_context_saver | [private]
flang | Request_context_saver | [private]
fr | Request_context_saver | [private]
method_frame | Request_context_saver | [private]
rcontext | Request_context_saver | [private]
Request_context_saver(Request &ar) | Request_context_saver | [inline]
restore() | Request_context_saver | [inline]
stack | Request_context_saver | [private]
wcontext | Request_context_saver | [private]


Request_info Class Reference

some information from web server. More...

List of all members.

Public Attributes

const char * | document_root
these filled by Request class user. More...

const char * | path_translated
these filled by Request class user. More...

const char * | method
these filled by Request class user. More...

const char * | query_string
these filled by Request class user. More...

const char * | uri
these filled by Request class user. More...

const char * | content_type
these filled by Request class user. More...

size_t | content_length
these filled by Request class user. More...

const char * | cookie
these filled by Request class user. More...

bool | mail_received
these filled by Request class user. More...

const char * | post_data
these are filed by Request class itself: user's post data. More...

size_t | post_size
these are filed by Request class itself: user's post data. More...

Detailed Description

some information from web server.

Definition at line 14 of file pa_request_info.h.

Member Data Documentation

const char* Request_info::document_root

these filled by Request class user.

Definition at line 17 of file pa_request_info.h.

Referenced by _exec_cgi(), _fullpath(), Request::absolute(), Request::core(), VRequest::get_element(), VRequest::put_element(), and real_parser_handler().

const char* Request_info::path_translated

these filled by Request class user.

Definition at line 18 of file pa_request_info.h.

Referenced by _exec_cgi(), Request::absolute(), Request::core(), and real_parser_handler().

const char* Request_info::method

these filled by Request class user.

Definition at line 19 of file pa_request_info.h.

Referenced by _exec_cgi(), MForm::configure_admin(), log_signal(), real_parser_handler(), and VForm::refill_fields_and_tables().

const char* Request_info::query_string

these filled by Request class user.

Definition at line 20 of file pa_request_info.h.

Referenced by _exec_cgi(), VRequest::get_element(), real_parser_handler(), and VForm::refill_fields_and_tables().

const char* Request_info::uri

these filled by Request class user.

Definition at line 21 of file pa_request_info.h.

Referenced by _exec_cgi(), _find(), Request::core(), Request::execute(), VRequest::get_element(), Request::get_exception_cstr(), log_signal(), and real_parser_handler().

const char* Request_info::content_type

these filled by Request class user.

Definition at line 22 of file pa_request_info.h.

Referenced by _exec_cgi(), real_parser_handler(), and VForm::refill_fields_and_tables().

size_t Request_info::content_length

these filled by Request class user.

Definition at line 23 of file pa_request_info.h.

Referenced by _exec_cgi(), MForm::configure_admin(), log_signal(), and real_parser_handler().

const char* Request_info::cookie

these filled by Request class user.

Definition at line 24 of file pa_request_info.h.

Referenced by VCookie::fill_fields(), and real_parser_handler().

bool Request_info::mail_received

these filled by Request class user.

Definition at line 25 of file pa_request_info.h.

Referenced by VMail::fill_received(), and real_parser_handler().

const char* Request_info::post_data

these are filed by Request class itself: user's post data.

Definition at line 28 of file pa_request_info.h.

Referenced by MForm::configure_admin(), VRequest::get_element(), and VForm::refill_fields_and_tables().

size_t Request_info::post_size

these are filed by Request class itself: user's post data.

Definition at line 28 of file pa_request_info.h.

Referenced by MForm::configure_admin(), VRequest::get_element(), and VForm::refill_fields_and_tables().

The documentation for this class was generated from the following file:
  • pa_request_info.h


Member List

Request_info Member List

This is the complete list of members for Request_info, including all inherited members.
content_length | Request_info
content_type | Request_info
cookie | Request_info
document_root | Request_info
mail_received | Request_info
method | Request_info
path_translated | Request_info
post_data | Request_info
post_size | Request_info
query_string | Request_info
uri | Request_info


SAPI Struct Reference

target web-Server API. More...

List of all members.

Static Public Methods

void | log (SAPI_Info &info, const char *fmt,...)
log error message. More...

void | die (const char *fmt,...)
log error message & exit. More...

void | abort (const char *fmt,...)
log error message & abort[write core]. More...

const char *const * | environment (SAPI_Info &info)
environment strings. More...

char * | get_env (SAPI_Info &info, const char *name)
get environment string. More...

size_t | read_post (SAPI_Info &info, char *buf, size_t max_bytes)
read POST request bytes. More...

void | add_header_attribute (SAPI_Info &info, const char *dont_store_key, const char *dont_store_value)
add response header attribute [but do not send it to client]. More...

void | send_header (SAPI_Info &info)
send collected header attributes to client. More...

size_t | send_body (SAPI_Info &info, const void *buf, size_t size)
output body bytes. More...

Detailed Description

target web-Server API.

Definition at line 23 of file pa_sapi.h.

Member Function Documentation

void SAPI::log | ( | SAPI_Info & | info,
 |  | const char * | fmt,
 |  | ... |
 | ) | [static]

log error message.

Definition at line 67 of file mod_parser3_core.C.

References MAX_STRING, pa_ap_log_rerror(), SAPI_Info::r, remove_crlf(), SAPI_info, size, and vsnprintf.

Referenced by Request::core(), HttpExtensionProc(), log_signal(), main(), pa_parser_handler(), and Request::~Request().

void SAPI::die | ( | const char * | fmt,
 |  | ... |
 | ) | [static]

log error message & exit.

Definition at line 90 of file mod_parser3_core.C.

References die_or_abort().

Referenced by main(), pa_fail_alloc(), and real_parser_handler().

void SAPI::abort | ( | const char * | fmt,
 |  | ... |
 | ) | [static]

log error message & abort[write core].

Definition at line 97 of file mod_parser3_core.C.

References die_or_abort().

Referenced by cstr_to_string_body_block(), and pa_setup_module_cells().

const char *const * SAPI::environment ( SAPI_Info & info ) [static]

environment strings.

Definition at line 127 of file mod_parser3_core.C.

References pa_ap_table_do(), pa_ap_table_size(), pa_table, SAPI_Info::r, result, SAPI_environment_append(), SAPI_info, and pa_request_rec_tag::subprocess_env.

Referenced by _exec_cgi().

char * SAPI::get_env | ( | SAPI_Info & | info,
 |  | const char * | name
 | ) | [static]

get environment string.

Definition at line 104 of file mod_parser3_core.C.

References pa_ap_table_get(), pa_strdup(), SAPI_Info::r, SAPI_info, and pa_request_rec_tag::subprocess_env.

Referenced by VEnv::get_element(), output_pieces(), and real_parser_handler().

size_t SAPI::read_post | ( | SAPI_Info & | info,
 |  | char * | buf,
 |  | size_t | max_bytes
 | ) | [static]

read POST request bytes.

Definition at line 135 of file mod_parser3_core.C.

References pa_ap_get_client_block(), pa_ap_hard_timeout(), pa_ap_reset_timeout(), pa_ap_setup_client_block(), pa_ap_should_client_block(), PA_REQUEST_CHUNKED_ERROR, PA_SIG_IGN, pa_signal(), PA_SIGPIPE, SAPI_Info::r, SAPI_info, and uint.

Referenced by MForm::configure_admin().

void SAPI::add_header_attribute | ( | SAPI_Info & | SAPI_info,
 |  | const char * | dont_store_key,
 |  | const char * | dont_store_value
 | ) | [static]

add response header attribute [but do not send it to client].

Test:
location provide with protocol. think about internal redirects

Definition at line 161 of file mod_parser3_core.C.

References atoi(), pa_request_rec_tag::content_type, pa_request_rec_tag::headers_out, pa_ap_pstrdup(), pa_ap_table_addn(), pa_request_rec_tag::pool, SAPI_Info::r, SAPI_info, and pa_request_rec_tag::status.

Referenced by add_header_attribute(), die_or_abort(), main(), output_pieces(), output_set_cookie_header(), output_sole_piece(), and pa_parser_handler().

void SAPI::send_header ( SAPI_Info & SAPI_info ) [static]

send collected header attributes to client.

Todo:
intelligent cache-control

Definition at line 181 of file mod_parser3_core.C.

References pa_ap_hard_timeout(), pa_ap_kill_timeout(), pa_ap_send_http_header(), SAPI_Info::r, and SAPI_info.

Referenced by die_or_abort(), main(), output_pieces(), output_sole_piece(), and pa_parser_handler().

size_t SAPI::send_body | ( | SAPI_Info & | info,
 |  | const void * | buf,
 |  | size_t | size
 | ) | [static]

output body bytes.

Definition at line 187 of file mod_parser3_core.C.

References pa_ap_hard_timeout(), pa_ap_kill_timeout(), pa_ap_rwrite(), SAPI_Info::r, SAPI_info, and size.

Referenced by die_or_abort(), HttpExtensionProc(), main(), output_pieces(), output_sole_piece(), and pa_parser_handler().

The documentation for this struct was generated from the following files:
  • pa_sapi.h
  • mod_parser3_core.C
  • parser3.C
  • parser3isapi.C


Member List

SAPI Member List

This is the complete list of members for SAPI, including all inherited members.
abort(const char *fmt,...) | SAPI | [static]
add_header_attribute(SAPI_Info &info, const char *dont_store_key, const char *dont_store_value) | SAPI | [static]
die(const char *fmt,...) | SAPI | [static]
environment(SAPI_Info &info) | SAPI | [static]
get_env(SAPI_Info &info, const char *name) | SAPI | [static]
log(SAPI_Info &info, const char *fmt,...) | SAPI | [static]
read_post(SAPI_Info &info, char *buf, size_t max_bytes) | SAPI | [static]
send_body(SAPI_Info &info, const void *buf, size_t size) | SAPI | [static]
send_header(SAPI_Info &info) | SAPI | [static]


SAPI_Info Class Reference

SAPI func decl. More...

Collaboration diagram for SAPI_Info:

[legend]
List of all members.

Public Attributes

pa_request_rec * r

Detailed Description

SAPI func decl.

Definition at line 62 of file mod_parser3_core.C.

Member Data Documentation

pa_request_rec* SAPI_Info::r

Definition at line 64 of file mod_parser3_core.C.

Referenced by SAPI::add_header_attribute(), SAPI::environment(), SAPI::get_env(), SAPI::log(), pa_parser_handler(), SAPI::read_post(), real_parser_handler(), SAPI::send_body(), and SAPI::send_header().

The documentation for this class was generated from the following file:
  • mod_parser3_core.C


Member List

SAPI_Info Member List

This is the complete list of members for SAPI_Info, including all inherited members.
r SAPI_Info


SMTP Class Reference

SIMPLE MAIL TRANSPORT PROTOCOL Win32 realization. More...

Inheritance diagram for SMTP:

[legend]
Collaboration diagram for SMTP:

[legend]
List of all members.

Public Methods

SMTP ()
override | ~SMTP ()
void | Send (const char *, const char *, const char *, char *, char *)
bool | MakeSmtpHeader (char *, char *, char *, char *)
void | prepare_message (char *, char *, const char *, const char *)
void | open_socket (const char *, const char *)
int | get_line (void)
void | SendSmtpError (const char *)
void | transform_and_send_edit_data (const char *)
void | send_data (const char *)
void | ConnectToHost (const char *, const char *)
int | GetBuffer (int)
int | GetChar (int, char *)
void | SendLine (const char *, unsigned long)
void | SendBuffer (const char *, unsigned long)
void | FlushBuffer ()
bool | CloseConnect ()
int | IsAddressARawIpaddress (const char *)
int | ResolveService (const char *, u_short *)
int | ResolveHostname (const char *, struct sockaddr_in *)
int | GetAndSetTheSocket (SOCKET *)
int | GetConnection (SOCKET, struct sockaddr_in *)
void | MiscSocketSetup (SOCKET, fd_set *, struct timeval *)

Private Attributes

char * | in_buffer
char * | out_buffer
unsigned int | in_index
unsigned int | out_index
unsigned int | in_buffer_total
unsigned int | out_buffer_total
unsigned int | last_winsock_error
fd_set | fds
timeval | timeout
SOCKET | the_socket
char | my_hostname [1024]
CHAR | ServerProtocol [100]
CHAR | RemoteAddress [100]
CHAR | RemoteHost [100]
CHAR | RemoteUser [100]
CHAR | HttpAccept [100]
CHAR | HttpUserAgent [256]
CHAR | FirstName [100]
CHAR | LastName [100]
CHAR | WebUse [100]
CHAR | EMail [100]
CHAR | HomePage [100]
CHAR | text [500]

Detailed Description

SIMPLE MAIL TRANSPORT PROTOCOL Win32 realization.

Definition at line 106 of file smtp.h.

Constructor & Destructor Documentation

SMTP::SMTP ( )

Definition at line 22 of file smtp.C.

References in_buffer, in_buffer_total, in_index, last_winsock_error, PA_Allocated::malloc(), out_buffer, out_buffer_total, out_index, SOCKET_BUFFER_SIZE, and the_socket.

SMTP::~SMTP ( )

Definition at line 36 of file smtp.C.

References PA_Allocated::free(), in_buffer, and out_buffer.

Member Function Documentation

void SMTP::Send | ( | const char * | ,
 |  | const char * | ,
 |  | const char * | ,
 |  | char * | ,
 |  | char * |
 | ) |

Definition at line 486 of file smtp.C.

References CloseConnect(), prepare_message(), send_data(), and SendLine().

Referenced by sendmail().

bool SMTP::MakeSmtpHeader | ( | char * | ,
 |  | char * | ,
 |  | char * | ,
 |  | char * |
 | ) |

void SMTP::prepare_message | ( | char * | ,
 |  | char * | ,
 |  | const char * | ,
 |  | const char * |
 | ) |

Definition at line 422 of file smtp.C.

References get_line(), MAXOUTLINE, my_hostname, open_socket(), SendLine(), SendSmtpError(), and snprintf.

Referenced by Send().

void SMTP::open_socket | ( | const char * | ,
 |  | const char * |
 | ) |

Definition at line 407 of file smtp.C.

References ConnectToHost(), and my_hostname.

Referenced by prepare_message().

int SMTP::get_line ( void )

Definition at line 188 of file smtp.C.

References GetChar(), and MAXOUTLINE.

Referenced by prepare_message(), and send_data().

void SMTP::SendSmtpError ( const char * )

Definition at line 323 of file smtp.C.

References CloseConnect(), and SendLine().

Referenced by prepare_message(), and send_data().

void SMTP::transform_and_send_edit_data ( const char * )

Definition at line 338 of file smtp.C.

References FlushBuffer(), and SendBuffer().

Referenced by send_data().

void SMTP::send_data ( const char * )

Definition at line 396 of file smtp.C.

References get_line(), SendSmtpError(), and transform_and_send_edit_data().

Referenced by Send().

void SMTP::ConnectToHost | ( | const char * | ,
 |  | const char * |
 | ) |

Definition at line 44 of file smtp.C.

References CloseConnect(), fds, GetAndSetTheSocket(), GetConnection(), MiscSocketSetup(), ResolveHostname(), ResolveService(), the_socket, and timeout.

Referenced by open_socket().

int SMTP::GetBuffer ( int )

Definition at line 80 of file smtp.C.

References bytes_read, fds, in_buffer, in_buffer_total, in_index, SOCKET_BUFFER_SIZE, the_socket, timeout, and WAIT_A_BIT.

Referenced by GetChar().

int SMTP::GetChar | ( | int | ,
 |  | char * |
 | ) |

Definition at line 172 of file smtp.C.

References GetBuffer(), in_buffer, in_buffer_total, and in_index.

Referenced by get_line().

void SMTP::SendLine | ( | const char * | ,
 |  | unsigned | long
 | ) |

Definition at line 220 of file smtp.C.

References data, fds, the_socket, and timeout.

Referenced by FlushBuffer(), prepare_message(), Send(), SendBuffer(), and SendSmtpError().

void SMTP::SendBuffer | ( | const char * | ,
 |  | unsigned | long
 | ) |

Definition at line 274 of file smtp.C.

References data, out_buffer, out_index, SendLine(), and SOCKET_BUFFER_SIZE.

Referenced by transform_and_send_edit_data().

void SMTP::FlushBuffer ( )

Definition at line 305 of file smtp.C.

References out_buffer, out_index, and SendLine().

Referenced by transform_and_send_edit_data().

bool SMTP::CloseConnect ( )

Definition at line 313 of file smtp.C.

References the_socket.

Referenced by ConnectToHost(), Send(), and SendSmtpError().

int SMTP::IsAddressARawIpaddress ( const char * )

Definition at line 14 of file comms.C.

int SMTP::ResolveService | ( | const char * | service,
 |  | u_short * | our_port
 | ) |

Bug:
getservbyname is not reenterant

Definition at line 30 of file comms.C.

Referenced by ConnectToHost().

int SMTP::ResolveHostname | ( | const char * | hostname,
 |  | struct sockaddr_in * | sa_in
 | ) |

Bug:
gethostbyname is not reenterant

Definition at line 79 of file comms.C.

References INADDR_NONE.

Referenced by ConnectToHost().

int SMTP::GetAndSetTheSocket ( SOCKET * )

Definition at line 103 of file comms.C.

References the_socket.

Referenced by ConnectToHost().

int SMTP::GetConnection | ( | SOCKET | ,
 |  | struct sockaddr_in * |
 | ) |

Definition at line 120 of file comms.C.

References the_socket.

Referenced by ConnectToHost().

void SMTP::MiscSocketSetup | ( | SOCKET | ,
 |  | fd_set * | ,
 |  | struct timeval * |
 | ) |

Definition at line 149 of file comms.C.

References fds, and timeout.

Referenced by ConnectToHost().

Member Data Documentation

char* SMTP::in_buffer [private]

Definition at line 107 of file smtp.h.

Referenced by GetBuffer(), GetChar(), SMTP(), and ~SMTP().

char* SMTP::out_buffer [private]

Definition at line 108 of file smtp.h.

Referenced by FlushBuffer(), SendBuffer(), SMTP(), and ~SMTP().

unsigned int SMTP::in_index [private]

Definition at line 109 of file smtp.h.

Referenced by GetBuffer(), GetChar(), and SMTP().

unsigned int SMTP::out_index [private]

Definition at line 110 of file smtp.h.

Referenced by FlushBuffer(), SendBuffer(), and SMTP().

unsigned int SMTP::in_buffer_total [private]

Definition at line 111 of file smtp.h.

Referenced by GetBuffer(), GetChar(), and SMTP().

unsigned int SMTP::out_buffer_total [private]

Definition at line 112 of file smtp.h.

Referenced by SMTP().

unsigned int SMTP::last_winsock_error [private]

Definition at line 113 of file smtp.h.

Referenced by SMTP().

fd_set SMTP::fds [private]

Definition at line 114 of file smtp.h.

Referenced by ConnectToHost(), GetBuffer(), MiscSocketSetup(), and SendLine().

struct timeval SMTP::timeout [private]

Definition at line 115 of file smtp.h.

Referenced by ConnectToHost(), GetBuffer(), MiscSocketSetup(), and SendLine().

SOCKET SMTP::the_socket [private]

Definition at line 117 of file smtp.h.

Referenced by CloseConnect(), ConnectToHost(), GetAndSetTheSocket(), GetBuffer(), GetConnection(), SendLine(), and SMTP().

char SMTP::my_hostname[1024] [private]

Definition at line 119 of file smtp.h.

Referenced by open_socket(), and prepare_message().

CHAR SMTP::ServerProtocol[100] [private]

Definition at line 121 of file smtp.h.

CHAR SMTP::RemoteAddress[100] [private]

Definition at line 122 of file smtp.h.

CHAR SMTP::RemoteHost[100] [private]

Definition at line 123 of file smtp.h.

CHAR SMTP::RemoteUser[100] [private]

Definition at line 124 of file smtp.h.

CHAR SMTP::HttpAccept[100] [private]

Definition at line 125 of file smtp.h.

CHAR SMTP::HttpUserAgent[256] [private]

Definition at line 126 of file smtp.h.

CHAR SMTP::FirstName[100] [private]

Definition at line 128 of file smtp.h.

CHAR SMTP::LastName[100] [private]

Definition at line 129 of file smtp.h.

CHAR SMTP::WebUse[100] [private]

Definition at line 130 of file smtp.h.

CHAR SMTP::EMail[100] [private]

Definition at line 131 of file smtp.h.

CHAR SMTP::HomePage[100] [private]

Definition at line 132 of file smtp.h.

CHAR SMTP::text[500] [private]

Definition at line 133 of file smtp.h.

The documentation for this class was generated from the following files:
  • smtp.h
  • comms.C
  • smtp.C


Member List

SMTP Member List

This is the complete list of members for SMTP, including all inherited members.
CloseConnect() | SMTP |
ConnectToHost(const char *, const char *) | SMTP |
EMail | SMTP | [private]
fds | SMTP | [private]
FirstName | SMTP | [private]
FlushBuffer() | SMTP |
free(void *ptr) | PA_Allocated | [inline, static]
get_line(void) | SMTP |
GetAndSetTheSocket(SOCKET *) | SMTP |
GetBuffer(int) | SMTP |
GetChar(int, char *) | SMTP |
GetConnection(SOCKET, struct sockaddr_in *) | SMTP |
HomePage | SMTP | [private]
HttpAccept | SMTP | [private]
HttpUserAgent | SMTP | [private]
in_buffer | SMTP | [private]
in_buffer_total | SMTP | [private]
in_index | SMTP | [private]
IsAddressARawIpaddress(const char *) | SMTP |
last_winsock_error | SMTP | [private]
LastName | SMTP | [private]
MakeSmtpHeader(char *, char *, char *, char *) | SMTP |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
MiscSocketSetup(SOCKET, fd_set *, struct timeval *) | SMTP |
my_hostname | SMTP | [private]
open_socket(const char *, const char *) | SMTP |
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
out_buffer | SMTP | [private]
out_buffer_total | SMTP | [private]
out_index | SMTP | [private]
prepare_message(char *, char *, const char *, const char *) | SMTP |
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
RemoteAddress | SMTP | [private]
RemoteHost | SMTP | [private]
RemoteUser | SMTP | [private]
ResolveHostname(const char *, struct sockaddr_in *) | SMTP |
ResolveService(const char *, u_short *) | SMTP |
Send(const char *, const char *, const char *, char *, char *) | SMTP |
send_data(const char *) | SMTP |
SendBuffer(const char *, unsigned long) | SMTP |
SendLine(const char *, unsigned long) | SMTP |
SendSmtpError(const char *) | SMTP |
ServerProtocol | SMTP | [private]
SMTP() | SMTP |
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
text | SMTP | [private]
the_socket | SMTP | [private]
timeout | SMTP | [private]
transform_and_send_edit_data(const char *) | SMTP |
WebUse | SMTP | [private]
~SMTP() | SMTP |


SQL_Connection Class Reference

SQL connection. handy wrapper around low level SQL_Driver. More...

Inheritance diagram for SQL_Connection:

[legend]
Collaboration diagram for SQL_Connection:

[legend]
List of all members.

Public Methods

SQL_Connection (const String &aurl, SQL_Driver &adriver, const char *arequest_charset)
SQL_Driver_services_impl & services ()
const String & | get_url ()
void | set_url ()
void | use ()
bool | expired (time_t older_dies)
time_t | get_time_used ()
bool | connected ()
void | connect (char *used_only_in_connect_url_cstr)
void | disconnect ()
bool | ping ()
const char * | quote (const char *str, unsigned int length)
void | query (const char *statement, size_t placeholders_count, SQL_Driver::Placeholder *placeholders, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers &handlers, const String &source)
void | commit ()
void | rollback ()
void | close ()
return to cache. More...

Private Attributes

const String & | furl
SQL_Driver & fdriver
SQL_Driver_services_impl fservices
void * | fconnection
time_t | time_used

Detailed Description

SQL connection. handy wrapper around low level SQL_Driver.

Definition at line 88 of file pa_sql_connection.h.

Constructor & Destructor Documentation

SQL_Connection::SQL_Connection | ( | const String & | aurl,
 |  | SQL_Driver & | adriver,
 |  | const char * | arequest_charset
 | ) | [inline]

Definition at line 97 of file pa_sql_connection.h.

References fconnection, and time_used.

Member Function Documentation

SQL_Driver_services_impl& SQL_Connection::services ( ) [inline]

Definition at line 105 of file pa_sql_connection.h.

Referenced by add_connection_to_status_cache_table().

const String& SQL_Connection::get_url ( ) [inline]

Definition at line 107 of file pa_sql_connection.h.

void SQL_Connection::set_url ( ) [inline]

Definition at line 109 of file pa_sql_connection.h.

References SQL_Driver_services_impl::set_url().

Referenced by SQL_Driver_manager::get_connection().

void SQL_Connection::use ( ) [inline]

Definition at line 112 of file pa_sql_connection.h.

References time_used.

bool SQL_Connection::expired ( time_t older_dies ) [inline]

Definition at line 115 of file pa_sql_connection.h.

References time_used.

Referenced by expire_connection().

time_t SQL_Connection::get_time_used ( ) [inline]

Definition at line 118 of file pa_sql_connection.h.

References time_used.

Referenced by add_connection_to_status_cache_table().

bool SQL_Connection::connected ( ) [inline]

Definition at line 120 of file pa_sql_connection.h.

References fconnection.

Referenced by add_connection_to_status_cache_table(), expire_connection(), SQL_Driver_manager::get_connection(), and SQL_Driver_manager::get_connection_from_cache().

void SQL_Connection::connect ( char * used_only_in_connect_url_cstr ) [inline]

Definition at line 121 of file pa_sql_connection.h.

References SQL_Driver::connect(), fconnection, and SQL_CONNECTION_SERVICED_FUNC_GUARDED.

Referenced by SQL_Driver_manager::get_connection().

void SQL_Connection::disconnect ( ) [inline]

Definition at line 126 of file pa_sql_connection.h.

References SQL_Driver::disconnect(), and fconnection.

Referenced by expire_connection(), and SQL_Driver_manager::get_connection().

bool SQL_Connection::ping ( ) [inline]

Definition at line 129 of file pa_sql_connection.h.

References fconnection, SQL_Driver::ping(), and SQL_CONNECTION_SERVICED_FUNC_GUARDED.

Referenced by SQL_Driver_manager::get_connection().

const char* SQL_Connection::quote | ( | const char * | str,
 |  | unsigned int | length
 | ) | [inline]

Definition at line 134 of file pa_sql_connection.h.

References fconnection, SQL_Driver::quote(), SQL_CONNECTION_SERVICED_FUNC_GUARDED, and str.

Referenced by _sql_string().

void SQL_Connection::query | ( | const char * | statement,
 |  | size_t | placeholders_count,
 |  | SQL_Driver::Placeholder * | placeholders,
 |  | unsigned long | offset,
 |  | unsigned long | limit,
 |  | SQL_Driver_query_event_handlers & | handlers,
 |  | const String & | source
 | ) | [inline]

Definition at line 140 of file pa_sql_connection.h.

References fconnection, offset, SQL_Driver::query(), rethrow, and SQL_CONNECTION_SERVICED_FUNC_GUARDED.

Referenced by _sql(), and sql_result_string().

void SQL_Connection::commit ( ) [inline]

Definition at line 165 of file pa_sql_connection.h.

References SQL_Driver::commit(), fconnection, and SQL_CONNECTION_SERVICED_FUNC_GUARDED.

Referenced by _connect().

void SQL_Connection::rollback ( ) [inline]

Definition at line 170 of file pa_sql_connection.h.

References fconnection, SQL_Driver::rollback(), and SQL_CONNECTION_SERVICED_FUNC_GUARDED.

Referenced by _connect().

void SQL_Connection::close ( ) [inline]

return to cache.

Definition at line 177 of file pa_sql_connection.h.

Referenced by _connect().

Member Data Documentation

const String& SQL_Connection::furl [private]

Definition at line 89 of file pa_sql_connection.h.

SQL_Driver& SQL_Connection::fdriver [private]

Definition at line 90 of file pa_sql_connection.h.

SQL_Driver_services_impl SQL_Connection::fservices [private]

Definition at line 91 of file pa_sql_connection.h.

void* SQL_Connection::fconnection [private]

Definition at line 92 of file pa_sql_connection.h.

Referenced by commit(), connect(), connected(), disconnect(), ping(), query(), quote(), rollback(), and SQL_Connection().

time_t SQL_Connection::time_used [private]

Definition at line 93 of file pa_sql_connection.h.

Referenced by expired(), get_time_used(), SQL_Connection(), and use().

The documentation for this class was generated from the following file:
  • pa_sql_connection.h


Member List

SQL_Connection Member List

This is the complete list of members for SQL_Connection, including all inherited members.
close() | SQL_Connection | [inline]
commit() | SQL_Connection | [inline]
connect(char *used_only_in_connect_url_cstr) | SQL_Connection | [inline]
connected() | SQL_Connection | [inline]
disconnect() | SQL_Connection | [inline]
expired(time_t older_dies) | SQL_Connection | [inline]
fconnection | SQL_Connection | [private]
fdriver | SQL_Connection | [private]
free(void *ptr) | PA_Allocated | [inline, static]
fservices | SQL_Connection | [private]
furl | SQL_Connection | [private]
get_time_used() | SQL_Connection | [inline]
get_url() | SQL_Connection | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
ping() | SQL_Connection | [inline]
query(const char *statement, size_t placeholders_count, SQL_Driver::Placeholder *placeholders, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers &handlers, const String &source) | SQL_Connection | [inline]
quote(const char *str, unsigned int length) | SQL_Connection | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
rollback() | SQL_Connection | [inline]
services() | SQL_Connection | [inline]
set_url() | SQL_Connection | [inline]
SQL_Connection(const String &aurl, SQL_Driver &adriver, const char *arequest_charset) | SQL_Connection | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
time_used | SQL_Connection | [private]
use() | SQL_Connection | [inline]


SQL_Driver Class Reference

SQL driver API. More...

List of all members.

Public Methods

virtual int | api_version ()=0
get api version. More...

virtual const char * | initialize (char *dlopen_file_spec)=0
initialize driver by loading sql dynamic link library. More...

virtual void | connect (char *url_cstr, SQL_Driver_services &services, void **connection)=0
connect to sql database using. More...

virtual void | disconnect (void *connection)=0
virtual void | commit (void *connection)=0
virtual void | rollback (void *connection)=0
virtual bool | ping (void *connection)=0
Returns:
true to indicate that connection still alive.
 More...

virtual const char * | quote (void *connection, const char *str, unsigned int length)=0
encodes the string in 'from' to an escaped SQL string. More...

virtual void | query (void *connection, const char *statement, size_t placeholders_count, Placeholder *placeholders, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers &handlers)=0

Static Public Methods

void * | operator new (size_t size)
allocated using our allocator,. More...

Detailed Description

SQL driver API.

Definition at line 117 of file pa_sql_driver.h.

Member Function Documentation

void* SQL_Driver::operator new ( size_t size ) [inline, static]

allocated using our allocator,.

Todo:
never freed

Definition at line 132 of file pa_sql_driver.h.

References abort(), result, and size.

virtual int SQL_Driver::api_version ( ) [pure virtual]

get api version.

Referenced by SQL_Driver_manager::get_connection().

virtual const char* SQL_Driver::initialize ( char * dlopen_file_spec ) [pure virtual]

initialize driver by loading sql dynamic link library.

Referenced by SQL_Driver_manager::get_connection().

virtual void SQL_Driver::connect | ( | char * | url_cstr,
 |  | SQL_Driver_services & | services,
 |  | void ** | connection
 | ) | [pure virtual]

connect to sql database using.

Parameters:
url_cstr format is driver specific
Returns:
true+'connection' on success. 'error' on failure

Referenced by SQL_Connection::connect().

virtual void SQL_Driver::disconnect ( void * connection ) [pure virtual]

Referenced by SQL_Connection::disconnect().

virtual void SQL_Driver::commit ( void * connection ) [pure virtual]

Referenced by SQL_Connection::commit().

virtual void SQL_Driver::rollback ( void * connection ) [pure virtual]

Referenced by SQL_Connection::rollback().

virtual bool SQL_Driver::ping ( void * connection ) [pure virtual]

Returns:
true to indicate that connection still alive.

Referenced by SQL_Connection::ping().

virtual const char* SQL_Driver::quote | ( | void * | connection,
 |  | const char * | str,
 |  | unsigned int | length
 | ) | [pure virtual]

encodes the string in 'from' to an escaped SQL string.

Referenced by SQL_Connection::quote().

virtual void SQL_Driver::query | ( | void * | connection,
 |  | const char * | statement,
 |  | size_t | placeholders_count,
 |  | Placeholder * | placeholders,
 |  | unsigned long | offset,
 |  | unsigned long | limit,
 |  | SQL_Driver_query_event_handlers & | handlers
 | ) | [pure virtual]

Referenced by SQL_Connection::query().

The documentation for this class was generated from the following file:
  • pa_sql_driver.h


Member List

SQL_Driver Member List

This is the complete list of members for SQL_Driver, including all inherited members.
api_version()=0 | SQL_Driver | [pure virtual]
commit(void *connection)=0 | SQL_Driver | [pure virtual]
connect(char *url_cstr, SQL_Driver_services &services, void **connection)=0 | SQL_Driver | [pure virtual]
disconnect(void *connection)=0 | SQL_Driver | [pure virtual]
initialize(char *dlopen_file_spec)=0 | SQL_Driver | [pure virtual]
operator new(size_t size) | SQL_Driver | [inline, static]
ping(void *connection)=0 | SQL_Driver | [pure virtual]
query(void *connection, const char *statement, size_t placeholders_count, Placeholder *placeholders, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers &handlers)=0 | SQL_Driver | [pure virtual]
quote(void *connection, const char *str, unsigned int length)=0 | SQL_Driver | [pure virtual]
rollback(void *connection)=0 | SQL_Driver | [pure virtual]


SQL_Driver::Placeholder Struct Reference

to pass IN and OUT int/double NOT in string format. More...

List of all members.

Public Attributes

const char * | name
const char * | value
bool | is_null
bool | were_updated

Detailed Description

to pass IN and OUT int/double NOT in string format.

Todo:
can be optimized to contain type information,

Definition at line 122 of file pa_sql_driver.h.

Member Data Documentation

const char* SQL_Driver::Placeholder::name

Definition at line 123 of file pa_sql_driver.h.

Referenced by marshal_bind(), and unmarshal_bind_updates().

const char* SQL_Driver::Placeholder::value

Definition at line 124 of file pa_sql_driver.h.

Referenced by marshal_bind(), and unmarshal_bind_updates().

bool SQL_Driver::Placeholder::is_null

Definition at line 125 of file pa_sql_driver.h.

Referenced by marshal_bind(), and unmarshal_bind_updates().

bool SQL_Driver::Placeholder::were_updated

Definition at line 126 of file pa_sql_driver.h.

Referenced by marshal_bind(), and unmarshal_bind_updates().

The documentation for this struct was generated from the following file:
  • pa_sql_driver.h


Member List

SQL_Driver::Placeholder Member List

This is the complete list of members for SQL_Driver::Placeholder, including all inherited members.
is_null | SQL_Driver::Placeholder
name | SQL_Driver::Placeholder
value | SQL_Driver::Placeholder
were_updated | SQL_Driver::Placeholder


SQL_Driver_manager Class Reference

sql driver manager. More...

Inheritance diagram for SQL_Driver_manager:

[legend]
Collaboration diagram for SQL_Driver_manager:

[legend]
List of all members.

Public Types

typedef Hash< const String::Body,
SQL_Driver * > 		driver_cache_type
typedef Stack< SQL_Connection * > | connection_cache_element_base_type
typedef Hash< const String::Body,
connection_cache_element_base_type * > 		connection_cache_type

Public Methods

SQL_Driver_manager ()
override | ~SQL_Driver_manager ()
SQL_Connection * | get_connection (const String &aurl, Table *protocol2driver_and_client, const char *arequest_charset)
connect to specified url, using driver dynamic library found in table, if not loaded yet checks driver version. More...

override Value * | get_status ()
if filter_server_id not null, returns status only Cachable -s with matching cacheable_item_server_id(). More...

override void | maybe_expire_cache ()

Private Methods

SQL_Driver * | get_driver_from_cache (driver_cache_type::key_type protocol)
void | put_driver_to_cache (driver_cache_type::key_type protocol, driver_cache_type::value_type driver)
SQL_Connection * | get_connection_from_cache (connection_cache_type::key_type url)
void | put_connection_to_cache (connection_cache_type::key_type url, SQL_Connection *connection)
void | close_connection (connection_cache_type::key_type url, SQL_Connection *connection)
caches connection. More...

Private Attributes

bool | is_dlinited
driver_cache_type driver_cache
connection_cache_type connection_cache
time_t | prev_expiration_pass_time

Friends

class | SQL_Connection

Detailed Description

sql driver manager.

Definition at line 32 of file pa_sql_driver_manager.h.

Member Typedef Documentation

typedef Hash<const String::Body, SQL_Driver *> SQL_Driver_manager::driver_cache_type

Definition at line 35 of file pa_sql_driver_manager.h.

typedef Stack<SQL_Connection*> SQL_Driver_manager::connection_cache_element_base_type

Definition at line 36 of file pa_sql_driver_manager.h.

typedef Hash<const String::Body, connection_cache_element_base_type*> SQL_Driver_manager::connection_cache_type

Definition at line 37 of file pa_sql_driver_manager.h.

Constructor & Destructor Documentation

SQL_Driver_manager::SQL_Driver_manager ( )

Definition at line 104 of file pa_sql_driver_manager.C.

SQL_Driver_manager::~SQL_Driver_manager ( )

Definition at line 108 of file pa_sql_driver_manager.C.

References connection_cache, expire_connections(), and Hash< const String::Body, connection_cache_element_base_type * >::for_each().

Member Function Documentation

SQL_Connection * SQL_Driver_manager::get_connection | ( | const String & | aurl,
 |  | Table * | protocol2driver_and_client,
 |  | const char * | arequest_charset
 | ) |

connect to specified url, using driver dynamic library found in table, if not loaded yet checks driver version.

Definition at line 116 of file pa_sql_driver_manager.C.

References SQL_Driver::api_version(), SQL_Connection::connect(), SQL_Connection::connected(), String::cstr(), String::cstrm(), SQL_Connection::disconnect(), filename, get_connection_from_cache(), get_driver_from_cache(), handle, SQL_Driver::initialize(), is_dlinited, Table::item(), String::L_AS_IS, String::L_FILE_SPEC, String::length(), Table::locate(), lsplit(), lt_dlinit(), MAIN_SQL_DRIVERS_NAME, MAIN_SQL_NAME, SQL_Connection::ping(), put_driver_to_cache(), SQL_Connection::set_url(), SQL_Connection, SQL_DRIVER_API_VERSION, SQL_Driver_create_func, and SQL_DRIVER_CREATE_NAME.

SQL_Driver * SQL_Driver_manager::get_driver_from_cache ( driver_cache_type::key_type protocol ) [private]

Definition at line 243 of file pa_sql_driver_manager.C.

References driver_cache, Hash< const String::Body, SQL_Driver * >::get(), and SYNCHRONIZED.

Referenced by get_connection().

void SQL_Driver_manager::put_driver_to_cache | ( | driver_cache_type::key_type | protocol,
 |  | driver_cache_type::value_type | driver
 | ) | [private]

Definition at line 249 of file pa_sql_driver_manager.C.

References driver_cache, Hash< const String::Body, SQL_Driver * >::put(), and SYNCHRONIZED.

Referenced by get_connection().

SQL_Connection * SQL_Driver_manager::get_connection_from_cache ( connection_cache_type::key_type url ) [private]

Todo:
get rid of memory spending Stack [zeros deep inside got accumulated]

Definition at line 259 of file pa_sql_driver_manager.C.

References SQL_Connection::connected(), result, and SYNCHRONIZED.

Referenced by get_connection().

void SQL_Driver_manager::put_connection_to_cache | ( | connection_cache_type::key_type | url,
 |  | SQL_Connection * | connection
 | ) | [private]

Definition at line 272 of file pa_sql_driver_manager.C.

References connection_cache, Hash< const String::Body, connection_cache_element_base_type * >::get(), Hash< const String::Body, connection_cache_element_base_type * >::put(), and SYNCHRONIZED.

Referenced by close_connection().

void SQL_Driver_manager::close_connection | ( | connection_cache_type::key_type | url,
 |  | SQL_Connection * | connection
 | ) | [private]

caches connection.

Definition at line 235 of file pa_sql_driver_manager.C.

References put_connection_to_cache().

Value * SQL_Driver_manager::get_status ( ) [virtual]

if filter_server_id not null, returns status only Cachable -s with matching cacheable_item_server_id().

Implements Cache_manager.

Definition at line 316 of file pa_sql_driver_manager.C.

References add_connections_to_status_cache_table(), connection_cache, Hash< const String::Body, connection_cache_element_base_type * >::count(), Hash< const String::Body, connection_cache_element_base_type * >::for_each(), Value::get_hash(), Hash< const String::Body, Value * >::put(), and result.

void SQL_Driver_manager::maybe_expire_cache ( ) [virtual]

Reimplemented from Cache_manager.

Definition at line 285 of file pa_sql_driver_manager.C.

References CHECK_EXPIRED_CONNECTIONS_SECONDS, connection_cache, expire_connections(), EXPIRE_UNUSED_CONNECTION_SECONDS, Hash< const String::Body, connection_cache_element_base_type * >::for_each(), and prev_expiration_pass_time.

Friends And Related Function Documentation

friend class SQL_Connection [friend]

Definition at line 41 of file pa_sql_driver_manager.h.

Referenced by get_connection().

Member Data Documentation

bool SQL_Driver_manager::is_dlinited [private]

Definition at line 43 of file pa_sql_driver_manager.h.

Referenced by get_connection().

driver_cache_type SQL_Driver_manager::driver_cache [private]

Definition at line 44 of file pa_sql_driver_manager.h.

Referenced by get_driver_from_cache(), and put_driver_to_cache().

connection_cache_type SQL_Driver_manager::connection_cache [private]

Definition at line 45 of file pa_sql_driver_manager.h.

Referenced by get_status(), maybe_expire_cache(), put_connection_to_cache(), and ~SQL_Driver_manager().

time_t SQL_Driver_manager::prev_expiration_pass_time [private]

Definition at line 72 of file pa_sql_driver_manager.h.

Referenced by maybe_expire_cache().

The documentation for this class was generated from the following files:
  • pa_sql_driver_manager.h
  • pa_sql_driver_manager.C


Member List

SQL_Driver_manager Member List

This is the complete list of members for SQL_Driver_manager, including all inherited members.
close_connection(connection_cache_type::key_type url, SQL_Connection *connection) | SQL_Driver_manager | [private]
connection_cache | SQL_Driver_manager | [private]
connection_cache_element_base_type typedef | SQL_Driver_manager |
connection_cache_type typedef | SQL_Driver_manager |
driver_cache | SQL_Driver_manager | [private]
driver_cache_type typedef | SQL_Driver_manager |
free(void *ptr) | PA_Allocated | [inline, static]
get_connection(const String &aurl, Table *protocol2driver_and_client, const char *arequest_charset) | SQL_Driver_manager |
get_connection_from_cache(connection_cache_type::key_type url) | SQL_Driver_manager | [private]
get_driver_from_cache(driver_cache_type::key_type protocol) | SQL_Driver_manager | [private]
get_status() | SQL_Driver_manager | [virtual]
is_dlinited | SQL_Driver_manager | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_expire_cache() | SQL_Driver_manager | [virtual]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
prev_expiration_pass_time | SQL_Driver_manager | [private]
put_connection_to_cache(connection_cache_type::key_type url, SQL_Connection *connection) | SQL_Driver_manager | [private]
put_driver_to_cache(driver_cache_type::key_type protocol, driver_cache_type::value_type driver) | SQL_Driver_manager | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
SQL_Connection class | SQL_Driver_manager | [friend]
SQL_Driver_manager() | SQL_Driver_manager |
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
~Cache_manager() | Cache_manager | [inline, virtual]
~SQL_Driver_manager() | SQL_Driver_manager |


SQL_Driver_query_event_handlers Class Reference

events, occuring when SQL_Driver::query()-ing. More...

List of all members.

Public Methods

virtual bool | add_column (SQL_Error &error, const char *str, size_t length)=0
virtual bool | before_rows (SQL_Error &error)=0
virtual bool | add_row (SQL_Error &error)=0
virtual bool | add_row_cell (SQL_Error &error, const char *str, size_t length)=0

Detailed Description

events, occuring when SQL_Driver::query()-ing.

when OK must return false. must NOT throw exceptions, must store them to error & return true.

Definition at line 108 of file pa_sql_driver.h.

Member Function Documentation

virtual bool SQL_Driver_query_event_handlers::add_column | ( | SQL_Error & | error,
 |  | const char * | str,
 |  | size_t | length
 | ) | [pure virtual]

virtual bool SQL_Driver_query_event_handlers::before_rows ( SQL_Error & error ) [pure virtual]

virtual bool SQL_Driver_query_event_handlers::add_row ( SQL_Error & error ) [pure virtual]

virtual bool SQL_Driver_query_event_handlers::add_row_cell | ( | SQL_Error & | error,
 |  | const char * | str,
 |  | size_t | length
 | ) | [pure virtual]

The documentation for this class was generated from the following file:
  • pa_sql_driver.h


Member List

SQL_Driver_query_event_handlers Member List

This is the complete list of members for SQL_Driver_query_event_handlers, including all inherited members.
add_column(SQL_Error &error, const char *str, size_t length)=0 | SQL_Driver_query_event_handlers | [pure virtual]
add_row(SQL_Error &error)=0 | SQL_Driver_query_event_handlers | [pure virtual]
add_row_cell(SQL_Error &error, const char *str, size_t length)=0 | SQL_Driver_query_event_handlers | [pure virtual]
before_rows(SQL_Error &error)=0 | SQL_Driver_query_event_handlers | [pure virtual]


SQL_Driver_services Class Reference

service functions for SQL driver to use. More...

Inheritance diagram for SQL_Driver_services:

[legend]
List of all members.

Public Methods

virtual void * | malloc (size_t size)=0
allocates some bytes. More...

virtual void * | malloc_atomic (size_t size)=0
allocates some bytes, user promises: no pointers inside. More...

virtual void * | realloc (void *ptr, size_t size)=0
reallocates bytes. More...

virtual const char * | request_charset ()=0
$request:charset. More...

virtual void | transcode (const char *src, size_t src_length, const char *&dst, size_t &dst_length, const char *charset_from_name, const char *charset_to_name)=0
transcoder. WARNING: can store pointers to charset names to speedup name-to-instance resolving so do NOT pass pointers to local vars and change those vars after that. More...

virtual void | _throw (const SQL_Error &e)=0
prepare throw exception. More...

virtual void | propagate_exception ()=0
throw C++ exception from prepared. More...

void | _throw (const char *comment)
helper func. More...

Public Attributes

jmp_buf | mark
regretrully public, because can't make stack frames: "nowhere to return to". More...

Detailed Description

service functions for SQL driver to use.

Definition at line 74 of file pa_sql_driver.h.

Member Function Documentation

virtual void* SQL_Driver_services::malloc ( size_t size ) [pure virtual]

allocates some bytes.

Implemented in SQL_Driver_services_impl.

virtual void* SQL_Driver_services::malloc_atomic ( size_t size ) [pure virtual]

allocates some bytes, user promises: no pointers inside.

Implemented in SQL_Driver_services_impl.

virtual void* SQL_Driver_services::realloc | ( | void * | ptr,
 |  | size_t | size
 | ) | [pure virtual]

reallocates bytes.

Implemented in SQL_Driver_services_impl.

virtual const char* SQL_Driver_services::request_charset ( ) [pure virtual]

$request:charset.

Implemented in SQL_Driver_services_impl.

virtual void SQL_Driver_services::transcode | ( | const char * | src,
 |  | size_t | src_length,
 |  | const char *& | dst,
 |  | size_t & | dst_length,
 |  | const char * | charset_from_name,
 |  | const char * | charset_to_name
 | ) | [pure virtual]

transcoder. WARNING: can store pointers to charset names to speedup name-to-instance resolving so do NOT pass pointers to local vars and change those vars after that.

Implemented in SQL_Driver_services_impl.

virtual void SQL_Driver_services::_throw ( const SQL_Error & e ) [pure virtual]

prepare throw exception.

Implemented in SQL_Driver_services_impl.

Referenced by _throw().

virtual void SQL_Driver_services::propagate_exception ( ) [pure virtual]

throw C++ exception from prepared.

Implemented in SQL_Driver_services_impl.

void SQL_Driver_services::_throw ( const char * comment ) [inline]

helper func.

Definition at line 97 of file pa_sql_driver.h.

References _throw().

Member Data Documentation

jmp_buf SQL_Driver_services::mark

regretrully public, because can't make stack frames: "nowhere to return to".

Definition at line 100 of file pa_sql_driver.h.

Referenced by SQL_Driver_services_impl::_throw().

The documentation for this class was generated from the following file:
  • pa_sql_driver.h


Member List

SQL_Driver_services Member List

This is the complete list of members for SQL_Driver_services, including all inherited members.
_throw(const SQL_Error &e)=0 | SQL_Driver_services | [pure virtual]
_throw(const char *comment) | SQL_Driver_services | [inline]
malloc(size_t size)=0 | SQL_Driver_services | [pure virtual]
malloc_atomic(size_t size)=0 | SQL_Driver_services | [pure virtual]
mark | SQL_Driver_services |
propagate_exception()=0 | SQL_Driver_services | [pure virtual]
realloc(void *ptr, size_t size)=0 | SQL_Driver_services | [pure virtual]
request_charset()=0 | SQL_Driver_services | [pure virtual]
transcode(const char *src, size_t src_length, const char *&dst, size_t &dst_length, const char *charset_from_name, const char *charset_to_name)=0 | SQL_Driver_services | [pure virtual]


SQL_Driver_services_impl Class Reference

SQL_Driver_services Pooled implementation. More...

Inheritance diagram for SQL_Driver_services_impl:

[legend]
Collaboration diagram for SQL_Driver_services_impl:

[legend]
List of all members.

Public Methods

SQL_Driver_services_impl (const char *arequest_charset)
void | set_url (const String &aurl)
const String & | url_without_login () const
override void * | malloc (size_t size)
allocates some bytes. More...

override void * | malloc_atomic (size_t size)
allocates some bytes, user promises: no pointers inside. More...

override void * | realloc (void *ptr, size_t size)
reallocates bytes. More...

override const char * | request_charset ()
$request:charset. More...

override void | transcode (const char *src, size_t src_length, const char *&dst, size_t &dst_length, const char *charset_from_name, const char *charset_to_name)
transcoder. WARNING: can store pointers to charset names to speedup name-to-instance resolving so do NOT pass pointers to local vars and change those vars after that. More...

override void | _throw (const SQL_Error &aexception)
normally we can't 'throw' from dynamic library, so the idea is to #1 jump to C++ some function to main body, where every function stack frame has exception unwind information and from there... More...

virtual void | propagate_exception ()
throw C++ exception from prepared. More...

Private Attributes

const String * | furl
Exception fexception
const char * | frequest_charset

Detailed Description

SQL_Driver_services Pooled implementation.

Definition at line 34 of file pa_sql_connection.h.

Constructor & Destructor Documentation

SQL_Driver_services_impl::SQL_Driver_services_impl ( const char * arequest_charset ) [inline]

Definition at line 39 of file pa_sql_connection.h.

References frequest_charset.

Member Function Documentation

void SQL_Driver_services_impl::set_url ( const String & aurl ) [inline]

Definition at line 40 of file pa_sql_connection.h.

Referenced by SQL_Connection::set_url().

const String & SQL_Driver_services_impl::url_without_login ( ) const

Definition at line 31 of file pa_sql_driver_manager.C.

References furl, String::length(), String::mid(), String::pos(), result, and STRING_NOT_FOUND.

Referenced by _throw(), and add_connection_to_status_cache_table().

override void* SQL_Driver_services_impl::malloc ( size_t size ) [inline, virtual]

allocates some bytes.

Implements SQL_Driver_services.

Definition at line 43 of file pa_sql_connection.h.

References override, pa_malloc(), and size.

override void* SQL_Driver_services_impl::malloc_atomic ( size_t size ) [inline, virtual]

allocates some bytes, user promises: no pointers inside.

Implements SQL_Driver_services.

Definition at line 44 of file pa_sql_connection.h.

References override, pa_malloc_atomic(), and size.

override void* SQL_Driver_services_impl::realloc | ( | void * | ptr,
 |  | size_t | size
 | ) | [inline, virtual]

reallocates bytes.

Implements SQL_Driver_services.

Definition at line 45 of file pa_sql_connection.h.

References override, pa_realloc(), and size.

override const char* SQL_Driver_services_impl::request_charset ( ) [inline, virtual]

$request:charset.

Implements SQL_Driver_services.

Definition at line 47 of file pa_sql_connection.h.

References frequest_charset, and override.

void SQL_Driver_services_impl::transcode | ( | const char * | src,
 |  | size_t | src_length,
 |  | const char *& | dst,
 |  | size_t & | dst_length,
 |  | const char * | charset_from_name,
 |  | const char * | charset_to_name
 | ) | [virtual]

transcoder. WARNING: can store pointers to charset names to speedup name-to-instance resolving so do NOT pass pointers to local vars and change those vars after that.

Implements SQL_Driver_services.

Definition at line 45 of file pa_sql_driver_manager.C.

References _throw(), String::C::length, result, String::C::str, and Charset::transcode().

override void SQL_Driver_services_impl::_throw ( const SQL_Error & aexception ) [inline, virtual]

normally we can't 'throw' from dynamic library, so the idea is to #1 jump to C++ some function to main body, where every function stack frame has exception unwind information and from there...

#2 propagate_exception()

but when parser configured --with-sjlj-exceptions one can simply 'throw' from dynamic library. [sad story: one can not longjump/throw due to some bug in gcc as of 3.2.1 version]

Implements SQL_Driver_services.

Definition at line 64 of file pa_sql_connection.h.

References SQL_Error::comment(), SQL_Driver_services::mark, override, SQL_Error::type(), and url_without_login().

Referenced by transcode().

virtual void SQL_Driver_services_impl::propagate_exception ( ) [inline, virtual]

throw C++ exception from prepared.

Implements SQL_Driver_services.

Definition at line 80 of file pa_sql_connection.h.

Member Data Documentation

const String* SQL_Driver_services_impl::furl [private]

Definition at line 35 of file pa_sql_connection.h.

Referenced by url_without_login().

Exception SQL_Driver_services_impl::fexception [private]

Definition at line 36 of file pa_sql_connection.h.

const char* SQL_Driver_services_impl::frequest_charset [private]

Definition at line 37 of file pa_sql_connection.h.

Referenced by request_charset(), and SQL_Driver_services_impl().

The documentation for this class was generated from the following files:
  • pa_sql_connection.h
  • pa_sql_driver_manager.C


Member List

SQL_Driver_services_impl Member List

This is the complete list of members for SQL_Driver_services_impl, including all inherited members.
_throw(const SQL_Error &aexception) | SQL_Driver_services_impl | [inline, virtual]
SQL_Driver_services::_throw(const char *comment) | SQL_Driver_services | [inline]
fexception | SQL_Driver_services_impl | [private]
frequest_charset | SQL_Driver_services_impl | [private]
furl | SQL_Driver_services_impl | [private]
malloc(size_t size) | SQL_Driver_services_impl | [inline, virtual]
malloc_atomic(size_t size) | SQL_Driver_services_impl | [inline, virtual]
mark | SQL_Driver_services |
propagate_exception() | SQL_Driver_services_impl | [inline, virtual]
realloc(void *ptr, size_t size) | SQL_Driver_services_impl | [inline, virtual]
request_charset() | SQL_Driver_services_impl | [inline, virtual]
set_url(const String &aurl) | SQL_Driver_services_impl | [inline]
SQL_Driver_services_impl(const char *arequest_charset) | SQL_Driver_services_impl | [inline]
transcode(const char *src, size_t src_length, const char *&dst, size_t &dst_length, const char *charset_from_name, const char *charset_to_name) | SQL_Driver_services_impl | [virtual]
url_without_login() const | SQL_Driver_services_impl |


SQL_Error Class Reference

fields are freed elsewhere. More...

List of all members.

Public Methods

SQL_Error ()
SQL_Error (const char *atype, const char *acomment)
SQL_Error (const char *acomment)
SQL_Error & | operator= (const SQL_Error &src)
bool | defined () const
const char * | type () const
const char * | comment () const

Private Attributes

bool | fdefined
const char * | ftype
const char * | fcomment

Detailed Description

fields are freed elsewhere.

Definition at line 44 of file pa_sql_driver.h.

Constructor & Destructor Documentation

SQL_Error::SQL_Error ( ) [inline]

Definition at line 49 of file pa_sql_driver.h.

References fdefined.

SQL_Error::SQL_Error | ( | const char * | atype,
 |  | const char * | acomment
 | ) | [inline]

Definition at line 51 of file pa_sql_driver.h.

References fcomment, fdefined, and ftype.

SQL_Error::SQL_Error ( const char * acomment ) [inline]

Definition at line 57 of file pa_sql_driver.h.

References fcomment, fdefined, and ftype.

Member Function Documentation

SQL_Error& SQL_Error::operator= ( const SQL_Error & src ) [inline]

Definition at line 61 of file pa_sql_driver.h.

References fcomment, fdefined, and ftype.

bool SQL_Error::defined ( ) const [inline]

Definition at line 68 of file pa_sql_driver.h.

References fdefined.

const char* SQL_Error::type ( ) const [inline]

Definition at line 69 of file pa_sql_driver.h.

References ftype.

Referenced by SQL_Driver_services_impl::_throw().

const char* SQL_Error::comment ( ) const [inline]

Definition at line 70 of file pa_sql_driver.h.

References fcomment.

Referenced by SQL_Driver_services_impl::_throw().

Member Data Documentation

bool SQL_Error::fdefined [private]

Definition at line 45 of file pa_sql_driver.h.

Referenced by defined(), operator=(), and SQL_Error().

const char* SQL_Error::ftype [private]

Definition at line 46 of file pa_sql_driver.h.

Referenced by operator=(), SQL_Error(), and type().

const char* SQL_Error::fcomment [private]

Definition at line 47 of file pa_sql_driver.h.

Referenced by comment(), operator=(), and SQL_Error().

The documentation for this class was generated from the following file:
  • pa_sql_driver.h


Member List

SQL_Error Member List

This is the complete list of members for SQL_Error, including all inherited members.
comment() const | SQL_Error | [inline]
defined() const | SQL_Error | [inline]
fcomment | SQL_Error | [private]
fdefined | SQL_Error | [private]
ftype | SQL_Error | [private]
operator=(const SQL_Error &src) | SQL_Error | [inline]
SQL_Error() | SQL_Error | [inline]
SQL_Error(const char *atype, const char *acomment) | SQL_Error | [inline]
SQL_Error(const char *acomment) | SQL_Error | [inline]
type() const | SQL_Error | [inline]


TemplateStack class Reference

Stack< T > Class Template Reference

simple stack based on Array. More...

Inheritance diagram for Stack:

[legend]
Collaboration diagram for Stack< T >:

[legend]
List of all members.

Public Methods

Stack ()
void | push (T item)
T | pop ()
bool | is_empty ()
size_t | top_index ()
void | set_top_index (size_t atop)
T | top_value ()
void | wipe_unused ()
call this prior to collecting garbage [in unused part of stack there may be pointers(unused)]. More...

Protected Attributes

size_t | ftop

Detailed Description

template<typename T>
class Stack< T >

simple stack based on Array.

Definition at line 17 of file pa_stack.h.

Constructor & Destructor Documentation

template<typename T>
Stack< T >::Stack ( ) [inline]

Definition at line 20 of file pa_stack.h.

Member Function Documentation

template<typename T>
void Stack< T >::push ( T item ) [inline]

Definition at line 22 of file pa_stack.h.

Referenced by Request::execute().

template<typename T>
T Stack< T >::pop ( ) [inline]

Definition at line 30 of file pa_stack.h.

Referenced by Request::execute().

template<typename T>
bool Stack< T >::is_empty ( ) [inline]

Reimplemented in Request::Exception_trace.

Definition at line 34 of file pa_stack.h.

Referenced by Stack< StackItem >::top_value().

template<typename T>
size_t Stack< T >::top_index ( ) [inline]

Definition at line 35 of file pa_stack.h.

Referenced by Request::execute().

template<typename T>
void Stack< T >::set_top_index ( size_t atop ) [inline]

Definition at line 36 of file pa_stack.h.

template<typename T>
T Stack< T >::top_value ( ) [inline]

Definition at line 37 of file pa_stack.h.

Referenced by Request::execute().

template<typename T>
void Stack< T >::wipe_unused ( ) [inline]

call this prior to collecting garbage [in unused part of stack there may be pointers(unused)].

Definition at line 43 of file pa_stack.h.

Referenced by Request::wipe_unused_execution_stack().

Member Data Documentation

template<typename T>
size_t Stack< T >::ftop [protected]

Definition at line 51 of file pa_stack.h.

Referenced by Stack< StackItem >::is_empty(), Stack< StackItem >::pop(), Stack< StackItem >::push(), Stack< StackItem >::set_top_index(), Stack< StackItem >::Stack(), Stack< StackItem >::top_index(), Stack< StackItem >::top_value(), and Stack< StackItem >::wipe_unused().

The documentation for this class was generated from the following file:
  • pa_stack.h


Member List

Stack< T > Member List

This is the complete list of members for Stack< T >, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< T > | [inline]
Array(size_t initial=3) | Array< T > | [inline]
count() const | Array< T > | [inline]
element_type typedef | Array< T > |
expand(size_t delta) | Array< T > | [inline, protected]
fallocated | Array< T > | [protected]
felements | Array< T > | [protected]
first_that(bool(*callback)(T, I), I info) const | Array< T > | [inline]
for_each(void(*callback)(T, I), I info) const | Array< T > | [inline]
for_each_ref(void(*callback)(T &, I), I info) | Array< T > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
ftop | Stack< T > | [protected]
fused | Array< T > | [protected]
get(size_t index) const | Array< T > | [inline]
get_ref(size_t index) const | Array< T > | [inline]
is_empty() | Stack< T > | [inline]
is_full() | Array< T > | [inline, protected]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(T src) | Array< T > | [inline]
operator[](size_t index) const | Array< T > | [inline]
pop() | Stack< T > | [inline]
push(T item) | Stack< T > | [inline]
put(size_t index, T element) | Array< T > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_top_index(size_t atop) | Stack< T > | [inline]
Stack() | Stack< T > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
top_index() | Stack< T > | [inline]
top_value() | Stack< T > | [inline]
wipe_unused() | Stack< T > | [inline]


String Class Reference

String which knows the lang of all it's langs. More...

Inheritance diagram for String:

[legend]
Collaboration diagram for String:

[legend]
List of all members.

Public Types

typedef void(* | Row_action )(Table &table, ArrayString *row, int prestart, int prefinish, int poststart, int postfinish, void *info)
enum Language {
L_UNSPECIFIED = 0, L_CLEAN = '0', L_AS_IS = 'A', L_PASS_APPENDED = 'P',
L_TAINTED = 'T', L_FILE_SPEC = 'F', L_HTTP_HEADER = 'h', L_MAIL_HEADER = 'm',
L_URI = 'U', L_SQL = 'Q', L_JS = 'J', L_XML = 'X',
L_HTML = 'H', L_REGEX = 'R', L_OPTIMIZE_BIT = 0x80
}
piece is tainted or not. More...

enum | Trim_kind { TRIM_BOTH, TRIM_START, TRIM_END }
enum | Change_case_kind { CC_UPPER, CC_LOWER }

Public Methods

String (const char *cstr=0, size_t helper_length=0, bool tainted=false)
String (const C cstr, bool tainted=false)
String (Body abody, Language alang)
String (const String &src)
operator const Body () const
for convinient hash lookup. More...

bool | is_empty () const
size_t | length () const
Body | cstr_to_string_body (Language lang=L_AS_IS, SQL_Connection *connection=0, const Request_charsets *charsets=0) const
convert to CORD. if 'lang' known, forcing 'lang' to it. More...

const char * | cstr (Language lang=L_AS_IS, SQL_Connection *connection=0, const Request_charsets *charsets=0) const
convert to constant C string. if 'lang' known, forcing 'lang' to it. More...

char * | cstrm (Language lang=L_AS_IS, SQL_Connection *connection=0, const Request_charsets *charsets=0) const
convert to Modifiable C string. if 'lang' known, forcing 'lang' to it. More...

Cm | serialize (size_t prolog_size) const
puts pieces to buf. More...

bool | deserialize (size_t prolog_size, void *buf, size_t buf_size)
appends pieces from buf to self. More...

String & | append_know_length (const char *str, size_t known_length, Language lang)
See also:
Body::append_know_length.
 More...

String & | append_help_length (const char *str, size_t helper_length, Language lang)
See also:
Body::append_help_length.
 More...

String & | append_strdup (const char *str, size_t helper_length, Language lang)
bool | operator== (const char *y) const
bool | operator!= (const char *y) const
bool | starts_with (const char *y) const
this starts with y. More...

bool | this_starts (const char *x) const
x starts with this. More...

String & | append_to (String &dest, Language lang, bool forced) const
appends to other String, marking all tainted pieces of it with lang. More...

String & | append (const String &src, Language lang, bool forced=false)
String & | operator<< (const String &src)
String & | operator<< (const char *src)
String & | operator<< (const Body src)
now that we've declared specialization we can use it. More...

char | first_char () const
extracts first char of a string, if any. More...

bool | operator< (const String &src) const
bool | operator> (const String &src) const
bool | operator<= (const String &src) const
bool | operator>= (const String &src) const
bool | operator!= (const String &src) const
bool | operator== (const String &src) const
String & | mid (size_t substr_begin, size_t substr_end) const
extracts [start, finish) piece of string. More...

size_t | pos (const Body substr, size_t this_offset=0, Language lang=L_UNSPECIFIED) const
ignore lang if it's L_UNSPECIFIED but when specified: look for substring that lies in ONE fragment in THAT lang. More...

size_t | pos (const String &substr, size_t this_offset=0, Language lang=L_UNSPECIFIED) const
String version of
See also:
pos(const char*, int, Language).
 More...

size_t | pos (char c, size_t this_offset=0) const
void | split (ArrayString &result, size_t &pos_after, const char *delim, Language lang=L_UNSPECIFIED, int limit=-1) const
void | split (ArrayString &result, size_t &pos_after, const String &delim, Language lang=L_UNSPECIFIED, int limit=-1) const
Table * | match (Charset &source_charset, const String &regexp, const String *options, Row_action row_action, void *info, bool &just_matched) const
String & | change_case (Charset &source_charset, Change_case_kind kind) const
const String & | replace (const Dictionary &dict) const
const String & | trim (Trim_kind kind=TRIM_BOTH, const char *chars=0) const
double | as_double () const
int | as_int () const

Static Public Attributes

const String | Empty

Private Methods

const char * | v () const
void | dump () const
String & | operator= (const String &)

Private Attributes

Body body
all characters of string. More...

Languages langs
string characters lang. More...

Detailed Description

String which knows the lang of all it's langs.

All pieces remember

  • whether they are tainted or not, and the lang which should be used to detaint them

Definition at line 60 of file pa_string.h.

Member Typedef Documentation

typedef void(* String::Row_action)(Table& table, ArrayString* row, int prestart, int prefinish, int poststart, int postfinish, void *info)

Definition at line 489 of file pa_string.h.

Member Enumeration Documentation

enum String::Language

piece is tainted or not.

the lang to use when detaint remember to change String_Untaint_lang_name @ untaint.C along

WARNING WARNING WARNING WARNING WARNING WARNING

pos function compares(<=) languages, that is used in searching for table column separator being L_CLEAN or L_AS_IS. they search for AS_IS, meaning AS_IS|CLEAN [doing <=L_AS_IS check].

letters assigned for debugging, but it's important for no language-letter come before L_AS_IS other then L_CLEAN

WARNING WARNING WARNING WARNING WARNING WARNING

Enumeration values:
L_UNSPECIFIED | no real string has parts of this lange: it's just convinient to check when string's empty.
L_CLEAN | clean WARNING: read above warning before changing.
L_AS_IS | leave all characters intact WARNING: read above warning before changing.
L_PASS_APPENDED leave lang built into string being appended.

just a flag, that value not stored

L_TAINTED | tainted, untaint lang as assigned later.
L_FILE_SPEC | file specification.
L_HTTP_HEADER | text in HTTP response header.
L_MAIL_HEADER | text in mail header.
L_URI | text in uri.
L_SQL | ^table:sql body.
L_JS | JavaScript code.
L_XML | ^dom:set xml.
L_HTML | HTML code.
L_REGEX | RegEx expression.
L_OPTIMIZE_BIT | flag, requiring cstr whitespace optimization.

Definition at line 77 of file pa_string.h.

Referenced by _taint(), _untaint(), append(), append_attribute_meaning(), append_fragment_nonoptimizing(), append_fragment_optimizing(), VVoid::as_vfile(), VString::as_vfile(), VObject::as_vfile(), VHash::as_vfile(), VFile::as_vfile(), Value::as_vfile(), attributed_meaning_to_string(), cstr(), cstr_to_string_body_block(), cstrm(), deserialize(), Request::execute(), read_pipe(), real_parser_handler(), Request::Request(), Request::restore_lang(), Request::set_lang(), String(), Temp_lang::Temp_lang(), text_value_to_string(), WContext::write(), VMethodFrame::write(), VCodeFrame::write(), and Request::write_no_lang().

enum String::Trim_kind

Enumeration values:
TRIM_BOTH
TRIM_START
TRIM_END

Definition at line 103 of file pa_string.h.

Referenced by _trim(), trim(), and String::Body::trim().

enum String::Change_case_kind

Enumeration values:
CC_UPPER
CC_LOWER

Definition at line 505 of file pa_string.h.

Referenced by change_case().

Constructor & Destructor Documentation

String::String | ( | const char * | cstr = 0,
 |  | size_t | helper_length = 0,
 |  | bool | tainted = false
 | ) | [explicit]

Definition at line 240 of file pa_string.C.

References append_help_length(), body, CORD_EMPTY, and cstr().

Referenced by change_case(), and replace().

String::String | ( | const C | cstr,
 |  | bool | tainted = false
 | ) | [explicit]

Definition at line 243 of file pa_string.C.

References append_know_length(), CORD_EMPTY, String::C::length, and String::C::str.

String::String | ( | Body | abody,
 |  | Language | alang
 | ) | [inline]

Definition at line 390 of file pa_string.h.

References ASSERT_STRING_INVARIANT, and Language.

String::String ( const String & src ) [inline]

Definition at line 393 of file pa_string.h.

References ASSERT_STRING_INVARIANT.

Member Function Documentation

const char * String::v ( ) const [private]

Definition at line 723 of file pa_string.C.

References body, String::Languages::count(), langs, PA_Allocated::malloc(), MAX_STRING, snprintf, uint, String::Languages::v(), and String::Body::v().

void String::dump ( ) const [private]

Definition at line 737 of file pa_string.C.

References body, String::Languages::dump(), String::Body::dump(), and langs.

String::operator const Body ( ) const [inline]

for convinient hash lookup.

Definition at line 398 of file pa_string.h.

bool String::is_empty ( ) const [inline]

Definition at line 400 of file pa_string.h.

References String::Body::is_empty().

Referenced by _double(), _int(), append_to(), change_case(), cstr_to_string_body(), extractEmail(), extractEmails(), first_char(), VString::is_defined(), match(), pa_dictionary_add_first(), VCookie::put_element(), VHashfile::put_field(), regex_options(), split(), and store_message_element().

size_t String::length ( ) const [inline]

Definition at line 401 of file pa_string.h.

References String::Body::length().

Referenced by _basename(), _create(), _exec_cgi(), _find(), _font(), _for(), _fullpath(), _justext(), _justname(), _list(), _menu(), _mid(), _right(), _save(), _trim(), _while(), VClass::add_property(), append_to(), basic_authorization_field(), change_case(), SQL_Driver_manager::get_connection(), VHashfile::get_field(), lastposafter(), TableSeparators::load(), match(), maybe_enclose(), mid(), one_foreach_cycle(), pa_exec(), pa_internal_file_read_http(), Exception::problem_source(), VImage::put_element(), VHashfile::put_field(), VHashfile::remove(), sendmail(), VHashfile::serialize_value(), split(), store_message_element(), store_UTF8(), this_starts(), trim(), and SQL_Driver_services_impl::url_without_login().

String::Body String::cstr_to_string_body | ( | Language | lang = L_AS_IS,
 |  | SQL_Connection * | connection = 0,
 |  | const Request_charsets * | charsets = 0
 | ) | const

convert to CORD. if 'lang' known, forcing 'lang' to it.

Definition at line 489 of file untaint.C.

References body, CORD_ec_init, CORD_ec_to_cord, cstr_to_string_body_block(), String::Languages::for_each(), is_empty(), langs, and String::Body::set_pos().

Referenced by cstr(), and cstrm().

const char* String::cstr | ( | Language | lang = L_AS_IS,
 |  | SQL_Connection * | connection = 0,
 |  | const Request_charsets * | charsets = 0
 | ) | const [inline]

convert to constant C string. if 'lang' known, forcing 'lang' to it.

Definition at line 409 of file pa_string.h.

References String::Body::cstr(), cstr_to_string_body(), L_AS_IS, and Language.

Referenced by _base64(), _create(), _crypt(), _exec_cgi(), _gif(), _list(), _load(), _md5(), _process(), _save(), _sort(), _sql(), _stat(), _throw_operator(), _trim(), VForm::AppendFormEntry(), as_double(), as_int(), VString::as_vfile(), basic_authorization_field(), buildCommand(), create_dir_for_file(), entry_exists(), Request::execute(), file_delete(), file_executable(), file_move(), file_read_action_under_lock(), file_stat(), file_value_to_string(), file_write_action_under_lock(), SQL_Driver_manager::get_connection(), VEnv::get_element(), VClass::get_element(), Request::get_exception_cstr(), VHashfile::get_field(), load(), match(), measure(), VStateless_class::name_cstr(), VHashfile::open(), output_pieces(), Request::output_result(), output_set_cookie_header(), pa_dictionary_add_first(), pa_exec(), pa_form2string(), pa_internal_file_read_http(), parse_range(), VRequest::put_element(), VImage::put_element(), VConsole::put_element(), VHashfile::put_field(), VHashfile::remove(), replace(), rmdir(), sendmail(), VHashfile::serialize_value(), VDate::set_tz(), sql_result_string(), store_message_element(), String(), Font::string_display(), Font::string_width(), and text_value_to_string().

char* String::cstrm | ( | Language | lang = L_AS_IS,
 |  | SQL_Connection * | connection = 0,
 |  | const Request_charsets * | charsets = 0
 | ) | const [inline]

convert to Modifiable C string. if 'lang' known, forcing 'lang' to it.

Definition at line 415 of file pa_string.h.

References cstr_to_string_body(), String::Body::cstrm(), L_AS_IS, and Language.

Referenced by _create(), _eval(), _string_format(), change_case(), entry_readable(), extractEmails(), SQL_Driver_manager::get_connection(), Request::output_result(), pa_exec(), and sendmail().

String::Cm String::serialize ( size_t prolog_size ) const

puts pieces to buf.

Definition at line 610 of file pa_string.C.

References body, String::Languages::count(), String::Languages::for_each(), String::Body::for_each(), langs, String::Body::length(), PointerFreeGC, result, serialize_body_char(), serialize_body_piece(), serialize_lang_piece(), and String::Cm::str.

bool String::deserialize | ( | size_t | prolog_size,
 |  | void * | buf,
 |  | size_t | buf_size
 | ) |

appends pieces from buf to self.

Definition at line 638 of file pa_string.C.

References String::Languages::append(), ASSERT_STRING_INVARIANT, body, langs, Language, and uchar.

Referenced by cache_get().

String & String::append_know_length | ( | const char * | str,
 |  | size_t | known_length,
 |  | Language | lang
 | ) |

See also:
Body::append_know_length.

Definition at line 247 of file pa_string.C.

References String::Languages::append(), String::Body::append_know_length(), ASSERT_STRING_INVARIANT, body, langs, and str.

Referenced by _exec_cgi(), _save(), append_help_length(), fill_month_days(), read_pipe(), VFile::set(), String(), and text_value_to_string().

String & String::append_help_length | ( | const char * | str,
 |  | size_t | helper_length,
 |  | Language | lang
 | ) |

See also:
Body::append_help_length.

Definition at line 259 of file pa_string.C.

References append_know_length(), and str.

Referenced by _save(), append_attribute_meaning(), Request::core(), extractEmail(), VEnv::get_element(), operator<<(), VFile::set(), and String().

String & String::append_strdup | ( | const char * | str,
 |  | size_t | helper_length,
 |  | Language | lang
 | ) |

Definition at line 268 of file pa_string.C.

References String::Languages::append(), String::Body::append_strdup_know_length(), ASSERT_STRING_INVARIANT, body, langs, and str.

Referenced by Request::core(), and store_message_element().

bool String::operator== ( const char * y ) const [inline]

Definition at line 430 of file pa_string.h.

bool String::operator!= ( const char * y ) const [inline]

Definition at line 431 of file pa_string.h.

bool String::starts_with ( const char * y ) const [inline]

this starts with y.

Definition at line 434 of file pa_string.h.

References String::Body::ncmp().

Referenced by Request::absolute(), VClass::add_method(), file_read(), parse_range(), and store_message_element().

bool String::this_starts ( const char * x ) const [inline]

x starts with this.

Definition at line 438 of file pa_string.h.

References length().

Referenced by Request::execute().

String & String::append_to | ( | String & | dest,
 |  | Language | lang,
 |  | bool | forced
 | ) | const

appends to other String, marking all tainted pieces of it with lang.

or marking ALL pieces of it with a lang when forced to, and propagating OPTIMIZE language bit.

Definition at line 185 of file untaint.C.

References String::Languages::append(), append_fragment_nonoptimizing(), append_fragment_optimizing(), ASSERT_STRING_INVARIANT, body, String::Languages::for_each(), is_empty(), L_OPTIMIZE_BIT, L_PASS_APPENDED, langs, length(), and String::Body::length().

Referenced by append().

String& String::append | ( | const String & | src,
 |  | Language | lang,
 |  | bool | forced = false
 | ) | [inline]

Definition at line 443 of file pa_string.h.

References append_to(), and Language.

Referenced by _append(), _exec_cgi(), _taint(), append_attribute_meaning(), Request::core(), form_string_value2string(), Request::get_details(), operator<<(), output_set_cookie_header(), pa_internal_file_read_http(), VCookie::put_element(), WContext::write(), and VCodeFrame::write().

String& String::operator<< ( const String & src ) [inline]

Definition at line 446 of file pa_string.h.

References append(), and L_PASS_APPENDED.

String& String::operator<< ( const char * src ) [inline]

Definition at line 447 of file pa_string.h.

References append_help_length(), and L_AS_IS.

String & String::operator<< ( const Body src ) [inline]

now that we've declared specialization we can use it.

Definition at line 534 of file pa_string.h.

References String::Languages::append(), body, L_AS_IS, langs, and String::Body::length().

char String::first_char ( ) const [inline]

extracts first char of a string, if any.

Definition at line 451 of file pa_string.h.

References String::Body::fetch(), and is_empty().

Referenced by _find(), _fullpath(), Request::absolute(), TableSeparators::load(), maybe_change_string_literal_to_double_literal(), pa_dictionary_add_first(), and Request::use_file().

bool String::operator< ( const String & src ) const [inline]

Definition at line 455 of file pa_string.h.

References body.

bool String::operator> ( const String & src ) const [inline]

Definition at line 456 of file pa_string.h.

References body.

bool String::operator<= ( const String & src ) const [inline]

Definition at line 457 of file pa_string.h.

References body.

bool String::operator>= ( const String & src ) const [inline]

Definition at line 458 of file pa_string.h.

References body.

bool String::operator!= ( const String & src ) const [inline]

Definition at line 459 of file pa_string.h.

References body.

bool String::operator== ( const String & src ) const [inline]

Definition at line 460 of file pa_string.h.

References body.

String & String::mid | ( | size_t | substr_begin,
 |  | size_t | substr_end
 | ) | const

extracts [start, finish) piece of string.

Todo:
check in doc: whether it documents NOW bad situation "abc".mid(-1, 3) =were?="ab"

Definition at line 283 of file pa_string.C.

References String::Languages::append(), ASSERT_STRING_INVARIANT, body, langs, length(), String::Body::mid(), and result.

Referenced by _basename(), _dirname(), _exec_cgi(), _find(), _fullpath(), _justext(), _justname(), _left(), _list(), _mid(), _right(), VClass::add_property(), create_dir_for_file(), match(), maybe_enclose(), pa_internal_file_read_http(), rmdir(), sendmail(), split(), store_message_element(), and SQL_Driver_services_impl::url_without_login().

size_t String::pos | ( | const Body | substr,
 |  | size_t | this_offset = 0,
 |  | Language | lang = L_UNSPECIFIED
 | ) | const

ignore lang if it's L_UNSPECIFIED but when specified: look for substring that lies in ONE fragment in THAT lang.

Returns:
position of substr in string, -1 means "not found" [const char* version]

Definition at line 302 of file pa_string.C.

References body, String::Languages::check_lang(), CORD_NOT_FOUND, langs, String::Body::length(), String::Body::pos(), and STRING_NOT_FOUND.

Referenced by _exec_cgi(), _pos(), Request::absolute(), create_dir_for_file(), Font::index_of(), lastposafter(), maybe_enclose(), output_sole_piece(), pa_internal_file_read_http(), pos(), regex_options(), rmdir(), sendmail(), split(), split_options(), and SQL_Driver_services_impl::url_without_login().

size_t String::pos | ( | const String & | substr,
 |  | size_t | this_offset = 0,
 |  | Language | lang = L_UNSPECIFIED
 | ) | const

String version of

See also:
pos(const char*, int, Language).

Definition at line 317 of file pa_string.C.

References body, and pos().

size_t String::pos | ( | char | c,
 |  | size_t | this_offset = 0
 | ) | const [inline]

Definition at line 475 of file pa_string.h.

References String::Body::pos().

void String::split | ( | ArrayString & | result,
 |  | size_t & | pos_after,
 |  | const char * | delim,
 |  | Language | lang = L_UNSPECIFIED,
 |  | int | limit = -1
 | ) | const

Definition at line 322 of file pa_string.C.

References delim, length(), mid(), pos(), result, and STRING_NOT_FOUND.

Referenced by _append(), _create(), _exec_cgi(), http_read_response(), pa_internal_file_read_http(), sendmail(), and split_list().

void String::split | ( | ArrayString & | result,
 |  | size_t & | pos_after,
 |  | const String & | delim,
 |  | Language | lang = L_UNSPECIFIED,
 |  | int | limit = -1
 | ) | const

Definition at line 345 of file pa_string.C.

References delim, is_empty(), length(), mid(), pos(), result, and STRING_NOT_FOUND.

Table * String::match | ( | Charset & | source_charset,
 |  | const String & | regexp,
 |  | const String * | options,
 |  | Row_action | row_action,
 |  | void * | info,
 |  | bool & | just_matched
 | ) | const

Returns:
table of found items, if any. table format is defined and fixed[can be used by others]:
            prematch/match/postmatch/1/2/3/...

Definition at line 399 of file pa_string.C.

References cstr(), Empty, is_empty(), L_UNSPECIFIED, length(), MAX_MATCH_GROUPS, mid(), pcre, pcre_compile(), PCRE_ERROR_NOMATCH, pcre_exec(), pcre_free, pcre_info(), Charset::pcre_tables, and regex_options().

Referenced by _match().

String & String::change_case | ( | Charset & | source_charset,
 |  | Change_case_kind | kind
 | ) | const

Definition at line 503 of file pa_string.C.

References assert, body, CC_LOWER, CC_UPPER, change_case_UTF8(), cstrm(), fcc_offset, is_empty(), Charset::isUTF8(), langs, lcc_offset, length(), Charset::pcre_tables, result, String(), and XMLByte.

Referenced by _exec_cgi(), change_case(), detect_charset(), VResponse::get_element(), VMail::message_hash_to_string(), Request::mime_type_of(), pa_internal_file_read_http(), and VResponse::put_element().

const String & String::replace ( const Dictionary & dict ) const

Definition at line 559 of file pa_string.C.

References String::Languages::append(), String::Body::append_strdup_know_length(), ASSERT_STRING_INVARIANT, body, cstr(), Dictionary::first_that_begins(), Dictionary::Subst::from_length, langs, result, String(), and Dictionary::Subst::to.

Referenced by _replace().

const String & String::trim | ( | Trim_kind | kind = TRIM_BOTH,
 |  | const char * | chars = 0
 | ) | const

Definition at line 741 of file pa_string.C.

References String::Languages::append(), ASSERT_STRING_INVARIANT, body, langs, length(), result, String::Body::trim(), and Trim_kind.

Referenced by _trim(), and pa_internal_file_read_http().

double String::as_double ( ) const [inline]

Definition at line 513 of file pa_string.h.

References cstr(), and pa_atod().

Referenced by _create(), _double(), _sql(), and VString::as_double().

int String::as_int ( ) const [inline]

Definition at line 514 of file pa_string.h.

References cstr(), and pa_atoi().

Referenced by _int(), _sql(), VString::as_int(), Table::column_name2index(), and http_read_response().

String& String::operator= ( const String & ) [inline, private]

Definition at line 518 of file pa_string.h.

Member Data Documentation

Body String::body [private]

all characters of string.

Definition at line 376 of file pa_string.h.

Referenced by append_know_length(), append_strdup(), append_to(), change_case(), cstr_to_string_body(), deserialize(), dump(), mid(), operator!=(), operator<(), operator<<(), operator<=(), operator==(), operator>(), operator>=(), pos(), replace(), serialize(), String(), trim(), and v().

Languages String::langs [private]

string characters lang.

Definition at line 377 of file pa_string.h.

Referenced by append_know_length(), append_strdup(), append_to(), change_case(), cstr_to_string_body(), deserialize(), dump(), mid(), operator<<(), pos(), replace(), serialize(), trim(), and v().

const String String::Empty [static]

Definition at line 18 of file pa_string.C.

Referenced by match().

The documentation for this class was generated from the following files:
  • pa_string.h
  • pa_string.C
  • untaint.C


Member List

String Member List

This is the complete list of members for String, including all inherited members.
append(const String &src, Language lang, bool forced=false) | String | [inline]
append_help_length(const char *str, size_t helper_length, Language lang) | String |
append_know_length(const char *str, size_t known_length, Language lang) | String |
append_strdup(const char *str, size_t helper_length, Language lang) | String |
append_to(String &dest, Language lang, bool forced) const | String |
as_double() const | String | [inline]
as_int() const | String | [inline]
body | String | [private]
CC_LOWER enum value | String |
CC_UPPER enum value | String |
change_case(Charset &source_charset, Change_case_kind kind) const | String |
Change_case_kind enum name | String |
cstr(Language lang=L_AS_IS, SQL_Connection *connection=0, const Request_charsets *charsets=0) const | String | [inline]
cstr_to_string_body(Language lang=L_AS_IS, SQL_Connection *connection=0, const Request_charsets *charsets=0) const | String |
cstrm(Language lang=L_AS_IS, SQL_Connection *connection=0, const Request_charsets *charsets=0) const | String | [inline]
deserialize(size_t prolog_size, void *buf, size_t buf_size) | String |
dump() const | String | [private]
Empty | String | [static]
first_char() const | String | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
is_empty() const | String | [inline]
L_AS_IS enum value | String |
L_CLEAN enum value | String |
L_FILE_SPEC enum value | String |
L_HTML enum value | String |
L_HTTP_HEADER enum value | String |
L_JS enum value | String |
L_MAIL_HEADER enum value | String |
L_OPTIMIZE_BIT enum value | String |
L_PASS_APPENDED enum value | String |
L_REGEX enum value | String |
L_SQL enum value | String |
L_TAINTED enum value | String |
L_UNSPECIFIED enum value | String |
L_URI enum value | String |
L_XML enum value | String |
langs | String | [private]
Language enum name | String |
length() const | String | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
match(Charset &source_charset, const String &regexp, const String *options, Row_action row_action, void *info, bool &just_matched) const | String |
mid(size_t substr_begin, size_t substr_end) const | String |
operator const Body() const | String | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator!=(const char *y) const | String | [inline]
operator!=(const String &src) const | String | [inline]
operator<(const String &src) const | String | [inline]
operator<<(const String &src) | String | [inline]
operator<<(const char *src) | String | [inline]
operator<<(const Body src) | String | [inline]
operator<=(const String &src) const | String | [inline]
operator=(const String &) | String | [inline, private]
operator==(const char *y) const | String | [inline]
operator==(const String &src) const | String | [inline]
operator>(const String &src) const | String | [inline]
operator>=(const String &src) const | String | [inline]
pos(const Body substr, size_t this_offset=0, Language lang=L_UNSPECIFIED) const | String |
pos(const String &substr, size_t this_offset=0, Language lang=L_UNSPECIFIED) const | String |
pos(char c, size_t this_offset=0) const | String | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace(const Dictionary &dict) const | String |
Row_action typedef | String |
serialize(size_t prolog_size) const | String |
split(ArrayString &result, size_t &pos_after, const char *delim, Language lang=L_UNSPECIFIED, int limit=-1) const | String |
split(ArrayString &result, size_t &pos_after, const String &delim, Language lang=L_UNSPECIFIED, int limit=-1) const | String |
starts_with(const char *y) const | String | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
String(const char *cstr=0, size_t helper_length=0, bool tainted=false) | String | [explicit]
String(const C cstr, bool tainted=false) | String | [explicit]
String(Body abody, Language alang) | String | [inline]
String(const String &src) | String | [inline]
this_starts(const char *x) const | String | [inline]
trim(Trim_kind kind=TRIM_BOTH, const char *chars=0) const | String |
TRIM_BOTH enum value | String |
TRIM_END enum value | String |
Trim_kind enum name | String |
TRIM_START enum value | String |
v() const | String | [private]


String::Body Class Reference

List of all members.

Public Methods

const char * | v () const
void | dump () const
Body ()
Body (CORD abody)
Body (const char *str, size_t helper_length)
WARNING: length is only HELPER length, str in ANY case should be zero-terminated. More...

void | clear ()
bool | operator! () const
uint | hash_code () const
const char * | cstr () const
char * | cstrm () const
size_t | length () const
bool | is_empty () const
void | append_know_length (const char *str, size_t known_length)
void | append_strdup_know_length (const char *str, size_t known_length)
void | append (char c)
Body & | operator<< (const Body src)
Body & | operator<< (const char *str)
bool | operator< (const Body src) const
bool | operator> (const Body src) const
bool | operator<= (const Body src) const
bool | operator>= (const Body src) const
bool | operator!= (const Body src) const
bool | operator== (const Body src) const
int | ncmp (size_t x_begin, const Body y, size_t y_begin, size_t size) const
char | fetch (size_t index) const
Body | mid (size_t index, size_t length) const
size_t | pos (const char *substr, size_t offset=0) const
size_t | pos (const Body substr, size_t offset=0) const
size_t | pos (char c, size_t offset=0) const
template<typename I> int | for_each (int(*f)(char c, I), I info) const
template<typename I> int | for_each (int(*f1)(char c, I), int(*f2)(const char *s, I), I info) const
void | set_pos (CORD_pos &pos, size_t index) const
Body | trim (Trim_kind kind=TRIM_BOTH, const char *chars=0, size_t *out_start=0, size_t *out_length=0) const
Returns:
this or 0 or mid. if returns this or 0 out_* are not filled.
 More...

Static Public Methods

Body | Format (int value)

Private Attributes

CORD body

Constructor & Destructor Documentation

String::Body::Body ( ) [inline]

Definition at line 264 of file pa_string.h.

References body, and CORD_EMPTY.

String::Body::Body ( CORD abody ) [inline]

Definition at line 265 of file pa_string.h.

References assert, body, and CORD.

String::Body::Body | ( | const char * | str,
 |  | size_t | helper_length
 | ) | [inline]

WARNING: length is only HELPER length, str in ANY case should be zero-terminated.

Definition at line 274 of file pa_string.h.

References append_know_length(), body, CORD_EMPTY, and str.

Member Function Documentation

const char * String::Body::v ( ) const

Definition at line 704 of file pa_string.C.

References body, and CORD_to_const_char_star().

Referenced by String::v().

void String::Body::dump ( ) const

Definition at line 707 of file pa_string.C.

References body, and CORD_dump().

Referenced by String::dump().

String::Body String::Body::Format ( int value ) [static]

Definition at line 163 of file pa_string.C.

References length(), MAX_NUMBER, pa_strdup(), snprintf, and value.

Referenced by Request::core(), parse_IFD_entry(), parse_IFD_entry_formatted_value(), and String_match_table_template_columns::String_match_table_template_columns().

void String::Body::clear ( ) [inline]

Definition at line 279 of file pa_string.h.

References body, and CORD_EMPTY.

bool String::Body::operator! ( ) const [inline]

Definition at line 281 of file pa_string.h.

References is_empty().

uint String::Body::hash_code ( ) const

Definition at line 230 of file pa_string.C.

References body, CORD_batched_iter_fn_generic_hash_code(), CORD_iter5(), result, and uint.

Referenced by hash_code().

const char* String::Body::cstr ( ) const [inline]

Definition at line 285 of file pa_string.h.

References body, and CORD_to_const_char_star().

Referenced by _connect(), and String::cstr().

char* String::Body::cstrm ( ) const [inline]

Definition at line 286 of file pa_string.h.

References body, and CORD_to_char_star().

Referenced by append_env_pair(), and String::cstrm().

size_t String::Body::length ( ) const [inline]

Definition at line 288 of file pa_string.h.

References body, and CORD_len().

Referenced by String::append_to(), detect_charset(), Format(), String::length(), mid(), String::operator<<(), pos(), String::pos(), String::serialize(), and trim().

bool String::Body::is_empty ( ) const [inline]

Definition at line 290 of file pa_string.h.

References body, and CORD_EMPTY.

Referenced by String::is_empty(), and operator!().

void String::Body::append_know_length | ( | const char * | str,
 |  | size_t | known_length
 | ) | [inline]

Definition at line 292 of file pa_string.h.

References body, CORD_cat_char_star(), and str.

Referenced by String::append_know_length(), append_strdup_know_length(), Body(), and operator<<().

void String::Body::append_strdup_know_length | ( | const char * | str,
 |  | size_t | known_length
 | ) | [inline]

Definition at line 296 of file pa_string.h.

References append_know_length(), pa_strdup(), and str.

Referenced by String::append_strdup(), and String::replace().

void String::Body::append ( char c ) [inline]

Definition at line 300 of file pa_string.h.

References body, and CORD_cat_char().

Body& String::Body::operator<< ( const Body src ) [inline]

Definition at line 301 of file pa_string.h.

References body, and CORD_cat().

Body& String::Body::operator<< ( const char * str ) [inline]

Definition at line 302 of file pa_string.h.

References append_know_length(), and str.

bool String::Body::operator< ( const Body src ) const [inline]

Definition at line 305 of file pa_string.h.

References body, and CORD_cmp().

bool String::Body::operator> ( const Body src ) const [inline]

Definition at line 306 of file pa_string.h.

References body, and CORD_cmp().

bool String::Body::operator<= ( const Body src ) const [inline]

Definition at line 307 of file pa_string.h.

References body, and CORD_cmp().

bool String::Body::operator>= ( const Body src ) const [inline]

Definition at line 308 of file pa_string.h.

References body, and CORD_cmp().

bool String::Body::operator!= ( const Body src ) const [inline]

Definition at line 309 of file pa_string.h.

References body, and CORD_cmp().

bool String::Body::operator== ( const Body src ) const [inline]

Definition at line 310 of file pa_string.h.

References body, and CORD_cmp().

int String::Body::ncmp | ( | size_t | x_begin,
 |  | const Body | y,
 |  | size_t | y_begin,
 |  | size_t | size
 | ) | const [inline]

Definition at line 312 of file pa_string.h.

References body, CORD_ncmp(), and size.

Referenced by String::starts_with().

char String::Body::fetch ( size_t index ) const [inline]

Definition at line 316 of file pa_string.h.

References body, and CORD_fetch().

Referenced by String::first_char().

Body String::Body::mid | ( | size_t | index,
 |  | size_t | length
 | ) | const [inline]

Definition at line 317 of file pa_string.h.

References body, CORD_substr(), and length().

Referenced by detect_charset(), String::mid(), and trim().

size_t String::Body::pos | ( | const char * | substr,
 |  | size_t | offset = 0
 | ) | const [inline]

Definition at line 318 of file pa_string.h.

References body, CORD_str(), and offset.

Referenced by detect_charset(), String::pos(), set_pos(), and trim().

size_t String::Body::pos | ( | const Body | substr,
 |  | size_t | offset = 0
 | ) | const [inline]

Definition at line 319 of file pa_string.h.

References body, CORD_str(), length(), offset, and STRING_NOT_FOUND.

size_t String::Body::pos | ( | char | c,
 |  | size_t | offset = 0
 | ) | const [inline]

Definition at line 326 of file pa_string.h.

References body, CORD_chr(), length(), offset, and STRING_NOT_FOUND.

template<typename I>
int String::Body::for_each | ( | int(* | f)(char c, I),
 |  | I | info
 | ) | const [inline]

Definition at line 334 of file pa_string.h.

References body, CORD_iter, CORD_iter_fn, and I.

Referenced by String::serialize().

template<typename I>
int String::Body::for_each | ( | int(* | f1)(char c, I),
 |  | int(* | f2)(const char *s, I),
 |  | I | info
 | ) | const [inline]

Definition at line 340 of file pa_string.h.

References body, CORD_batched_iter_fn, CORD_iter5(), CORD_iter_fn, and I.

void String::Body::set_pos | ( | CORD_pos & | pos,
 |  | size_t | index
 | ) | const [inline]

Definition at line 347 of file pa_string.h.

References body, CORD_set_pos(), and pos().

Referenced by String::cstr_to_string_body(), and trim().

String::Body String::Body::trim | ( | Trim_kind | kind = TRIM_BOTH,
 |  | const char * | chars = 0,
 |  | size_t * | out_start = 0,
 |  | size_t * | out_length = 0
 | ) | const

Returns:
this or 0 or mid. if returns this or 0 out_* are not filled.

Definition at line 169 of file pa_string.C.

References CORD_next, CORD_pos_fetch, CORD_prev, length(), mid(), pos(), set_pos(), and String::Trim_kind.

Referenced by String::trim().

Member Data Documentation

CORD String::Body::body [private]

Definition at line 257 of file pa_string.h.

Referenced by append(), append_know_length(), Body(), clear(), cstr(), cstrm(), dump(), fetch(), for_each(), hash_code(), is_empty(), length(), mid(), ncmp(), operator!=(), operator<(), operator<<(), operator<=(), operator==(), operator>(), operator>=(), pos(), set_pos(), and v().

The documentation for this class was generated from the following files:
  • pa_string.h
  • pa_string.C


Member List

String::Body Member List

This is the complete list of members for String::Body, including all inherited members.
append(char c) | String::Body | [inline]
append_know_length(const char *str, size_t known_length) | String::Body | [inline]
append_strdup_know_length(const char *str, size_t known_length) | String::Body | [inline]
Body() | String::Body | [inline]
Body(CORD abody) | String::Body | [inline]
Body(const char *str, size_t helper_length) | String::Body | [inline]
body | String::Body | [private]
clear() | String::Body | [inline]
cstr() const | String::Body | [inline]
cstrm() const | String::Body | [inline]
dump() const | String::Body |
fetch(size_t index) const | String::Body | [inline]
for_each(int(*f)(char c, I), I info) const | String::Body | [inline]
for_each(int(*f1)(char c, I), int(*f2)(const char *s, I), I info) const | String::Body | [inline]
Format(int value) | String::Body | [static]
hash_code() const | String::Body |
is_empty() const | String::Body | [inline]
length() const | String::Body | [inline]
mid(size_t index, size_t length) const | String::Body | [inline]
ncmp(size_t x_begin, const Body y, size_t y_begin, size_t size) const | String::Body | [inline]
operator!() const | String::Body | [inline]
operator!=(const Body src) const | String::Body | [inline]
operator<(const Body src) const | String::Body | [inline]
operator<<(const Body src) | String::Body | [inline]
operator<<(const char *str) | String::Body | [inline]
operator<=(const Body src) const | String::Body | [inline]
operator==(const Body src) const | String::Body | [inline]
operator>(const Body src) const | String::Body | [inline]
operator>=(const Body src) const | String::Body | [inline]
pos(const char *substr, size_t offset=0) const | String::Body | [inline]
pos(const Body substr, size_t offset=0) const | String::Body | [inline]
pos(char c, size_t offset=0) const | String::Body | [inline]
set_pos(CORD_pos &pos, size_t index) const | String::Body | [inline]
trim(Trim_kind kind=TRIM_BOTH, const char *chars=0, size_t *out_start=0, size_t *out_length=0) const | String::Body |
v() const | String::Body |


String::C Struct Reference

List of all members.

Public Methods

operator const char * ()
C ()
C (const char *astr, size_t asize)

Public Attributes

const char * | str
size_t | length

Constructor & Destructor Documentation

String::C::C ( ) [inline]

Definition at line 362 of file pa_string.h.

References length, and str.

String::C::C | ( | const char * | astr,
 |  | size_t | asize
 | ) | [inline]

Definition at line 363 of file pa_string.h.

References length, and str.

Member Function Documentation

String::C::operator const char * ( ) [inline]

Definition at line 361 of file pa_string.h.

References str.

Member Data Documentation

const char* String::C::str

Definition at line 359 of file pa_string.h.

Referenced by append_attribute_meaning(), C(), cstr_to_string_body_block(), element2case(), operator const char *(), output_sole_piece(), pa_internal_file_read_http(), store_message_element(), String::String(), text_value_to_string(), and SQL_Driver_services_impl::transcode().

size_t String::C::length

Definition at line 360 of file pa_string.h.

Referenced by append_attribute_meaning(), C(), element2case(), output_sole_piece(), pa_internal_file_read_http(), store_message_element(), String::String(), text_value_to_string(), and SQL_Driver_services_impl::transcode().

The documentation for this struct was generated from the following file:
  • pa_string.h


Member List

String::C Member List

This is the complete list of members for String::C, including all inherited members.
C() | String::C | [inline]
C(const char *astr, size_t asize) | String::C | [inline]
length | String::C |
operator const char *() | String::C | [inline]
str | String::C |


String::Cm Struct Reference

List of all members.

Public Methods

Cm ()
Cm (char *astr, size_t asize)

Public Attributes

char * | str
size_t | length

Constructor & Destructor Documentation

String::Cm::Cm ( ) [inline]

Definition at line 370 of file pa_string.h.

References length, and str.

String::Cm::Cm | ( | char * | astr,
 |  | size_t | asize
 | ) | [inline]

Definition at line 371 of file pa_string.h.

References length, and str.

Member Data Documentation

char* String::Cm::str

Definition at line 367 of file pa_string.h.

Referenced by Cm(), locked_process_and_cache_put_action(), and String::serialize().

size_t String::Cm::length

Definition at line 368 of file pa_string.h.

Referenced by Cm(), and locked_process_and_cache_put_action().

The documentation for this struct was generated from the following file:
  • pa_string.h


Member List

String::Cm Member List

This is the complete list of members for String::Cm, including all inherited members.
Cm() | String::Cm | [inline]
Cm(char *astr, size_t asize) | String::Cm | [inline]
length | String::Cm |
str | String::Cm |


String::Languages Union Reference

List of all members.

Public Methods

template<typename C> CORD | make_langs (C current) const
CORD | make_langs (size_t aoffset, size_t alength) const
template<typename C> void | append (C current, const CORD to_nonempty_target_langs)
appending when 'langs' already contain something [simple cases handled elsewhere]. More...

const char * | v () const
void | dump () const
Languages ()
Languages (Language alang)
template<typename C> void | append (C current, Language alang, size_t asize)
MUST be called exactly prior to modification of current [uses it's length]. More...

template<typename C> void | append (C current, size_t appending_length, const Languages src)
MUST be called exactly prior to modification of current [uses it's length]. More...

template<typename C> void | append (C current, const Languages src, size_t aoffset, size_t alength)
MUST be called exactly prior to modification of current [uses it's length]. More...

bool | check_lang (Language alang, size_t aoffset, size_t alength) const
checks if we have lang<=alang all from aoffset to aoffset+alength. More...

size_t | count () const
Returns:
count of blocks.
 More...

template<typename C, typename I> void | for_each (C current, int callback(char, size_t, I), I info) const
bool | invariant (size_t current_length) const

Public Attributes

struct {
Language lang:8
int is_not_just_lang:sizeof(CORD)*8-8
} opt
CORD langs

Constructor & Destructor Documentation

String::Languages::Languages ( ) [inline]

Definition at line 159 of file pa_string.h.

References langs.

String::Languages::Languages ( Language alang ) [inline]

Definition at line 160 of file pa_string.h.

References opt.

Member Function Documentation

template<typename C>
CORD String::Languages::make_langs ( C current ) const [inline]

Definition at line 125 of file pa_string.h.

References CORD, CORD_chars(), get_length(), langs, and opt.

Referenced by append().

CORD String::Languages::make_langs | ( | size_t | aoffset,
 |  | size_t | alength
 | ) | const [inline]

Definition at line 131 of file pa_string.h.

References CORD, CORD_chars(), CORD_substr(), langs, and opt.

template<typename C>
void String::Languages::append | ( | C | current,
 |  | const CORD | to_nonempty_target_langs
 | ) | [inline]

appending when 'langs' already contain something [simple cases handled elsewhere].

Definition at line 139 of file pa_string.h.

References assert, CORD, CORD_cat(), CORD_chars(), get_length(), langs, and opt.

Referenced by append(), String::append_know_length(), String::append_strdup(), String::append_to(), String::deserialize(), String::mid(), String::operator<<(), String::replace(), and String::trim().

const char * String::Languages::v ( ) const

Definition at line 711 of file pa_string.C.

References CORD_to_const_char_star(), langs, and opt.

Referenced by String::v().

void String::Languages::dump ( ) const

Definition at line 717 of file pa_string.C.

References CORD_dump(), langs, and opt.

Referenced by String::dump().

template<typename C>
void String::Languages::append | ( | C | current,
 |  | Language | alang,
 |  | size_t | asize
 | ) | [inline]

MUST be called exactly prior to modification of current [uses it's length].

Definition at line 167 of file pa_string.h.

References append(), assert, CORD_chars(), and opt.

template<typename C>
void String::Languages::append | ( | C | current,
 |  | size_t | appending_length,
 |  | const Languages | src
 | ) | [inline]

MUST be called exactly prior to modification of current [uses it's length].

Definition at line 185 of file pa_string.h.

References append(), assert, langs, make_langs(), and opt.

template<typename C>
void String::Languages::append | ( | C | current,
 |  | const Languages | src,
 |  | size_t | aoffset,
 |  | size_t | alength
 | ) | [inline]

MUST be called exactly prior to modification of current [uses it's length].

Definition at line 199 of file pa_string.h.

References append(), assert, CORD_substr(), langs, make_langs(), and opt.

bool String::Languages::check_lang | ( | Language | alang,
 |  | size_t | aoffset,
 |  | size_t | alength
 | ) | const [inline]

checks if we have lang<=alang all from aoffset to aoffset+alength.

Definition at line 216 of file pa_string.h.

References CORD_range_contains_chr_greater_then(), langs, and opt.

Referenced by String::pos().

size_t String::Languages::count ( ) const [inline]

Returns:
count of blocks.

Todo:
currently there can be adjucent blocks of same language. someday merge them

Definition at line 228 of file pa_string.h.

References CORD_block_count(), langs, and opt.

Referenced by String::serialize(), and String::v().

template<typename C, typename I>
void String::Languages::for_each | ( | C | current,
 |  | int callback(char, size_t, I) | ,
 |  | I | info
 | ) | const [inline]

Definition at line 237 of file pa_string.h.

References CORD_block_iter(), CORD_block_iter_fn, get_length(), I, langs, and opt.

Referenced by String::append_to(), String::cstr_to_string_body(), and String::serialize().

bool String::Languages::invariant ( size_t current_length ) const [inline]

Definition at line 246 of file pa_string.h.

References CORD_len(), langs, and opt.

Member Data Documentation

Language String::Languages::lang

Definition at line 113 of file pa_string.h.

int String::Languages::is_not_just_lang

Definition at line 114 of file pa_string.h.

struct { ... } String::Languages::opt

Referenced by append(), check_lang(), count(), dump(), for_each(), invariant(), Languages(), make_langs(), and v().

CORD String::Languages::langs

Definition at line 122 of file pa_string.h.

Referenced by append(), check_lang(), count(), dump(), for_each(), invariant(), Languages(), make_langs(), and v().

The documentation for this union was generated from the following files:
  • pa_string.h
  • pa_string.C


Member List

String::Languages Member List

This is the complete list of members for String::Languages, including all inherited members.
append(C current, const CORD to_nonempty_target_langs) | String::Languages | [inline]
append(C current, Language alang, size_t asize) | String::Languages | [inline]
append(C current, size_t appending_length, const Languages src) | String::Languages | [inline]
append(C current, const Languages src, size_t aoffset, size_t alength) | String::Languages | [inline]
check_lang(Language alang, size_t aoffset, size_t alength) const | String::Languages | [inline]
count() const | String::Languages | [inline]
dump() const | String::Languages |
for_each(C current, int callback(char, size_t, I), I info) const | String::Languages | [inline]
invariant(size_t current_length) const | String::Languages | [inline]
is_not_just_lang | String::Languages |
lang | String::Languages |
langs | String::Languages |
Languages() | String::Languages | [inline]
Languages(Language alang) | String::Languages | [inline]
make_langs(C current) const | String::Languages | [inline]
make_langs(size_t aoffset, size_t alength) const | String::Languages | [inline]
opt | String::Languages |
v() const | String::Languages |


String_match_table_template_columns Class Reference

Inheritance diagram for String_match_table_template_columns:

[legend]
Collaboration diagram for String_match_table_template_columns:

[legend]
List of all members.

Public Methods

String_match_table_template_columns ()

Constructor & Destructor Documentation

String_match_table_template_columns::String_match_table_template_columns ( ) [inline]

Definition at line 149 of file pa_string.C.

References String::Body::Format(), String::L_CLEAN, and MAX_MATCH_GROUPS.

The documentation for this class was generated from the following file:
  • pa_string.C


Member List

String_match_table_template_columns Member List

This is the complete list of members for String_match_table_template_columns, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< const String * > | [inline]
Array(size_t initial=3) | Array< const String * > | [inline]
count() const | Array< const String * > | [inline]
element_type typedef | Array< const String * > |
expand(size_t delta) | Array< const String * > | [inline, protected]
fallocated | Array< const String * > | [protected]
felements | Array< const String * > | [protected]
first_that(bool(*callback)(const String *, I), I info) const | Array< const String * > | [inline]
for_each(void(*callback)(const String *, I), I info) const | Array< const String * > | [inline]
for_each_ref(void(*callback)(const String *&, I), I info) | Array< const String * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fused | Array< const String * > | [protected]
get(size_t index) const | Array< const String * > | [inline]
get_ref(size_t index) const | Array< const String * > | [inline]
is_full() | Array< const String * > | [inline, protected]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(const String *src) | Array< const String * > | [inline]
operator[](size_t index) const | Array< const String * > | [inline]
put(size_t index, const String *element) | Array< const String * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
String_match_table_template_columns() | String_match_table_template_columns | [inline]


StringOrValue Class Reference

Collaboration diagram for StringOrValue:

[legend]
List of all members.

Public Methods

StringOrValue ()
StringOrValue (const String &astring)
anticipating either String or Value [must not be 0&0]. More...

StringOrValue (Value &avalue)
void | set_string (const String &astring)
void | set_value (Value &avalue)
const String * | get_string ()
Value * get_value ()
Value & | as_value () const
const String & | as_string () const

Private Attributes

const String * | fstring
Value * fvalue

Constructor & Destructor Documentation

StringOrValue::StringOrValue ( ) [inline]

Definition at line 21 of file pa_wcontext.h.

References fstring, and fvalue.

StringOrValue::StringOrValue ( const String & astring ) [inline]

anticipating either String or Value [must not be 0&0].

Definition at line 23 of file pa_wcontext.h.

References fstring, and fvalue.

StringOrValue::StringOrValue ( Value & avalue ) [inline]

Definition at line 24 of file pa_wcontext.h.

References fstring, and fvalue.

Member Function Documentation

void StringOrValue::set_string ( const String & astring ) [inline]

Definition at line 26 of file pa_wcontext.h.

References fstring.

Referenced by Request::process().

void StringOrValue::set_value ( Value & avalue ) [inline]

Definition at line 27 of file pa_wcontext.h.

References fvalue.

const String* StringOrValue::get_string ( ) [inline]

Definition at line 28 of file pa_wcontext.h.

References fstring.

Referenced by _for(), _menu(), _while(), and one_foreach_cycle().

Value* StringOrValue::get_value ( ) [inline]

Definition at line 29 of file pa_wcontext.h.

References fvalue.

Value& StringOrValue::as_value ( ) const [inline]

Definition at line 30 of file pa_wcontext.h.

References fstring, fvalue, and result.

Referenced by Request::core(), Request::execute(), and Request::process_to_value().

const String& StringOrValue::as_string ( ) const [inline]

Definition at line 34 of file pa_wcontext.h.

References Value::as_string(), fstring, and fvalue.

Referenced by Request::core(), Request::execute_method(), and table_row_to_hash().

Member Data Documentation

const String* StringOrValue::fstring [private]

Definition at line 38 of file pa_wcontext.h.

Referenced by as_string(), as_value(), get_string(), set_string(), and StringOrValue().

Value* StringOrValue::fvalue [private]

Definition at line 39 of file pa_wcontext.h.

Referenced by as_string(), as_value(), get_value(), set_value(), and StringOrValue().

The documentation for this class was generated from the following file:
  • pa_wcontext.h


Member List

StringOrValue Member List

This is the complete list of members for StringOrValue, including all inherited members.
as_string() const | StringOrValue | [inline]
as_value() const | StringOrValue | [inline]
fstring | StringOrValue | [private]
fvalue | StringOrValue | [private]
get_string() | StringOrValue | [inline]
get_value() | StringOrValue | [inline]
set_string(const String &astring) | StringOrValue | [inline]
set_value(Value &avalue) | StringOrValue | [inline]
StringOrValue() | StringOrValue | [inline]
StringOrValue(const String &astring) | StringOrValue | [inline]
StringOrValue(Value &avalue) | StringOrValue | [inline]


Stylesheet_connection Class Reference

Connection with stylesheet: remembers time and can figure out that it needs recompilation. More...

Inheritance diagram for Stylesheet_connection:

[legend]
Collaboration diagram for Stylesheet_connection:

[legend]
List of all members.

Public Methods

Stylesheet_connection (String::Body afile_spec)
String::Body file_spec ()
bool | uncachable ()
bool | expired (time_t older_dies)
time_t | get_time_used ()
void | disconnect ()
bool | connected ()
xsltStylesheet * | stylesheet ()

Private Methods

void | close ()
return to cache. More...

time_t | get_new_disk_time ()
void | load (time_t new_disk_time)
time_t | get_disk_time ()
void | use ()
void | unuse ()

Private Attributes

String::Body ffile_spec
xsltStylesheet * | fstylesheet
HashStringBool * dependencies
time_t | time_used
time_t | prev_disk_time
int | used

Friends

class | Stylesheet_connection_ptr

Detailed Description

Connection with stylesheet: remembers time and can figure out that it needs recompilation.

Definition at line 27 of file pa_stylesheet_connection.h.

Constructor & Destructor Documentation

Stylesheet_connection::Stylesheet_connection ( String::Body afile_spec ) [inline]

Definition at line 41 of file pa_stylesheet_connection.h.

References fstylesheet, prev_disk_time, time_used, and used.

Member Function Documentation

String::Body Stylesheet_connection::file_spec ( ) [inline]

Definition at line 50 of file pa_stylesheet_connection.h.

bool Stylesheet_connection::uncachable ( ) [inline]

Definition at line 52 of file pa_stylesheet_connection.h.

Referenced by expired(), and stylesheet().

bool Stylesheet_connection::expired ( time_t older_dies ) [inline]

Definition at line 56 of file pa_stylesheet_connection.h.

References time_used, uncachable(), and used.

time_t Stylesheet_connection::get_time_used ( ) [inline]

Definition at line 59 of file pa_stylesheet_connection.h.

References time_used.

void Stylesheet_connection::disconnect ( ) [inline]

Definition at line 61 of file pa_stylesheet_connection.h.

References fstylesheet.

bool Stylesheet_connection::connected ( ) [inline]

Definition at line 65 of file pa_stylesheet_connection.h.

References fstylesheet.

xsltStylesheet* Stylesheet_connection::stylesheet ( ) [inline]

Definition at line 67 of file pa_stylesheet_connection.h.

References fstylesheet, get_new_disk_time(), load(), and uncachable().

void Stylesheet_connection::close ( ) [private]

return to cache.

Referenced by unuse().

time_t Stylesheet_connection::get_new_disk_time ( ) [inline, private]

Definition at line 81 of file pa_stylesheet_connection.h.

References get_disk_time(), and prev_disk_time.

Referenced by stylesheet().

void Stylesheet_connection::load ( time_t new_disk_time ) [private]

Referenced by stylesheet().

time_t Stylesheet_connection::get_disk_time ( ) [private]

Referenced by get_new_disk_time().

void Stylesheet_connection::use ( ) [inline, private]

Definition at line 92 of file pa_stylesheet_connection.h.

References time_used, and used.

Referenced by Stylesheet_connection_ptr::operator=(), and Stylesheet_connection_ptr::Stylesheet_connection_ptr().

void Stylesheet_connection::unuse ( ) [inline, private]

Definition at line 96 of file pa_stylesheet_connection.h.

References close(), and used.

Referenced by Stylesheet_connection_ptr::operator=(), and Stylesheet_connection_ptr::~Stylesheet_connection_ptr().

Friends And Related Function Documentation

friend class Stylesheet_connection_ptr [friend]

Definition at line 29 of file pa_stylesheet_connection.h.

Member Data Documentation

String::Body Stylesheet_connection::ffile_spec [private]

Definition at line 33 of file pa_stylesheet_connection.h.

xsltStylesheet* Stylesheet_connection::fstylesheet [private]

Definition at line 34 of file pa_stylesheet_connection.h.

Referenced by connected(), disconnect(), stylesheet(), and Stylesheet_connection().

HashStringBool* Stylesheet_connection::dependencies [private]

Definition at line 35 of file pa_stylesheet_connection.h.

time_t Stylesheet_connection::time_used [private]

Definition at line 36 of file pa_stylesheet_connection.h.

Referenced by expired(), get_time_used(), Stylesheet_connection(), and use().

time_t Stylesheet_connection::prev_disk_time [private]

Definition at line 37 of file pa_stylesheet_connection.h.

Referenced by get_new_disk_time(), and Stylesheet_connection().

int Stylesheet_connection::used [private]

Definition at line 91 of file pa_stylesheet_connection.h.

Referenced by expired(), Stylesheet_connection(), unuse(), and use().

The documentation for this class was generated from the following file:
  • pa_stylesheet_connection.h


Member List

Stylesheet_connection Member List

This is the complete list of members for Stylesheet_connection, including all inherited members.
close() | Stylesheet_connection | [private]
connected() | Stylesheet_connection | [inline]
dependencies | Stylesheet_connection | [private]
disconnect() | Stylesheet_connection | [inline]
expired(time_t older_dies) | Stylesheet_connection | [inline]
ffile_spec | Stylesheet_connection | [private]
file_spec() | Stylesheet_connection | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fstylesheet | Stylesheet_connection | [private]
get_disk_time() | Stylesheet_connection | [private]
get_new_disk_time() | Stylesheet_connection | [inline, private]
get_time_used() | Stylesheet_connection | [inline]
load(time_t new_disk_time) | Stylesheet_connection | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
prev_disk_time | Stylesheet_connection | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
stylesheet() | Stylesheet_connection | [inline]
Stylesheet_connection(String::Body afile_spec) | Stylesheet_connection | [inline]
Stylesheet_connection_ptr class | Stylesheet_connection | [friend]
time_used | Stylesheet_connection | [private]
uncachable() | Stylesheet_connection | [inline]
unuse() | Stylesheet_connection | [inline, private]
use() | Stylesheet_connection | [inline, private]
used | Stylesheet_connection | [private]


Stylesheet_connection_ptr Class Reference

Auto-object used to track Stylesheet_connection usage. More...

Collaboration diagram for Stylesheet_connection_ptr:

[legend]
List of all members.

Public Methods

Stylesheet_connection_ptr (Stylesheet_connection *aconnection)
~Stylesheet_connection_ptr ()
Stylesheet_connection * operator-> ()
Stylesheet_connection_ptr (const Stylesheet_connection_ptr &src)
Stylesheet_connection_ptr & operator= (const Stylesheet_connection_ptr &src)

Private Attributes

Stylesheet_connection * fconnection

Detailed Description

Auto-object used to track Stylesheet_connection usage.

Definition at line 105 of file pa_stylesheet_connection.h.

Constructor & Destructor Documentation

Stylesheet_connection_ptr::Stylesheet_connection_ptr ( Stylesheet_connection * aconnection ) [inline, explicit]

Definition at line 108 of file pa_stylesheet_connection.h.

References Stylesheet_connection::use().

Stylesheet_connection_ptr::~Stylesheet_connection_ptr ( ) [inline]

Definition at line 112 of file pa_stylesheet_connection.h.

References Stylesheet_connection::unuse().

Stylesheet_connection_ptr::Stylesheet_connection_ptr ( const Stylesheet_connection_ptr & src ) [inline]

Definition at line 123 of file pa_stylesheet_connection.h.

References Stylesheet_connection::use().

Member Function Documentation

Stylesheet_connection* Stylesheet_connection_ptr::operator-> ( ) [inline]

Definition at line 115 of file pa_stylesheet_connection.h.

Stylesheet_connection_ptr& Stylesheet_connection_ptr::operator= ( const Stylesheet_connection_ptr & src ) [inline]

Definition at line 126 of file pa_stylesheet_connection.h.

References fconnection, Stylesheet_connection::unuse(), and Stylesheet_connection::use().

Member Data Documentation

Stylesheet_connection* Stylesheet_connection_ptr::fconnection [private]

Definition at line 106 of file pa_stylesheet_connection.h.

Referenced by operator=().

The documentation for this class was generated from the following file:
  • pa_stylesheet_connection.h


Member List

Stylesheet_connection_ptr Member List

This is the complete list of members for Stylesheet_connection_ptr, including all inherited members.
fconnection | Stylesheet_connection_ptr | [private]
operator->() | Stylesheet_connection_ptr | [inline]
operator=(const Stylesheet_connection_ptr &src) | Stylesheet_connection_ptr | [inline]
Stylesheet_connection_ptr(Stylesheet_connection *aconnection) | Stylesheet_connection_ptr | [inline, explicit]
Stylesheet_connection_ptr(const Stylesheet_connection_ptr &src) | Stylesheet_connection_ptr | [inline]
~Stylesheet_connection_ptr() | Stylesheet_connection_ptr | [inline]


Stylesheet_manager Class Reference

XSLT stylesheet driver manager maintains stylesheet cache expiring unused stylesheets. More...

Inheritance diagram for Stylesheet_manager:

[legend]
Collaboration diagram for Stylesheet_manager:

[legend]
List of all members.

Public Types

typedef Stack< Stylesheet_connection * > | connection_cache_value_type
typedef Hash< const String::Body,
connection_cache_value_type * > 		connection_cache_type

Public Methods

Stylesheet_manager ()
override | ~Stylesheet_manager ()
Stylesheet_connection_ptr | get_connection (String::Body file_spec)
check for disk update of "{file_spec}" or "{file_spec}.stamp", if not updated return cached version[if any] otherwise load/compile/return. More...

override Value * | get_status ()
if filter_server_id not null, returns status only Cachable -s with matching cacheable_item_server_id(). More...

override void | maybe_expire_cache ()

Private Methods

Stylesheet_connection * | get_connection_from_cache (String::Body file_spec)
void | put_connection_to_cache (String::Body file_spec, Stylesheet_connection &connection)
void | close_connection (String::Body file_spec, Stylesheet_connection &connection)
caches connection. More...

Private Attributes

time_t | prev_expiration_pass_time
connection_cache_type connection_cache

Friends

class | Stylesheet_connection

Detailed Description

XSLT stylesheet driver manager maintains stylesheet cache expiring unused stylesheets.

Definition at line 26 of file pa_stylesheet_manager.h.

Member Typedef Documentation

typedef Stack<Stylesheet_connection*> Stylesheet_manager::connection_cache_value_type

Definition at line 51 of file pa_stylesheet_manager.h.

typedef Hash<const String::Body, connection_cache_value_type*> Stylesheet_manager::connection_cache_type

Definition at line 52 of file pa_stylesheet_manager.h.

Constructor & Destructor Documentation

Stylesheet_manager::Stylesheet_manager ( )

override Stylesheet_manager::~Stylesheet_manager ( )

Member Function Documentation

Stylesheet_connection_ptr Stylesheet_manager::get_connection ( String::Body file_spec )

check for disk update of "{file_spec}" or "{file_spec}.stamp", if not updated return cached version[if any] otherwise load/compile/return.

Stylesheet_connection* Stylesheet_manager::get_connection_from_cache ( String::Body file_spec ) [private]

void Stylesheet_manager::put_connection_to_cache | ( | String::Body | file_spec,
 |  | Stylesheet_connection & | connection
 | ) | [private]

void Stylesheet_manager::close_connection | ( | String::Body | file_spec,
 |  | Stylesheet_connection & | connection
 | ) | [private]

caches connection.

override Value* Stylesheet_manager::get_status ( ) [virtual]

if filter_server_id not null, returns status only Cachable -s with matching cacheable_item_server_id().

Implements Cache_manager.

override void Stylesheet_manager::maybe_expire_cache ( ) [virtual]

Reimplemented from Cache_manager.

Friends And Related Function Documentation

friend class Stylesheet_connection [friend]

Definition at line 27 of file pa_stylesheet_manager.h.

Member Data Documentation

time_t Stylesheet_manager::prev_expiration_pass_time [private]

Definition at line 43 of file pa_stylesheet_manager.h.

connection_cache_type Stylesheet_manager::connection_cache [private]

Definition at line 54 of file pa_stylesheet_manager.h.

The documentation for this class was generated from the following file:
  • pa_stylesheet_manager.h


Member List

Stylesheet_manager Member List

This is the complete list of members for Stylesheet_manager, including all inherited members.
close_connection(String::Body file_spec, Stylesheet_connection &connection) | Stylesheet_manager | [private]
connection_cache | Stylesheet_manager | [private]
connection_cache_type typedef | Stylesheet_manager |
connection_cache_value_type typedef | Stylesheet_manager |
free(void *ptr) | PA_Allocated | [inline, static]
get_connection(String::Body file_spec) | Stylesheet_manager |
get_connection_from_cache(String::Body file_spec) | Stylesheet_manager | [private]
get_status() | Stylesheet_manager | [virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_expire_cache() | Stylesheet_manager | [virtual]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
prev_expiration_pass_time | Stylesheet_manager | [private]
put_connection_to_cache(String::Body file_spec, Stylesheet_connection &connection) | Stylesheet_manager | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
Stylesheet_connection class | Stylesheet_manager | [friend]
Stylesheet_manager() | Stylesheet_manager |
~Cache_manager() | Cache_manager | [inline, virtual]
~Stylesheet_manager() | Stylesheet_manager |


substr_args Struct Reference

Collaboration diagram for substr_args:

[legend]
List of all members.

Public Attributes

CordRep * sa_cord
size_t sa_index

Member Data Documentation

CordRep* substr_args::sa_cord

Definition at line 331 of file cordbscs.c.

Referenced by CORD_apply_access_fn(), CORD_block_iter(), CORD_index_access_fn(), CORD_substr_checked(), and CORD_substr_closure().

size_t substr_args::sa_index

Definition at line 332 of file cordbscs.c.

Referenced by CORD_apply_access_fn(), CORD_index_access_fn(), CORD_substr_checked(), and CORD_substr_closure().

The documentation for this struct was generated from the following file:
  • cordbscs.c


Member List

substr_args Member List

This is the complete list of members for substr_args, including all inherited members.
sa_cord | substr_args
sa_index | substr_args


Table Class Reference

VTable backend. More...

Inheritance diagram for Table:

[legend]
Collaboration diagram for Table:

[legend]
List of all members.

Public Types

typedef ArrayString * | columns_type

Public Methods

Table (columns_type acolumns, size_t initial_rows=3)
Table (const Table &src, Action_options &options)
columns_type columns ()
gets column names. More...

void | set_current (size_t acurrent)
moves current pointer. More...

size_t | current () const
Returns:
current pointer.
 More...

void | offset (bool absolute, int offset)
int | column_name2index (const String &column, bool bark) const
const String * | item (size_t column)
Returns:
item from column.
 More...

const String * | item (const String &column)
Returns:
item from column. '0' if no such column.
 More...

void | save (bool nameless_save, const String &file_spec)
saves to text file. More...

template<typename I> void | table_for_each (void(*func)(Table &self, I *info), I *info, Action_options &o)
template<typename I> bool | table_first_that (bool(*func)(Table &self, I info), I info, Action_options &o)
bool | locate (int column, const String &value, Action_options &options)
bool | locate (const String &column, const String &value, Action_options &options)

Private Types

typedef Hash< const String::Body,
int > 		name2number_hash_class
column name->number lookup table. More...

Private Methods

bool | valid (size_t index) const
is that index falid? More...

Private Attributes

size_t | fcurrent
current row. More...

columns_type fcolumns
columns. More...

name2number_hash_class * name2number

Detailed Description

VTable backend.

holds:

  • column names[if any]
  • data rows
  • current row pointer
uses String for column names and data items

hence most of tables are "named", no need to uptimize nameless onces. rows and strings stored are read-only. once stored they can be removed, but not altered. that's handy for quick copying & co. see table:join

Definition at line 31 of file pa_table.h.

Member Typedef Documentation

typedef ArrayString* Table::columns_type

Definition at line 33 of file pa_table.h.

Referenced by _columns(), _create(), _hash(), _keys(), _list(), _load(), _sql(), VForm::AppendFormEntry(), Request::core(), VTable::fields_element(), fill_week_days(), join_named_row(), pa_internal_file_read_http(), split_horizontal(), and split_vertical().

typedef Hash<const String::Body, int> Table::name2number_hash_class [private]

column name->number lookup table.

Definition at line 131 of file pa_table.h.

Constructor & Destructor Documentation

Table::Table | ( | columns_type | acolumns,
 |  | size_t | initial_rows = 3
 | ) |

Definition at line 14 of file pa_table.C.

References fcolumns, Array_iterator< T >::has_next(), name2number, new, Array_iterator< T >::next(), and Hash< const String::Body, int >::put().

Table::Table | ( | const Table & | src,
 |  | Action_options & | options
 | ) |

Definition at line 30 of file pa_table.C.

References Array< ArrayString * >::append(), ARRAY_OPTION_LIMIT_ALL, and offset().

Member Function Documentation

columns_type Table::columns ( ) [inline]

gets column names.

Definition at line 41 of file pa_table.h.

References fcolumns.

Referenced by _columns(), _hash(), _join(), _save(), _select(), _sort(), VTable::fields_element(), and join_named_row().

void Table::set_current ( size_t acurrent ) [inline]

moves current pointer.

Definition at line 44 of file pa_table.h.

References assert, Array< ArrayString * >::count(), and fcurrent.

Referenced by _hash(), _menu(), _select(), _sort(), table_first_that(), and table_for_each().

size_t Table::current ( ) const [inline]

Returns:
current pointer.

Definition at line 50 of file pa_table.h.

References fcurrent.

Referenced by _hash(), _menu(), _offset(), _select(), get_action_options(), join_nameless_row(), table_first_that(), and table_for_each().

void Table::offset | ( | bool | absolute,
 |  | int | offset
 | ) |

Definition at line 83 of file pa_table.C.

References Array< ArrayString * >::count(), fcurrent, offset(), and offset.

Referenced by _offset(), offset(), and Table().

int Table::column_name2index | ( | const String & | column,
 |  | bool | bark
 | ) | const

Returns:
column index from column_name. '<0' if no such column if no such - 'bark'

Definition at line 40 of file pa_table.C.

References String::as_int(), Hash< const String::Body, int >::get(), name2number, and result.

Referenced by _hash(), VTable::get_element(), item(), and locate().

const String * Table::item ( size_t column )

Returns:
item from column.

Definition at line 52 of file pa_table.C.

References Array< ArrayString * >::element_type, fcurrent, Array< ArrayString * >::get(), and valid().

Referenced by SQL_Driver_manager::get_connection(), VTable::get_element(), item(), join_named_row(), locate_int_string(), and Request::mime_type_of().

const String* Table::item ( const String & column ) [inline]

Returns:
item from column. '0' if no such column.

Definition at line 62 of file pa_table.h.

References column_name2index(), and item().

void Table::save | ( | bool | nameless_save,
 |  | const String & | file_spec
 | ) |

saves to text file.

template<typename I>
void Table::table_for_each | ( | void(* | func)(Table &self, I *info),
 |  | I * | info,
 |  | Action_options & | o
 | ) | [inline]

Definition at line 71 of file pa_table.h.

References Array< ArrayString * >::count(), current(), func, I, and set_current().

Referenced by _join().

template<typename I>
bool Table::table_first_that | ( | bool(* | func)(Table &self, I info),
 |  | I | info,
 |  | Action_options & | o
 | ) | [inline]

Definition at line 92 of file pa_table.h.

References Array< ArrayString * >::count(), current(), func, I, and set_current().

Referenced by _locate_expression(), and locate().

bool Table::locate | ( | int | column,
 |  | const String & | value,
 |  | Action_options & | options
 | ) |

Definition at line 72 of file pa_table.C.

References locate_int_string(), table_first_that(), and value.

Referenced by _locate_name_value(), SQL_Driver_manager::get_connection(), locate(), and Request::mime_type_of().

bool Table::locate | ( | const String & | column,
 |  | const String & | value,
 |  | Action_options & | options
 | ) |

Definition at line 78 of file pa_table.C.

References column_name2index(), locate(), and value.

bool Table::valid ( size_t index ) const [inline, private]

is that index falid?

Definition at line 135 of file pa_table.h.

References Array< ArrayString * >::count().

Referenced by item().

Member Data Documentation

size_t Table::fcurrent [private]

current row.

Definition at line 125 of file pa_table.h.

Referenced by current(), item(), offset(), and set_current().

columns_type Table::fcolumns [private]

columns.

Definition at line 128 of file pa_table.h.

Referenced by columns(), and Table().

name2number_hash_class* Table::name2number [private]

Definition at line 132 of file pa_table.h.

Referenced by column_name2index(), and Table().

The documentation for this class was generated from the following files:
  • pa_table.h
  • pa_table.C


Member List

Table Member List

This is the complete list of members for Table, including all inherited members.
append(const Array &src, size_t offset=0, size_t limit=ARRAY_OPTION_LIMIT_ALL, bool reverse=false) | Array< ArrayString * > | [inline]
Array(size_t initial=3) | Array< ArrayString * > | [inline]
column_name2index(const String &column, bool bark) const | Table |
columns() | Table | [inline]
columns_type typedef | Table |
count() const | Array< ArrayString * > | [inline]
current() const | Table | [inline]
element_type typedef | Array< ArrayString * > |
expand(size_t delta) | Array< ArrayString * > | [inline, protected]
fallocated | Array< ArrayString * > | [protected]
fcolumns | Table | [private]
fcurrent | Table | [private]
felements | Array< ArrayString * > | [protected]
first_that(bool(*callback)(ArrayString *, I), I info) const | Array< ArrayString * > | [inline]
for_each(void(*callback)(ArrayString *, I), I info) const | Array< ArrayString * > | [inline]
for_each_ref(void(*callback)(ArrayString *&, I), I info) | Array< ArrayString * > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
fused | Array< ArrayString * > | [protected]
get(size_t index) const | Array< ArrayString * > | [inline]
get_ref(size_t index) const | Array< ArrayString * > | [inline]
is_full() | Array< ArrayString * > | [inline, protected]
item(size_t column) | Table |
item(const String &column) | Table | [inline]
locate(int column, const String &value, Action_options &options) | Table |
locate(const String &column, const String &value, Action_options &options) | Table |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name2number | Table | [private]
name2number_hash_class typedef | Table | [private]
offset(bool absolute, int offset) | Table |
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
operator+=(ArrayString *src) | Array< ArrayString * > | [inline]
operator[](size_t index) const | Array< ArrayString * > | [inline]
put(size_t index, ArrayString *element) | Array< ArrayString * > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
save(bool nameless_save, const String &file_spec) | Table |
set_current(size_t acurrent) | Table | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
Table(columns_type acolumns, size_t initial_rows=3) | Table |
Table(const Table &src, Action_options &options) | Table |
table_first_that(bool(*func)(Table &self, I info), I info, Action_options &o) | Table | [inline]
table_for_each(void(*func)(Table &self, I *info), I *info, Action_options &o) | Table | [inline]
valid(size_t index) const | Table | [inline, private]


TableSeparators Struct Reference

Collaboration diagram for TableSeparators:

[legend]
List of all members.

Public Methods

TableSeparators ()
int | load (HashStringValue &options)

Public Attributes

char | column
const String * | scolumn
char | encloser
const String * | sencloser

Constructor & Destructor Documentation

TableSeparators::TableSeparators ( ) [inline]

Definition at line 266 of file table.C.

References column, encloser, and new.

Member Function Documentation

int TableSeparators::load ( HashStringValue & options ) [inline]

Definition at line 270 of file table.C.

References Value::as_string(), column, encloser, String::first_char(), Hash< const String::Body, Value * >::get(), String::length(), PA_COLUMN_ENCLOSER_NAME, PA_COLUMN_SEPARATOR_NAME, and result.

Referenced by _load(), and _save().

Member Data Documentation

char TableSeparators::column

Definition at line 263 of file table.C.

Referenced by _load(), _save(), load(), and TableSeparators().

const String* TableSeparators::scolumn

Definition at line 263 of file table.C.

Referenced by _save().

char TableSeparators::encloser

Definition at line 264 of file table.C.

Referenced by _load(), _save(), load(), and TableSeparators().

const String* TableSeparators::sencloser

Definition at line 264 of file table.C.

Referenced by _save().

The documentation for this struct was generated from the following file:
  • table.C


Member List

TableSeparators Member List

This is the complete list of members for TableSeparators, including all inherited members.
column | TableSeparators |
encloser | TableSeparators |
load(HashStringValue &options) | TableSeparators | [inline]
scolumn | TableSeparators |
sencloser | TableSeparators |
TableSeparators() | TableSeparators | [inline]


Temp_client_charset Class Reference

Collaboration diagram for Temp_client_charset:

[legend]
List of all members.

Public Methods

Temp_client_charset (Request_charsets &acharsets, Charset &aclient)
~Temp_client_charset ()

Private Attributes

Request_charsets & fcharsets
Charset & fclient

Constructor & Destructor Documentation

Temp_client_charset::Temp_client_charset | ( | Request_charsets & | acharsets,
 |  | Charset & | aclient
 | ) | [inline]

Definition at line 38 of file pa_request_charsets.h.

References Request_charsets::set_client().

Temp_client_charset::~Temp_client_charset ( ) [inline]

Definition at line 43 of file pa_request_charsets.h.

References Request_charsets::set_client().

Member Data Documentation

Request_charsets& Temp_client_charset::fcharsets [private]

Definition at line 34 of file pa_request_charsets.h.

Charset& Temp_client_charset::fclient [private]

Definition at line 35 of file pa_request_charsets.h.

The documentation for this class was generated from the following file:
  • pa_request_charsets.h


Member List

Temp_client_charset Member List

This is the complete list of members for Temp_client_charset, including all inherited members.
fcharsets | Temp_client_charset | [private]
fclient | Temp_client_charset | [private]
Temp_client_charset(Request_charsets &acharsets, Charset &aclient) | Temp_client_charset | [inline]
~Temp_client_charset() | Temp_client_charset | [inline]


Temp_connection Class Reference

Auto-object used for temporary changing Request::fconnection. More...

Collaboration diagram for Temp_connection:

[legend]
List of all members.

Public Methods

Temp_connection (Request &arequest, SQL_Connection *aconnection)
~Temp_connection ()

Private Attributes

Request & frequest
SQL_Connection * saved_connection

Detailed Description

Auto-object used for temporary changing Request::fconnection.

Definition at line 483 of file pa_request.h.

Constructor & Destructor Documentation

Temp_connection::Temp_connection | ( | Request & | arequest,
 |  | SQL_Connection * | aconnection
 | ) | [inline]

Definition at line 487 of file pa_request.h.

Temp_connection::~Temp_connection ( ) [inline]

Definition at line 491 of file pa_request.h.

References Request::restore_connection().

Member Data Documentation

Request& Temp_connection::frequest [private]

Definition at line 484 of file pa_request.h.

SQL_Connection* Temp_connection::saved_connection [private]

Definition at line 485 of file pa_request.h.

The documentation for this class was generated from the following file:
  • pa_request.h


Member List

Temp_connection Member List

This is the complete list of members for Temp_connection, including all inherited members.
frequest | Temp_connection | [private]
saved_connection | Temp_connection | [private]
Temp_connection(Request &arequest, SQL_Connection *aconnection) | Temp_connection | [inline]
~Temp_connection() | Temp_connection | [inline]


Temp_derived Class Reference

Collaboration diagram for Temp_derived:

[legend]
List of all members.

Public Methods

Temp_derived (Value &avalue, VObject *aderived)
~Temp_derived ()

Private Attributes

Value & fvalue
VObject * fsaved_derived

Constructor & Destructor Documentation

Temp_derived::Temp_derived | ( | Value & | avalue,
 |  | VObject * | aderived
 | ) | [inline]

Definition at line 101 of file pa_vobject.h.

Temp_derived::~Temp_derived ( ) [inline]

Definition at line 104 of file pa_vobject.h.

References Value::set_derived().

Member Data Documentation

Value& Temp_derived::fvalue [private]

Definition at line 98 of file pa_vobject.h.

VObject* Temp_derived::fsaved_derived [private]

Definition at line 99 of file pa_vobject.h.

The documentation for this class was generated from the following file:
  • pa_vobject.h


Member List

Temp_derived Member List

This is the complete list of members for Temp_derived, including all inherited members.
fsaved_derived | Temp_derived | [private]
fvalue | Temp_derived | [private]
Temp_derived(Value &avalue, VObject *aderived) | Temp_derived | [inline]
~Temp_derived() | Temp_derived | [inline]


TemplateTemp_hash_value class Reference

Temp_hash_value< K, V > Class Template Reference

Auto-object used to temporarily substituting/removing hash values. More...

Collaboration diagram for Temp_hash_value< K, V >:

[legend]
List of all members.

Public Methods

Temp_hash_value (Hash< K, V > &ahash, K aname, V avalue)
~Temp_hash_value ()

Private Attributes

Hash< K, V > & | fhash
K | fname
V | saved_value

Detailed Description

template<typename K, typename V>
class Temp_hash_value< K, V >

Auto-object used to temporarily substituting/removing hash values.

Definition at line 472 of file pa_hash.h.

Constructor & Destructor Documentation

template<typename K, typename V>
Temp_hash_value< K, V >::Temp_hash_value | ( | Hash< K, V > & | ahash,
 |  | K | aname,
 |  | V | avalue
 | ) | [inline]

Definition at line 477 of file pa_hash.h.

References Temp_hash_value< K, V >::fname, Hash< K, V >::put(), and Temp_hash_value< K, V >::saved_value.

template<typename K, typename V>
Temp_hash_value< K, V >::~Temp_hash_value ( ) [inline]

Definition at line 483 of file pa_hash.h.

References Temp_hash_value< K, V >::fname, Hash< K, V >::put(), and Temp_hash_value< K, V >::saved_value.

Member Data Documentation

template<typename K, typename V>
Hash<K, V>& Temp_hash_value< K, V >::fhash [private]

Definition at line 473 of file pa_hash.h.

template<typename K, typename V>
K Temp_hash_value< K, V >::fname [private]

Definition at line 474 of file pa_hash.h.

Referenced by Temp_hash_value< K, V >::Temp_hash_value(), and Temp_hash_value< K, V >::~Temp_hash_value().

template<typename K, typename V>
V Temp_hash_value< K, V >::saved_value [private]

Definition at line 475 of file pa_hash.h.

Referenced by Temp_hash_value< K, V >::Temp_hash_value(), and Temp_hash_value< K, V >::~Temp_hash_value().

The documentation for this class was generated from the following file:
  • pa_hash.h


Member List

Temp_hash_value< K, V > Member List

This is the complete list of members for Temp_hash_value< K, V >, including all inherited members.
fhash | Temp_hash_value< K, V > | [private]
fname | Temp_hash_value< K, V > | [private]
saved_value | Temp_hash_value< K, V > | [private]
Temp_hash_value(Hash< K, V > &ahash, K aname, V avalue) | Temp_hash_value< K, V > | [inline]
~Temp_hash_value() | Temp_hash_value< K, V > | [inline]


Temp_lang Class Reference

Auto-object used for temporary changing Request::flang. More...

Collaboration diagram for Temp_lang:

[legend]
List of all members.

Public Methods

Temp_lang (Request &arequest, String::Language alang)
~Temp_lang ()

Private Attributes

Request & frequest
String::Language saved_lang

Detailed Description

Auto-object used for temporary changing Request::flang.

Definition at line 469 of file pa_request.h.

Constructor & Destructor Documentation

Temp_lang::Temp_lang | ( | Request & | arequest,
 |  | String::Language | alang
 | ) | [inline]

Definition at line 473 of file pa_request.h.

References String::Language, and saved_lang.

Temp_lang::~Temp_lang ( ) [inline]

Definition at line 477 of file pa_request.h.

References Request::restore_lang(), and saved_lang.

Member Data Documentation

Request& Temp_lang::frequest [private]

Definition at line 470 of file pa_request.h.

String::Language Temp_lang::saved_lang [private]

Definition at line 471 of file pa_request.h.

Referenced by Temp_lang(), and ~Temp_lang().

The documentation for this class was generated from the following file:
  • pa_request.h


Member List

Temp_lang Member List

This is the complete list of members for Temp_lang, including all inherited members.
frequest | Temp_lang | [private]
saved_lang | Temp_lang | [private]
Temp_lang(Request &arequest, String::Language alang) | Temp_lang | [inline]
~Temp_lang() | Temp_lang | [inline]


Temp_method Class Reference

Auto-object used for temporarily substituting/removing class method. More...

Collaboration diagram for Temp_method:

[legend]
List of all members.

Public Methods

Temp_method (VStateless_class &aclass, const String &aname, Method *amethod)
~Temp_method ()

Private Attributes

VStateless_class & fclass
const String & fname
Method * saved_method

Detailed Description

Auto-object used for temporarily substituting/removing class method.

Definition at line 141 of file pa_vstateless_class.h.

Constructor & Destructor Documentation

Temp_method::Temp_method | ( | VStateless_class & | aclass,
 |  | const String & | aname,
 |  | Method * | amethod
 | ) | [inline]

Definition at line 146 of file pa_vstateless_class.h.

References VStateless_class::put_method().

Temp_method::~Temp_method ( ) [inline]

Definition at line 152 of file pa_vstateless_class.h.

References VStateless_class::put_method().

Member Data Documentation

VStateless_class& Temp_method::fclass [private]

Definition at line 142 of file pa_vstateless_class.h.

const String& Temp_method::fname [private]

Definition at line 143 of file pa_vstateless_class.h.

Method* Temp_method::saved_method [private]

Definition at line 144 of file pa_vstateless_class.h.

The documentation for this class was generated from the following file:
  • pa_vstateless_class.h


Member List

Temp_method Member List

This is the complete list of members for Temp_method, including all inherited members.
fclass | Temp_method | [private]
fname | Temp_method | [private]
saved_method | Temp_method | [private]
Temp_method(VStateless_class &aclass, const String &aname, Method *amethod) | Temp_method | [inline]
~Temp_method() | Temp_method | [inline]


Temp_method_frame_self Class Reference

Auto-object used for temporary changing VMethod_frame::fself. More...

Collaboration diagram for Temp_method_frame_self:

[legend]
List of all members.

Public Methods

Temp_method_frame_self (VMethodFrame &amethod_frame, Value &aself)
~Temp_method_frame_self ()

Private Attributes

VMethodFrame & fmethod_frame
Value * saved_self

Detailed Description

Auto-object used for temporary changing VMethod_frame::fself.

Definition at line 234 of file pa_vmethod_frame.h.

Constructor & Destructor Documentation

Temp_method_frame_self::Temp_method_frame_self | ( | VMethodFrame & | amethod_frame,
 |  | Value & | aself
 | ) | [inline]

Definition at line 238 of file pa_vmethod_frame.h.

References VMethodFrame::set_self().

Temp_method_frame_self::~Temp_method_frame_self ( ) [inline]

Definition at line 243 of file pa_vmethod_frame.h.

References VMethodFrame::set_self().

Member Data Documentation

VMethodFrame& Temp_method_frame_self::fmethod_frame [private]

Definition at line 235 of file pa_vmethod_frame.h.

Value* Temp_method_frame_self::saved_self [private]

Definition at line 236 of file pa_vmethod_frame.h.

The documentation for this class was generated from the following file:
  • pa_vmethod_frame.h


Member List

Temp_method_frame_self Member List

This is the complete list of members for Temp_method_frame_self, including all inherited members.
fmethod_frame | Temp_method_frame_self | [private]
saved_self | Temp_method_frame_self | [private]
Temp_method_frame_self(VMethodFrame &amethod_frame, Value &aself) | Temp_method_frame_self | [inline]
~Temp_method_frame_self() | Temp_method_frame_self | [inline]


Temp_value_element Class Reference

Auto-object used for temporarily substituting/removing elements. More...

Collaboration diagram for Temp_value_element:

[legend]
List of all members.

Public Methods

Temp_value_element (Value &awhere, const String &aname, Value *awhat)
~Temp_value_element ()

Private Attributes

Value & fwhere
const String & fname
Value * saved

Detailed Description

Auto-object used for temporarily substituting/removing elements.

Definition at line 93 of file pa_method.h.

Constructor & Destructor Documentation

Temp_value_element::Temp_value_element | ( | Value & | awhere,
 |  | const String & | aname,
 |  | Value * | awhat
 | ) | [inline]

Definition at line 98 of file pa_method.h.

References Value::put_element().

Temp_value_element::~Temp_value_element ( ) [inline]

Definition at line 104 of file pa_method.h.

References Value::put_element().

Member Data Documentation

Value& Temp_value_element::fwhere [private]

Definition at line 94 of file pa_method.h.

const String& Temp_value_element::fname [private]

Definition at line 95 of file pa_method.h.

Value* Temp_value_element::saved [private]

Definition at line 96 of file pa_method.h.

The documentation for this class was generated from the following file:
  • pa_method.h


Member List

Temp_value_element Member List

This is the complete list of members for Temp_value_element, including all inherited members.
fname | Temp_value_element | [private]
fwhere | Temp_value_element | [private]
saved | Temp_value_element | [private]
Temp_value_element(Value &awhere, const String &aname, Value *awhat) | Temp_value_element | [inline]
~Temp_value_element() | Temp_value_element | [inline]


Untaint_lang_name2enum Class Reference

Inheritance diagram for Untaint_lang_name2enum:

[legend]
Collaboration diagram for Untaint_lang_name2enum:

[legend]
List of all members.

Public Methods

Untaint_lang_name2enum ()

Constructor & Destructor Documentation

Untaint_lang_name2enum::Untaint_lang_name2enum ( ) [inline]

Definition at line 64 of file op.C.

References String::L_OPTIMIZE_BIT, and XML.

The documentation for this class was generated from the following file:
  • op.C


Member List

Untaint_lang_name2enum Member List

This is the complete list of members for Untaint_lang_name2enum, including all inherited members.
clear() | Hash< const String::Body, String::Language > | [inline]
count() const | Hash< const String::Body, String::Language > | [inline]
first_that(bool callback(const String::Body, String::Language, I), I info) const | Hash< const String::Body, String::Language > | [inline]
for_each(void callback(const String::Body, String::Language, I), I info) const | Hash< const String::Body, String::Language > | [inline]
for_each_ref(void callback(const String::Body, String::Language &, I), I info) const | Hash< const String::Body, String::Language > | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
get(const String::Body key) const | Hash< const String::Body, String::Language > | [inline]
Hash() | Hash< const String::Body, String::Language > | [inline]
Hash(const Hash &source) | Hash< const String::Body, String::Language > | [inline]
key_type typedef | Hash< const String::Body, String::Language > |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
maybe_put_replaced(const String::Body key, String::Language value, F prevent) | Hash< const String::Body, String::Language > | [inline]
maybe_replace_maybe_append(const String::Body key, String::Language value, F1 prevent_replace, F2 prevent_append, I info) | Hash< const String::Body, String::Language > | [inline]
maybe_replace_never_append(const String::Body key, String::Language value, F1 prevent_replace, I info) | Hash< const String::Body, String::Language > | [inline]
merge_dont_replace(const Hash &src) | Hash< const String::Body, String::Language > | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put(const String::Body key, String::Language value) | Hash< const String::Body, String::Language > | [inline]
put_dont_replace(const String::Body key, String::Language value) | Hash< const String::Body, String::Language > | [inline]
put_replaced(const String::Body key, String::Language value) | Hash< const String::Body, String::Language > | [inline]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
remove(const String::Body key) | Hash< const String::Body, String::Language > | [inline]
replace_maybe_append(const String::Body key, String::Language value, F prevent, I info) | Hash< const String::Body, String::Language > | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
Untaint_lang_name2enum() | Untaint_lang_name2enum | [inline]
value_type typedef | Hash< const String::Body, String::Language > |


uuid Struct Reference

to hell with extra bytes on 64bit platforms. More...

List of all members.

Public Attributes

unsigned int | time_low
unsigned short | time_mid
unsigned short | time_hi_and_version
unsigned short | clock_seq
unsigned char | node [6]

Detailed Description

to hell with extra bytes on 64bit platforms.

Definition at line 315 of file math.C.

Member Data Documentation

unsigned int uuid::time_low

Definition at line 316 of file math.C.

Referenced by _uuid().

unsigned short uuid::time_mid

Definition at line 317 of file math.C.

Referenced by _uuid().

unsigned short uuid::time_hi_and_version

Definition at line 318 of file math.C.

Referenced by _uuid().

unsigned short uuid::clock_seq

Definition at line 319 of file math.C.

Referenced by _uuid().

unsigned char uuid::node[6]

Definition at line 320 of file math.C.

Referenced by _uuid().

The documentation for this struct was generated from the following file:
  • math.C


Member List

uuid Member List

This is the complete list of members for uuid, including all inherited members.
clock_seq | uuid
node | uuid
time_hi_and_version | uuid
time_low | uuid
time_mid | uuid


Value Class Reference

grandfather of all values in Parser. More...

Inheritance diagram for Value:

[legend]
Collaboration diagram for Value:

[legend]
List of all members.

Public Methods

virtual const char * | type () const=0
value type, used for error reporting and 'is' expression operator. More...

virtual VObject * | set_derived (VObject *)
remember derived class instance - VObject: the only client. More...

virtual Value * | as (const char *atype, bool)
all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type. More...

bool | is (const char *atype)
type checking helper, uses Value::as. More...

virtual bool | is_defined () const
is this value defined? More...

virtual bool | is_string () const
is this value string? More...

virtual bool | is_void () const
is this value void? More...

virtual bool | is_evaluated_expr () const
is this value number? More...

virtual Value & | as_expr_result (bool=false)
what's the meaning of this value in context of expression? More...

virtual HashStringValue * | get_hash ()
extract HashStringValue if any WARNING: FOR LOCAL USE ONLY, THIS POINTER IS NOT TO PASS TO ANYBODY! More...

virtual const String * | get_string ()
extract const String. More...

virtual double | as_double () const
extract double. More...

virtual int | as_int () const
extract integer. More...

virtual bool | as_bool () const
extract bool. More...

virtual VFile * | as_vfile (String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0)
extract file. More...

virtual Junction * | get_junction ()
extract Junction. More...

virtual Property * | get_property ()
extract Property. More...

virtual Value * | base_object ()
extract base object of Value. More...

virtual Value * | get_element (const String &, Value &, bool)
Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.
 More...

virtual const VJunction * | put_element (Value &, const String &aname, Value *, bool)
store Value element under name
Returns:
putter method junction, or it can just report[PUT_ELEMENT_REPLACED_ELEMENT] that it replaced something in base fields.
 More...

virtual VStateless_class * | get_class ()=0
extract VStateless_class. More...

virtual VStateless_class * | get_last_derived_class ()
extract VStateless_class. More...

virtual Value * | base ()
extract base object or class of Value, if any. More...

virtual Table * | get_table ()
extract VTable. More...

const String & | as_string ()
Returns:
sure String. if it doesn't have string value barks.
 More...

Protected Methods

Value * | bark (const char *reason, const String *problem_source=0) const
throws exception specifying bark-reason and name type() of problematic value. More...

Detailed Description

grandfather of all values in Parser.

Definition at line 38 of file pa_value.h.

Member Function Documentation

virtual const char* Value::type ( ) const [pure virtual]

value type, used for error reporting and 'is' expression operator.

Implemented in VBool, VClass, VCodeFrame, VConsole, VCookie, VDate, VDouble, VEnv, VFile, VForm, VHash, VHashfile, VImage, VInt, VJunction, VMail, VMath, VMemory, VMethodFrame, VObject, VProperty, VRequest, VResponse, VStateless_class, VStatus, VString, VTable, VVoid, VXdoc, VXnode, WContext, and WWrapper.

Referenced by append_attribute_meaning(), as(), Method::check_actual_numbered_params(), Request::execute(), VMethodFrame::store_param(), and WContext::write().

VObject * Value::set_derived ( VObject * ) [virtual]

remember derived class instance - VObject: the only client.

Reimplemented in VObject.

Definition at line 26 of file pa_value.C.

Referenced by Temp_derived::~Temp_derived().

virtual Value* Value::as | ( | const char * | atype,
 |  | bool |
 | ) | [inline, virtual]

all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type.

Reimplemented in VClass, VObject, and VXdoc.

Definition at line 53 of file pa_value.h.

References type().

Referenced by _create_or_add(), append_attribute_meaning(), VObject::as(), VClass::as(), as_image(), is(), Request::output_result(), output_set_cookie_header(), and VHashfile::put_field().

bool Value::is ( const char * atype ) [inline]

type checking helper, uses Value::as.

Definition at line 57 of file pa_value.h.

References as().

Referenced by Request::execute().

virtual bool Value::is_defined ( ) const [inline, virtual]

is this value defined?

Reimplemented in VBool, VHash, VJunction, VObject, VProperty, VString, VTable, and VVoid.

Definition at line 60 of file pa_value.h.

Referenced by _sql(), Request::execute(), VObject::is_defined(), and sql_result_string().

virtual bool Value::is_string ( ) const [inline, virtual]

is this value string?

Reimplemented in VString.

Definition at line 63 of file pa_value.h.

Referenced by _case(), _hash(), _html(), _sort(), _sql(), Request::configure_admin(), MMail::configure_user(), Request::core(), get_action_options(), output_set_cookie_header(), pa_internal_file_read_http(), VCookie::put_element(), sql_result_string(), try_catch(), and Request::use_file().

virtual bool Value::is_void ( ) const [inline, virtual]

is this value void?

Reimplemented in VVoid.

Definition at line 66 of file pa_value.h.

Referenced by _case().

virtual bool Value::is_evaluated_expr ( ) const [inline, virtual]

is this value number?

Reimplemented in VBool, VDouble, and VInt.

Definition at line 69 of file pa_value.h.

Referenced by MethodParams::as_bool(), MethodParams::as_double(), and MethodParams::as_int().

virtual Value& Value::as_expr_result ( bool = false ) [inline, virtual]

what's the meaning of this value in context of expression?

Reimplemented in VBool, VClass, VDate, VDouble, VFile, VHash, VImage, VInt, VJunction, VObject, VProperty, VString, VTable, VVoid, VXdoc, and VXnode.

Definition at line 72 of file pa_value.h.

References bark().

Referenced by _eval(), _sort(), VObject::as_expr_result(), and Request::execute().

virtual HashStringValue* Value::get_hash ( ) [inline, virtual]

extract HashStringValue if any WARNING: FOR LOCAL USE ONLY, THIS POINTER IS NOT TO PASS TO ANYBODY!

Reimplemented in VHash, VHashfile, VObject, and VResponse.

Definition at line 81 of file pa_value.h.

Referenced by _create_or_add(), _exec_cgi(), _hash(), _html(), _intersection(), _intersects(), _load(), _process(), _save(), _send(), _sql(), _sub(), _union(), attributed_meaning_to_string(), Request::configure_admin(), MMail::configure_user(), VTable::fields_element(), file_value_to_string(), get_action_options(), VCookie::get_element(), VObject::get_hash(), SQL_Driver_manager::get_status(), VMail::message_hash_to_string(), Request::output_result(), output_set_cookie_header(), pa_internal_file_read_http(), VCookie::put_element(), VHashfile::put_field(), sql_result_string(), and text_value_to_string().

virtual const String* Value::get_string ( ) [inline, virtual]

extract const String.

Reimplemented in VDouble, VInt, VMethodFrame, VString, VVoid, and WContext.

Definition at line 84 of file pa_value.h.

Referenced by _hash(), _measure(), _process(), append_attribute_meaning(), Request::core(), Request::execute(), get_action_options(), VMethodFrame::get_string(), LA2S(), output_set_cookie_header(), VCookie::put_element(), try_catch(), WContext::write(), and VCodeFrame::write().

virtual double Value::as_double ( ) const [inline, virtual]

extract double.

Reimplemented in VBool, VDate, VDouble, VHash, VInt, VString, VTable, and VVoid.

Definition at line 87 of file pa_value.h.

References bark().

Referenced by _case(), _eval(), _sort(), _sql(), _string_format(), VObject::as_double(), MethodParams::as_double(), as_expires(), MForm::configure_admin(), Request::execute(), output_set_cookie_header(), VHashfile::put_field(), and sql_result_string().

virtual int Value::as_int ( ) const [inline, virtual]

extract integer.

Reimplemented in VBool, VDouble, VHash, VInt, VObject, VString, VTable, and VVoid.

Definition at line 90 of file pa_value.h.

References bark().

Referenced by _load(), _process(), _sql(), VObject::as_int(), MethodParams::as_int(), Request::execute(), get_action_options(), pa_internal_file_read_http(), and VImage::put_element().

virtual bool Value::as_bool ( ) const [inline, virtual]

extract bool.

Reimplemented in VBool, VClass, VDate, VDouble, VFile, VHash, VImage, VInt, VJunction, VObject, VProperty, VString, VTable, VVoid, VXdoc, and VXnode.

Definition at line 93 of file pa_value.h.

References bark().

Referenced by _hash(), _select(), _sql(), _while(), VObject::as_bool(), MethodParams::as_bool(), Request::core(), Request::execute(), get_action_options(), pa_internal_file_read_http(), and try_catch().

VFile * Value::as_vfile | ( | String::Language | lang = String::L_UNSPECIFIED,
 |  | const Request_charsets * | charsets = 0
 | ) | [virtual]

extract file.

Reimplemented in VFile, VHash, VObject, VString, and VVoid.

Definition at line 37 of file pa_value.C.

References bark(), and String::Language.

Referenced by _measure(), VObject::as_vfile(), Request::core(), and file_value_to_string().

Junction * Value::get_junction ( ) [virtual]

extract Junction.

Reimplemented in VJunction.

Definition at line 28 of file pa_value.C.

Referenced by _hash(), _match(), _process(), Request::core(), Request::execute(), Request::execute_virtual_method(), MethodParams::get_as(), Request::get_element(), Request::process(), VHashfile::put_field(), text_value_to_string(), and try_catch().

virtual Property* Value::get_property ( ) [inline, virtual]

extract Property.

Reimplemented in VProperty.

Definition at line 103 of file pa_value.h.

Referenced by VClass::add_property(), VClass::get_element(), and VClass::prevent_overwrite_property().

Value * Value::base_object ( ) [virtual]

extract base object of Value.

Returns:
for
  • VObject: fbase

Definition at line 30 of file pa_value.C.

References bark().

Value * Value::get_element | ( | const String & | ,
 |  | Value & | ,
 |  | bool |
 | ) | [virtual]

Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.

Reimplemented in MXnode, VClass, VCodeFrame, VConsole, VCookie, VDate, VEnv, VFile, VForm, VHash, VHashfile, VImage, VMail, VMath, VMemory, VMethodFrame, VObject, VRequest, VResponse, VStateless_class, VStateless_object, VStatus, VString, VTable, VVoid, VXdoc, VXnode, and WWrapper.

Definition at line 32 of file pa_value.C.

References bark().

Referenced by _connect(), MForm::configure_admin(), Request::execute_virtual_method(), WWrapper::get_element(), VMethodFrame::get_element(), VCodeFrame::get_element(), Request::get_element(), and try_catch().

virtual const VJunction* Value::put_element | ( | Value & | ,
 |  | const String & | aname,
 |  | Value * | ,
 |  | bool |
 | ) | [inline, virtual]

store Value element under name

Returns:
putter method junction, or it can just report[PUT_ELEMENT_REPLACED_ELEMENT] that it replaced something in base fields.

Reimplemented in VClass, VCodeFrame, VConsole, VCookie, VHash, VHashfile, VImage, VMethodFrame, VObject, VRequest, VResponse, VStateless_object, VVoid, VXnode, and WWrapper.

Definition at line 119 of file pa_value.h.

Referenced by Request::execute(), one_foreach_cycle(), VClass::prevent_append_if_exists_in_base(), WWrapper::put_element(), VVoid::put_element(), VStateless_object::put_element(), VRequest::put_element(), VMethodFrame::put_element(), VCodeFrame::put_element(), VClass::put_element(), Request::put_element(), Temp_value_element::Temp_value_element(), and Temp_value_element::~Temp_value_element().

virtual VStateless_class* Value::get_class ( ) [pure virtual]

extract VStateless_class.

Implemented in VBool, VConsole, VCookie, VDate, VDouble, VEnv, VFile, VHash, VHashfile, VImage, VInt, VJunction, VMethodFrame, VObject, VProperty, VRequest, VResponse, VStateless_class, VStatus, VString, VTable, VVoid, VXdoc, VXnode, and WContext.

Referenced by VClass::add_property(), Method::check_actual_numbered_params(), Request::execute(), WContext::get_class(), VMethodFrame::get_class(), VStateless_object::get_element(), Request::get_element(), VStateless_object::put_element(), Request::Request(), VMethodFrame::store_param(), and WContext::write().

virtual VStateless_class* Value::get_last_derived_class ( ) [inline, virtual]

extract VStateless_class.

Reimplemented in VObject.

Definition at line 131 of file pa_value.h.

Referenced by _process().

virtual Value* Value::base ( ) [inline, virtual]

extract base object or class of Value, if any.

Reimplemented in VMethodFrame, VObject, and VStateless_class.

Definition at line 135 of file pa_value.h.

Referenced by VMethodFrame::base(), VStateless_class::get_element(), Request::get_element(), VClass::prevent_append_if_exists_in_base(), and VClass::put_element().

virtual Table* Value::get_table ( ) [inline, virtual]

extract VTable.

Reimplemented in VObject, and VTable.

Definition at line 138 of file pa_value.h.

Referenced by _connect(), _hash(), _join(), _polybar(), _polygon(), _polyline(), _replace(), VForm::AppendFormEntry(), Request::configure(), VObject::get_table(), pa_internal_file_read_http(), and Request::use_file().

const String& Value::as_string ( ) [inline]

Returns:
sure String. if it doesn't have string value barks.

Definition at line 143 of file pa_value.h.

References result.

Referenced by _case(), _create(), _delete(), _eval(), _exec_cgi(), _find(), _hash(), _list(), _load(), _match(), _measure(), _move(), _pos(), _process(), _save(), _send(), _sort(), _sql(), _stat(), _taint(), _throw_operator(), _use(), StringOrValue::as_string(), MethodParams::as_string(), Request::execute(), file_value_to_string(), TableSeparators::load(), VMail::message_hash_to_string(), Request::output_result(), output_sole_piece(), pa_internal_file_read_http(), VResponse::put_element(), VRequest::put_element(), VImage::put_element(), VCookie::put_element(), VConsole::put_element(), VHashfile::put_field(), sendmail(), split_list(), Request::StackItem::string(), text_value_to_string(), and Request::use_file().

Value* Value::bark | ( | const char * | reason,
 |  | const String * | problem_source = 0
 | ) | const [inline, protected]

throws exception specifying bark-reason and name type() of problematic value.

Definition at line 154 of file pa_value.h.

References type.

Referenced by as_bool(), as_double(), as_expr_result(), as_int(), as_vfile(), base_object(), VProperty::get_class(), VString::get_element(), VRequest::get_element(), VDate::get_element(), get_element(), VProperty::is_defined(), and VTable::table().

The documentation for this class was generated from the following files:
  • pa_value.h
  • pa_value.C


Member List

Value Member List

This is the complete list of members for Value, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
get_class()=0 | Value | [pure virtual]
get_element(const String &, Value &, bool) | Value | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const=0 | Value | [pure virtual]


VBool Class Reference

VBool. More...

Inheritance diagram for VBool:

[legend]
Collaboration diagram for VBool:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
VBool: 0. More...

override bool | is_evaluated_expr () const
VBool: true. More...

override Value & | as_expr_result (bool)
VBool: clone. More...

virtual bool | is_defined () const
VBool: fbool. More...

override bool | as_bool () const
VBool: fbool. More...

override double | as_double () const
VBool: fbool. More...

override int | as_int () const
VBool: fbool. More...

VBool (bool abool)

Private Attributes

bool | fbool

Detailed Description

VBool.

Definition at line 21 of file pa_vbool.h.

Constructor & Destructor Documentation

VBool::VBool ( bool abool ) [inline]

Definition at line 42 of file pa_vbool.h.

References fbool.

Referenced by as_expr_result().

Member Function Documentation

override const char* VBool::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 24 of file pa_vbool.h.

References override.

override VStateless_class* VBool::get_class ( ) [inline, virtual]

VBool: 0.

Implements Value.

Definition at line 26 of file pa_vbool.h.

References override.

override bool VBool::is_evaluated_expr ( ) const [inline, virtual]

VBool: true.

Reimplemented from Value.

Definition at line 28 of file pa_vbool.h.

References override.

override Value& VBool::as_expr_result ( bool ) [inline, virtual]

VBool: clone.

Reimplemented from Value.

Definition at line 30 of file pa_vbool.h.

References fbool, override, and VBool().

virtual bool VBool::is_defined ( ) const [inline, virtual]

VBool: fbool.

Reimplemented from Value.

Definition at line 32 of file pa_vbool.h.

References as_bool().

override bool VBool::as_bool ( ) const [inline, virtual]

VBool: fbool.

Reimplemented from Value.

Definition at line 34 of file pa_vbool.h.

References fbool, and override.

Referenced by is_defined().

override double VBool::as_double ( ) const [inline, virtual]

VBool: fbool.

Reimplemented from Value.

Definition at line 36 of file pa_vbool.h.

References fbool, and override.

override int VBool::as_int ( ) const [inline, virtual]

VBool: fbool.

Reimplemented from Value.

Definition at line 38 of file pa_vbool.h.

References fbool, and override.

Member Data Documentation

bool VBool::fbool [private]

Definition at line 46 of file pa_vbool.h.

Referenced by as_bool(), as_double(), as_expr_result(), as_int(), and VBool().

The documentation for this class was generated from the following file:
  • pa_vbool.h


Member List

VBool Member List

This is the complete list of members for VBool, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VBool | [inline, virtual]
as_double() const | VBool | [inline, virtual]
as_expr_result(bool) | VBool | [inline, virtual]
as_int() const | VBool | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fbool | VBool | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VBool | [inline, virtual]
get_element(const String &, Value &, bool) | Value | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VBool | [inline, virtual]
is_evaluated_expr() const | VBool | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VBool | [inline, virtual]
VBool(bool abool) | VBool | [inline]


VClass Class Reference

stores - static fields: VClass::ffields. More...

Inheritance diagram for VClass:

[legend]
Collaboration diagram for VClass:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override Value * | as (const char *atype, bool looking_up)
all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type. More...

override Value & | as_expr_result (bool)
VClass: true. More...

override bool | as_bool () const
VClass: true. More...

override Value * | get_element (const String &aname, Value &aself, bool)
VClass: $CLASS, (field/property)=STATIC value;(method)=method_ref with self=object_class. More...

override const VJunction * | put_element (Value &self, const String &name, Value *value, bool replace)
VClass: (field/property)=value - static values only. More...

override Value * | create_new_value (Pool &apool, HashStringValue &afields)
Returns:
object of this class.
 More...

override void | add_method (const String &name, Method &method)
override to pre-cache property accessors into fields. More...

Private Methods

Property & | add_property (const String &aname)

Static Private Methods

const VJunction * | prevent_overwrite_property (Value *value, Prevent_info *info)
const VJunction * | prevent_append_if_exists_in_base (Value *value, Prevent_info *info)

Private Attributes

HashStringValue ffields

Detailed Description

stores - static fields: VClass::ffields.

Definition at line 22 of file pa_vclass.h.

Member Function Documentation

const char* VClass::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from VStateless_class.

Definition at line 25 of file pa_vclass.h.

References VStateless_class::name_cstr().

Value * VClass::as | ( | const char * | atype,
 |  | bool | looking_up
 | ) | [virtual]

all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type.

Reimplemented from Value.

Definition at line 44 of file pa_vclass.C.

References Value::as(), VStateless_class::fbase, and result.

override Value& VClass::as_expr_result ( bool ) [inline, virtual]

VClass: true.

Reimplemented from Value.

Definition at line 30 of file pa_vclass.h.

References as_bool(), and override.

override bool VClass::as_bool ( ) const [inline, virtual]

VClass: true.

Reimplemented from Value.

Definition at line 32 of file pa_vclass.h.

References override.

Referenced by as_expr_result().

Value * VClass::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VClass: $CLASS, (field/property)=STATIC value;(method)=method_ref with self=object_class.

Reimplemented from VStateless_class.

Definition at line 52 of file pa_vclass.C.

References String::cstr(), ffields, Hash< const String::Body, Value * >::get(), VStateless_class::get_element(), Value::get_property(), Property::getter, and result.

const VJunction * VClass::put_element | ( | Value & | self,
 |  | const String & | name,
 |  | Value * | value,
 |  | bool | replace
 | ) | [virtual]

VClass: (field/property)=value - static values only.

Reimplemented from Value.

Definition at line 101 of file pa_vclass.C.

References Value::base(), VStateless_class::fbase, ffields, Hash< const String::Body, Value * >::maybe_replace_maybe_append(), Hash< const String::Body, Value * >::maybe_replace_never_append(), prevent_append_if_exists_in_base(), prevent_overwrite_property(), PROPERTY_BUT_NO_SETTER_IN_SELF, Value::put_element(), and result.

Value * VClass::create_new_value | ( | Pool & | apool,
 |  | HashStringValue & | afields
 | ) | [virtual]

Returns:
object of this class.

Reimplemented from VStateless_class.

Definition at line 134 of file pa_vclass.C.

void VClass::add_method | ( | const String & | name,
 |  | Method & | method
 | ) | [virtual]

override to pre-cache property accessors into fields.

Reimplemented from VStateless_class.

Definition at line 31 of file pa_vclass.C.

References VStateless_class::add_method(), add_property(), Property::getter, Property::setter, and String::starts_with().

Property & VClass::add_property ( const String & aname ) [private]

Definition at line 12 of file pa_vclass.C.

References ffields, VProperty::get(), Hash< const String::Body, Value * >::get(), Value::get_class(), Value::get_property(), String::length(), String::mid(), VStateless_class::name_cstr(), Hash< const String::Body, Value * >::put(), result, and value.

Referenced by add_method().

const VJunction * VClass::prevent_overwrite_property | ( | Value * | value,
 |  | Prevent_info * | info
 | ) | [static, private]

Definition at line 81 of file pa_vclass.C.

References Value::get_property(), PROPERTY_BUT_NO_SETTER_IN_SELF, VClass::Prevent_info::self, Property::setter, and value.

Referenced by put_element().

const VJunction * VClass::prevent_append_if_exists_in_base | ( | Value * | value,
 |  | Prevent_info * | info
 | ) | [static, private]

Definition at line 91 of file pa_vclass.C.

References VClass::Prevent_info::_this, Value::base(), VStateless_class::fbase, VClass::Prevent_info::name, Value::put_element(), result, VClass::Prevent_info::self, and value.

Referenced by put_element().

Member Data Documentation

HashStringValue VClass::ffields [private]

Definition at line 59 of file pa_vclass.h.

Referenced by add_property(), get_element(), and put_element().

The documentation for this class was generated from the following files:
  • pa_vclass.h
  • pa_vclass.C


Member List

VClass Member List

This is the complete list of members for VClass, including all inherited members.
add_method(const String &name, Method &method) | VClass | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
add_property(const String &aname) | VClass | [private]
as(const char *atype, bool looking_up) | VClass | [virtual]
as_bool() const | VClass | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VClass | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &apool, HashStringValue &afields) | VClass | [virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
ffields | VClass | [private]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VClass | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
prevent_append_if_exists_in_base(Value *value, Prevent_info *info) | VClass | [private, static]
prevent_overwrite_property(Value *value, Prevent_info *info) | VClass | [private, static]
put_element(Value &self, const String &name, Value *value, bool replace) | VClass | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VClass | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VClass::Prevent_info Struct Reference

Collaboration diagram for VClass::Prevent_info:

[legend]
List of all members.

Public Attributes

VClass * _this
Value * self
const String * name

Member Data Documentation

VClass* VClass::Prevent_info::_this

Definition at line 50 of file pa_vclass.h.

Referenced by VClass::prevent_append_if_exists_in_base().

Value* VClass::Prevent_info::self

Definition at line 51 of file pa_vclass.h.

Referenced by VClass::prevent_append_if_exists_in_base(), and VClass::prevent_overwrite_property().

const String* VClass::Prevent_info::name

Definition at line 52 of file pa_vclass.h.

Referenced by VClass::prevent_append_if_exists_in_base().

The documentation for this struct was generated from the following file:
  • pa_vclass.h


Member List

VClass::Prevent_info Member List

This is the complete list of members for VClass::Prevent_info, including all inherited members.
_this | VClass::Prevent_info
name | VClass::Prevent_info
self | VClass::Prevent_info


VClassMAIN Class Reference

Inheritance diagram for VClassMAIN:

[legend]
Collaboration diagram for VClassMAIN:

[legend]
List of all members.

Public Methods

VClassMAIN ()

Constructor & Destructor Documentation

VClassMAIN::VClassMAIN ( )

Definition at line 798 of file op.C.

References _cache(), _case(), _connect(), _eval(), _for(), _if(), _process(), _rem(), _sleep_operator(), _switch(), _taint(), _throw_operator(), _try_operator(), _untaint(), _use(), _while(), VStateless_class::add_native_method(), Method::CT_ANY, MAIN_CLASS_NAME, and VStateless_class::set_name().

The documentation for this class was generated from the following file:
  • op.C


Member List

VClassMAIN Member List

This is the complete list of members for VClassMAIN, including all inherited members.
add_method(const String &name, Method &method) | VClass | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool looking_up) | VClass | [virtual]
as_bool() const | VClass | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VClass | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &apool, HashStringValue &afields) | VClass | [virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VClass | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &self, const String &name, Value *value, bool replace) | VClass | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VClass | [inline, virtual]
VClassMAIN() | VClassMAIN |
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VCodeFrame Class Reference

specialized write wrapper, completely transparent, but intercepting string writes. More...

Inheritance diagram for VCodeFrame:

[legend]
Collaboration diagram for VCodeFrame:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VCodeFrame: twice transparent. More...

override const VJunction * | put_element (Value &aself, const String &aname, Value *avalue, bool areplace)
VCodeFrame: twice transparent. More...

override void | write (const String &string, String::Language lang)
VCodeFrame: intercepting string writes. More...

override void | write (Value &avalue)
VCodeFrame: twice transparent. More...

VCodeFrame (WContext &awcontext, WContext *parent)

Private Attributes

WContext & wcontext

Detailed Description

specialized write wrapper, completely transparent, but intercepting string writes.

Definition at line 17 of file pa_vcode_frame.h.

Constructor & Destructor Documentation

VCodeFrame::VCodeFrame | ( | WContext & | awcontext,
 |  | WContext * | parent
 | ) | [inline]

Definition at line 56 of file pa_vcode_frame.h.

References wcontext.

Member Function Documentation

override const char* VCodeFrame::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from WContext.

Definition at line 20 of file pa_vcode_frame.h.

References override.

override Value* VCodeFrame::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VCodeFrame: twice transparent.

Reimplemented from Value.

Definition at line 22 of file pa_vcode_frame.h.

References Value::get_element(), override, and wcontext.

override const VJunction* VCodeFrame::put_element | ( | Value & | aself,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool | areplace
 | ) | [inline, virtual]

VCodeFrame: twice transparent.

Reimplemented from Value.

Definition at line 26 of file pa_vcode_frame.h.

References override, Value::put_element(), and wcontext.

override void VCodeFrame::write | ( | const String & | string,
 |  | String::Language | lang
 | ) | [inline, virtual]

VCodeFrame: intercepting string writes.

Reimplemented from WContext.

Definition at line 35 of file pa_vcode_frame.h.

References String::append(), WContext::fstring, String::Language, and override.

Referenced by write().

override void VCodeFrame::write ( Value & avalue ) [inline, virtual]

VCodeFrame: twice transparent.

if value is VString writes fstring, else writes Value; raises an error if already

$hash[^if(1){$hash}]

Reimplemented from WContext.

Definition at line 46 of file pa_vcode_frame.h.

References Value::get_string(), String::L_PASS_APPENDED, override, wcontext, WContext::write(), and write().

Member Data Documentation

WContext& VCodeFrame::wcontext [private]

Definition at line 62 of file pa_vcode_frame.h.

Referenced by get_element(), put_element(), VCodeFrame(), and write().

The documentation for this class was generated from the following file:
  • pa_vcode_frame.h


Member List

VCodeFrame Member List

This is the complete list of members for VCodeFrame, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
attach_junction(Junction *ajunction) | WContext | [inline]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
fstring | WContext | [protected]
fvalue | WContext | [protected]
get_class() | WContext | [inline, virtual]
get_constructing() | WContext | [inline]
get_element(const String &aname, Value &aself, bool looking_up) | VCodeFrame | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_in_expression() | WContext | [inline]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_somebody_entered_some_class() | WContext | [inline]
get_string() | WContext | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VCodeFrame | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
result() | WContext | [inline, virtual]
set_constructing(bool aconstructing) | WContext | [inline]
set_derived(VObject *) | Value | [virtual]
set_in_expression(bool ain_expression) | WContext | [inline]
set_somebody_entered_some_class() | WContext | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VCodeFrame | [inline, virtual]
VCodeFrame(WContext &awcontext, WContext *parent) | VCodeFrame | [inline]
WContext(Value *avalue, WContext *aparent) | WContext | [inline]
wcontext | VCodeFrame | [private]
write(const String &string, String::Language lang) | VCodeFrame | [inline, virtual]
write(Value &avalue) | VCodeFrame | [inline, virtual]
WContext::write(Value &avalue, String::Language alang) | WContext | [inline]
~WContext() | WContext | [inline, virtual]


VConsole Class Reference

console class. More...

Inheritance diagram for VConsole:

[legend]
Collaboration diagram for VConsole:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

VStateless_class * get_class ()
VConsole: 0. More...

Value * | get_element (const String &aname, Value &, bool)
Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.
 More...

override const VJunction * | put_element (Value &, const String &aname, Value *avalue, bool)
VConsole: $line. More...

VConsole ()

Detailed Description

console class.

Definition at line 27 of file pa_vconsole.h.

Constructor & Destructor Documentation

VConsole::VConsole ( ) [inline]

Definition at line 69 of file pa_vconsole.h.

Member Function Documentation

const char* VConsole::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 30 of file pa_vconsole.h.

VStateless_class* VConsole::get_class ( ) [inline, virtual]

VConsole: 0.

Implements Value.

Definition at line 32 of file pa_vconsole.h.

Value* VConsole::get_element | ( | const String & | aname,
 |  | Value & | ,
 |  | bool |
 | ) | [inline, virtual]

Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.

Reimplemented from Value.

Definition at line 35 of file pa_vconsole.h.

References CONSOLE_LINE_NAME, MAX_STRING, and PA_Allocated::strdup().

override const VJunction* VConsole::put_element | ( | Value & | ,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool |
 | ) | [inline, virtual]

VConsole: $line.

Reimplemented from Value.

Definition at line 52 of file pa_vconsole.h.

References Value::as_string(), CONSOLE_LINE_NAME, String::cstr(), override, and PUT_ELEMENT_REPLACED_ELEMENT.

The documentation for this class was generated from the following file:
  • pa_vconsole.h


Member List

VConsole Member List

This is the complete list of members for VConsole, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VConsole | [inline, virtual]
get_element(const String &aname, Value &, bool) | VConsole | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *avalue, bool) | VConsole | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VConsole | [inline, virtual]
VConsole() | VConsole | [inline]


VCookie Class Reference

cookie class. More...

Inheritance diagram for VCookie:

[legend]
Collaboration diagram for VCookie:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
VCookie: 0. More...

override Value * | get_element (const String &aname, Value &aself, bool)
Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.
 More...

override const VJunction * | put_element (Value &self, const String &name, Value *value, bool replace)
store Value element under name
Returns:
putter method junction, or it can just report[PUT_ELEMENT_REPLACED_ELEMENT] that it replaced something in base fields.
 More...

void | fill_fields (Request_info &request_info)
void | output_result (SAPI_Info &sapi_info)

Private Attributes

HashStringValue before
HashStringValue after
HashStringValue deleted

Detailed Description

cookie class.

Definition at line 22 of file pa_vcookie.h.

Member Function Documentation

override const char* VCookie::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 28 of file pa_vcookie.h.

References override.

override VStateless_class* VCookie::get_class ( ) [inline, virtual]

VCookie: 0.

Implements Value.

Definition at line 30 of file pa_vcookie.h.

References override.

Value * VCookie::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.

Reimplemented from Value.

Definition at line 32 of file pa_vcookie.C.

References after, before, CLASS_NAME, deleted, Hash< const String::Body, Value * >::get(), and Value::get_hash().

const VJunction * VCookie::put_element | ( | Value & | self,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool | replace
 | ) | [virtual]

store Value element under name

Returns:
putter method junction, or it can just report[PUT_ELEMENT_REPLACED_ELEMENT] that it replaced something in base fields.

Reimplemented from Value.

Definition at line 52 of file pa_vcookie.C.

References after, String::append(), Value::as_string(), deleted, Hash< const String::Body, Value * >::get(), Value::get_hash(), Value::get_string(), String::is_empty(), Value::is_string(), String::L_TAINTED, and PUT_ELEMENT_REPLACED_ELEMENT.

void VCookie::fill_fields ( Request_info & request_info )

Definition at line 98 of file pa_vcookie.C.

References before, Request_info::cookie, Hash< const String::Body, Value * >::put(), request_info, search_stop(), PA_Allocated::strdup(), and unescape_chars().

Referenced by Request::core().

void VCookie::output_result ( SAPI_Info & sapi_info )

Definition at line 231 of file pa_vcookie.C.

References after, deleted, Hash< const String::Body, Value * >::for_each(), output_after(), and output_deleted().

Referenced by Request::output_result().

Member Data Documentation

HashStringValue VCookie::before [private]

Definition at line 24 of file pa_vcookie.h.

Referenced by fill_fields(), and get_element().

HashStringValue VCookie::after [private]

Definition at line 24 of file pa_vcookie.h.

Referenced by get_element(), output_result(), and put_element().

HashStringValue VCookie::deleted [private]

Definition at line 24 of file pa_vcookie.h.

Referenced by get_element(), output_result(), and put_element().

The documentation for this class was generated from the following files:
  • pa_vcookie.h
  • pa_vcookie.C


Member List

VCookie Member List

This is the complete list of members for VCookie, including all inherited members.
after | VCookie | [private]
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
before | VCookie | [private]
deleted | VCookie | [private]
fill_fields(Request_info &request_info) | VCookie |
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VCookie | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VCookie | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
output_result(SAPI_Info &sapi_info) | VCookie |
put_element(Value &self, const String &name, Value *value, bool replace) | VCookie | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VCookie | [inline, virtual]


VDate Class Reference

value of type 'date'. implemented with time_t. More...

Inheritance diagram for VDate:

[legend]
Collaboration diagram for VDate:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override Value & | as_expr_result (bool)
VDate: ftime -> float days. More...

override double | as_double () const
VDate: ftime -> float days. More...

override bool | as_bool () const
VDate: 0 or !0. More...

tm & | get_localtime ()
@TODO 'static' approach is NOT thread safe! More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VDate: method,field. More...

VDate (time_t adate)
VDate (tm tmIn)
time_t | get_time () const
void | set_time (time_t atime)
void | set_time (tm tmIn)
void | set_tz (const String *atz)

Static Public Methods

int | week_no (tm &tms)

Private Attributes

time_t | ftime
const String * | ftz
const char * | ftz_cstr

Detailed Description

value of type 'date'. implemented with time_t.

Definition at line 40 of file pa_vdate.h.

Constructor & Destructor Documentation

VDate::VDate ( time_t adate ) [inline]

Definition at line 112 of file pa_vdate.h.

References ftz, ftz_cstr, and set_time().

VDate::VDate ( tm tmIn ) [inline]

Definition at line 118 of file pa_vdate.h.

References ftime, ftz, ftz_cstr, and set_time().

Member Function Documentation

override const char* VDate::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 43 of file pa_vdate.h.

References override, and VDATE_TYPE.

override VStateless_class* VDate::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 44 of file pa_vdate.h.

References override.

override Value& VDate::as_expr_result ( bool ) [inline, virtual]

VDate: ftime -> float days.

Reimplemented from Value.

Definition at line 47 of file pa_vdate.h.

References as_double(), and override.

override double VDate::as_double ( ) const [inline, virtual]

VDate: ftime -> float days.

Reimplemented from Value.

Definition at line 50 of file pa_vdate.h.

References ftime, override, and SECS_PER_DAY.

Referenced by as_expr_result().

override bool VDate::as_bool ( ) const [inline, virtual]

VDate: 0 or !0.

Reimplemented from Value.

Definition at line 52 of file pa_vdate.h.

References ftime, and override.

tm& VDate::get_localtime ( ) [inline]

@TODO 'static' approach is NOT thread safe!

Definition at line 55 of file pa_vdate.h.

References ftime, ftz_cstr, MAX_STRING, and result.

Referenced by _sql_string(), and get_element().

override Value* VDate::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VDate: method,field.

Reimplemented from VStateless_object.

Definition at line 83 of file pa_vdate.h.

References Value::bark(), ftz, VStateless_object::get_element(), get_localtime(), override, result, and week_no().

time_t VDate::get_time ( ) const [inline]

Definition at line 125 of file pa_vdate.h.

References ftime.

Referenced by _roll(), _unix_timestamp(), and date_attribute().

void VDate::set_time ( time_t atime ) [inline]

Definition at line 126 of file pa_vdate.h.

References ftime.

Referenced by _create(), _now(), _roll(), _unix_timestamp(), set_time(), and VDate().

void VDate::set_time ( tm tmIn ) [inline]

Definition at line 133 of file pa_vdate.h.

References set_time().

void VDate::set_tz ( const String * atz ) [inline]

Definition at line 144 of file pa_vdate.h.

References String::cstr(), ftz, and ftz_cstr.

Referenced by _roll().

int VDate::week_no ( tm & tms ) [inline, static]

Definition at line 149 of file pa_vdate.h.

Referenced by fill_month_days(), and get_element().

Member Data Documentation

time_t VDate::ftime [private]

Definition at line 158 of file pa_vdate.h.

Referenced by as_bool(), as_double(), get_localtime(), get_time(), set_time(), and VDate().

const String* VDate::ftz [private]

Definition at line 159 of file pa_vdate.h.

Referenced by get_element(), set_tz(), and VDate().

const char* VDate::ftz_cstr [private]

Definition at line 160 of file pa_vdate.h.

Referenced by get_localtime(), set_tz(), and VDate().

The documentation for this class was generated from the following file:
  • pa_vdate.h


Member List

VDate Member List

This is the complete list of members for VDate, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VDate | [inline, virtual]
as_double() const | VDate | [inline, virtual]
as_expr_result(bool) | VDate | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
ftime | VDate | [private]
ftz | VDate | [private]
ftz_cstr | VDate | [private]
get_class() | VDate | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VDate | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_localtime() | VDate | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
get_time() const | VDate | [inline]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
set_time(time_t atime) | VDate | [inline]
set_time(tm tmIn) | VDate | [inline]
set_tz(const String *atz) | VDate | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VDate | [inline, virtual]
VDate(time_t adate) | VDate | [inline]
VDate(tm tmIn) | VDate | [inline]
week_no(tm &tms) | VDate | [inline, static]


VDouble Class Reference

value of type 'double'. implemented with double. More...

Inheritance diagram for VDouble:

[legend]
Collaboration diagram for VDouble:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | is_evaluated_expr () const
VDouble: true. More...

override Value & | as_expr_result (bool)
VDouble: clone. More...

override const String * | get_string ()
VDouble: fdouble. More...

override double | as_double () const
VDouble: fdouble. More...

override int | as_int () const
VDouble: fdouble. More...

override bool | as_bool () const
VDouble: 0 or !0. More...

VDouble (double adouble)
int | get_int () const
double | get_double () const
void | inc (double increment)
void | mul (double k)
void | div (double d)
void | mod (int d)

Private Methods

bool | has_frac ()

Private Attributes

double | fdouble

Detailed Description

value of type 'double'. implemented with double.

Definition at line 24 of file pa_vdouble.h.

Constructor & Destructor Documentation

VDouble::VDouble ( double adouble ) [inline]

Definition at line 51 of file pa_vdouble.h.

References fdouble.

Referenced by as_expr_result().

Member Function Documentation

override const char* VDouble::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 27 of file pa_vdouble.h.

References override.

override VStateless_class* VDouble::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 28 of file pa_vdouble.h.

References override.

override bool VDouble::is_evaluated_expr ( ) const [inline, virtual]

VDouble: true.

Reimplemented from Value.

Definition at line 31 of file pa_vdouble.h.

References override.

override Value& VDouble::as_expr_result ( bool ) [inline, virtual]

VDouble: clone.

Reimplemented from Value.

Definition at line 33 of file pa_vdouble.h.

References fdouble, override, and VDouble().

override const String* VDouble::get_string ( ) [inline, virtual]

VDouble: fdouble.

Reimplemented from Value.

Definition at line 37 of file pa_vdouble.h.

References fdouble, has_frac(), MAX_NUMBER, override, snprintf, and PA_Allocated::strdup().

override double VDouble::as_double ( ) const [inline, virtual]

VDouble: fdouble.

Reimplemented from Value.

Definition at line 43 of file pa_vdouble.h.

References fdouble, and override.

Referenced by _double().

override int VDouble::as_int ( ) const [inline, virtual]

VDouble: fdouble.

Reimplemented from Value.

Definition at line 45 of file pa_vdouble.h.

References get_int(), and override.

Referenced by _int().

override bool VDouble::as_bool ( ) const [inline, virtual]

VDouble: 0 or !0.

Reimplemented from Value.

Definition at line 47 of file pa_vdouble.h.

References fdouble, and override.

int VDouble::get_int ( ) const [inline]

Definition at line 53 of file pa_vdouble.h.

References fdouble.

Referenced by as_int().

double VDouble::get_double ( ) const [inline]

Definition at line 54 of file pa_vdouble.h.

References fdouble.

void VDouble::inc ( double increment ) [inline]

Definition at line 56 of file pa_vdouble.h.

References fdouble.

Referenced by __dec(), and __inc().

void VDouble::mul ( double k ) [inline]

Definition at line 57 of file pa_vdouble.h.

References fdouble.

Referenced by __mul().

void VDouble::div ( double d ) [inline]

Definition at line 58 of file pa_vdouble.h.

References fdouble.

Referenced by __div().

void VDouble::mod ( int d ) [inline]

Definition at line 59 of file pa_vdouble.h.

References fdouble.

Referenced by __mod().

bool VDouble::has_frac ( ) [inline, private]

Definition at line 63 of file pa_vdouble.h.

References fdouble.

Referenced by get_string().

Member Data Documentation

double VDouble::fdouble [private]

Definition at line 69 of file pa_vdouble.h.

Referenced by as_bool(), as_double(), as_expr_result(), div(), get_double(), get_int(), get_string(), has_frac(), inc(), mod(), mul(), and VDouble().

The documentation for this class was generated from the following file:
  • pa_vdouble.h


Member List

VDouble Member List

This is the complete list of members for VDouble, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VDouble | [inline, virtual]
as_double() const | VDouble | [inline, virtual]
as_expr_result(bool) | VDouble | [inline, virtual]
as_int() const | VDouble | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
div(double d) | VDouble | [inline]
fdouble | VDouble | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VDouble | [inline, virtual]
get_double() const | VDouble | [inline]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_object | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_int() const | VDouble | [inline]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | VDouble | [inline, virtual]
get_table() | Value | [inline, virtual]
has_frac() | VDouble | [inline, private]
inc(double increment) | VDouble | [inline]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | VDouble | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
mod(int d) | VDouble | [inline]
mul(double k) | VDouble | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VDouble | [inline, virtual]
VDouble(double adouble) | VDouble | [inline]


VEnv Class Reference

env class. More...

Inheritance diagram for VEnv:

[legend]
Collaboration diagram for VEnv:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

VStateless_class * get_class ()
VEnv: 0. More...

Value * | get_element (const String &aname, Value &, bool)
Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.
 More...

VEnv (SAPI_Info &ainfo)

Private Attributes

SAPI_Info & finfo

Detailed Description

env class.

Definition at line 24 of file pa_venv.h.

Constructor & Destructor Documentation

VEnv::VEnv ( SAPI_Info & ainfo ) [inline]

Definition at line 37 of file pa_venv.h.

Member Function Documentation

const char* VEnv::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 28 of file pa_venv.h.

VStateless_class* VEnv::get_class ( ) [inline, virtual]

VEnv: 0.

Implements Value.

Definition at line 30 of file pa_venv.h.

Value * VEnv::get_element | ( | const String & | aname,
 |  | Value & | ,
 |  | bool |
 | ) | [virtual]

Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.

Reimplemented from Value.

Definition at line 16 of file pa_venv.C.

References String::append_help_length(), String::cstr(), finfo, SAPI::get_env(), String::L_TAINTED, result, and PA_Allocated::strdup().

Member Data Documentation

SAPI_Info& VEnv::finfo [private]

Definition at line 25 of file pa_venv.h.

Referenced by get_element().

The documentation for this class was generated from the following files:
  • pa_venv.h
  • pa_venv.C


Member List

VEnv Member List

This is the complete list of members for VEnv, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
finfo | VEnv | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VEnv | [inline, virtual]
get_element(const String &aname, Value &, bool) | VEnv | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VEnv | [inline, virtual]
VEnv(SAPI_Info &ainfo) | VEnv | [inline]


VFile Class Reference

holds received from user or read from disk file. More...

Inheritance diagram for VFile:

[legend]
Collaboration diagram for VFile:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | as_bool () const
VFile: true. More...

override Value & | as_expr_result (bool)
VFile: true. More...

override VFile * | as_vfile (String::Language, const Request_charsets *)
VFile: this. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VFile: method,field. More...

VFile::VFile ()
VFile::VFile (HashStringValue &afields)
void | set (bool tainted, const char *avalue_ptr, size_t avalue_size, const char *afile_name_cstr=0, Value *acontent_type=0)
WARNING: when setting text files be sure to append terminating zero to avalue_ptr. More...

void | save (const String &file_spec, bool is_text)
const char * | value_ptr () const
size_t | value_size () const
HashStringValue & fields ()

Private Methods

Value * fields_element ()

Private Attributes

const char * | ffile_name_cstr
const char * | fvalue_ptr
size_t | fvalue_size
HashStringValue ffields

Detailed Description

holds received from user or read from disk file.

See also:
VForm

Definition at line 32 of file pa_vfile.h.

Member Function Documentation

override const char* VFile::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 41 of file pa_vfile.h.

References override.

VStateless_class * VFile::get_class ( ) [virtual]

extract VStateless_class.

Implements Value.

Definition at line 32 of file pa_vfile.C.

override bool VFile::as_bool ( ) const [inline, virtual]

VFile: true.

Reimplemented from Value.

Definition at line 45 of file pa_vfile.h.

References override.

Referenced by as_expr_result().

override Value& VFile::as_expr_result ( bool ) [inline, virtual]

VFile: true.

Reimplemented from Value.

Definition at line 48 of file pa_vfile.h.

References as_bool(), and override.

override VFile* VFile::as_vfile | ( | String::Language | ,
 |  | const Request_charsets * |
 | ) | [inline, virtual]

VFile: this.

Reimplemented from Value.

Definition at line 51 of file pa_vfile.h.

References String::Language, and override.

Value * VFile::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [virtual]

VFile: method,field.

Reimplemented from VStateless_object.

Definition at line 75 of file pa_vfile.C.

References ffields, Hash< const String::Body, Value * >::get(), VStateless_object::get_element(), and result.

VFile::VFile::VFile ( ) [inline]

Definition at line 59 of file pa_vfile.h.

References fvalue_ptr, fvalue_size, and VFile::VFile().

Referenced by VFile::VFile().

VFile::VFile::VFile ( HashStringValue & afields ) [inline]

Definition at line 61 of file pa_vfile.h.

void VFile::set | ( | bool | tainted,
 |  | const char * | avalue_ptr,
 |  | size_t | avalue_size,
 |  | const char * | afile_name_cstr = 0,
 |  | Value * | acontent_type = 0
 | ) |

WARNING: when setting text files be sure to append terminating zero to avalue_ptr.

Definition at line 34 of file pa_vfile.C.

References String::append_help_length(), String::append_know_length(), Hash< const String::Body, Value * >::clear(), ffields, fix_line_breaks(), fvalue_ptr, fvalue_size, String::L_AS_IS, String::L_FILE_SPEC, String::L_TAINTED, NONAME_DAT, Hash< const String::Body, Value * >::put(), rsplit(), and PA_Allocated::strdup().

Referenced by _base64(), _create(), _exec_cgi(), _gif(), _load(), _sql(), _stat(), VForm::AppendFormEntry(), VVoid::as_vfile(), and VString::as_vfile().

void VFile::save | ( | const String & | file_spec,
 |  | bool | is_text
 | ) | [inline]

Definition at line 70 of file pa_vfile.h.

References file_write().

const char* VFile::value_ptr ( ) const [inline]

Definition at line 79 of file pa_vfile.h.

Referenced by _base64(), _exec_cgi(), _measure(), _sql_string(), output_sole_piece(), and pa_uuencode().

size_t VFile::value_size ( ) const [inline]

Definition at line 87 of file pa_vfile.h.

Referenced by _base64(), _exec_cgi(), _measure(), _sql_string(), output_sole_piece(), and pa_uuencode().

HashStringValue& VFile::fields ( ) [inline]

Definition at line 88 of file pa_vfile.h.

Referenced by _exec_cgi(), _load(), _measure(), _stat(), file_value_to_string(), and Request::output_result().

Value* VFile::fields_element ( ) [private]

Member Data Documentation

const char* VFile::ffile_name_cstr [private]

Definition at line 34 of file pa_vfile.h.

const char* VFile::fvalue_ptr [private]

Definition at line 35 of file pa_vfile.h.

Referenced by set(), and VFile::VFile().

size_t VFile::fvalue_size [private]

Definition at line 36 of file pa_vfile.h.

Referenced by set(), and VFile::VFile().

HashStringValue VFile::ffields [private]

Definition at line 37 of file pa_vfile.h.

Referenced by get_element(), and set().

The documentation for this class was generated from the following files:
  • pa_vfile.h
  • pa_vfile.C


Member List

VFile Member List

This is the complete list of members for VFile, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VFile | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VFile | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language, const Request_charsets *) | VFile | [inline, virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
ffields | VFile | [private]
ffile_name_cstr | VFile | [private]
fields() | VFile | [inline]
fields_element() | VFile | [private]
free(void *ptr) | PA_Allocated | [inline, static]
fvalue_ptr | VFile | [private]
fvalue_size | VFile | [private]
get_class() | VFile | [virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VFile | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
save(const String &file_spec, bool is_text) | VFile | [inline]
set(bool tainted, const char *avalue_ptr, size_t avalue_size, const char *afile_name_cstr=0, Value *acontent_type=0) | VFile |
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VFile | [inline, virtual]
value_ptr() const | VFile | [inline]
value_size() const | VFile | [inline]
VFile::VFile() | VFile | [inline]
VFile::VFile(HashStringValue &afields) | VFile | [inline]


VForm Class Reference

derivates from VStateless_class so that :CLASS element referred to this. More...

Inheritance diagram for VForm:

[legend]
Collaboration diagram for VForm:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

Value * | get_element (const String &aname, Value &aself, bool)
VStateless_class: $CLASS, $method. More...

VForm (Request_charsets &acharsets, Request_info &arequest_info)

Private Methods

char * | strpart (const char *str, size_t len)
char * | getAttributeValue (const char *data, char *attr, size_t len)
void | UnescapeChars (char **sp, const char *cp, size_t len)
void | ParseGetFormInput (const char *query_string, size_t length)
void | ParseFormInput (const char *data, size_t length)
void | ParseMimeInput (char *content_type, const char *data, size_t length)
void | AppendFormEntry (const char *cname_cstr, const char *raw_cvalue_ptr, const size_t raw_cvalue_size, const char *copy_me_file_name_cstr=0)
bool | should_refill_fields_and_tables ()
void | refill_fields_and_tables ()
String::C | transcode (const char *client, size_t client_size)

Private Attributes

Request_charsets & fcharsets
Request_info & frequest_info
Charset * filled_source
Charset * filled_client
HashStringValue fields
HashStringValue tables
HashStringValue imap

Detailed Description

derivates from VStateless_class so that :CLASS element referred to this.

and users could do such tricks:

        ^rem{pass somebody something with elements}

        ^rem{this time that would be elements of a form}
        ^somebody[$form:CLASS]

        ^rem{this time that would be elements of a table record}
        $news[^table:sql[select * from news]]
        ^somebody[^news.record[]]

Definition at line 45 of file pa_vform.h.

Constructor & Destructor Documentation

VForm::VForm | ( | Request_charsets & | acharsets,
 |  | Request_info & | arequest_info
 | ) |

Definition at line 63 of file pa_vform.C.

Member Function Documentation

const char* VForm::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from VStateless_class.

Definition at line 48 of file pa_vform.h.

Value * VForm::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VStateless_class: $CLASS, $method.

Reimplemented from VStateless_class.

Definition at line 297 of file pa_vform.C.

References fields, FORM_FIELDS_ELEMENT_NAME, FORM_IMAP_ELEMENT_NAME, FORM_TABLES_ELEMENT_NAME, Hash< const String::Body, Value * >::get(), VStateless_class::get_element(), imap, refill_fields_and_tables(), result, should_refill_fields_and_tables(), and tables.

char * VForm::strpart | ( | const char * | str,
 |  | size_t | len
 | ) | [private]

Definition at line 70 of file pa_vform.C.

References result, and str.

Referenced by getAttributeValue().

char * VForm::getAttributeValue | ( | const char * | data,
 |  | char * | attr,
 |  | size_t | len
 | ) | [private]

Definition at line 77 of file pa_vform.C.

References data, searchAttribute(), strpart(), and value.

Referenced by ParseMimeInput().

void VForm::UnescapeChars | ( | char ** | sp,
 |  | const char * | cp,
 |  | size_t | len
 | ) | [private]

void VForm::ParseGetFormInput | ( | const char * | query_string,
 |  | size_t | length
 | ) | [private]

Definition at line 100 of file pa_vform.C.

References ParseFormInput().

Referenced by refill_fields_and_tables().

void VForm::ParseFormInput | ( | const char * | data,
 |  | size_t | length
 | ) | [private]

Definition at line 111 of file pa_vform.C.

References AppendFormEntry(), atoi(), data, imap, Hash< const String::Body, Value * >::put(), unescape_chars(), and value.

Referenced by ParseGetFormInput(), and refill_fields_and_tables().

void VForm::ParseMimeInput | ( | char * | content_type,
 |  | const char * | data,
 |  | size_t | length
 | ) | [private]

Definition at line 171 of file pa_vform.C.

References AppendFormEntry(), data, getAttributeValue(), getHeader(), pa_tolower(), and searchAttribute().

Referenced by refill_fields_and_tables().

void VForm::AppendFormEntry | ( | const char * | cname_cstr,
 |  | const char * | raw_cvalue_ptr,
 |  | const size_t | raw_cvalue_size,
 |  | const char * | copy_me_file_name_cstr = 0
 | ) | [private]

Definition at line 208 of file pa_vform.C.

References ArrayString, Table::columns_type, String::cstr(), Array< ArrayString * >::element_type, fields, fix_line_breaks(), Hash< const String::Body, Value * >::get(), Value::get_table(), Hash< const String::Body, Value * >::put(), Hash< const String::Body, Value * >::put_dont_replace(), VFile::set(), PA_Allocated::strdup(), tables, transcode(), and value.

Referenced by ParseFormInput(), and ParseMimeInput().

bool VForm::should_refill_fields_and_tables ( ) [private]

Definition at line 292 of file pa_vform.C.

References Request_charsets::client(), fcharsets, filled_client, filled_source, and Request_charsets::source().

Referenced by get_element().

void VForm::refill_fields_and_tables ( ) [private]

Definition at line 252 of file pa_vform.C.

References Hash< const String::Body, Value * >::clear(), Request_charsets::client(), Request_info::content_type, data, fcharsets, fields, file_read(), filled_client, filled_source, frequest_info, imap, Request_info::method, ParseFormInput(), ParseGetFormInput(), ParseMimeInput(), Request_info::post_data, Request_info::post_size, Request_info::query_string, request, Request_charsets::source(), PA_Allocated::strdup(), StrEqNc(), and tables.

Referenced by get_element().

String::C VForm::transcode | ( | const char * | client,
 |  | size_t | client_size
 | ) | [private]

Definition at line 93 of file pa_vform.C.

References Request_charsets::client(), fcharsets, Request_charsets::source(), PA_Allocated::strdup(), and Charset::transcode().

Referenced by AppendFormEntry().

Member Data Documentation

Request_charsets& VForm::fcharsets [private]

Definition at line 59 of file pa_vform.h.

Referenced by refill_fields_and_tables(), should_refill_fields_and_tables(), and transcode().

Request_info& VForm::frequest_info [private]

Definition at line 60 of file pa_vform.h.

Referenced by refill_fields_and_tables().

Charset* VForm::filled_source [private]

Definition at line 78 of file pa_vform.h.

Referenced by refill_fields_and_tables(), and should_refill_fields_and_tables().

Charset* VForm::filled_client [private]

Definition at line 79 of file pa_vform.h.

Referenced by refill_fields_and_tables(), and should_refill_fields_and_tables().

HashStringValue VForm::fields [private]

Definition at line 80 of file pa_vform.h.

Referenced by AppendFormEntry(), get_element(), and refill_fields_and_tables().

HashStringValue VForm::tables [private]

Definition at line 81 of file pa_vform.h.

Referenced by AppendFormEntry(), get_element(), and refill_fields_and_tables().

HashStringValue VForm::imap [private]

Definition at line 82 of file pa_vform.h.

Referenced by get_element(), ParseFormInput(), and refill_fields_and_tables().

The documentation for this class was generated from the following files:
  • pa_vform.h
  • pa_vform.C


Member List

VForm Member List

This is the complete list of members for VForm, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
AppendFormEntry(const char *cname_cstr, const char *raw_cvalue_ptr, const size_t raw_cvalue_size, const char *copy_me_file_name_cstr=0) | VForm | [private]
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fcharsets | VForm | [private]
fields | VForm | [private]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
filled_client | VForm | [private]
filled_source | VForm | [private]
free(void *ptr) | PA_Allocated | [inline, static]
frequest_info | VForm | [private]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VForm | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
getAttributeValue(const char *data, char *attr, size_t len) | VForm | [private]
imap | VForm | [private]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
ParseFormInput(const char *data, size_t length) | VForm | [private]
ParseGetFormInput(const char *query_string, size_t length) | VForm | [private]
ParseMimeInput(char *content_type, const char *data, size_t length) | VForm | [private]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
refill_fields_and_tables() | VForm | [private]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
should_refill_fields_and_tables() | VForm | [private]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
strpart(const char *str, size_t len) | VForm | [private]
tables | VForm | [private]
transcode(const char *client, size_t client_size) | VForm | [private]
type() const | VForm | [inline, virtual]
UnescapeChars(char **sp, const char *cp, size_t len) | VForm | [private]
VForm(Request_charsets &acharsets, Request_info &arequest_info) | VForm |
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VHash Class Reference

value of type 'hash', implemented with Hash. More...

Inheritance diagram for VHash:

[legend]
Collaboration diagram for VHash:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override int | as_int () const
VHash: finteger. More...

override double | as_double () const
VHash: finteger. More...

override bool | is_defined () const
VHash: count!=0. More...

override bool | as_bool () const
VHash: count!=0. More...

override Value & | as_expr_result (bool)
VHash: count. More...

override HashStringValue * | get_hash ()
VHash: fhash. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VHash: (key)=value. More...

override const VJunction * | put_element (Value &, const String &aname, Value *avalue, bool)
VHash: (key)=value. More...

override VFile * | as_vfile (String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0)
extract file. More...

VHash ()
VHash (const HashStringValue &source)
HashStringValue & hash ()
void | set_default (Value *adefault)
Value * get_default ()
void | extract_default ()
void | check_lock ()

Private Attributes

HashStringValue fhash
bool | flocked
Value * _default

Friends

class | VHash_lock

Detailed Description

value of type 'hash', implemented with Hash.

Definition at line 35 of file pa_vhash.h.

Constructor & Destructor Documentation

VHash::VHash ( ) [inline]

Definition at line 95 of file pa_vhash.h.

References _default, and flocked.

VHash::VHash ( const HashStringValue & source ) [inline]

Definition at line 97 of file pa_vhash.h.

References _default, fhash, and flocked.

Member Function Documentation

override const char* VHash::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 39 of file pa_vhash.h.

References override, and VHASH_TYPE.

override VStateless_class* VHash::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 40 of file pa_vhash.h.

References override.

override int VHash::as_int ( ) const [inline, virtual]

VHash: finteger.

Reimplemented from Value.

Definition at line 43 of file pa_vhash.h.

References Hash< const String::Body, Value * >::count(), fhash, and override.

Referenced by as_bool(), as_double(), and as_expr_result().

override double VHash::as_double ( ) const [inline, virtual]

VHash: finteger.

Reimplemented from Value.

Definition at line 45 of file pa_vhash.h.

References as_int(), and override.

override bool VHash::is_defined ( ) const [inline, virtual]

VHash: count!=0.

Reimplemented from Value.

Definition at line 47 of file pa_vhash.h.

References as_bool(), and override.

override bool VHash::as_bool ( ) const [inline, virtual]

VHash: count!=0.

Reimplemented from Value.

Definition at line 49 of file pa_vhash.h.

References as_int(), and override.

Referenced by is_defined().

override Value& VHash::as_expr_result ( bool ) [inline, virtual]

VHash: count.

Reimplemented from Value.

Definition at line 51 of file pa_vhash.h.

References as_int(), and override.

override HashStringValue* VHash::get_hash ( ) [inline, virtual]

VHash: fhash.

Reimplemented from Value.

Definition at line 54 of file pa_vhash.h.

References hash(), and override.

override Value* VHash::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VHash: (key)=value.

Reimplemented from VStateless_object.

Definition at line 57 of file pa_vhash.h.

References fhash, Hash< const String::Body, Value * >::get(), get_default(), VStateless_object::get_element(), HASH_FIELDS_NAME, override, and result.

override const VJunction* VHash::put_element | ( | Value & | ,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool |
 | ) | [inline, virtual]

VHash: (key)=value.

Reimplemented from VStateless_object.

Definition at line 75 of file pa_vhash.h.

References fhash, HASH_DEFAULT_ELEMENT_NAME, override, Hash< const String::Body, Value * >::put(), PUT_ELEMENT_REPLACED_ELEMENT, Hash< const String::Body, Value * >::put_replaced(), and set_default().

VFile * VHash::as_vfile | ( | String::Language | lang = String::L_UNSPECIFIED,
 |  | const Request_charsets * | charsets = 0
 | ) | [virtual]

extract file.

Reimplemented from Value.

Definition at line 13 of file pa_vhash.C.

References fhash, and String::Language.

HashStringValue& VHash::hash ( ) [inline]

Definition at line 99 of file pa_vhash.h.

References check_lock(), and fhash.

Referenced by _create_or_add(), _foreach(), _hash(), Request::core(), VMail::fill_received(), Request::get_details(), get_hash(), memory_element(), VMail::message_hash_to_string(), Request::output_result(), pa_internal_file_read_http(), parse_exif(), parse_IFD_entry_formatted_value(), rusage_element(), table_row_to_hash(), and try_catch().

void VHash::set_default ( Value * adefault ) [inline]

Definition at line 104 of file pa_vhash.h.

References _default.

Referenced by _create_or_add(), and put_element().

Value* VHash::get_default ( ) [inline]

Definition at line 107 of file pa_vhash.h.

References _default.

Referenced by _create_or_add(), and get_element().

void VHash::extract_default ( )

Definition at line 19 of file pa_vhash.C.

References _default, fhash, Hash< const String::Body, Value * >::get(), HASH_DEFAULT_ELEMENT_NAME, and Hash< const String::Body, Value * >::remove().

Referenced by _hash().

void VHash::check_lock ( ) [inline]

Definition at line 113 of file pa_vhash.h.

Referenced by hash().

Friends And Related Function Documentation

friend class VHash_lock [friend]

Definition at line 36 of file pa_vhash.h.

Member Data Documentation

HashStringValue VHash::fhash [private]

Definition at line 122 of file pa_vhash.h.

Referenced by as_int(), as_vfile(), extract_default(), get_element(), hash(), put_element(), and VHash().

bool VHash::flocked [private]

Definition at line 123 of file pa_vhash.h.

Referenced by VHash(), VHash_lock::VHash_lock(), and VHash_lock::~VHash_lock().

Value* VHash::_default [private]

Definition at line 124 of file pa_vhash.h.

Referenced by extract_default(), get_default(), set_default(), and VHash().

The documentation for this class was generated from the following files:
  • pa_vhash.h
  • pa_vhash.C


Member List

VHash Member List

This is the complete list of members for VHash, including all inherited members.
_default | VHash | [private]
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VHash | [inline, virtual]
as_double() const | VHash | [inline, virtual]
as_expr_result(bool) | VHash | [inline, virtual]
as_int() const | VHash | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | VHash | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
check_lock() | VHash | [inline]
extract_default() | VHash |
fhash | VHash | [private]
flocked | VHash | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VHash | [inline, virtual]
get_default() | VHash | [inline]
get_element(const String &aname, Value &aself, bool looking_up) | VHash | [inline, virtual]
get_hash() | VHash | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
hash() | VHash | [inline]
is(const char *atype) | Value | [inline]
is_defined() const | VHash | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *avalue, bool) | VHash | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_default(Value *adefault) | VHash | [inline]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VHash | [inline, virtual]
VHash() | VHash | [inline]
VHash(const HashStringValue &source) | VHash | [inline]
VHash_lock class | VHash | [friend]


VHash_lock Class Reference

Collaboration diagram for VHash_lock:

[legend]
List of all members.

Public Methods

VHash_lock (VHash &ahash)
~VHash_lock ()

Private Attributes

VHash & fhash
bool saved

Constructor & Destructor Documentation

VHash_lock::VHash_lock ( VHash & ahash ) [inline]

Definition at line 132 of file pa_vhash.h.

References VHash::flocked, and saved.

VHash_lock::~VHash_lock ( ) [inline]

Definition at line 136 of file pa_vhash.h.

References VHash::flocked, and saved.

Member Data Documentation

VHash& VHash_lock::fhash [private]

Definition at line 129 of file pa_vhash.h.

bool VHash_lock::saved [private]

Definition at line 130 of file pa_vhash.h.

Referenced by VHash_lock(), and ~VHash_lock().

The documentation for this class was generated from the following file:
  • pa_vhash.h


Member List

VHash_lock Member List

This is the complete list of members for VHash_lock, including all inherited members.
fhash | VHash_lock | [private]
saved | VHash_lock | [private]
VHash_lock(VHash &ahash) | VHash_lock | [inline]
~VHash_lock() | VHash_lock | [inline]


VHashfile Class Reference

value of type 'hashfile', implemented with SDBM library bundled in ../libs/sdbm. More...

Inheritance diagram for VHashfile:

[legend]
Collaboration diagram for VHashfile:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override HashStringValue * | get_hash ()
VHashfile: convert to VHash. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VHashfile: (key)=value. More...

override const VJunction * | put_element (Value &, const String &aname, Value *avalue, bool)
VHashfile: (key)=value, (key)=(value+expires). More...

VHashfile (Pool &apool)
override | ~VHashfile ()
void | open (const String &afile_name)
void | close ()
void | check_db () const
apr_sdbm_t * | get_db_for_reading () const
apr_sdbm_t * get_db_for_writing ()
void | clear ()
void | delete_files ()
void | remove (const String &aname)
void | for_each (void callback(apr_sdbm_datum_t, void *), void *info) const
void | for_each (void callback(const String::Body, const String &, void *), void *info)
void | remove (const apr_sdbm_datum_t key)
apr_sdbm_datum_t | serialize_value (const String &string, time_t time_to_die) const
const String * | deserialize_value (const apr_sdbm_datum_t key, const apr_sdbm_datum_t value)

Private Methods

Value * | get_field (const String &aname)
void | put_field (const String &aname, Value *avalue)

Private Attributes

const char * | file_name
apr_sdbm_t * m_db

Detailed Description

value of type 'hashfile', implemented with SDBM library bundled in ../libs/sdbm.

Definition at line 30 of file pa_vhashfile.h.

Constructor & Destructor Documentation

VHashfile::VHashfile ( Pool & apool ) [inline]

Definition at line 57 of file pa_vhashfile.h.

References m_db.

VHashfile::~VHashfile ( )

Definition at line 79 of file pa_vhashfile.C.

References close().

Member Function Documentation

override const char* VHashfile::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 33 of file pa_vhashfile.h.

References override, and VHASHFILE_TYPE.

Referenced by check_db().

override VStateless_class* VHashfile::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 34 of file pa_vhashfile.h.

References override.

HashStringValue * VHashfile::get_hash ( ) [virtual]

VHashfile: convert to VHash.

Reimplemented from Value.

Definition at line 270 of file pa_vhashfile.C.

References for_each(), get_hash__put(), HashStringValue, and result.

Referenced by _hash().

override Value* VHashfile::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VHashfile: (key)=value.

Reimplemented from VStateless_object.

Definition at line 40 of file pa_vhashfile.h.

References VStateless_object::get_element(), get_field(), override, and result.

override const VJunction* VHashfile::put_element | ( | Value & | ,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool |
 | ) | [inline, virtual]

VHashfile: (key)=value, (key)=(value+expires).

Reimplemented from VStateless_object.

Definition at line 50 of file pa_vhashfile.h.

References override, and put_field().

void VHashfile::open ( const String & afile_name )

Definition at line 35 of file pa_vhashfile.C.

References APR_CREATE, APR_READ, APR_SHARELOCK, check(), create_dir_for_file(), String::cstr(), entry_exists(), file_name, String::L_FILE_SPEC, and m_db.

Referenced by _open().

void VHashfile::close ( )

Definition at line 46 of file pa_vhashfile.C.

References check(), check_db(), and m_db.

Referenced by delete_files(), get_db_for_writing(), and ~VHashfile().

void VHashfile::check_db ( ) const

Definition at line 52 of file pa_vhashfile.C.

References m_db, and type().

Referenced by close(), get_db_for_reading(), and get_db_for_writing().

apr_sdbm_t * VHashfile::get_db_for_reading ( ) const

Definition at line 59 of file pa_vhashfile.C.

References check_db(), and m_db.

Referenced by for_each(), and get_field().

apr_sdbm_t * VHashfile::get_db_for_writing ( )

Definition at line 65 of file pa_vhashfile.C.

References APR_WRITE, check(), check_db(), close(), file_name, and m_db.

Referenced by clear(), put_field(), and remove().

void VHashfile::clear ( )

Definition at line 260 of file pa_vhashfile.C.

References clear_delete_key(), for_each(), and get_db_for_writing().

Referenced by _clear().

void VHashfile::delete_files ( )

Definition at line 283 of file pa_vhashfile.C.

References APR_SDBM_DIRFEXT, APR_SDBM_PAGFEXT, close(), delete_file(), and file_name.

Referenced by _delete().

void VHashfile::remove ( const String & aname )

Definition at line 193 of file pa_vhashfile.C.

References String::cstr(), apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, and String::length().

Referenced by _delete(), and deserialize_value().

void VHashfile::for_each | ( | void callback(apr_sdbm_datum_t, void *) | ,
 |  | void * | info
 | ) | const

Definition at line 201 of file pa_vhashfile.C.

References APR_FLOCK_SHARED, APR_SUCCESS, check(), apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, Array< T >::for_each(), get_db_for_reading(), pa_strdup(), and rethrow.

Referenced by _foreach(), clear(), for_each(), and get_hash().

void VHashfile::for_each | ( | void callback(const String::Body, const String &, void *) | ,
 |  | void * | info
 | ) |

Definition at line 247 of file pa_vhashfile.C.

References for_each(), and for_each_string_callback().

void VHashfile::remove ( const apr_sdbm_datum_t key )

Definition at line 187 of file pa_vhashfile.C.

References check(), and get_db_for_writing().

apr_sdbm_datum_t VHashfile::serialize_value | ( | const String & | string,
 |  | time_t | time_to_die
 | ) | const

Definition at line 89 of file pa_vhashfile.C.

References String::cstr(), apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, HASHFILE_VALUE_SERIALIZED_VERSION, String::length(), result, Hashfile_value_serialized_prolog::time_to_die, and Hashfile_value_serialized_prolog::version.

Referenced by put_field().

const String * VHashfile::deserialize_value | ( | const apr_sdbm_datum_t | key,
 |  | const apr_sdbm_datum_t | value
 | ) |

Definition at line 107 of file pa_vhashfile.C.

References apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, HASHFILE_VALUE_SERIALIZED_VERSION, pa_strdup(), remove(), Hashfile_value_serialized_prolog::time_to_die, value, and Hashfile_value_serialized_prolog::version.

Referenced by get_field().

Value * VHashfile::get_field ( const String & aname ) [private]

Definition at line 172 of file pa_vhashfile.C.

References check(), String::cstr(), deserialize_value(), apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, get_db_for_reading(), String::length(), and value.

Referenced by get_element().

void VHashfile::put_field | ( | const String & | aname,
 |  | Value * | avalue
 | ) | [private]

Definition at line 130 of file pa_vhashfile.C.

References APR_SDBM_REPLACE, Value::as(), Value::as_double(), Value::as_string(), check(), String::cstr(), apr_sdbm_datum_t::dptr, apr_sdbm_datum_t::dsize, Hash< const String::Body, Value * >::get(), get_db_for_writing(), Value::get_hash(), Value::get_junction(), String::is_empty(), String::length(), serialize_value(), value, VALUE_NAME, and VDATE_TYPE.

Referenced by put_element().

Member Data Documentation

const char* VHashfile::file_name [private]

Definition at line 86 of file pa_vhashfile.h.

Referenced by delete_files(), get_db_for_writing(), and open().

apr_sdbm_t* VHashfile::m_db [private]

Definition at line 87 of file pa_vhashfile.h.

Referenced by check_db(), close(), get_db_for_reading(), get_db_for_writing(), open(), and VHashfile().

The documentation for this class was generated from the following files:
  • pa_vhashfile.h
  • pa_vhashfile.C


Member List

VHashfile Member List

This is the complete list of members for VHashfile, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
check_db() const | VHashfile |
clear() | VHashfile |
close() | VHashfile |
delete_files() | VHashfile |
deserialize_value(const apr_sdbm_datum_t key, const apr_sdbm_datum_t value) | VHashfile |
file_name | VHashfile | [private]
for_each(void callback(apr_sdbm_datum_t, void *), void *info) const | VHashfile |
for_each(void callback(const String::Body, const String &, void *), void *info) | VHashfile |
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VHashfile | [inline, virtual]
get_db_for_reading() const | VHashfile |
get_db_for_writing() | VHashfile |
get_element(const String &aname, Value &aself, bool looking_up) | VHashfile | [inline, virtual]
get_field(const String &aname) | VHashfile | [private]
get_hash() | VHashfile | [virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
m_db | VHashfile | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
open(const String &afile_name) | VHashfile |
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
Pooled(Pool &apool) | Pooled | [private]
put_element(Value &, const String &aname, Value *avalue, bool) | VHashfile | [inline, virtual]
put_field(const String &aname, Value *avalue) | VHashfile | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
remove(const String &aname) | VHashfile |
remove(const apr_sdbm_datum_t key) | VHashfile |
serialize_value(const String &string, time_t time_to_die) const | VHashfile |
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VHashfile | [inline, virtual]
VHashfile(Pool &apool) | VHashfile | [inline]
~Pooled() | Pooled | [private, virtual]
~VHashfile() | VHashfile |


VImage Class Reference

holds img attributes and [image itself]. More...

Inheritance diagram for VImage:

[legend]
Collaboration diagram for VImage:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | as_bool () const
VImage: true. More...

override Value & | as_expr_result (bool)
VImage: true. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VImage: method,field. More...

override const VJunction * | put_element (Value &self, const String &name, Value *value, bool replace)
VImage: field. More...

void | set (const String *src, int width, int height, gdImage *aimage, Value *aexif=0)
HashStringValue & fields ()
gdImage & image ()
void | set_font (Font *afont)
Font & font ()

Private Attributes

gdImage * fimage
Font * ffont
HashStringValue ffields
Value * fexif

Detailed Description

holds img attributes and [image itself].

Definition at line 61 of file pa_vimage.h.

Member Function Documentation

override const char* VImage::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 64 of file pa_vimage.h.

References override, and VIMAGE_TYPE.

override VStateless_class* VImage::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 65 of file pa_vimage.h.

References override.

override bool VImage::as_bool ( ) const [inline, virtual]

VImage: true.

Reimplemented from Value.

Definition at line 68 of file pa_vimage.h.

References override.

Referenced by as_expr_result().

override Value& VImage::as_expr_result ( bool ) [inline, virtual]

VImage: true.

Reimplemented from Value.

Definition at line 71 of file pa_vimage.h.

References as_bool(), and override.

Value * VImage::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [virtual]

VImage: method,field.

Reimplemented from VStateless_object.

Definition at line 40 of file pa_vimage.C.

References EXIF_ELEMENT_NAME, fexif, ffields, Hash< const String::Body, Value * >::get(), VStateless_object::get_element(), and result.

const VJunction * VImage::put_element | ( | Value & | self,
 |  | const String & | name,
 |  | Value * | value,
 |  | bool | replace
 | ) | [virtual]

VImage: field.

Reimplemented from VStateless_object.

Definition at line 53 of file pa_vimage.C.

References Value::as_int(), Value::as_string(), String::cstr(), ffields, fimage, String::L_AS_IS, String::length(), Hash< const String::Body, Value * >::put(), PUT_ELEMENT_REPLACED_ELEMENT, gdImage::SetLineStyle(), and gdImage::SetLineWidth().

void VImage::set | ( | const String * | src,
 |  | int | width,
 |  | int | height,
 |  | gdImage * | aimage,
 |  | Value * | aexif = 0
 | ) |

Definition at line 15 of file pa_vimage.C.

References fexif, ffields, fimage, and Hash< const String::Body, Value * >::put().

HashStringValue& VImage::fields ( ) [inline]

Definition at line 85 of file pa_vimage.h.

References ffields.

gdImage& VImage::image ( ) [inline]

Definition at line 89 of file pa_vimage.h.

References fimage.

Referenced by _text().

void VImage::set_font ( Font * afont ) [inline]

Definition at line 98 of file pa_vimage.h.

References ffont.

Font& VImage::font ( ) [inline]

Definition at line 99 of file pa_vimage.h.

References ffont.

Referenced by _length(), and _text().

Member Data Documentation

gdImage* VImage::fimage [private]

Definition at line 109 of file pa_vimage.h.

Referenced by image(), put_element(), and set().

Font* VImage::ffont [private]

Definition at line 110 of file pa_vimage.h.

Referenced by font(), and set_font().

HashStringValue VImage::ffields [private]

Definition at line 111 of file pa_vimage.h.

Referenced by fields(), get_element(), put_element(), and set().

Value* VImage::fexif [private]

Definition at line 112 of file pa_vimage.h.

Referenced by get_element(), and set().

The documentation for this class was generated from the following files:
  • pa_vimage.h
  • pa_vimage.C


Member List

VImage Member List

This is the complete list of members for VImage, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VImage | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VImage | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fexif | VImage | [private]
ffields | VImage | [private]
ffont | VImage | [private]
fields() | VImage | [inline]
fimage | VImage | [private]
font() | VImage | [inline]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VImage | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VImage | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
image() | VImage | [inline]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &self, const String &name, Value *value, bool replace) | VImage | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set(const String *src, int width, int height, gdImage *aimage, Value *aexif=0) | VImage |
set_derived(VObject *) | Value | [virtual]
set_font(Font *afont) | VImage | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VImage | [inline, virtual]


VInt Class Reference

value of type 'int'. implemented with int. More...

Inheritance diagram for VInt:

[legend]
Collaboration diagram for VInt:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | is_evaluated_expr () const
VInt: true. More...

override Value & | as_expr_result (bool)
VInt: clone. More...

override const String * | get_string ()
VInt: finteger. More...

override double | as_double () const
VInt: finteger. More...

override int | as_int () const
VInt: finteger. More...

override bool | as_bool () const
VInt: 0 or !0. More...

VInt (int ainteger)
int | get_int ()
void | set_int (int ainteger)
void | inc (int increment)
void | mul (double k)
void | div (double d)
void | mod (int d)

Private Attributes

int | finteger

Detailed Description

value of type 'int'. implemented with int.

Definition at line 20 of file pa_vint.h.

Constructor & Destructor Documentation

VInt::VInt ( int ainteger ) [inline]

Definition at line 46 of file pa_vint.h.

References finteger.

Referenced by as_expr_result().

Member Function Documentation

override const char* VInt::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 23 of file pa_vint.h.

References override.

override VStateless_class* VInt::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 24 of file pa_vint.h.

References override.

override bool VInt::is_evaluated_expr ( ) const [inline, virtual]

VInt: true.

Reimplemented from Value.

Definition at line 27 of file pa_vint.h.

References override.

override Value& VInt::as_expr_result ( bool ) [inline, virtual]

VInt: clone.

Reimplemented from Value.

Definition at line 29 of file pa_vint.h.

References finteger, override, and VInt().

override const String* VInt::get_string ( ) [inline, virtual]

VInt: finteger.

Reimplemented from Value.

Definition at line 32 of file pa_vint.h.

References finteger, MAX_NUMBER, override, snprintf, and PA_Allocated::strdup().

override double VInt::as_double ( ) const [inline, virtual]

VInt: finteger.

Reimplemented from Value.

Definition at line 38 of file pa_vint.h.

References as_int(), and override.

Referenced by _double().

override int VInt::as_int ( ) const [inline, virtual]

VInt: finteger.

Reimplemented from Value.

Definition at line 40 of file pa_vint.h.

References finteger, and override.

Referenced by as_double().

override bool VInt::as_bool ( ) const [inline, virtual]

VInt: 0 or !0.

Reimplemented from Value.

Definition at line 42 of file pa_vint.h.

References finteger, and override.

int VInt::get_int ( ) [inline]

Definition at line 48 of file pa_vint.h.

References finteger.

Referenced by _int().

void VInt::set_int ( int ainteger ) [inline]

Definition at line 49 of file pa_vint.h.

References finteger.

Referenced by _for().

void VInt::inc ( int increment ) [inline]

Definition at line 51 of file pa_vint.h.

References finteger.

Referenced by __dec(), and __inc().

void VInt::mul ( double k ) [inline]

Definition at line 52 of file pa_vint.h.

References finteger.

Referenced by __mul().

void VInt::div ( double d ) [inline]

Definition at line 53 of file pa_vint.h.

References finteger.

Referenced by __div().

void VInt::mod ( int d ) [inline]

Definition at line 54 of file pa_vint.h.

References finteger.

Referenced by __mod().

Member Data Documentation

int VInt::finteger [private]

Definition at line 58 of file pa_vint.h.

Referenced by as_bool(), as_expr_result(), as_int(), div(), get_int(), get_string(), inc(), mod(), mul(), set_int(), and VInt().

The documentation for this class was generated from the following file:
  • pa_vint.h


Member List

VInt Member List

This is the complete list of members for VInt, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VInt | [inline, virtual]
as_double() const | VInt | [inline, virtual]
as_expr_result(bool) | VInt | [inline, virtual]
as_int() const | VInt | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
div(double d) | VInt | [inline]
finteger | VInt | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VInt | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_object | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_int() | VInt | [inline]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | VInt | [inline, virtual]
get_table() | Value | [inline, virtual]
inc(int increment) | VInt | [inline]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | VInt | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
mod(int d) | VInt | [inline]
mul(double k) | VInt | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
set_int(int ainteger) | VInt | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VInt | [inline, virtual]
VInt(int ainteger) | VInt | [inline]


VJunction Class Reference

junction is method+self+context, implemented with Junction. More...

Inheritance diagram for VJunction:

[legend]
Collaboration diagram for VJunction:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
VJunction: 0. More...

override bool | is_defined () const
VJunction: false. More...

override bool | as_bool () const
VJunction: false. More...

override Value & | as_expr_result (bool)
VJunction: false. More...

override Junction * | get_junction ()
VJunction: method, root,self,rcontext, code. More...

VJunction (Value &aself, const Method *amethod, VMethodFrame *amethod_frame, Value *arcontext, WContext *awcontext, ArrayOperation *acode)
Code-Junction constructor. More...

VJunction (Value &aself, const Method *amethod, bool ais_getter=false)
Method-Junction or Getter-Junction constructor. More...

const Junction & | junction () const

Private Attributes

Junction fjunction

Detailed Description

junction is method+self+context, implemented with Junction.

Definition at line 20 of file pa_vjunction.h.

Constructor & Destructor Documentation

VJunction::VJunction | ( | Value & | aself,
 |  | const Method * | amethod,
 |  | VMethodFrame * | amethod_frame,
 |  | Value * | arcontext,
 |  | WContext * | awcontext,
 |  | ArrayOperation * | acode
 | ) | [inline]

Code-Junction constructor.

Definition at line 43 of file pa_vjunction.h.

References fjunction.

VJunction::VJunction | ( | Value & | aself,
 |  | const Method * | amethod,
 |  | bool | ais_getter = false
 | ) | [inline]

Method-Junction or Getter-Junction constructor.

Definition at line 51 of file pa_vjunction.h.

References fjunction.

Member Function Documentation

override const char* VJunction::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 23 of file pa_vjunction.h.

References override.

override VStateless_class* VJunction::get_class ( ) [inline, virtual]

VJunction: 0.

Implements Value.

Definition at line 26 of file pa_vjunction.h.

References override.

override bool VJunction::is_defined ( ) const [inline, virtual]

VJunction: false.

Reimplemented from Value.

Definition at line 29 of file pa_vjunction.h.

References override.

Referenced by as_bool().

override bool VJunction::as_bool ( ) const [inline, virtual]

VJunction: false.

Reimplemented from Value.

Definition at line 32 of file pa_vjunction.h.

References is_defined(), and override.

Referenced by as_expr_result().

override Value& VJunction::as_expr_result ( bool ) [inline, virtual]

VJunction: false.

Reimplemented from Value.

Definition at line 35 of file pa_vjunction.h.

References as_bool(), and override.

override Junction* VJunction::get_junction ( ) [inline, virtual]

VJunction: method, root,self,rcontext, code.

Reimplemented from Value.

Definition at line 38 of file pa_vjunction.h.

References fjunction, and override.

const Junction& VJunction::junction ( ) const [inline]

Definition at line 55 of file pa_vjunction.h.

References fjunction.

Referenced by Request::put_element().

Member Data Documentation

Junction VJunction::fjunction [private]

Definition at line 59 of file pa_vjunction.h.

Referenced by get_junction(), junction(), and VJunction().

The documentation for this class was generated from the following file:
  • pa_vjunction.h


Member List

VJunction Member List

This is the complete list of members for VJunction, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VJunction | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VJunction | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fjunction | VJunction | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VJunction | [inline, virtual]
get_element(const String &, Value &, bool) | Value | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | VJunction | [inline, virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VJunction | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
junction() const | VJunction | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VJunction | [inline, virtual]
VJunction(Value &aself, const Method *amethod, VMethodFrame *amethod_frame, Value *arcontext, WContext *awcontext, ArrayOperation *acode) | VJunction | [inline]
VJunction(Value &aself, const Method *amethod, bool ais_getter=false) | VJunction | [inline]


VMail Class Reference

$mail:received letter. More...

Inheritance diagram for VMail:

[legend]
Collaboration diagram for VMail:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

Value * | get_element (const String &aname, Value &aself, bool)
VStateless_class: $CLASS, $method. More...

VMail ()
void | fill_received (Request &r)
const String & | message_hash_to_string (Request &r, HashStringValue *message_hash, int level, const String *&from, bool extract_to, String *&to)

Private Attributes

VHash vreceived

Detailed Description

$mail:received letter.

Definition at line 29 of file pa_vmail.h.

Constructor & Destructor Documentation

VMail::VMail ( )

Definition at line 65 of file pa_vmail.C.

Member Function Documentation

override const char* VMail::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from VStateless_class.

Definition at line 35 of file pa_vmail.h.

References override.

Value * VMail::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VStateless_class: $CLASS, $method.

Reimplemented from VStateless_class.

Definition at line 849 of file pa_vmail.C.

References VStateless_class::get_element(), MAIL_RECEIVED_ELEMENT_NAME, result, and vreceived.

void VMail::fill_received ( Request & r )

Definition at line 329 of file pa_vmail.C.

References Request::charsets, VHash::hash(), Request_info::mail_received, Request::request_info, rethrow, Request_charsets::source(), VALUE_NAME, and vreceived.

Referenced by Request::core().

const String & VMail::message_hash_to_string | ( | Request & | r,
 |  | HashStringValue * | message_hash,
 |  | int | level,
 |  | const String *& | from,
 |  | bool | extract_to,
 |  | String *& | to
 | ) |

Todo:
files and messages in order (file, file2, ...)

Definition at line 718 of file pa_vmail.C.

References ArrayValue, Value::as_string(), String::CC_UPPER, String::change_case(), Request::charsets, Array< Value * >::count(), file_value_to_string(), Hash< const String::Body, Value * >::for_each(), Array< Value * >::get(), Hash< const String::Body, Value * >::get(), Value::get_hash(), VHash::hash(), MAX_NUMBER, P_FILE, P_HTML, P_MESSAGE, P_TEXT, P_TYPES_COUNT, PartType, Hash< const String::Body, Value * >::put(), Hash< const String::Body, Value * >::remove(), result, Request_charsets::set_mail(), snprintf, Request_charsets::source(), store_message_element(), and text_value_to_string().

Member Data Documentation

VHash VMail::vreceived [private]

Definition at line 31 of file pa_vmail.h.

Referenced by fill_received(), and get_element().

The documentation for this class was generated from the following files:
  • pa_vmail.h
  • pa_vmail.C


Member List

VMail Member List

This is the complete list of members for VMail, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
fill_received(Request &r) | VMail |
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VMail | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
message_hash_to_string(Request &r, HashStringValue *message_hash, int level, const String *&from, bool extract_to, String *&to) | VMail |
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VMail | [inline, virtual]
VMail() | VMail |
vreceived | VMail | [private]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VMath Class Reference

Inheritance diagram for VMath:

[legend]
Collaboration diagram for VMath:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

Value * | get_element (const String &aname, Value &aself, bool looking_up)
VStateless_class: $CLASS, $method. More...

VMath ()

Private Attributes

HashStringValue fconsts

Constructor & Destructor Documentation

VMath::VMath ( )

Definition at line 19 of file pa_vmath.C.

References fconsts, PI, and Hash< const String::Body, Value * >::put().

Member Function Documentation

const char* VMath::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from VStateless_class.

Definition at line 27 of file pa_vmath.h.

Value* VMath::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VStateless_class: $CLASS, $method.

Reimplemented from VStateless_class.

Definition at line 30 of file pa_vmath.h.

References fconsts, Hash< const String::Body, Value * >::get(), VStateless_class::get_element(), and result.

Member Data Documentation

HashStringValue VMath::fconsts [private]

Definition at line 45 of file pa_vmath.h.

Referenced by get_element(), and VMath().

The documentation for this class was generated from the following files:
  • pa_vmath.h
  • pa_vmath.C


Member List

VMath Member List

This is the complete list of members for VMath, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fconsts | VMath | [private]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VMath | [inline, virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VMath | [inline, virtual]
VMath() | VMath |
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VMemory Class Reference

Inheritance diagram for VMemory:

[legend]
Collaboration diagram for VMemory:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

Value * | get_element (const String &aname, Value &aself, bool looking_up)
memory: CLASS,method. More...

VMemory ()

Constructor & Destructor Documentation

VMemory::VMemory ( ) [inline]

Definition at line 34 of file pa_vmemory.h.

Member Function Documentation

const char* VMemory::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from VStateless_class.

Definition at line 23 of file pa_vmemory.h.

Value* VMemory::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

memory: CLASS,method.

Reimplemented from VStateless_class.

Definition at line 26 of file pa_vmemory.h.

References VStateless_class::get_element(), and result.

The documentation for this class was generated from the following file:
  • pa_vmemory.h


Member List

VMemory Member List

This is the complete list of members for VMemory, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VMemory | [inline, virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VMemory | [inline, virtual]
VMemory() | VMemory | [inline]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VMethodFrame Class Reference

Method frame write context accepts values written by method code also handles method parameters and local variables. More...

Inheritance diagram for VMethodFrame:

[legend]
Collaboration diagram for VMethodFrame:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override const String * | get_string ()
VMethodFrame: $result | parent get_string(=accumulated fstring). More...

override Value * | get_element (const String &aname, Value &, bool looking_up)
VMethodFrame: my or self_transparent or $caller. More...

override const VJunction * | put_element (Value &, const String &aname, Value *avalue, bool)
VMethodFrame: my or self_transparent. More...

override VStateless_class * | get_class ()
VMethodFrame: self_transparent. More...

override Value * | base ()
VMethodFrame: self_transparent. More...

override StringOrValue | result ()
retrives the resulting value that can be String if value==0 or the Value object wmethod_frame first checks for $result and if there is one, returns it instead. More...

void | write (Value &avalue, String::Language alang)
if value is VString writes fstring, else writes Value; raises an error if already, providing origin. More...

VMethodFrame (const Junction &ajunction, VMethodFrame *acaller)
VMethodFrame * | caller ()
void | set_self (Value &aself)
Value & self ()
we sure that someone already set our self with VMethodFrame::set_self(Value&). More...

bool | can_store_param ()
void | store_param (Value &value)
void | fill_unspecified_params ()
MethodParams * numbered_params ()

Public Attributes

const Junction & | junction

Private Methods

void | set_my_variable (const String &fname, Value &value)
Value * get_result_variable ()

Private Attributes

VMethodFrame * | fcaller
size_t | store_param_index
HashStringValue * my
MethodParams * fnumbered_params
Value * fself
Value * fresult_initial_void

Detailed Description

Method frame write context accepts values written by method code also handles method parameters and local variables.

Definition at line 102 of file pa_vmethod_frame.h.

Constructor & Destructor Documentation

VMethodFrame::VMethodFrame | ( | const Junction & | ajunction,
 |  | VMethodFrame * | acaller
 | ) |

Definition at line 25 of file pa_vmethod_frame.C.

References fnumbered_params, fresult_initial_void, Array_iterator< T >::has_next(), junction, Method::locals_names, Method::max_numbered_params_count, Junction::method, my, Array_iterator< T >::next(), and set_my_variable().

Member Function Documentation

override const char* VMethodFrame::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from WContext.

Definition at line 113 of file pa_vmethod_frame.h.

References override.

override const String* VMethodFrame::get_string ( ) [inline, virtual]

VMethodFrame: $result | parent get_string(=accumulated fstring).

Reimplemented from WContext.

Definition at line 116 of file pa_vmethod_frame.h.

References get_result_variable(), WContext::get_string(), Value::get_string(), override, and result().

override Value* VMethodFrame::get_element | ( | const String & | aname,
 |  | Value & | ,
 |  | bool | looking_up
 | ) | [inline, virtual]

VMethodFrame: my or self_transparent or $caller.

Reimplemented from Value.

Definition at line 124 of file pa_vmethod_frame.h.

References caller(), CALLER_ELEMENT_NAME, Hash< const String::Body, Value * >::get(), Value::get_element(), override, result(), self(), and SELF_ELEMENT_NAME.

override const VJunction* VMethodFrame::put_element | ( | Value & | ,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool |
 | ) | [inline, virtual]

VMethodFrame: my or self_transparent.

Reimplemented from Value.

Definition at line 141 of file pa_vmethod_frame.h.

References override, Value::put_element(), PUT_ELEMENT_REPLACED_ELEMENT, Hash< const String::Body, Value * >::put_replaced(), and self().

Referenced by _for(), and try_catch().

override VStateless_class* VMethodFrame::get_class ( ) [inline, virtual]

VMethodFrame: self_transparent.

Reimplemented from WContext.

Definition at line 149 of file pa_vmethod_frame.h.

References Value::get_class(), override, and self().

override Value* VMethodFrame::base ( ) [inline, virtual]

VMethodFrame: self_transparent.

Reimplemented from Value.

Definition at line 152 of file pa_vmethod_frame.h.

References Value::base(), override, and self().

override StringOrValue VMethodFrame::result ( ) [inline, virtual]

retrives the resulting value that can be String if value==0 or the Value object wmethod_frame first checks for $result and if there is one, returns it instead.

Reimplemented from WContext.

Definition at line 156 of file pa_vmethod_frame.h.

References get_result_variable(), override, and WContext::result().

Referenced by get_element(), get_result_variable(), and get_string().

void VMethodFrame::write | ( | Value & | avalue,
 |  | String::Language | alang
 | ) | [inline]

if value is VString writes fstring, else writes Value; raises an error if already, providing origin.

Reimplemented from WContext.

Definition at line 163 of file pa_vmethod_frame.h.

References String::Language, and WContext::write().

Referenced by Request::execute().

VMethodFrame* VMethodFrame::caller ( ) [inline]

Definition at line 173 of file pa_vmethod_frame.h.

Referenced by _for(), _process(), and get_element().

void VMethodFrame::set_self ( Value & aself ) [inline]

Definition at line 175 of file pa_vmethod_frame.h.

Referenced by Request::core(), Request::execute(), Request::execute_method(), Request::process(), Request::put_element(), Temp_method_frame_self::Temp_method_frame_self(), and Temp_method_frame_self::~Temp_method_frame_self().

Value& VMethodFrame::self ( ) [inline]

we sure that someone already set our self with VMethodFrame::set_self(Value&).

Definition at line 177 of file pa_vmethod_frame.h.

Referenced by _process(), base(), get_class(), get_element(), Request::get_self(), and put_element().

bool VMethodFrame::can_store_param ( ) [inline]

Definition at line 179 of file pa_vmethod_frame.h.

References Array< const String * >::count(), junction, Junction::method, Method::params_names, and store_param_index.

Referenced by Request::execute_method().

void VMethodFrame::store_param ( Value & value ) [inline]

Definition at line 183 of file pa_vmethod_frame.h.

References Array< const String * >::count(), Value::get_class(), junction, Method::max_numbered_params_count, Junction::method, VStateless_class::name_cstr(), Method::params_names, Junction::self, set_my_variable(), store_param_index, Value::type(), and value.

Referenced by Request::core(), Request::execute(), Request::execute_method(), and Request::put_element().

void VMethodFrame::fill_unspecified_params ( ) [inline]

Definition at line 206 of file pa_vmethod_frame.h.

References Array< const String * >::count(), junction, Junction::method, Method::params_names, Hash< const String::Body, Value * >::put(), and store_param_index.

Referenced by Request::execute(), and Request::execute_method().

MethodParams* VMethodFrame::numbered_params ( ) [inline]

Definition at line 217 of file pa_vmethod_frame.h.

Referenced by Request::execute().

void VMethodFrame::set_my_variable | ( | const String & | fname,
 |  | Value & | value
 | ) | [inline, private]

Definition at line 221 of file pa_vmethod_frame.h.

References Hash< const String::Body, Value * >::put(), and value.

Referenced by store_param(), and VMethodFrame().

Value * VMethodFrame::get_result_variable ( ) [private]

Definition at line 62 of file pa_vmethod_frame.C.

References fresult_initial_void, Hash< const String::Body, Value * >::get(), my, and result().

Referenced by get_string(), and result().

Member Data Documentation

VMethodFrame* VMethodFrame::fcaller [private]

Definition at line 103 of file pa_vmethod_frame.h.

size_t VMethodFrame::store_param_index [private]

Definition at line 105 of file pa_vmethod_frame.h.

Referenced by can_store_param(), fill_unspecified_params(), and store_param().

HashStringValue* VMethodFrame::my [private]

Definition at line 106 of file pa_vmethod_frame.h.

Referenced by get_result_variable(), and VMethodFrame().

MethodParams* VMethodFrame::fnumbered_params [private]

Definition at line 106 of file pa_vmethod_frame.h.

Referenced by VMethodFrame().

Value* VMethodFrame::fself [private]

Definition at line 107 of file pa_vmethod_frame.h.

Value* VMethodFrame::fresult_initial_void [private]

Definition at line 109 of file pa_vmethod_frame.h.

Referenced by get_result_variable(), and VMethodFrame().

const Junction& VMethodFrame::junction

Definition at line 229 of file pa_vmethod_frame.h.

Referenced by can_store_param(), Request::execute(), fill_unspecified_params(), Request::process(), Request::put_element(), store_param(), and VMethodFrame().

The documentation for this class was generated from the following files:
  • pa_vmethod_frame.h
  • pa_vmethod_frame.C


Member List

VMethodFrame Member List

This is the complete list of members for VMethodFrame, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
attach_junction(Junction *ajunction) | WContext | [inline]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VMethodFrame | [inline, virtual]
base_object() | Value | [virtual]
caller() | VMethodFrame | [inline]
can_store_param() | VMethodFrame | [inline]
fcaller | VMethodFrame | [private]
fill_unspecified_params() | VMethodFrame | [inline]
fnumbered_params | VMethodFrame | [private]
free(void *ptr) | PA_Allocated | [inline, static]
fresult_initial_void | VMethodFrame | [private]
fself | VMethodFrame | [private]
fstring | WContext | [protected]
fvalue | WContext | [protected]
get_class() | VMethodFrame | [inline, virtual]
get_constructing() | WContext | [inline]
get_element(const String &aname, Value &, bool looking_up) | VMethodFrame | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_in_expression() | WContext | [inline]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_result_variable() | VMethodFrame | [private]
get_somebody_entered_some_class() | WContext | [inline]
get_string() | VMethodFrame | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
junction | VMethodFrame |
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
my | VMethodFrame | [private]
numbered_params() | VMethodFrame | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *avalue, bool) | VMethodFrame | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
result() | VMethodFrame | [inline, virtual]
self() | VMethodFrame | [inline]
set_constructing(bool aconstructing) | WContext | [inline]
set_derived(VObject *) | Value | [virtual]
set_in_expression(bool ain_expression) | WContext | [inline]
set_my_variable(const String &fname, Value &value) | VMethodFrame | [inline, private]
set_self(Value &aself) | VMethodFrame | [inline]
set_somebody_entered_some_class() | WContext | [inline]
store_param(Value &value) | VMethodFrame | [inline]
store_param_index | VMethodFrame | [private]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VMethodFrame | [inline, virtual]
VMethodFrame(const Junction &ajunction, VMethodFrame *acaller) | VMethodFrame |
WContext(Value *avalue, WContext *aparent) | WContext | [inline]
write(Value &avalue, String::Language alang) | VMethodFrame | [inline]
WContext::write(const String &astring, String::Language alang) | WContext | [inline, virtual]
WContext::write(Value &avalue) | WContext | [virtual]
~WContext() | WContext | [inline, virtual]


VObject Class Reference

parser class instance, stores - class VObject::fclass; - fields VObject::ffields (dynamic, not static, which are stored in class). More...

Inheritance diagram for VObject:

[legend]
Collaboration diagram for VObject:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override Value * | as (const char *atype, bool looking_up)
all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type. More...

override VStateless_class * | get_class ()
VObject: fclass. More...

override VStateless_class * | get_last_derived_class ()
extract VStateless_class. More...

override Value * | base ()
extract base object or class of Value, if any. More...

override bool | is_defined () const
VObject: from possible parent, if any. More...

override Value & | as_expr_result (bool)
VObject: from possible parent, if any. More...

override int | as_int () const
VObject: from possible parent, if any. More...

override double | as_double ()
VObject: from possible parent, if any. More...

override bool | as_bool () const
VObject: from possible parent, if any. More...

override VFile * | as_vfile (String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0)
VObject: from possible parent, if any. More...

override HashStringValue * | get_hash ()
VObject: from possible parent, if any. More...

override Table * | get_table ()
VObject: from possible 'table' parent. More...

override Value * | get_element (const String &aname, Value &aself, bool)
VObject: (field)=value;(CLASS)=vclass;(method)=method_ref. More...

override const VJunction * | put_element (Value &self, const String &name, Value *value, bool replace)
VObject: (field/property)=value. More...

override VObject * | set_derived (VObject *aderived)
VObject: remember derived [the only client]. More...

VObject (Pool &apool, VStateless_class &aclass, HashStringValue &afields)

Private Methods

VObject & | get_last_derived ()
Value * | stateless_object__get_element (const String &aname, Value &aself)
const VJunction * | stateless_object__put_element (Value &aself, const String &aname, Value *avalue)

Static Private Methods

const VJunction * | prevent_append_if_exists_in_static_or_base (Value *value, Prevent_append_if_exists_in_static_or_base_info *info)

Private Attributes

VStateless_class & fclass
HashStringValue & ffields
VObject * | fderived
Value * fbase

Detailed Description

parser class instance, stores - class VObject::fclass; - fields VObject::ffields (dynamic, not static, which are stored in class).

  • links to base/derived instances [VObject::fbase, VObject::fderived]

Definition at line 29 of file pa_vobject.h.

Constructor & Destructor Documentation

VObject::VObject | ( | Pool & | apool,
 |  | VStateless_class & | aclass,
 |  | HashStringValue & | afields
 | ) | [inline]

Definition at line 69 of file pa_vobject.h.

References VStateless_class::base_class(), VStateless_class::create_new_value(), and set_derived().

Member Function Documentation

const char* VObject::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 38 of file pa_vobject.h.

References VStateless_class::name_cstr().

Value * VObject::as | ( | const char * | atype,
 |  | bool | looking_up
 | ) | [virtual]

all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type.

Reimplemented from Value.

Definition at line 14 of file pa_vobject.C.

References Value::as(), fbase, get_last_derived(), and result.

Referenced by get_hash(), and get_table().

override VStateless_class* VObject::get_class ( ) [inline, virtual]

VObject: fclass.

Implements Value.

Definition at line 42 of file pa_vobject.h.

References override.

Referenced by get_element(), and get_last_derived_class().

override VStateless_class* VObject::get_last_derived_class ( ) [inline, virtual]

extract VStateless_class.

Reimplemented from Value.

Definition at line 43 of file pa_vobject.h.

References get_class(), get_last_derived(), and override.

override Value* VObject::base ( ) [inline, virtual]

extract base object or class of Value, if any.

Reimplemented from Value.

Definition at line 44 of file pa_vobject.h.

References override.

bool VObject::is_defined ( ) const [virtual]

VObject: from possible parent, if any.

Reimplemented from Value.

Definition at line 33 of file pa_vobject.C.

References fbase, and Value::is_defined().

Value & VObject::as_expr_result ( bool ) [virtual]

VObject: from possible parent, if any.

Reimplemented from Value.

Definition at line 37 of file pa_vobject.C.

References Value::as_expr_result(), and fbase.

int VObject::as_int ( ) const [virtual]

VObject: from possible parent, if any.

Reimplemented from Value.

Definition at line 41 of file pa_vobject.C.

References Value::as_int(), and fbase.

double VObject::as_double ( )

VObject: from possible parent, if any.

Definition at line 45 of file pa_vobject.C.

References Value::as_double(), and fbase.

bool VObject::as_bool ( ) const [virtual]

VObject: from possible parent, if any.

Reimplemented from Value.

Definition at line 49 of file pa_vobject.C.

References Value::as_bool(), and fbase.

VFile * VObject::as_vfile | ( | String::Language | lang = String::L_UNSPECIFIED,
 |  | const Request_charsets * | charsets = 0
 | ) | [virtual]

VObject: from possible parent, if any.

Reimplemented from Value.

Definition at line 53 of file pa_vobject.C.

References Value::as_vfile(), fbase, and String::Language.

HashStringValue * VObject::get_hash ( ) [virtual]

VObject: from possible parent, if any.

Reimplemented from Value.

Definition at line 59 of file pa_vobject.C.

References as(), Value::get_hash(), get_last_derived(), and VHASH_TYPE.

Table * VObject::get_table ( ) [virtual]

VObject: from possible 'table' parent.

Reimplemented from Value.

Definition at line 66 of file pa_vobject.C.

References as(), get_last_derived(), Value::get_table(), and VTABLE_TYPE.

Value * VObject::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VObject: (field)=value;(CLASS)=vclass;(method)=method_ref.

Reimplemented from VStateless_object.

Definition at line 74 of file pa_vobject.C.

References CLASS_NAME, ffields, Hash< const String::Body, Value * >::get(), get_class(), get_last_derived(), result, and stateless_object__get_element().

const VJunction * VObject::put_element | ( | Value & | self,
 |  | const String & | name,
 |  | Value * | value,
 |  | bool | replace
 | ) | [virtual]

VObject: (field/property)=value.

Reimplemented from VStateless_object.

Definition at line 104 of file pa_vobject.C.

References ffields, prevent_append_if_exists_in_static_or_base(), and Hash< const String::Body, Value * >::replace_maybe_append().

override VObject* VObject::set_derived ( VObject * aderived ) [inline, virtual]

VObject: remember derived [the only client].

Reimplemented from Value.

Definition at line 61 of file pa_vobject.h.

References override, and result.

Referenced by VObject().

VObject& VObject::get_last_derived ( ) [inline, private]

Definition at line 76 of file pa_vobject.h.

Referenced by as(), get_element(), get_hash(), get_last_derived_class(), get_table(), and prevent_append_if_exists_in_static_or_base().

Value* VObject::stateless_object__get_element | ( | const String & | aname,
 |  | Value & | aself
 | ) | [inline, private]

Definition at line 80 of file pa_vobject.h.

References VStateless_object::get_element().

Referenced by get_element().

const VJunction* VObject::stateless_object__put_element | ( | Value & | aself,
 |  | const String & | aname,
 |  | Value * | avalue
 | ) | [inline, private]

Definition at line 84 of file pa_vobject.h.

References VStateless_object::put_element().

Referenced by prevent_append_if_exists_in_static_or_base().

const VJunction * VObject::prevent_append_if_exists_in_static_or_base | ( | Value * | value,
 |  | Prevent_append_if_exists_in_static_or_base_info * | info
 | ) | [static, private]

Definition at line 94 of file pa_vobject.C.

References VObject::Prevent_append_if_exists_in_static_or_base_info::_this, get_last_derived(), VObject::Prevent_append_if_exists_in_static_or_base_info::name, result, stateless_object__put_element(), and value.

Referenced by put_element().

Member Data Documentation

VStateless_class& VObject::fclass [private]

Definition at line 31 of file pa_vobject.h.

HashStringValue& VObject::ffields [private]

Definition at line 32 of file pa_vobject.h.

Referenced by get_element(), and put_element().

VObject* VObject::fderived [private]

Definition at line 33 of file pa_vobject.h.

Value* VObject::fbase [private]

Definition at line 34 of file pa_vobject.h.

Referenced by as(), as_bool(), as_double(), as_expr_result(), as_int(), as_vfile(), and is_defined().

The documentation for this class was generated from the following files:
  • pa_vobject.h
  • pa_vobject.C


Member List

VObject Member List

This is the complete list of members for VObject, including all inherited members.
as(const char *atype, bool looking_up) | VObject | [virtual]
as_bool() const | VObject | [virtual]
as_double() | VObject |
VStateless_object::as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VObject | [virtual]
as_int() const | VObject | [virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | VObject | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VObject | [inline, virtual]
base_object() | Value | [virtual]
fbase | VObject | [private]
fclass | VObject | [private]
fderived | VObject | [private]
ffields | VObject | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VObject | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VObject | [virtual]
get_hash() | VObject | [virtual]
get_junction() | Value | [virtual]
get_last_derived() | VObject | [inline, private]
get_last_derived_class() | VObject | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | VObject | [virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VObject | [virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
prevent_append_if_exists_in_static_or_base(Value *value, Prevent_append_if_exists_in_static_or_base_info *info) | VObject | [private, static]
put_element(Value &self, const String &name, Value *value, bool replace) | VObject | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *aderived) | VObject | [inline, virtual]
stateless_object__get_element(const String &aname, Value &aself) | VObject | [inline, private]
stateless_object__put_element(Value &aself, const String &aname, Value *avalue) | VObject | [inline, private]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VObject | [inline, virtual]
VObject(Pool &apool, VStateless_class &aclass, HashStringValue &afields) | VObject | [inline]


VObject::Prevent_append_if_exists_in_static_or_base_info Struct Reference

Collaboration diagram for VObject::Prevent_append_if_exists_in_static_or_base_info:

[legend]
List of all members.

Public Attributes

VObject * _this
const String * name

Member Data Documentation

VObject* VObject::Prevent_append_if_exists_in_static_or_base_info::_this

Definition at line 89 of file pa_vobject.h.

Referenced by VObject::prevent_append_if_exists_in_static_or_base().

const String* VObject::Prevent_append_if_exists_in_static_or_base_info::name

Definition at line 90 of file pa_vobject.h.

Referenced by VObject::prevent_append_if_exists_in_static_or_base().

The documentation for this struct was generated from the following file:
  • pa_vobject.h


Member List

VObject::Prevent_append_if_exists_in_static_or_base_info Member List

This is the complete list of members for VObject::Prevent_append_if_exists_in_static_or_base_info, including all inherited members.
_this | VObject::Prevent_append_if_exists_in_static_or_base_info
name | VObject::Prevent_append_if_exists_in_static_or_base_info


VProperty Class Reference

property two methods. More...

Inheritance diagram for VProperty:

[legend]
Collaboration diagram for VProperty:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
VProperty: 0. More...

override bool | is_defined () const
VProperty: false. More...

override bool | as_bool () const
VProperty: false. More...

override Value & | as_expr_result (bool)
VProperty: false. More...

override Property * | get_property ()
VProperty: property. More...

Property & get ()

Private Attributes

Property fproperty

Detailed Description

property two methods.

Definition at line 20 of file pa_vproperty.h.

Member Function Documentation

override const char* VProperty::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 23 of file pa_vproperty.h.

References override.

override VStateless_class* VProperty::get_class ( ) [inline, virtual]

VProperty: 0.

Implements Value.

Definition at line 26 of file pa_vproperty.h.

References Value::bark(), and override.

override bool VProperty::is_defined ( ) const [inline, virtual]

VProperty: false.

Reimplemented from Value.

Definition at line 29 of file pa_vproperty.h.

References Value::bark(), and override.

Referenced by as_bool().

override bool VProperty::as_bool ( ) const [inline, virtual]

VProperty: false.

Reimplemented from Value.

Definition at line 32 of file pa_vproperty.h.

References is_defined(), and override.

Referenced by as_expr_result().

override Value& VProperty::as_expr_result ( bool ) [inline, virtual]

VProperty: false.

Reimplemented from Value.

Definition at line 35 of file pa_vproperty.h.

References as_bool(), and override.

override Property* VProperty::get_property ( ) [inline, virtual]

VProperty: property.

Reimplemented from Value.

Definition at line 38 of file pa_vproperty.h.

References fproperty, and override.

Property& VProperty::get ( ) [inline]

Definition at line 42 of file pa_vproperty.h.

References fproperty.

Referenced by VClass::add_property().

Member Data Documentation

Property VProperty::fproperty [private]

Definition at line 46 of file pa_vproperty.h.

Referenced by get(), and get_property().

The documentation for this class was generated from the following file:
  • pa_vproperty.h


Member List

VProperty Member List

This is the complete list of members for VProperty, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VProperty | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VProperty | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fproperty | VProperty | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get() | VProperty | [inline]
get_class() | VProperty | [inline, virtual]
get_element(const String &, Value &, bool) | Value | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | VProperty | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VProperty | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VProperty | [inline, virtual]


VRequest Class Reference

request class. More...

Inheritance diagram for VRequest:

[legend]
Collaboration diagram for VRequest:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
VRequest: 0. More...

override Value * | get_element (const String &name, Value &aself, bool)
request: fields. More...

override const VJunction * | put_element (Value &self, const String &name, Value *value, bool replace)
request: (key)=value. More...

VRequest (Request_info &ainfo, Request_charsets &acharsets)

Private Attributes

Request_info & finfo
Request_charsets & fcharsets

Detailed Description

request class.

Definition at line 27 of file pa_vrequest.h.

Constructor & Destructor Documentation

VRequest::VRequest | ( | Request_info & | ainfo,
 |  | Request_charsets & | acharsets
 | ) | [inline]

Definition at line 46 of file pa_vrequest.h.

Member Function Documentation

override const char* VRequest::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 34 of file pa_vrequest.h.

References override.

override VStateless_class* VRequest::get_class ( ) [inline, virtual]

VRequest: 0.

Implements Value.

Definition at line 36 of file pa_vrequest.h.

References override.

Value * VRequest::get_element | ( | const String & | name,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

request: fields.

Reimplemented from Value.

Definition at line 22 of file pa_vrequest.C.

References Value::bark(), Request_info::document_root, DOCUMENT_ROOT_NAME, fcharsets, finfo, String::L_TAINTED, Charset::NAME(), Request_info::post_data, Request_info::post_size, Request_info::query_string, size, Request_charsets::source(), and Request_info::uri.

const VJunction * VRequest::put_element | ( | Value & | self,
 |  | const String & | name,
 |  | Value * | value,
 |  | bool | replace
 | ) | [virtual]

request: (key)=value.

Reimplemented from Value.

Definition at line 45 of file pa_vrequest.C.

References Value::as_string(), String::CC_UPPER, change_case(), String::cstr(), Request_info::document_root, DOCUMENT_ROOT_NAME, fcharsets, finfo, String::L_FILE_SPEC, Value::put_element(), PUT_ELEMENT_REPLACED_ELEMENT, and Request_charsets::set_source().

Member Data Documentation

Request_info& VRequest::finfo [private]

Definition at line 29 of file pa_vrequest.h.

Referenced by get_element(), and put_element().

Request_charsets& VRequest::fcharsets [private]

Definition at line 30 of file pa_vrequest.h.

Referenced by get_element(), and put_element().

The documentation for this class was generated from the following files:
  • pa_vrequest.h
  • pa_vrequest.C


Member List

VRequest Member List

This is the complete list of members for VRequest, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fcharsets | VRequest | [private]
finfo | VRequest | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VRequest | [inline, virtual]
get_element(const String &name, Value &aself, bool) | VRequest | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &self, const String &name, Value *value, bool replace) | VRequest | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VRequest | [inline, virtual]
VRequest(Request_info &ainfo, Request_charsets &acharsets) | VRequest | [inline]


VResponse Class Reference

value of type 'response'. More...

Inheritance diagram for VResponse:

[legend]
Collaboration diagram for VResponse:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override HashStringValue * | get_hash ()
Response: ffields. More...

override Value * | get_element (const String &aname, Value &aself, bool)
Response: method,fields. More...

override const VJunction * | put_element (Value &self, const String &name, Value *value, bool replace)
Response: (attribute)=value. More...

VResponse (Request_info &ainfo, Request_charsets &acharsets)
HashStringValue & fields ()
used in pa_request.C. More...

Private Attributes

Request_info & finfo
Request_charsets & fcharsets
HashStringValue ffields

Detailed Description

value of type 'response'.

Definition at line 28 of file pa_vresponse.h.

Constructor & Destructor Documentation

VResponse::VResponse | ( | Request_info & | ainfo,
 |  | Request_charsets & | acharsets
 | ) | [inline]

Definition at line 51 of file pa_vresponse.h.

Member Function Documentation

override const char* VResponse::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 37 of file pa_vresponse.h.

References override.

override VStateless_class* VResponse::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 38 of file pa_vresponse.h.

References override.

Referenced by Request::Request().

override HashStringValue* VResponse::get_hash ( ) [inline, virtual]

Response: ffields.

Reimplemented from Value.

Definition at line 41 of file pa_vresponse.h.

References override.

Value * VResponse::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

Response: method,fields.

Reimplemented from VStateless_object.

Definition at line 22 of file pa_vresponse.C.

References String::CC_LOWER, String::change_case(), Request_charsets::client(), fcharsets, ffields, Hash< const String::Body, Value * >::get(), VStateless_object::get_element(), String::L_TAINTED, Charset::NAME(), REQUEST_HEADERS_ELEMENT_NAME, result, and Request_charsets::source().

const VJunction * VResponse::put_element | ( | Value & | self,
 |  | const String & | name,
 |  | Value * | value,
 |  | bool | replace
 | ) | [virtual]

Response: (attribute)=value.

Reimplemented from VStateless_object.

Definition at line 39 of file pa_vresponse.C.

References Value::as_string(), String::CC_LOWER, String::CC_UPPER, String::change_case(), change_case(), fcharsets, ffields, Hash< const String::Body, Value * >::put(), PUT_ELEMENT_REPLACED_ELEMENT, Request_charsets::set_client(), and Request_charsets::source().

HashStringValue& VResponse::fields ( ) [inline]

used in pa_request.C.

Definition at line 55 of file pa_vresponse.h.

Referenced by Request::core(), and Request::output_result().

Member Data Documentation

Request_info& VResponse::finfo [private]

Definition at line 30 of file pa_vresponse.h.

Request_charsets& VResponse::fcharsets [private]

Definition at line 31 of file pa_vresponse.h.

Referenced by get_element(), and put_element().

HashStringValue VResponse::ffields [private]

Definition at line 33 of file pa_vresponse.h.

Referenced by get_element(), and put_element().

The documentation for this class was generated from the following files:
  • pa_vresponse.h
  • pa_vresponse.C


Member List

VResponse Member List

This is the complete list of members for VResponse, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fcharsets | VResponse | [private]
ffields | VResponse | [private]
fields() | VResponse | [inline]
finfo | VResponse | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VResponse | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VResponse | [virtual]
get_hash() | VResponse | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &self, const String &name, Value *value, bool replace) | VResponse | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VResponse | [inline, virtual]
VResponse(Request_info &ainfo, Request_charsets &acharsets) | VResponse | [inline]


VStateless_class Class Reference

object' class. More...

Inheritance diagram for VStateless_class:

[legend]
Collaboration diagram for VStateless_class:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
VStateless_class: this. More...

override Value * | base ()
VStateless_class: fbase. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VStateless_class: $CLASS, $method. More...

VStateless_class (const String *aname=0, VStateless_class *abase=0)
void | lock ()
const String & | name () const
const char * | name_cstr () const
void | set_name (const String &aname)
Method * | get_method (const String &aname) const
virtual void | add_method (const String &name, Method &method)
virtual for VClass to override to pre-cache property accessors into fields. More...

void | add_native_method (const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count)
void | set_base (VStateless_class *abase)
VStateless_class * | base_class ()
bool | derived_from (VStateless_class &vclass)
virtual Value * | create_new_value (Pool &, HashStringValue &)
Returns:
new value for current class, used in classes/ & VClass.
 More...

just stubs, real onces defined below the hierarchy
virtual Value * | get_field (const String &)
virtual bool | replace_field (const String &, Value *)

Protected Methods

void | fill_properties (HashStringValue &acache)

Protected Attributes

VStateless_class * | fbase

Private Methods

void | put_method (const String &aname, Method *amethod)

Private Attributes

const String * | fname
const char * | fname_cstr
Hash< const String::Body,
Method * > 		fmethods
bool | flocked

Friends

class | Temp_method

Detailed Description

object' class.

stores

  • base: VClass::base()
  • methods: VStateless_class::fmethods
See also:
Method, VStateless_object, Temp_method

Definition at line 38 of file pa_vstateless_class.h.

Constructor & Destructor Documentation

VStateless_class::VStateless_class | ( | const String * | aname = 0,
 |  | VStateless_class * | abase = 0
 | ) | [inline]

Definition at line 63 of file pa_vstateless_class.h.

References flocked.

Member Function Documentation

const char* VStateless_class::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Reimplemented in VClass, VForm, VMail, VMath, and VMemory.

Definition at line 53 of file pa_vstateless_class.h.

override VStateless_class* VStateless_class::get_class ( ) [inline, virtual]

VStateless_class: this.

Implements Value.

Definition at line 56 of file pa_vstateless_class.h.

References override.

Referenced by Request::Request().

override Value* VStateless_class::base ( ) [inline, virtual]

VStateless_class: fbase.

Reimplemented from Value.

Definition at line 58 of file pa_vstateless_class.h.

References override.

Value * VStateless_class::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [virtual]

VStateless_class: $CLASS, $method.

Reimplemented from Value.

Reimplemented in MXnode, VClass, VForm, VMail, VMath, and VMemory.

Definition at line 41 of file pa_vstateless_class.C.

References Value::base(), CLASS_NAME, fbase, and get_method().

Referenced by _connect(), Request::configure(), Request::configure_admin(), MForm::configure_admin(), MMail::configure_user(), Request::core(), MXnode::get_element(), VStateless_object::get_element(), VMemory::get_element(), VMath::get_element(), VMail::get_element(), VForm::get_element(), VClass::get_element(), and Request::use_file().

void VStateless_class::lock ( ) [inline]

Definition at line 71 of file pa_vstateless_class.h.

References flocked.

Referenced by Methoded::register_directly_used().

const String& VStateless_class::name ( ) const [inline]

Definition at line 73 of file pa_vstateless_class.h.

Referenced by _send(), add_native_method(), MMail::configure_user(), Request::execute(), name_cstr(), Methoded::register_directly_used(), Request::Request(), and WContext::write().

const char* VStateless_class::name_cstr ( ) const [inline]

Definition at line 85 of file pa_vstateless_class.h.

References String::cstr(), fname_cstr, and name().

Referenced by VClass::add_property(), Method::check_actual_numbered_params(), Request::get_element(), VMethodFrame::store_param(), VObject::type(), and VClass::type().

void VStateless_class::set_name ( const String & aname ) [inline]

Definition at line 93 of file pa_vstateless_class.h.

Referenced by VClassMAIN::VClassMAIN().

Method* VStateless_class::get_method ( const String & aname ) const [inline]

Definition at line 97 of file pa_vstateless_class.h.

References Hash< K, V >::get().

Referenced by _process(), Request::execute_nonvirtual_method(), get_element(), and Request::get_element().

void VStateless_class::add_method | ( | const String & | name,
 |  | Method & | method
 | ) | [virtual]

virtual for VClass to override to pre-cache property accessors into fields.

Reimplemented in VClass.

Definition at line 14 of file pa_vstateless_class.C.

References put_method().

Referenced by VClass::add_method(), and add_native_method().

void VStateless_class::add_native_method | ( | const char * | cstr_name,
 |  | Method::Call_type | call_type,
 |  | NativeCodePtr | native_code,
 |  | int | min_numbered_params_count,
 |  | int | max_numbered_params_count
 | ) |

Definition at line 23 of file pa_vstateless_class.C.

References add_method(), Method::Call_type, name(), and NativeCodePtr.

Referenced by MDate::MDate(), MDouble::MDouble(), MFile::MFile(), MHash::MHash(), MHashfile::MHashfile(), MImage::MImage(), MInt::MInt(), MMail::MMail(), MMemory::MMemory(), MResponse::MResponse(), MString::MString(), MTable::MTable(), MVoid::MVoid(), and VClassMAIN::VClassMAIN().

void VStateless_class::set_base ( VStateless_class * abase ) [inline]

Definition at line 110 of file pa_vstateless_class.h.

VStateless_class* VStateless_class::base_class ( ) [inline]

Definition at line 114 of file pa_vstateless_class.h.

Referenced by Request::Request(), and VObject::VObject().

bool VStateless_class::derived_from ( VStateless_class & vclass ) [inline]

Definition at line 116 of file pa_vstateless_class.h.

Referenced by Request::get_element().

virtual Value* VStateless_class::get_field ( const String & ) [inline, virtual]

Definition at line 124 of file pa_vstateless_class.h.

virtual bool VStateless_class::replace_field | ( | const String & | ,
 |  | Value * |
 | ) | [inline, virtual]

Definition at line 125 of file pa_vstateless_class.h.

virtual Value* VStateless_class::create_new_value | ( | Pool & | ,
 |  | HashStringValue & |
 | ) | [inline, virtual]

Returns:
new value for current class, used in classes/ & VClass.

Reimplemented in MDate, MFile, MHash, MHashfile, MImage, MTable, MXnode, and VClass.

Definition at line 129 of file pa_vstateless_class.h.

Referenced by Request::execute(), and VObject::VObject().

void VStateless_class::fill_properties ( HashStringValue & acache ) [protected]

void VStateless_class::put_method | ( | const String & | aname,
 |  | Method * | amethod
 | ) | [private]

Definition at line 58 of file pa_vstateless_class.C.

References fmethods, and Hash< const String::Body, Method * >::put().

Referenced by add_method(), Temp_method::Temp_method(), and Temp_method::~Temp_method().

Friends And Related Function Documentation

friend class Temp_method [friend]

Definition at line 39 of file pa_vstateless_class.h.

Member Data Documentation

const String* VStateless_class::fname [private]

Definition at line 41 of file pa_vstateless_class.h.

const char* VStateless_class::fname_cstr [private]

Definition at line 42 of file pa_vstateless_class.h.

Referenced by name_cstr().

Hash<const String::Body, Method*> VStateless_class::fmethods [private]

Definition at line 43 of file pa_vstateless_class.h.

Referenced by put_method().

bool VStateless_class::flocked [private]

Definition at line 45 of file pa_vstateless_class.h.

Referenced by lock(), and VStateless_class().

VStateless_class* VStateless_class::fbase [protected]

Definition at line 49 of file pa_vstateless_class.h.

Referenced by VClass::as(), get_element(), VClass::prevent_append_if_exists_in_base(), and VClass::put_element().

The documentation for this class was generated from the following files:
  • pa_vstateless_class.h
  • pa_vstateless_class.C


Member List

VStateless_class Member List

This is the complete list of members for VStateless_class, including all inherited members.
add_method(const String &name, Method &method) | VStateless_class | [virtual]
add_native_method(const char *cstr_name, Method::Call_type call_type, NativeCodePtr native_code, int min_numbered_params_count, int max_numbered_params_count) | VStateless_class |
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | VStateless_class | [inline, virtual]
base_class() | VStateless_class | [inline]
base_object() | Value | [virtual]
create_new_value(Pool &, HashStringValue &) | VStateless_class | [inline, virtual]
derived_from(VStateless_class &vclass) | VStateless_class | [inline]
fbase | VStateless_class | [protected]
fill_properties(HashStringValue &acache) | VStateless_class | [protected]
flocked | VStateless_class | [private]
fmethods | VStateless_class | [private]
fname | VStateless_class | [private]
fname_cstr | VStateless_class | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStateless_class | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_class | [virtual]
get_field(const String &) | VStateless_class | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_method(const String &aname) const | VStateless_class | [inline]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
lock() | VStateless_class | [inline]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
name() const | VStateless_class | [inline]
name_cstr() const | VStateless_class | [inline]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
put_method(const String &aname, Method *amethod) | VStateless_class | [private]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
replace_field(const String &, Value *) | VStateless_class | [inline, virtual]
set_base(VStateless_class *abase) | VStateless_class | [inline]
set_derived(VObject *) | Value | [virtual]
set_name(const String &aname) | VStateless_class | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
Temp_method class | VStateless_class | [friend]
type() const | VStateless_class | [inline, virtual]
VStateless_class(const String *aname=0, VStateless_class *abase=0) | VStateless_class | [inline]


VStateless_object Class Reference

the object of some class. More...

Inheritance diagram for VStateless_object:

[legend]
Collaboration diagram for VStateless_object:

[legend]
List of all members.

Public Methods

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VStateless_object: class_transparent. More...

override const VJunction * | put_element (Value &aself, const String &aname, Value *avalue, bool areplace)
VStateless_object: class_transparent. More...

Detailed Description

the object of some class.

"of some class" means "with some set of methods and CLASS_fields".

Definition at line 22 of file pa_vstateless_object.h.

Member Function Documentation

override Value* VStateless_object::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VStateless_object: class_transparent.

Reimplemented from Value.

Reimplemented in VDate, VFile, VHash, VHashfile, VImage, VObject, VResponse, VString, VTable, VVoid, VXdoc, and VXnode.

Definition at line 26 of file pa_vstateless_object.h.

References Value::get_class(), VStateless_class::get_element(), and override.

Referenced by VVoid::get_element(), VTable::get_element(), VString::get_element(), VResponse::get_element(), VImage::get_element(), VHashfile::get_element(), VHash::get_element(), VFile::get_element(), VDate::get_element(), and VObject::stateless_object__get_element().

override const VJunction* VStateless_object::put_element | ( | Value & | aself,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool | areplace
 | ) | [inline, virtual]

VStateless_object: class_transparent.

Reimplemented from Value.

Reimplemented in VHash, VHashfile, VImage, VObject, VResponse, VVoid, and VXnode.

Definition at line 31 of file pa_vstateless_object.h.

References Value::get_class(), override, and Value::put_element().

Referenced by VObject::stateless_object__put_element().

The documentation for this class was generated from the following file:
  • pa_vstateless_object.h


Member List

VStateless_object Member List

This is the complete list of members for VStateless_object, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
get_class()=0 | Value | [pure virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VStateless_object | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const=0 | Value | [pure virtual]


VStatus Class Reference

status class. More...

Inheritance diagram for VStatus:

[legend]
Collaboration diagram for VStatus:

[legend]
List of all members.

Public Methods

const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

VStateless_class * get_class ()
extract VStateless_class. More...

Value * | get_element (const String &aname, Value &aself, bool)
Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.
 More...

Detailed Description

status class.

Definition at line 22 of file pa_vstatus.h.

Member Function Documentation

const char* VStatus::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 26 of file pa_vstatus.h.

VStateless_class* VStatus::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 27 of file pa_vstatus.h.

Value * VStatus::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

Returns:
Value element; can return Junction for methods; Code-Junction for code; Getter-Junction for property.

Reimplemented from Value.

Definition at line 215 of file pa_vstatus.C.

References Cache_manager::get_status(), memory_element(), pa_get_thread_id(), and rusage_element().

The documentation for this class was generated from the following files:
  • pa_vstatus.h
  • pa_vstatus.C


Member List

VStatus Member List

This is the complete list of members for VStatus, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VStatus | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VStatus | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VStatus | [inline, virtual]


VString Class Reference

value of type 'string'. implemented with String. More...

Inheritance diagram for VString:

[legend]
Collaboration diagram for VString:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | is_defined () const
VString: eq ''=false, ne ''=true. More...

override bool | as_bool () const
VString: 0 or !0. More...

override bool | is_string () const
VString: true. More...

override Value & | as_expr_result (bool return_string_as_is=false)
VString: fstring as VDouble or this depending on return_string_as_is. More...

override const String * | get_string ()
VString: fstring. More...

override double | as_double () const
VString: fstring. More...

override int | as_int () const
VString: fstring. More...

override VFile * | as_vfile (String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0)
VString: vfile. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VString: $method. More...

VString ()
VString (const String &avalue)
const String & | string () const
void | set_string (const String &astring)

Private Attributes

const String * | fstring

Detailed Description

value of type 'string'. implemented with String.

Definition at line 23 of file pa_vstring.h.

Constructor & Destructor Documentation

VString::VString ( ) [inline]

Definition at line 64 of file pa_vstring.h.

References fstring, and new.

VString::VString ( const String & avalue ) [inline]

Definition at line 65 of file pa_vstring.h.

References fstring.

Member Function Documentation

override const char* VString::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 26 of file pa_vstring.h.

References override.

override VStateless_class* VString::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 27 of file pa_vstring.h.

References override.

override bool VString::is_defined ( ) const [inline, virtual]

VString: eq ''=false, ne ''=true.

Reimplemented from Value.

Definition at line 29 of file pa_vstring.h.

References fstring, String::is_empty(), and override.

override bool VString::as_bool ( ) const [inline, virtual]

VString: 0 or !0.

Reimplemented from Value.

Definition at line 31 of file pa_vstring.h.

References as_double(), and override.

override bool VString::is_string ( ) const [inline, virtual]

VString: true.

Reimplemented from Value.

Definition at line 33 of file pa_vstring.h.

References override.

override Value& VString::as_expr_result ( bool return_string_as_is = false ) [inline, virtual]

VString: fstring as VDouble or this depending on return_string_as_is.

Reimplemented from Value.

Definition at line 35 of file pa_vstring.h.

References as_double(), and override.

Referenced by maybe_change_string_literal_to_double_literal().

override const String* VString::get_string ( ) [inline, virtual]

VString: fstring.

Reimplemented from Value.

Definition at line 42 of file pa_vstring.h.

References fstring, and override.

override double VString::as_double ( ) const [inline, virtual]

VString: fstring.

Reimplemented from Value.

Definition at line 44 of file pa_vstring.h.

References String::as_double(), fstring, and override.

Referenced by as_bool(), and as_expr_result().

override int VString::as_int ( ) const [inline, virtual]

VString: fstring.

Reimplemented from Value.

Definition at line 46 of file pa_vstring.h.

References String::as_int(), fstring, and override.

VFile * VString::as_vfile | ( | String::Language | lang = String::L_UNSPECIFIED,
 |  | const Request_charsets * | charsets = 0
 | ) | [virtual]

VString: vfile.

Reimplemented from Value.

Definition at line 13 of file pa_vstring.C.

References String::cstr(), fstring, String::Language, result, and VFile::set().

Referenced by Request::core().

override Value* VString::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VString: $method.

Reimplemented from VStateless_object.

Definition at line 53 of file pa_vstring.h.

References Value::bark(), VStateless_object::get_element(), override, and result.

const String& VString::string ( ) const [inline]

Definition at line 67 of file pa_vstring.h.

References fstring.

Referenced by _append(), _base64(), and maybe_change_string_literal_to_double_literal().

void VString::set_string ( const String & astring ) [inline]

Definition at line 68 of file pa_vstring.h.

References fstring.

Referenced by _append().

Member Data Documentation

const String* VString::fstring [private]

Definition at line 71 of file pa_vstring.h.

Referenced by as_double(), as_int(), as_vfile(), get_string(), is_defined(), set_string(), string(), and VString().

The documentation for this class was generated from the following files:
  • pa_vstring.h
  • pa_vstring.C


Member List

VString Member List

This is the complete list of members for VString, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VString | [inline, virtual]
as_double() const | VString | [inline, virtual]
as_expr_result(bool return_string_as_is=false) | VString | [inline, virtual]
as_int() const | VString | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | VString | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
fstring | VString | [private]
get_class() | VString | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VString | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | VString | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VString | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | VString | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
set_string(const String &astring) | VString | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
string() const | VString | [inline]
type() const | VString | [inline, virtual]
VString() | VString | [inline]
VString(const String &avalue) | VString | [inline]


VTable Class Reference

value of type 'table'. implemented with Table. More...

Inheritance diagram for VTable:

[legend]
Collaboration diagram for VTable:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override int | as_int () const
VTable: count. More...

override double | as_double () const
VTable: count. More...

override bool | is_defined () const
VTable: count!=0. More...

override bool | as_bool () const
VTable: 0 or !0. More...

override Value & | as_expr_result (bool)
VTable: count. More...

override Table * | get_table ()
extract VTable. More...

override Value * | get_element (const String &aname, Value &aself, bool)
VTable: columns,methods. More...

VTable (Table *atable=0)
void | set_table (Table &avalue)
Table & | table () const

Private Methods

Value * fields_element ()

Private Attributes

Table * ftable

Detailed Description

value of type 'table'. implemented with Table.

Definition at line 28 of file pa_vtable.h.

Constructor & Destructor Documentation

VTable::VTable ( Table * atable = 0 ) [inline]

Definition at line 50 of file pa_vtable.h.

References ftable.

Member Function Documentation

override const char* VTable::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 31 of file pa_vtable.h.

References override, and VTABLE_TYPE.

override VStateless_class* VTable::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 32 of file pa_vtable.h.

References override.

override int VTable::as_int ( ) const [inline, virtual]

VTable: count.

Reimplemented from Value.

Definition at line 34 of file pa_vtable.h.

References Array< ArrayString * >::count(), override, and table().

Referenced by as_bool(), as_double(), and as_expr_result().

override double VTable::as_double ( ) const [inline, virtual]

VTable: count.

Reimplemented from Value.

Definition at line 36 of file pa_vtable.h.

References as_int(), and override.

override bool VTable::is_defined ( ) const [inline, virtual]

VTable: count!=0.

Reimplemented from Value.

Definition at line 38 of file pa_vtable.h.

References as_bool(), and override.

override bool VTable::as_bool ( ) const [inline, virtual]

VTable: 0 or !0.

Reimplemented from Value.

Definition at line 40 of file pa_vtable.h.

References as_int(), and override.

Referenced by is_defined().

override Value& VTable::as_expr_result ( bool ) [inline, virtual]

VTable: count.

Reimplemented from Value.

Definition at line 42 of file pa_vtable.h.

References as_int(), and override.

override Table* VTable::get_table ( ) [inline, virtual]

extract VTable.

Reimplemented from Value.

Definition at line 44 of file pa_vtable.h.

References ftable, and override.

Referenced by table_row_to_hash().

Value * VTable::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VTable: columns,methods.

Reimplemented from VStateless_object.

Definition at line 42 of file pa_vtable.C.

References Table::column_name2index(), fields_element(), ftable, VStateless_object::get_element(), Table::item(), result, and TABLE_FIELDS_ELEMENT_NAME.

void VTable::set_table ( Table & avalue ) [inline]

Definition at line 52 of file pa_vtable.h.

References ftable.

Table& VTable::table ( ) const [inline]

Definition at line 55 of file pa_vtable.h.

References Value::bark(), and ftable.

Referenced by as_int(), and fields_element().

Value * VTable::fields_element ( ) [private]

Definition at line 30 of file pa_vtable.C.

References Table::columns(), Table::columns_type, Hash< const String::Body, Value * >::for_each(), Value::get_hash(), result, store_column_item_to_hash(), and table().

Referenced by get_element().

Member Data Documentation

Table* VTable::ftable [private]

Definition at line 68 of file pa_vtable.h.

Referenced by get_element(), get_table(), set_table(), table(), and VTable().

The documentation for this class was generated from the following files:
  • pa_vtable.h
  • pa_vtable.C


Member List

VTable Member List

This is the complete list of members for VTable, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VTable | [inline, virtual]
as_double() const | VTable | [inline, virtual]
as_expr_result(bool) | VTable | [inline, virtual]
as_int() const | VTable | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
fields_element() | VTable | [private]
free(void *ptr) | PA_Allocated | [inline, static]
ftable | VTable | [private]
get_class() | VTable | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VTable | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | VTable | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VTable | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VStateless_object | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
set_table(Table &avalue) | VTable | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
table() const | VTable | [inline]
type() const | VTable | [inline, virtual]
VTable(Table *atable=0) | VTable | [inline]


VVoid Class Reference

value of type 'void'. ex: usually $sjfklsjfksjdfk has this type. More...

Inheritance diagram for VVoid:

[legend]
Collaboration diagram for VVoid:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | is_void () const
VVoid: true [the only one, that reports true]. More...

override const String * | get_string ()
VVoid: "". More...

override bool | as_bool () const
VVoid: false. More...

override bool | is_defined () const
VVoid: false. More...

override double | as_double () const
VVoid: 0. More...

override int | as_int () const
VVoid: 0. More...

override Value & | as_expr_result (bool)
VVoid: this. More...

override VFile * | as_vfile (String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0)
VVoid: empty vfile. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
VVoid: methods. More...

override const VJunction * | put_element (Value &aself, const String &aname, Value *avalue, bool areplace)
VVoid: bark. More...

Static Private Attributes

const String | void_string_value

Detailed Description

value of type 'void'. ex: usually $sjfklsjfksjdfk has this type.

Definition at line 20 of file pa_vvoid.h.

Member Function Documentation

override const char* VVoid::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Definition at line 23 of file pa_vvoid.h.

References override.

override VStateless_class* VVoid::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Definition at line 24 of file pa_vvoid.h.

References override.

override bool VVoid::is_void ( ) const [inline, virtual]

VVoid: true [the only one, that reports true].

Reimplemented from Value.

Definition at line 27 of file pa_vvoid.h.

References override.

override const String* VVoid::get_string ( ) [inline, virtual]

VVoid: "".

Reimplemented from Value.

Definition at line 29 of file pa_vvoid.h.

References override, and void_string_value.

override bool VVoid::as_bool ( ) const [inline, virtual]

VVoid: false.

Reimplemented from Value.

Definition at line 31 of file pa_vvoid.h.

References override.

override bool VVoid::is_defined ( ) const [inline, virtual]

VVoid: false.

Reimplemented from Value.

Definition at line 33 of file pa_vvoid.h.

References override.

override double VVoid::as_double ( ) const [inline, virtual]

VVoid: 0.

Reimplemented from Value.

Definition at line 35 of file pa_vvoid.h.

References override.

Referenced by _double().

override int VVoid::as_int ( ) const [inline, virtual]

VVoid: 0.

Reimplemented from Value.

Definition at line 37 of file pa_vvoid.h.

References override.

Referenced by _int().

override Value& VVoid::as_expr_result ( bool ) [inline, virtual]

VVoid: this.

Reimplemented from Value.

Definition at line 39 of file pa_vvoid.h.

References override.

VFile * VVoid::as_vfile | ( | String::Language | lang = String::L_UNSPECIFIED,
 |  | const Request_charsets * | charsets = 0
 | ) | [virtual]

VVoid: empty vfile.

Reimplemented from Value.

Definition at line 15 of file pa_vvoid.C.

References String::Language, result, and VFile::set().

override Value* VVoid::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

VVoid: methods.

Reimplemented from VStateless_object.

Definition at line 46 of file pa_vvoid.h.

References VStateless_object::get_element(), override, and result.

override const VJunction* VVoid::put_element | ( | Value & | aself,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool | areplace
 | ) | [inline, virtual]

VVoid: bark.

Reimplemented from VStateless_object.

Definition at line 55 of file pa_vvoid.h.

References override, and Value::put_element().

Member Data Documentation

const String VVoid::void_string_value [static, private]

Definition at line 13 of file pa_vvoid.C.

Referenced by get_string().

The documentation for this class was generated from the following files:
  • pa_vvoid.h
  • pa_vvoid.C


Member List

VVoid Member List

This is the complete list of members for VVoid, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VVoid | [inline, virtual]
as_double() const | VVoid | [inline, virtual]
as_expr_result(bool) | VVoid | [inline, virtual]
as_int() const | VVoid | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | VVoid | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VVoid | [inline, virtual]
get_element(const String &aname, Value &aself, bool looking_up) | VVoid | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | VVoid | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | VVoid | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | VVoid | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | VVoid | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VVoid | [inline, virtual]
void_string_value | VVoid | [private, static]


VXdoc Class Reference

value of type 'xdoc'. implemented with libxml & co. More...

Inheritance diagram for VXdoc:

[legend]
Collaboration diagram for VXdoc:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override Value * | as (const char *atype, bool looking_up)
all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | as_bool () const
VXdoc: true. More...

override Value & | as_expr_result (bool)
VXdoc: true. More...

override Value * | get_element (const String &aname, Value &aself, bool)
VXdoc: $CLASS,$method, fields. More...

override xmlNode & | get_xmlnode ()
override VXdoc & | get_vxdoc ()
VXdoc ()
VXdoc (Request_charsets &acharsets, xmlDoc &adocument)
void | set_xmldoc (Request_charsets &acharsets, xmlDoc &adocument)
xmlDoc & | get_xmldoc ()
Request_charsets & charsets ()
VXnode & | wrap (xmlNode &anode)

Public Attributes

VHash search_namespaces
VXdoc::Output_options output_options

Private Attributes

Request_charsets * fcharsets
xmlDoc * | fdocument

Detailed Description

value of type 'xdoc'. implemented with libxml & co.

Definition at line 28 of file pa_vxdoc.h.

Constructor & Destructor Documentation

VXdoc::VXdoc ( ) [inline]

Definition at line 57 of file pa_vxdoc.h.

References fcharsets, and fdocument.

VXdoc::VXdoc | ( | Request_charsets & | acharsets,
 |  | xmlDoc & | adocument
 | ) | [inline]

Definition at line 62 of file pa_vxdoc.h.

References set_xmldoc().

Member Function Documentation

override const char* VXdoc::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from VXnode.

Definition at line 31 of file pa_vxdoc.h.

References override, and VXDOC_TYPE.

override Value* VXdoc::as | ( | const char * | atype,
 |  | bool | looking_up
 | ) | [virtual]

all except VObject/VClass: this if @atype eq type() VObject/VClass: can locate parent class by it's type.

Reimplemented from Value.

override VStateless_class* VXdoc::get_class ( ) [inline, virtual]

extract VStateless_class.

Reimplemented from VXnode.

Definition at line 34 of file pa_vxdoc.h.

References override.

override bool VXdoc::as_bool ( ) const [inline, virtual]

VXdoc: true.

Reimplemented from VXnode.

Definition at line 37 of file pa_vxdoc.h.

References override.

Referenced by as_expr_result().

override Value& VXdoc::as_expr_result ( bool ) [inline, virtual]

VXdoc: true.

Reimplemented from VXnode.

Definition at line 40 of file pa_vxdoc.h.

References as_bool(), and override.

override Value* VXdoc::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VXdoc: $CLASS,$method, fields.

Reimplemented from VXnode.

override xmlNode& VXdoc::get_xmlnode ( ) [inline, virtual]

Reimplemented from VXnode.

Definition at line 47 of file pa_vxdoc.h.

References get_xmldoc(), and override.

override VXdoc& VXdoc::get_vxdoc ( ) [inline, virtual]

Reimplemented from VXnode.

Definition at line 51 of file pa_vxdoc.h.

References override.

void VXdoc::set_xmldoc | ( | Request_charsets & | acharsets,
 |  | xmlDoc & | adocument
 | ) | [inline]

Definition at line 68 of file pa_vxdoc.h.

References fcharsets, and fdocument.

Referenced by VXdoc().

xmlDoc& VXdoc::get_xmldoc ( ) [inline]

Definition at line 73 of file pa_vxdoc.h.

References fdocument.

Referenced by get_xmlnode().

Request_charsets& VXdoc::charsets ( ) [inline]

Reimplemented from VXnode.

Definition at line 81 of file pa_vxdoc.h.

References fcharsets.

VXnode& VXdoc::wrap ( xmlNode & anode )

Member Data Documentation

VHash VXdoc::search_namespaces

Definition at line 93 of file pa_vxdoc.h.

struct VXdoc::Output_options VXdoc::output_options

Request_charsets* VXdoc::fcharsets [private]

Definition at line 112 of file pa_vxdoc.h.

Referenced by charsets(), set_xmldoc(), and VXdoc().

xmlDoc* VXdoc::fdocument [private]

Definition at line 113 of file pa_vxdoc.h.

Referenced by get_xmldoc(), set_xmldoc(), and VXdoc().

The documentation for this class was generated from the following file:
  • pa_vxdoc.h


Member List

VXdoc Member List

This is the complete list of members for VXdoc, including all inherited members.
as(const char *atype, bool looking_up) | VXdoc | [virtual]
as_bool() const | VXdoc | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VXdoc | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
charsets() | VXdoc | [inline]
fcharsets | VXdoc | [private]
fdocument | VXdoc | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VXdoc | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VXdoc | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
get_vxdoc() | VXdoc | [inline, virtual]
get_xmldoc() | VXdoc | [inline]
get_xmlnode() | VXdoc | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
output_options | VXdoc |
put_element(Value &self, const String &aname, Value *avalue, bool replace) | VXnode | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
search_namespaces | VXdoc |
set_derived(VObject *) | Value | [virtual]
set_xmldoc(Request_charsets &acharsets, xmlDoc &adocument) | VXdoc | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VXdoc | [inline, virtual]
VXdoc() | VXdoc | [inline]
VXdoc(Request_charsets &acharsets, xmlDoc &adocument) | VXdoc | [inline]
VXnode(xmlNode &anode) | VXnode | [inline]
wrap(xmlNode &anode) | VXdoc |


VXdoc::Output_options Struct Reference

Collaboration diagram for VXdoc::Output_options:

[legend]
List of all members.

Public Methods

Output_options ()

Public Attributes

const String * | method
const String * | encoding
const String * | mediaType
int | indent
const String * | version
int | standalone
int | omitXmlDeclaration

Constructor & Destructor Documentation

VXdoc::Output_options::Output_options ( ) [inline]

Definition at line 104 of file pa_vxdoc.h.

References indent, omitXmlDeclaration, and standalone.

Member Data Documentation

const String* VXdoc::Output_options::method

Definition at line 96 of file pa_vxdoc.h.

const String* VXdoc::Output_options::encoding

Definition at line 97 of file pa_vxdoc.h.

const String* VXdoc::Output_options::mediaType

Definition at line 98 of file pa_vxdoc.h.

int VXdoc::Output_options::indent

Definition at line 99 of file pa_vxdoc.h.

Referenced by Output_options().

const String* VXdoc::Output_options::version

Definition at line 100 of file pa_vxdoc.h.

int VXdoc::Output_options::standalone

Definition at line 101 of file pa_vxdoc.h.

Referenced by Output_options().

int VXdoc::Output_options::omitXmlDeclaration

Definition at line 102 of file pa_vxdoc.h.

Referenced by Output_options().

The documentation for this struct was generated from the following file:
  • pa_vxdoc.h


Member List

VXdoc::Output_options Member List

This is the complete list of members for VXdoc::Output_options, including all inherited members.
encoding | VXdoc::Output_options |
indent | VXdoc::Output_options |
mediaType | VXdoc::Output_options |
method | VXdoc::Output_options |
omitXmlDeclaration | VXdoc::Output_options |
Output_options() | VXdoc::Output_options | [inline]
standalone | VXdoc::Output_options |
version | VXdoc::Output_options |


VXnode Class Reference

value of type 'xnode'. implemented with xmlNode. More...

Inheritance diagram for VXnode:

[legend]
Collaboration diagram for VXnode:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override VStateless_class * | get_class ()
extract VStateless_class. More...

override bool | as_bool () const
VXnode: true. More...

override Value & | as_expr_result (bool)
VXnode: true. More...

override Value * | get_element (const String &aname, Value &aself, bool)
VXnode: $CLASS,$method, fields. More...

override const VJunction * | put_element (Value &self, const String &aname, Value *avalue, bool replace)
VXnode: $nodeValue. More...

VXnode (xmlNode &anode)
virtual xmlNode & | get_xmlnode ()
virtual VXdoc & | get_vxdoc ()
Request_charsets & charsets ()

Private Attributes

xmlNode & | fnode

Detailed Description

value of type 'xnode'. implemented with xmlNode.

Definition at line 34 of file pa_vxnode.h.

Constructor & Destructor Documentation

VXnode::VXnode ( xmlNode & anode ) [inline]

Definition at line 54 of file pa_vxnode.h.

References fnode.

Member Function Documentation

override const char* VXnode::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Reimplemented in VXdoc.

Definition at line 37 of file pa_vxnode.h.

References override, and VXNODE_TYPE.

override VStateless_class* VXnode::get_class ( ) [inline, virtual]

extract VStateless_class.

Implements Value.

Reimplemented in VXdoc.

Definition at line 38 of file pa_vxnode.h.

References override.

override bool VXnode::as_bool ( ) const [inline, virtual]

VXnode: true.

Reimplemented from Value.

Reimplemented in VXdoc.

Definition at line 41 of file pa_vxnode.h.

References override.

Referenced by as_expr_result().

override Value& VXnode::as_expr_result ( bool ) [inline, virtual]

VXnode: true.

Reimplemented from Value.

Reimplemented in VXdoc.

Definition at line 44 of file pa_vxnode.h.

References as_bool(), and override.

override Value* VXnode::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool |
 | ) | [virtual]

VXnode: $CLASS,$method, fields.

Reimplemented from VStateless_object.

Reimplemented in VXdoc.

override const VJunction* VXnode::put_element | ( | Value & | self,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool | replace
 | ) | [virtual]

VXnode: $nodeValue.

Reimplemented from VStateless_object.

virtual xmlNode& VXnode::get_xmlnode ( ) [inline, virtual]

Reimplemented in VXdoc.

Definition at line 59 of file pa_vxnode.h.

References fnode.

virtual VXdoc& VXnode::get_vxdoc ( ) [inline, virtual]

Reimplemented in VXdoc.

Definition at line 63 of file pa_vxnode.h.

References assert, fnode, and result.

Request_charsets& VXnode::charsets ( )

Reimplemented in VXdoc.

Member Data Documentation

xmlNode& VXnode::fnode [private]

Definition at line 74 of file pa_vxnode.h.

Referenced by get_vxdoc(), get_xmlnode(), and VXnode().

The documentation for this class was generated from the following file:
  • pa_vxnode.h


Member List

VXnode Member List

This is the complete list of members for VXnode, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | VXnode | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool) | VXnode | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
charsets() | VXnode |
fnode | VXnode | [private]
free(void *ptr) | PA_Allocated | [inline, static]
get_class() | VXnode | [inline, virtual]
get_element(const String &aname, Value &aself, bool) | VXnode | [virtual]
get_hash() | Value | [inline, virtual]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_string() | Value | [inline, virtual]
get_table() | Value | [inline, virtual]
get_vxdoc() | VXnode | [inline, virtual]
get_xmlnode() | VXnode | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &self, const String &aname, Value *avalue, bool replace) | VXnode | [virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
set_derived(VObject *) | Value | [virtual]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | VXnode | [inline, virtual]
VXnode(xmlNode &anode) | VXnode | [inline]


WContext Class Reference

Write context they do different write()s here, later picking up the result. More...

Inheritance diagram for WContext:

[legend]
Collaboration diagram for WContext:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override const String * | get_string ()
WContext: accumulated fstring. More...

override VStateless_class * | get_class ()
WContext: none yet | transparent. More...

virtual void | write (const String &astring, String::Language alang)
appends a fstring to result. More...

virtual void | write (Value &avalue)
writes Value; raises an error if already, providing origin. More...

void | write (Value &avalue, String::Language alang)
if value is VString writes fstring, else writes Value; raises an error if already, providing origin. More...

virtual StringOrValue | result ()
retrives the resulting value that can be String if value==0 or the Value object wmethod_frame first checks for $result and if there is one, returns it instead. More...

void | attach_junction (Junction *ajunction)
WContext (Value *avalue, WContext *aparent)
virtual | ~WContext ()
void | set_constructing (bool aconstructing)
bool | get_constructing ()
void | set_in_expression (bool ain_expression)
bool | get_in_expression ()
void | set_somebody_entered_some_class ()
bool | get_somebody_entered_some_class ()

Protected Attributes

String & fstring
Value * fvalue

Private Methods

void | detach_junctions ()

Private Attributes

bool | constructing
bool | in_expression
bool | entered_object
bool | entered_class
bool | were_string_writes
WContext * | fparent
Array< Junction * > junctions

Friends

class | Request

Detailed Description

Write context they do different write()s here, later picking up the result.

See also:
Request::wcontext

Definition at line 46 of file pa_wcontext.h.

Constructor & Destructor Documentation

WContext::WContext | ( | Value * | avalue,
 |  | WContext * | aparent
 | ) | [inline]

Definition at line 94 of file pa_wcontext.h.

References constructing, entered_class, entered_object, fparent, fstring, fvalue, in_expression, new, and were_string_writes.

virtual WContext::~WContext ( ) [inline, virtual]

Definition at line 100 of file pa_wcontext.h.

References detach_junctions().

Member Function Documentation

override const char* WContext::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Implements Value.

Reimplemented in VCodeFrame, VMethodFrame, and WWrapper.

Definition at line 51 of file pa_wcontext.h.

References override.

override const String* WContext::get_string ( ) [inline, virtual]

WContext: accumulated fstring.

Reimplemented from Value.

Reimplemented in VMethodFrame.

Definition at line 53 of file pa_wcontext.h.

References fstring, and override.

Referenced by Request::execute(), VMethodFrame::get_string(), and Request::process().

override VStateless_class* WContext::get_class ( ) [inline, virtual]

WContext: none yet | transparent.

Implements Value.

Reimplemented in VMethodFrame.

Definition at line 56 of file pa_wcontext.h.

References fvalue, Value::get_class(), and override.

virtual void WContext::write | ( | const String & | astring,
 |  | String::Language | alang
 | ) | [inline, virtual]

appends a fstring to result.

Reimplemented in VCodeFrame.

Definition at line 61 of file pa_wcontext.h.

References String::append(), fstring, and String::Language.

Referenced by Request::execute_method(), Request::put_element(), write(), VMethodFrame::write(), and VCodeFrame::write().

void WContext::write ( Value & avalue ) [virtual]

writes Value; raises an error if already, providing origin.

Reimplemented in VCodeFrame.

Definition at line 13 of file pa_wcontext.C.

References fvalue, Value::get_class(), VStateless_class::name(), and Value::type().

void WContext::write | ( | Value & | avalue,
 |  | String::Language | alang
 | ) | [inline]

if value is VString writes fstring, else writes Value; raises an error if already, providing origin.

Reimplemented in VMethodFrame.

Definition at line 71 of file pa_wcontext.h.

References fstring, Value::get_string(), String::Language, and write().

virtual StringOrValue WContext::result ( ) [inline, virtual]

retrives the resulting value that can be String if value==0 or the Value object wmethod_frame first checks for $result and if there is one, returns it instead.

Reimplemented in VMethodFrame.

Definition at line 84 of file pa_wcontext.h.

References fstring, and fvalue.

Referenced by Request::execute(), Request::execute_method(), Request::process(), and VMethodFrame::result().

void WContext::attach_junction ( Junction * ajunction ) [inline]

Definition at line 88 of file pa_wcontext.h.

References junctions.

Referenced by Junction::Junction(), and Junction::reattach().

void WContext::set_constructing ( bool aconstructing ) [inline]

Definition at line 104 of file pa_wcontext.h.

References constructing.

Referenced by Request::execute(), and WWrapper::put_element().

bool WContext::get_constructing ( ) [inline]

Definition at line 105 of file pa_wcontext.h.

References constructing.

Referenced by Request::execute(), and Request::get_element().

void WContext::set_in_expression ( bool ain_expression ) [inline]

Definition at line 107 of file pa_wcontext.h.

References in_expression.

Referenced by Request::execute().

bool WContext::get_in_expression ( ) [inline]

Definition at line 108 of file pa_wcontext.h.

References in_expression.

Referenced by Request::execute().

void WContext::set_somebody_entered_some_class ( ) [inline]

Definition at line 110 of file pa_wcontext.h.

References entered_class.

Referenced by Request::execute().

bool WContext::get_somebody_entered_some_class ( ) [inline]

Definition at line 111 of file pa_wcontext.h.

References entered_class.

Referenced by Request::get_element().

void WContext::detach_junctions ( ) [private]

Definition at line 26 of file pa_wcontext.C.

References fparent, Array_iterator< T >::has_next(), junctions, and Array_iterator< T >::next().

Referenced by ~WContext().

Friends And Related Function Documentation

friend class Request [friend]

Definition at line 47 of file pa_wcontext.h.

Member Data Documentation

String& WContext::fstring [protected]

Definition at line 118 of file pa_wcontext.h.

Referenced by get_string(), result(), WContext(), write(), and VCodeFrame::write().

Value* WContext::fvalue [protected]

Definition at line 119 of file pa_wcontext.h.

Referenced by WWrapper::as_value(), get_class(), WWrapper::put_element(), result(), WContext(), and write().

bool WContext::constructing [private]

Definition at line 123 of file pa_wcontext.h.

Referenced by get_constructing(), set_constructing(), and WContext().

bool WContext::in_expression [private]

Definition at line 124 of file pa_wcontext.h.

Referenced by get_in_expression(), set_in_expression(), and WContext().

bool WContext::entered_object [private]

Definition at line 125 of file pa_wcontext.h.

Referenced by WContext().

bool WContext::entered_class [private]

Definition at line 126 of file pa_wcontext.h.

Referenced by get_somebody_entered_some_class(), set_somebody_entered_some_class(), and WContext().

bool WContext::were_string_writes [private]

Definition at line 127 of file pa_wcontext.h.

Referenced by WContext().

WContext* WContext::fparent [private]

Definition at line 131 of file pa_wcontext.h.

Referenced by detach_junctions(), and WContext().

Array<Junction*> WContext::junctions [private]

Definition at line 132 of file pa_wcontext.h.

Referenced by attach_junction(), and detach_junctions().

The documentation for this class was generated from the following files:
  • pa_wcontext.h
  • pa_wcontext.C


Member List

WContext Member List

This is the complete list of members for WContext, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
attach_junction(Junction *ajunction) | WContext | [inline]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
constructing | WContext | [private]
detach_junctions() | WContext | [private]
entered_class | WContext | [private]
entered_object | WContext | [private]
fparent | WContext | [private]
free(void *ptr) | PA_Allocated | [inline, static]
fstring | WContext | [protected]
fvalue | WContext | [protected]
get_class() | WContext | [inline, virtual]
get_constructing() | WContext | [inline]
get_element(const String &, Value &, bool) | Value | [virtual]
get_hash() | Value | [inline, virtual]
get_in_expression() | WContext | [inline]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_somebody_entered_some_class() | WContext | [inline]
get_string() | WContext | [inline, virtual]
get_table() | Value | [inline, virtual]
in_expression | WContext | [private]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
junctions | WContext | [private]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &, const String &aname, Value *, bool) | Value | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
Request class | WContext | [friend]
result() | WContext | [inline, virtual]
set_constructing(bool aconstructing) | WContext | [inline]
set_derived(VObject *) | Value | [virtual]
set_in_expression(bool ain_expression) | WContext | [inline]
set_somebody_entered_some_class() | WContext | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | WContext | [inline, virtual]
WContext(Value *avalue, WContext *aparent) | WContext | [inline]
were_string_writes | WContext | [private]
write(const String &astring, String::Language alang) | WContext | [inline, virtual]
write(Value &avalue) | WContext | [virtual]
write(Value &avalue, String::Language alang) | WContext | [inline]
~WContext() | WContext | [inline, virtual]


WWrapper Class Reference

specialized write context, adds to WContext VHash autocreation ability. More...

Inheritance diagram for WWrapper:

[legend]
Collaboration diagram for WWrapper:

[legend]
List of all members.

Public Methods

override const char * | type () const
value type, used for error reporting and 'is' expression operator. More...

override Value * | get_element (const String &aname, Value &aself, bool looking_up)
WWrapper: transparent. More...

override const VJunction * | put_element (Value &aself, const String &aname, Value *avalue, bool areplace)
WWrapper: transparent. More...

WWrapper (Value *avalue, WContext *aparent)

Private Methods

Value & | as_value () const

Detailed Description

specialized write context, adds to WContext VHash autocreation ability.

Definition at line 17 of file pa_wwrapper.h.

Constructor & Destructor Documentation

WWrapper::WWrapper | ( | Value * | avalue,
 |  | WContext * | aparent
 | ) | [inline]

Definition at line 44 of file pa_wwrapper.h.

Member Function Documentation

override const char* WWrapper::type ( ) const [inline, virtual]

value type, used for error reporting and 'is' expression operator.

Reimplemented from WContext.

Definition at line 20 of file pa_wwrapper.h.

References override.

override Value* WWrapper::get_element | ( | const String & | aname,
 |  | Value & | aself,
 |  | bool | looking_up
 | ) | [inline, virtual]

WWrapper: transparent.

Reimplemented from Value.

Definition at line 22 of file pa_wwrapper.h.

References as_value(), Value::get_element(), and override.

override const VJunction* WWrapper::put_element | ( | Value & | aself,
 |  | const String & | aname,
 |  | Value * | avalue,
 |  | bool | areplace
 | ) | [inline, virtual]

WWrapper: transparent.

Reimplemented from Value.

Definition at line 26 of file pa_wwrapper.h.

References WContext::fvalue, override, Value::put_element(), and WContext::set_constructing().

Value& WWrapper::as_value ( ) const [inline, private]

Definition at line 50 of file pa_wwrapper.h.

References WContext::fvalue.

Referenced by get_element().

The documentation for this class was generated from the following file:
  • pa_wwrapper.h


Member List

WWrapper Member List

This is the complete list of members for WWrapper, including all inherited members.
as(const char *atype, bool) | Value | [inline, virtual]
as_bool() const | Value | [inline, virtual]
as_double() const | Value | [inline, virtual]
as_expr_result(bool=false) | Value | [inline, virtual]
as_int() const | Value | [inline, virtual]
as_string() | Value | [inline]
as_value() const | WWrapper | [inline, private]
as_vfile(String::Language lang=String::L_UNSPECIFIED, const Request_charsets *charsets=0) | Value | [virtual]
attach_junction(Junction *ajunction) | WContext | [inline]
bark(const char *reason, const String *problem_source=0) const | Value | [inline, protected]
base() | Value | [inline, virtual]
base_object() | Value | [virtual]
free(void *ptr) | PA_Allocated | [inline, static]
fstring | WContext | [protected]
fvalue | WContext | [protected]
get_class() | WContext | [inline, virtual]
get_constructing() | WContext | [inline]
get_element(const String &aname, Value &aself, bool looking_up) | WWrapper | [inline, virtual]
get_hash() | Value | [inline, virtual]
get_in_expression() | WContext | [inline]
get_junction() | Value | [virtual]
get_last_derived_class() | Value | [inline, virtual]
get_property() | Value | [inline, virtual]
get_somebody_entered_some_class() | WContext | [inline]
get_string() | WContext | [inline, virtual]
get_table() | Value | [inline, virtual]
is(const char *atype) | Value | [inline]
is_defined() const | Value | [inline, virtual]
is_evaluated_expr() const | Value | [inline, virtual]
is_string() const | Value | [inline, virtual]
is_void() const | Value | [inline, virtual]
malloc(size_t size) | PA_Allocated | [inline, static]
malloc_atomic(size_t size) | PA_Allocated | [inline, static]
operator delete(void *ptr) | PA_Allocated | [inline, static]
operator new(size_t size) | PA_Allocated | [inline, static]
put_element(Value &aself, const String &aname, Value *avalue, bool areplace) | WWrapper | [inline, virtual]
realloc(void *ptr, size_t size) | PA_Allocated | [inline, static]
result() | WContext | [inline, virtual]
set_constructing(bool aconstructing) | WContext | [inline]
set_derived(VObject *) | Value | [virtual]
set_in_expression(bool ain_expression) | WContext | [inline]
set_somebody_entered_some_class() | WContext | [inline]
strdup(const char *auto_variable_never_null, size_t helper_length=0) | PA_Allocated | [inline, static]
type() const | WWrapper | [inline, virtual]
WContext(Value *avalue, WContext *aparent) | WContext | [inline]
write(const String &astring, String::Language alang) | WContext | [inline, virtual]
write(Value &avalue) | WContext | [virtual]
write(Value &avalue, String::Language alang) | WContext | [inline]
WWrapper(Value *avalue, WContext *aparent) | WWrapper | [inline]
~WContext() | WContext | [inline, virtual]


Hierarchical Index

Parser3 Source Code Class Hierarchy

Go to the graphical class hierarchy

This inheritance list is sorted roughly, but not completely, alphabetically:

  • _IO_COUNTERS_
  • apr_file_t
  • apr_finfo_t
  • apr_sdbm_datum_t
  • apr_sdbm_t
  • Array< T >::Action_options
  • Array_iterator< T >
  • AutoSYNCHRONIZED
  • cache_line
  • Charset::Tables
  • Charset::Tables::Rec
  • Charset::UTF8CaseTable
  • Charset::UTF8CaseTable::Rec
  • chr_data
  • compile_data
  • CORD_ec_struct
  • CORD_fill_data
  • CORD_pe
  • CORD_Pos
  • CordRep
  • CordRep::Concatenation
  • CordRep::Function
  • CordRep::Generic
  • Dictionary::Subst
  • dirent
  • Exception
  • ffblk
  • File_read_result
  • ForestElement
  • FT
  • gdBuf
  • gdImage::Point
  • GIF_Header
  • Hashfile_value_serialized_prolog
  • JPG_Exif_IFD_begin
  • JPG_Exif_IFD_entry
  • JPG_Exif_segment_begin
  • JPG_Exif_TIFF_header
  • JPG_Segment_head
  • JPG_Size_segment_body
  • Junction
  • lf_state
  • lsplit_result
  • lt_dlhandle_struct
  • lt_dlinfo
  • lt_dlloader
  • lt_dlsymlist
  • lt_dlsymlists_t
  • lt_user_dlloader
  • match_data
  • Mutex
  • Operation
  • Operation::Origin
  • PA_Allocated
    • Array< T >
      • Stack< T >
    • Array< ArrayString * >
      • Table
    • Array< const String * >
      • Date_calendar_table_template_columns
      • String_match_table_template_columns
    • Array< Methoded * >
      • Methoded_array
    • Array< Trace >
      • Stack< Trace >
        • Request::Exception_trace
    • Array< Value * >
      • MethodParams
    • Cache_manager
      • SQL_Driver_manager
      • Stylesheet_manager
    • Charset
    • Dictionary
    • Font
    • gdGifEncoder
    • gdGrowingBuf
    • gdImage
    • Hash< K, V >
    • Hash< K, V >::Pair
    • Hash< const String::Body, Cache_manager * >
      • Cache_managers
    • Hash< const String::Body, Charset * >
      • Charsets
    • Hash< const String::Body, String::Language >
      • Untaint_lang_name2enum
    • Hash< int, const char * >
      • EXIF_tag_value2name
    • Method
    • Property
    • Request
    • SMTP
    • SQL_Connection
    • String
    • Stylesheet_connection
    • Value
      • VBool
      • VConsole
      • VCookie
      • VEnv
      • VJunction
      • VProperty
      • VRequest
      • VStateless_class
        • Methoded
          • MDate
          • MDouble
          • MFile
          • MForm
          • MHash
          • MHashfile
          • MImage
          • MInt
          • MMail
          • MMath
          • MMemory
          • MResponse
          • MString
          • MTable
          • MVoid
          • MXnode
        • VClass
          • VClassMAIN
        • VForm
        • VMail
        • VMath
        • VMemory
      • VStateless_object
        • VDate
        • VDouble
        • VFile
        • VHash
        • VHashfile
        • VImage
        • VInt
        • VObject
        • VResponse
        • VString
        • VTable
        • VVoid
        • VXnode
          • VXdoc
      • VStatus
      • WContext
        • VCodeFrame
        • VMethodFrame
        • WWrapper
  • PA_Cleaned
  • PA_exec_result
  • PA_MD5_CTX
  • pa_request_rec_tag
  • Parse_control
  • Parser_module_config_tag
  • PNG_Header
  • Pool
  • Pool::Cleanup
  • Pooled
    • VHashfile
  • Pos
  • Random_provider
  • real_pcre
  • real_pcre_extra
  • refill_data
  • Request::Exception_details
  • Request::Execute_nonvirtual_method_result
  • Request::StackItem
  • Request::Trace
  • Request_charsets
  • Request_context_saver
  • Request_info
  • SAPI
  • SAPI_Info
  • SQL_Driver
  • SQL_Driver::Placeholder
  • SQL_Driver_query_event_handlers
  • SQL_Driver_services
    • SQL_Driver_services_impl
  • SQL_Error
  • String::Body
  • String::C
  • String::Cm
  • String::Languages
  • StringOrValue
  • Stylesheet_connection_ptr
  • substr_args
  • TableSeparators
  • Temp_client_charset
  • Temp_connection
  • Temp_derived
  • Temp_hash_value< K, V >
  • Temp_lang
  • Temp_method
  • Temp_method_frame_self
  • Temp_value_element
  • uuid
  • VClass::Prevent_info
  • VHash_lock
  • VObject::Prevent_append_if_exists_in_static_or_base_info
  • VXdoc::Output_options


Compound Member Index

Parser3 Source Code Compound Members

_ | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | ~

Here is a list of all class members with links to the class documentation for each member:

- _ -

  • _default : VHash
  • _this : VObject::Prevent_append_if_exists_in_static_or_base_info, VClass::Prevent_info
  • _throw() : SQL_Driver_services, SQL_Driver_services_impl

- a -
  • a_count : gdGifEncoder
  • abort() : SAPI
  • absolute() : Request
  • accum : gdGifEncoder
  • acquire() : Mutex, Random_provider
  • Action_options() : Array< T >::Action_options
  • add_column() : SQL_Driver_query_event_handlers
  • add_header_attribute() : SAPI
  • add_method() : VStateless_class, VClass
  • add_native_method() : VStateless_class
  • add_property() : VClass
  • add_row() : SQL_Driver_query_event_handlers
  • add_row_cell() : SQL_Driver_query_event_handlers
  • addEncoding() : Charset
  • address : lt_dlsymlist
  • adjust() : Array< T >::Action_options
  • after : VCookie
  • alias_method() : Parse_control
  • allocated : Hash< K, V >
  • allocates_index : Hash< K, V >
  • alphabet : Font
  • anti_endless_execute_recoursion : Request_context_saver, Request
  • api_version() : SQL_Driver
  • append() : gdGrowingBuf, String, String::Body, String::Languages, Array< T >
  • append_help_length() : String
  • append_know_length() : String, String::Body
  • append_strdup() : String
  • append_strdup_know_length() : String::Body
  • append_to() : String
  • AppendFormEntry() : VForm
  • Arc() : gdImage
  • args : pa_request_rec_tag
  • Array() : Array< T >
  • Array_iterator() : Array_iterator< T >
  • Array_iterator< T > : Array< T >
  • as() : VXdoc, VObject, VClass, Value
  • as_bool() : VXnode, VXdoc, VVoid, VTable, VString, VProperty, VObject, MethodParams, VJunction, VInt, VImage, VHash, VFile, VDouble, VDate, VClass, VBool, Value
  • as_double() : VVoid, VTable, VString, VObject, MethodParams, VInt, VHash, VDouble, VDate, VBool, Value, String
  • as_expr_result() : VXnode, VXdoc, VVoid, VTable, VString, VProperty, VObject, VJunction, VInt, VImage, VHash, VFile, VDouble, VDate, VClass, VBool, Value
  • as_int() : VVoid, VTable, VString, VObject, MethodParams, VInt, VHash, VDouble, VBool, Value, String
  • as_junction() : MethodParams
  • as_no_junction() : MethodParams
  • as_string() : StringOrValue, MethodParams, Value
  • as_value() : WWrapper, StringOrValue
  • as_vfile() : VVoid, VString, VObject, VHash, VFile, Value
  • attach_junction() : WContext
  • AutoSYNCHRONIZED : AutoSYNCHRONIZED, Mutex

- b -
  • bark() : Value
  • base() : VStateless_class, VObject, VMethodFrame, Value
  • base_class() : VStateless_class
  • base_object() : Value
  • before : VCookie
  • before_rows() : SQL_Driver_query_event_handlers
  • blkno : apr_sdbm_t
  • blkptr : apr_sdbm_t
  • blue : gdImage
  • Blue() : gdImage
  • body : String, String::Body
  • Body() : String::Body
  • bottom_index() : Request::Exception_trace
  • bottom_value() : Request::Exception_trace
  • BoundsSafe() : gdImage
  • brackets_nestages : Parse_control
  • buf : gdGifEncoder, CORD_fill_data
  • buffer : PA_MD5_CTX
  • BumpPixel() : gdGifEncoder
  • byte_align_identifier : JPG_Exif_TIFF_header

- c -
  • C() : String::C
  • c : ForestElement
  • Cache_managers() : Cache_managers
  • Call_type : Method
  • call_type : Method
  • caller() : VMethodFrame
  • caller_data : lt_dlhandle_struct
  • calloc() : PA_Allocated
  • cAlternateFileName : ffblk
  • can_store_param() : VMethodFrame
  • cbits : compile_data
  • CC_LOWER : String
  • CC_UPPER : String
  • cclass : Parse_control
  • change_case() : String
  • Change_case_kind : String
  • char_init() : gdGifEncoder
  • char_out() : gdGifEncoder
  • Charset() : Charset
  • charsets : VXnode, VXdoc, Request
  • Charsets() : Charsets
  • check_actual_numbered_params() : Method
  • check_db() : VHashfile
  • check_lang() : String::Languages
  • check_lock() : VHash
  • cl_block() : gdGifEncoder
  • cl_hash() : gdGifEncoder
  • classes() : Request
  • classes_conf : Request
  • Cleanup() : Pool::Cleanup
  • cleanup : PA_Cleaned, Pool::Cleanup
  • cleanups : Pool
  • clear() : VHashfile, Pos, String::Body, Request::Exception_trace, Request::Trace, Hash< K, V >
  • clear_flg : gdGifEncoder
  • ClearCode : gdGifEncoder
  • client() : Request_charsets
  • client_data : CordRep::Function
  • clock_seq : uuid
  • close() : VHashfile, Stylesheet_connection, SQL_Connection
  • close_connection() : Stylesheet_manager, SQL_Driver_manager
  • CloseConnect() : SMTP
  • Cm() : String::Cm
  • code : Junction, real_pcre, Operation, Hash< K, V >::Pair, JPG_Segment_head
  • code_int : gdGifEncoder
  • codetab : gdGifEncoder
  • col : Pos, Operation::Origin
  • Color() : gdImage
  • ColorAllocate() : gdImage
  • ColorClosest() : gdImage
  • ColorDeallocate() : gdImage
  • ColorExact() : gdImage
  • ColorRGB() : gdImage
  • colorsTotal : gdImage
  • ColorsTotal() : gdImage
  • column : TableSeparators
  • column_name2index() : Table
  • columns() : Table
  • columns_type : Table
  • comment() : SQL_Error, Exception
  • commit() : SQL_Driver, SQL_Connection
  • compile() : Request
  • components_count : JPG_Exif_IFD_entry
  • compress() : gdGifEncoder
  • concatenation : CordRep
  • configure() : Request
  • configure_admin() : Request, MForm, Methoded_array, Methoded
  • configure_admin_done : Request
  • configure_user() : MMail, Methoded_array, Methoded
  • connect() : SQL_Driver, SQL_Connection
  • connected() : Stylesheet_connection, SQL_Connection
  • connection() : Request
  • connection_cache : Stylesheet_manager, SQL_Driver_manager
  • connection_cache_element_base_type : SQL_Driver_manager
  • connection_cache_type : Stylesheet_manager, SQL_Driver_manager
  • connection_cache_value_type : Stylesheet_manager
  • ConnectToHost() : SMTP
  • construct_statics() : Methoded
  • constructing : WContext
  • constructor_line : Dictionary
  • consts : MXnode
  • content_length : Request_info
  • content_type : pa_request_rec_tag, Request_info
  • cookie : Request_info, Request
  • Copy() : gdImage
  • CopyResampled() : gdImage
  • core() : Request
  • count : String::Languages, Hash< K, V >, Array< T >, PA_MD5_CTX, CORD_fill_data
  • count_int : gdGifEncoder
  • CountDown : gdGifEncoder
  • create() : Operation::Origin
  • Create() : gdImage
  • create_new_value() : VStateless_class, VClass, MXnode, MTable, MImage, MHashfile, MHash, MFile, MDate
  • CreateFromGif() : gdImage
  • cstr() : String, String::Body
  • cstr_to_string_body() : String
  • cstrm() : String, String::Body
  • CT_ANY : Method
  • CT_DYNAMIC : Method
  • CT_STATIC : Method
  • ctypes : match_data, compile_data
  • cur_accum : gdGifEncoder
  • cur_bits : gdGifEncoder
  • cur_end : CORD_Pos
  • cur_leaf : CORD_Pos
  • cur_pos : CORD_Pos
  • cur_start : CORD_Pos
  • curbit : apr_sdbm_t
  • current() : Table
  • curx : gdGifEncoder
  • cury : gdGifEncoder

- d -
  • d_name : dirent
  • data : cache_line, Pool::Cleanup, JPG_Size_segment_body
  • Date_calendar_table_template_columns() : Date_calendar_table_template_columns
  • DecodeColor() : gdImage
  • defined : SQL_Error, Array< T >::Action_options
  • delete_files() : VHashfile
  • deleted : VCookie
  • delim : lsplit_result
  • depcount : lt_dlhandle_struct
  • dependencies : Stylesheet_connection
  • deplibs : lt_dlhandle_struct
  • depth : CordRep::Generic, CordRep::Function, CordRep::Concatenation
  • derived_from() : VStateless_class
  • deserialize() : String
  • deserialize_value() : VHashfile
  • detach_junctions() : WContext
  • Dictionary() : Dictionary
  • die() : SAPI
  • dif : GIF_Header
  • dirbno : apr_sdbm_t
  • dirbuf : apr_sdbm_t
  • directory_entry_count : JPG_Exif_IFD_begin
  • dirf : apr_sdbm_t
  • disconnect() : SQL_Driver, Stylesheet_connection, SQL_Connection
  • div() : VInt, VDouble
  • dlloader_data : lt_user_dlloader, lt_dlloader
  • dlloader_exit : lt_user_dlloader, lt_dlloader
  • document_root : Request_info
  • DoExtension() : gdImage
  • DoSetPixel() : gdImage
  • dptr : apr_sdbm_datum_t
  • driver_cache : SQL_Driver_manager
  • driver_cache_type : SQL_Driver_manager
  • dsize : apr_sdbm_datum_t
  • dummy : JPG_Exif_TIFF_header, PNG_Header
  • dump() : String, String::Body, String::Languages
  • dwReserved0 : ffblk
  • dwReserved1 : ffblk

- e -
  • ec_buf : CORD_ec_struct
  • ec_bufptr : CORD_ec_struct
  • ec_cord : CORD_ec_struct
  • element_type : Array< T >
  • EMail : SMTP
  • Empty : String
  • encloser : TableSeparators
  • encode() : gdGifEncoder
  • encoding : VXdoc::Output_options
  • end_match_ptr : match_data
  • end_offset_top : match_data
  • end_subject : match_data
  • endonly : match_data
  • entered_class : WContext
  • entered_object : WContext
  • environment() : SAPI
  • EOFCode : gdGifEncoder
  • err : PA_exec_result
  • error : Parse_control
  • errorcode : match_data
  • Exception() : Exception
  • Exception_details() : Request::Exception_details
  • Exception_trace : Request::Exception_trace, Request
  • exception_trace : Request
  • exception_trace_bottom : Request_context_saver
  • exception_trace_top : Request_context_saver
  • execute() : Request
  • execute_method() : Request
  • execute_nonvirtual_method() : Request
  • Execute_nonvirtual_method_result() : Request::Execute_nonvirtual_method_result
  • execute_virtual_method() : Request
  • EXIF_tag_value2name() : EXIF_tag_value2name
  • expand() : gdGrowingBuf, Hash< K, V >, Array< T >
  • expired() : Stylesheet_connection, SQL_Connection
  • explicit_result : Parse_control
  • extCh : Charset::Tables::Rec
  • extract_default() : VHash
  • extract_origin() : Request::Exception_trace

- f -
  • fail_register_cleanup() : Pool
  • fallocated : gdGrowingBuf, Array< T >
  • farray : Array_iterator< T >
  • fbase : VStateless_class, VObject
  • fbool : VBool
  • fbottom : Request::Exception_trace
  • fcaller : VMethodFrame
  • fcc : compile_data
  • fcharsets : VXdoc, VResponse, VRequest, VForm, Temp_client_charset
  • fclass : Temp_method, VObject
  • fclasses : Request
  • fclient : Temp_client_charset, Request_charsets
  • fcolumns : Table
  • fcomment : SQL_Error, Exception
  • fconnection : Stylesheet_connection_ptr, SQL_Connection, Request_context_saver, Request
  • fconsts : VMath
  • fcurrent : Table, Array_iterator< T >
  • fdefault_lang : Request
  • fdefined : SQL_Error
  • fderived : VObject
  • fdocument : VXdoc
  • fdouble : VDouble
  • fdriver : SQL_Connection
  • fds : SMTP
  • felements : Array< T >
  • fetch() : String::Body
  • fexception : SQL_Driver_services_impl
  • fexif : VImage
  • ff_attrib : ffblk
  • ff_name : ffblk
  • ffields : VResponse, VObject, VImage, VFile, VClass
  • ffile_name_cstr : VFile
  • ffile_spec : Stylesheet_connection
  • ffont : VImage
  • fhash : VHash_lock, VHash, Temp_hash_value< K, V >
  • fhProv : Random_provider
  • fields : VResponse, VImage, VFile, VForm
  • fields_element() : VTable, VFile
  • file_list : Request
  • file_name : VHashfile
  • file_no : Parse_control, Operation::Origin
  • file_pos : refill_data
  • file_spec() : Stylesheet_connection
  • filename : pa_request_rec_tag, lt_dlinfo
  • Fill() : gdImage
  • fill_fields() : VCookie
  • fill_properties() : VStateless_class
  • fill_received() : VMail
  • fill_unspecified_params() : VMethodFrame
  • filled_client : VForm
  • filled_source : VForm
  • FilledPolygon() : gdImage
  • FilledPolygonReplaceColor() : gdImage
  • FilledRectangle() : gdImage
  • FillToBorder() : gdImage
  • fimage : VImage
  • find_sym : lt_user_dlloader, lt_dlloader
  • finfo : VResponse, VRequest, VEnv, pa_request_rec_tag
  • finteger : VInt
  • finterrupted : Request
  • first_char : String, real_pcre
  • first_IFD_offset : JPG_Exif_TIFF_header
  • first_that() : Hash< K, V >, Array< T >
  • first_that_begins() : Dictionary
  • FirstName : SMTP
  • fisUTF8 : Charset
  • fjunction : VJunction
  • flags : apr_sdbm_t, lt_dlhandle_struct
  • flang : Request_context_saver, Request
  • flast : Array_iterator< T >
  • flocked : VStateless_class, VHash
  • flush_char() : gdGifEncoder
  • FlushBuffer() : SMTP
  • fmail : Request_charsets
  • fmethod_frame : Temp_method_frame_self, Request::StackItem
  • fmethods : VStateless_class
  • fn : CordRep::Function
  • fname : Temp_method, VStateless_class, Temp_value_element, Request::Trace, Temp_hash_value< K, V >
  • FNAME : Charset
  • FNAME_CSTR : Charset
  • fname_cstr : VStateless_class
  • fnode : VXnode
  • fnumbered_params : VMethodFrame
  • fonColor : GIF_Header
  • Font() : Font
  • font() : VImage
  • fops : Request::StackItem
  • for_each() : VHashfile, String::Body, String::Languages, Hash< K, V >, Array< T >
  • for_each_ref() : Hash< K, V >, Array< T >
  • forigin : Request::Trace
  • form : Request
  • format : JPG_Exif_IFD_entry
  • Format() : String::Body
  • fpairs_count : Hash< K, V >
  • fparent : WContext
  • fpool : Request, Pooled
  • fproblem_source : Exception
  • fproperty : VProperty
  • fptr : gdGrowingBuf
  • fr : Request_context_saver
  • free() : PA_Allocated
  • free_ent : gdGifEncoder
  • frequest : Temp_connection, Temp_lang
  • frequest_charset : SQL_Driver_services_impl
  • frequest_info : VForm
  • fresult_initial_void : VMethodFrame
  • from : Dictionary::Subst, Charset::UTF8CaseTable::Rec
  • from_length : Dictionary::Subst
  • fromTable : Charset::Tables
  • fsaved_derived : Temp_derived
  • fself : VMethodFrame
  • fservices : SQL_Connection
  • fsource : Request_charsets
  • fstring : WContext, StringOrValue, VString
  • fstylesheet : Stylesheet_connection
  • ft_scalar : FT
  • ft_struct : FT
  • ftable : VTable
  • ftCreationTime : ffblk
  • ftime : VDate
  • ftLastAccessTime : ffblk
  • ftLastWriteTime : ffblk
  • ftop : Stack< T >
  • ftranscoder : Charset
  • ftype : SQL_Error, Exception
  • ftz : VDate
  • ftz_cstr : VDate
  • function : CordRep
  • function_buf : CORD_Pos
  • furl : SQL_Connection, SQL_Driver_services_impl
  • fused : gdGrowingBuf, Array< T >
  • fused_refs : Hash< K, V >
  • fvalue : WContext, StringOrValue, Temp_derived, Request::StackItem
  • fvalue_ptr : VFile
  • fvalue_size : VFile
  • fwhere : Temp_value_element

- g -
  • g_init_bits : gdGifEncoder
  • gdBuf() : gdBuf
  • gdGifEncoder() : gdGifEncoder
  • gdGrowingBuf() : gdGrowingBuf
  • generate() : Random_provider
  • generic : CordRep
  • get() : VProperty, Hash< K, V >, Charsets, Array< T >
  • get_as() : MethodParams
  • get_class() : WContext, VXnode, VXdoc, VVoid, VTable, VString, VStatus, VStateless_class, VResponse, VRequest, VProperty, VObject, VMethodFrame, VJunction, VInt, VImage, VHashfile, VHash, VFile, VEnv, VDouble, VDate, VCookie, VConsole, VBool, Value
  • get_connection() : Stylesheet_manager, SQL_Driver_manager
  • get_connection_from_cache() : Stylesheet_manager, SQL_Driver_manager
  • get_constructing() : WContext
  • get_db_for_reading() : VHashfile
  • get_db_for_writing() : VHashfile
  • get_default() : VHash
  • get_details() : Request
  • get_disk_time() : Stylesheet_connection
  • get_double() : VDouble
  • get_driver_from_cache() : SQL_Driver_manager
  • get_element() : WWrapper, VXnode, VXdoc, VVoid, VTable, VString, VStatus, VStateless_object, VStateless_class, VResponse, VRequest, VObject, VMethodFrame, VMemory, VMath, VMail, VImage, VHashfile, VHash, VForm, VFile, VEnv, VDate, VCookie, VConsole, VCodeFrame, VClass, Value, Request, MXnode
  • get_env() : SAPI
  • get_exception_cstr() : Request
  • get_field() : VStateless_class, VHashfile
  • get_hash() : VResponse, VObject, VHashfile, VHash, Value
  • get_in_expression() : WContext
  • get_int() : VInt, VDouble
  • get_interrupted() : Request
  • get_junction() : VJunction, Value
  • get_last_derived() : VObject
  • get_last_derived_class() : VObject, Value
  • get_line() : SMTP
  • get_localtime() : VDate
  • get_method() : VStateless_class
  • get_method_frame() : Request
  • get_new_disk_time() : Stylesheet_connection
  • get_processed() : MethodParams
  • get_property() : VProperty, Value
  • get_ref() : Array< T >
  • get_result_variable() : VMethodFrame
  • get_self() : Request
  • get_somebody_entered_some_class() : WContext
  • get_status() : Stylesheet_manager, SQL_Driver_manager, Cache_manager
  • get_string() : WContext, StringOrValue, VVoid, VString, VMethodFrame, VInt, VDouble, Value
  • get_table() : VTable, VObject, Value
  • get_time() : VDate
  • get_time_used() : Stylesheet_connection, SQL_Connection
  • get_url() : SQL_Connection
  • get_value() : StringOrValue
  • get_vxdoc() : VXnode, VXdoc
  • get_xmldoc() : VXdoc
  • get_xmlnode() : VXnode, VXdoc
  • GetAndSetTheSocket() : SMTP
  • getAttributeValue() : VForm
  • GetBuffer() : SMTP
  • GetChar() : SMTP
  • GetCode() : gdImage
  • GetConnection() : SMTP
  • GetDataBlock() : gdImage
  • GetInterlaced() : gdImage
  • GetPixel() : gdImage
  • getter : Property
  • GetTransparent() : gdImage
  • Gif() : gdImage
  • GIFNextPixel() : gdGifEncoder
  • green : gdImage
  • Green() : gdImage

- h -
  • handle : apr_file_t, Mutex, ffblk
  • has_frac() : VDouble
  • has_next() : Array_iterator< T >
  • Hash() : Hash< K, V >
  • hash() : VHash
  • hash_code() : String::Body
  • header : CordRep::Generic, CordRep::Function, CordRep::Concatenation
  • header_only : pa_request_rec_tag
  • headers : File_read_result
  • headers_out : pa_request_rec_tag
  • Height : gdGifEncoder
  • height : Font, JPG_Size_segment_body, GIF_Header, PNG_Header
  • high_height : PNG_Header
  • high_width : PNG_Header
  • hmask : apr_sdbm_t
  • HomePage : SMTP
  • hsize : gdGifEncoder
  • htab : gdGifEncoder
  • HttpAccept : SMTP
  • HttpUserAgent : SMTP

- i -
  • ifont : Font
  • im : gdGifEncoder
  • image() : VImage
  • imap : VForm
  • in_buffer : SMTP
  • in_buffer_total : SMTP
  • in_call_value : Parse_control
  • in_count : gdGifEncoder
  • in_expression : WContext
  • in_index : SMTP
  • inc() : VInt, VDouble
  • indent : VXdoc::Output_options
  • index_display() : Font
  • index_of() : Font
  • index_width() : Font
  • info : lt_dlhandle_struct
  • initialize() : SQL_Driver
  • initTranscoder() : Charset
  • intCh : Charset::Tables::Rec
  • interlace : gdImage
  • Interlace : gdGifEncoder
  • invariant() : String::Languages
  • is() : Value
  • is_defined() : VVoid, VTable, VString, VProperty, VObject, VJunction, VHash, VBool, Value
  • is_dlinited : SQL_Driver_manager
  • is_empty() : String, String::Body, Stack< T >, Request::Exception_trace
  • is_evaluated_expr() : VInt, VDouble, VBool, Value
  • is_full() : Hash< K, V >, Array< T >
  • is_getter : Junction
  • is_not_just_lang : String::Languages
  • is_null : SQL_Driver::Placeholder
  • is_string() : VString, Value
  • is_void() : VVoid, Value
  • IsAddressARawIpaddress() : SMTP
  • isUTF8() : Charset
  • item() : Table

- j -
  • Junction() : Junction
  • junction : VJunction, VMethodFrame
  • junctions : WContext

- k -
  • key : Hash< K, V >::Pair
  • key_type : Hash< K, V >
  • keyptr : apr_sdbm_t

- l -
  • L_AS_IS : String
  • L_CLEAN : String
  • L_FILE_SPEC : String
  • L_HTML : String
  • L_HTTP_HEADER : String
  • L_JS : String
  • L_MAIL_HEADER : String
  • L_OPTIMIZE_BIT : String
  • L_PASS_APPENDED : String
  • L_REGEX : String
  • L_SQL : String
  • L_TAINTED : String
  • L_UNSPECIFIED : String
  • L_URI : String
  • L_XML : String
  • lang : String::Languages
  • langs : String, String::Languages
  • Language : String
  • Languages() : String::Languages
  • last() : MethodParams
  • last_line_end_col : Parse_control
  • last_winsock_error : SMTP
  • LastName : SMTP
  • lcc : match_data, compile_data
  • lckcnt : apr_sdbm_t
  • left : CordRep::Concatenation
  • left_len : CordRep::Generic, CordRep::Function, CordRep::Concatenation
  • len : CORD_fill_data, ForestElement, CordRep::Generic, CordRep::Function, CordRep::Concatenation
  • length : String, String::Body, String::Cm, String::C, File_read_result, JPG_Segment_head
  • letter_spacing : Font
  • lf_cache : lf_state
  • lf_current : lf_state
  • lf_file : lf_state
  • limit : Array< T >::Action_options
  • Line() : gdImage
  • line : Pos, Operation::Origin
  • LineReplaceColor() : gdImage
  • lineStyle : gdImage
  • lineWidth : gdImage
  • link : Hash< K, V >::Pair
  • load() : Stylesheet_connection, TableSeparators
  • load_charset() : Charsets
  • load_definition() : Charset
  • loader : lt_dlhandle_struct
  • loader_name : lt_dlloader
  • locals_names : Method
  • locate() : Table
  • lock() : VStateless_class
  • log() : SAPI
  • ls : Parse_control
  • ls_sp : Parse_control
  • ls_stack : Parse_control
  • LWZReadByte() : gdImage

- m -
  • m_db : VHashfile
  • magic_number : real_pcre
  • mail : Request_charsets, Request
  • mail_received : Request_info
  • main_alias : Parse_control
  • main_class : Request
  • make_langs() : String::Languages
  • MakeSmtpHeader() : SMTP
  • malloc() : SQL_Driver_services, SQL_Driver_services_impl, PA_Allocated
  • malloc_atomic() : SQL_Driver_services, SQL_Driver_services_impl, PA_Allocated
  • mark : SQL_Driver_services
  • marker : JPG_Segment_head
  • match() : String
  • max_numbered_params_count : Method
  • maxbits : gdGifEncoder
  • maxbno : apr_sdbm_t
  • maxcode : gdGifEncoder
  • maxmaxcode : gdGifEncoder
  • maybe_expire() : Cache_managers
  • maybe_expire_cache() : Stylesheet_manager, SQL_Driver_manager, Cache_manager
  • maybe_put_replaced() : Hash< K, V >
  • maybe_replace_maybe_append() : Hash< K, V >
  • maybe_replace_never_append() : Hash< K, V >
  • MDate() : MDate
  • MDouble() : MDouble
  • mediaType : VXdoc::Output_options
  • merge_dont_replace() : Hash< K, V >
  • message_hash_to_string() : VMail
  • method : VXdoc::Output_options, Junction, pa_request_rec_tag, Request_info, Request::Execute_nonvirtual_method_result
  • Method::Method() : Method
  • method_frame : Request::StackItem, Junction, Request_context_saver, Request
  • Methoded() : Methoded
  • Methoded_array() : Methoded_array
  • MFile() : MFile
  • MForm() : MForm
  • MHash() : MHash
  • MHashfile() : MHashfile
  • mid() : String, String::Body
  • MImage() : MImage
  • mime_type_of() : Request
  • mime_types : Request
  • min_numbered_params_count : Method
  • MInt() : MInt
  • MiscSocketSetup() : SMTP
  • MMail() : MMail
  • MMath() : MMath
  • MMemory() : MMemory
  • mod() : VInt, VDouble
  • module : lt_dlhandle_struct
  • module_close : lt_user_dlloader, lt_dlloader
  • module_open : lt_user_dlloader, lt_dlloader
  • monospace : Font
  • MResponse() : MResponse
  • MString() : MString
  • MTable() : MTable
  • mul() : VInt, VDouble
  • Mutex() : Mutex
  • MVoid() : MVoid
  • MXnode() : MXnode
  • my : VMethodFrame
  • my_hostname : SMTP

- n -
  • n_bits : gdGifEncoder
  • NAME() : Charset
  • name : VStateless_class, Request::Trace, VObject::Prevent_append_if_exists_in_static_or_base_info, VClass::Prevent_info, SQL_Driver::Placeholder, lt_dlinfo, lt_dlsymlist
  • name2number : Table
  • name2number_hash_class : Table
  • NAME_CSTR() : Charset
  • name_cstr() : VStateless_class
  • native_code : Method
  • ncmp() : String::Body
  • new_cache : refill_data
  • next : Array_iterator< T >, lt_dlsymlists_t, lt_dlhandle_struct, lt_dlloader
  • nFileSizeHigh : ffblk
  • nFileSizeLow : ffblk
  • node : uuid
  • notbol : match_data
  • notempty : match_data
  • noteol : match_data
  • null : CordRep::Generic, CordRep::Function, CordRep::Concatenation
  • nulls : GIF_Header
  • numbered_params() : VMethodFrame
  • numComponents : JPG_Size_segment_body

- o -
  • offset : Table, gdGifEncoder, Array< T >::Action_options
  • offset_end : match_data
  • offset_max : match_data
  • offset_overflow : match_data
  • offset_vector : match_data
  • omitXmlDeclaration : VXdoc::Output_options
  • open : VHashfile, gdImage
  • open_socket() : SMTP
  • Operation() : Operation
  • operator bool() : Pos, Request::Trace, Exception, Dictionary::Subst, lsplit_result
  • operator const Body() : String
  • operator const char *() : String::C
  • operator delete() : PA_Allocated
  • operator gdBuf() : gdGrowingBuf
  • operator new() : SQL_Driver, PA_Allocated
  • operator!() : String::Body
  • operator!=() : String, String::Body
  • operator+=() : Array< T >
  • operator->() : Stylesheet_connection_ptr
  • operator<() : String, String::Body
  • operator<<() : String, String::Body
  • operator<=() : String, String::Body
  • operator=() : SQL_Error, Stylesheet_connection_ptr, String, Pool, Hash< K, V >, Exception, Array< T >
  • operator==() : String, String::Body
  • operator>() : String, String::Body
  • operator>=() : String, String::Body
  • operator[]() : MethodParams, Array< T >
  • ops : Request::StackItem, Operation
  • opt : String::Languages
  • options : real_pcre_extra, real_pcre
  • origin : Request::Trace, Operation
  • OtherOperationCount : _IO_COUNTERS_
  • OtherTransferCount : _IO_COUNTERS_
  • out : PA_exec_result
  • out_buffer : SMTP
  • out_buffer_total : SMTP
  • out_count : gdGifEncoder
  • out_index : SMTP
  • output() : gdGifEncoder
  • Output_options() : VXdoc::Output_options
  • output_options : VXdoc
  • output_result() : VCookie, Request

- p -
  • PA_Cleaned() : PA_Cleaned
  • pa_dictionary_add_first : Dictionary
  • PA_exec_result() : PA_exec_result
  • pagbno : apr_sdbm_t
  • pagbuf : apr_sdbm_t
  • pagf : apr_sdbm_t
  • Pair() : Hash< K, V >::Pair
  • params_names : Method
  • Parse_control() : Parse_control
  • ParseFormInput() : VForm
  • ParseGetFormInput() : VForm
  • ParseMimeInput() : VForm
  • parser_code : Method
  • parser_config_filespec : Parser_module_config_tag
  • parser_status_allowed : Parser_module_config_tag
  • Pass : gdGifEncoder
  • path : CORD_Pos
  • path_info : pa_request_rec_tag
  • path_len : CORD_Pos
  • path_translated : Request_info
  • pcre_tables : Charset
  • pe_cord : CORD_pe
  • pe_start_pos : CORD_pe
  • pending_state : Parse_control
  • piece : lsplit_result
  • ping() : SQL_Driver, SQL_Connection
  • pixels : gdImage
  • polyAllocated : gdImage
  • Polygon() : gdImage
  • polyInts : gdImage
  • Pool() : Pool
  • pool : Request, pa_request_rec_tag, apr_sdbm_t
  • Pooled() : Pooled
  • pop() : Stack< T >
  • Pos() : Pos
  • pos : String, String::Body, Parse_control, chr_data
  • pos_next_c() : Parse_control
  • pos_next_line() : Parse_control
  • pos_prev_c() : Parse_control
  • post_data : Request_info
  • post_size : Request_info
  • prepare_encoder() : gdGifEncoder
  • prepare_message() : SMTP
  • prev_disk_time : Stylesheet_connection
  • prev_expiration_pass_time : Stylesheet_manager, SQL_Driver_manager
  • prevent_append_if_exists_in_base() : VClass
  • prevent_append_if_exists_in_static_or_base() : VObject
  • prevent_overwrite_property() : VClass
  • problem_source : Exception, Request::Exception_details
  • process() : Request
  • process_to_string() : Request
  • process_to_value() : Request
  • propagate_exception() : SQL_Driver_services, SQL_Driver_services_impl
  • ptr : gdBuf
  • push() : Stack< T >
  • put() : Hash< K, V >, Array< T >
  • put_connection_to_cache() : Stylesheet_manager, SQL_Driver_manager
  • put_dont_replace() : Hash< K, V >
  • put_driver_to_cache() : SQL_Driver_manager
  • put_element() : WWrapper, VXnode, VVoid, VStateless_object, VResponse, VRequest, VObject, VMethodFrame, VImage, VHashfile, VHash, VCookie, VConsole, VCodeFrame, VClass, Value, Request, Methoded
  • put_field() : VHashfile
  • put_method() : VStateless_class
  • put_replaced() : Hash< K, V >
  • Putbyte() : gdGifEncoder
  • Putword() : gdGifEncoder

- q -
  • query() : SQL_Driver, SQL_Connection
  • query_string : Request_info
  • quote() : SQL_Driver, SQL_Connection

- r -
  • r : SAPI_Info
  • Random_provider() : Random_provider
  • rcontext : Junction, Request_context_saver, Request
  • read_post() : SAPI
  • ReadImage() : gdImage
  • ReadOperationCount : _IO_COUNTERS_
  • ReadTransferCount : _IO_COUNTERS_
  • real_register_cleanup() : Pool
  • real_request_rec : pa_request_rec_tag
  • realloc() : SQL_Driver_services, SQL_Driver_services_impl, PA_Allocated
  • reattach() : Junction
  • records : Charset::UTF8CaseTable
  • recoursion_checked_execute() : Request
  • Rectangle() : gdImage
  • Red() : gdImage
  • red : gdImage
  • ref_count : lt_dlinfo
  • refill_fields_and_tables() : VForm
  • refs : Hash< K, V >
  • register_cleanup() : Pool
  • register_directly_used() : Methoded_array, Methoded
  • register_file() : Request
  • relative() : Request
  • release() : Mutex, Random_provider
  • RemoteAddress : SMTP
  • RemoteHost : SMTP
  • RemoteUser : SMTP
  • remove() : VHashfile, Hash< K, V >
  • replace() : String
  • replace_field() : VStateless_class
  • replace_maybe_append() : Hash< K, V >
  • req_char : real_pcre
  • request : Parse_control
  • Request : Request, WContext
  • request_charset() : SQL_Driver_services, SQL_Driver_services_impl
  • Request_charsets() : Request_charsets
  • Request_context_saver : Request_context_saver, Request
  • request_info : Request
  • ResolveHostname() : SMTP
  • ResolveService() : SMTP
  • response : Request
  • restore() : Request_context_saver
  • restore_connection() : Request
  • restore_lang() : Request
  • result() : WContext, VMethodFrame
  • reverse : Array< T >::Action_options
  • right : CordRep::Concatenation
  • rollback() : SQL_Driver, SQL_Connection
  • Row_action : String

- s -
  • sa_cord : substr_args
  • sa_index : substr_args
  • sapi_info : Request
  • save() : VFile, Table
  • saved : VHash_lock, Temp_value_element
  • saved_connection : Temp_connection
  • saved_lang : Temp_lang
  • saved_method : Temp_method
  • saved_self : Temp_method_frame_self
  • saved_value : Temp_hash_value< K, V >
  • scolumn : TableSeparators
  • search_namespaces : VXdoc
  • Sector() : gdImage
  • self : VMethodFrame, VClass::Prevent_info, Junction
  • sencloser : TableSeparators
  • Send() : SMTP
  • send_body() : SAPI
  • send_data() : SMTP
  • send_header() : SAPI
  • SendBuffer() : SMTP
  • SendLine() : SMTP
  • SendSmtpError() : SMTP
  • serialize() : String
  • serialize_value() : VHashfile
  • ServerProtocol : SMTP
  • services() : SQL_Connection
  • set() : VImage, VFile
  • set_base() : VStateless_class
  • set_bottom_index() : Request::Exception_trace
  • set_client() : Request_charsets
  • set_connection() : Request
  • set_constructing() : WContext
  • set_current() : Table
  • set_default() : VHash
  • set_derived() : VObject, Value
  • set_font() : VImage
  • set_in_expression() : WContext
  • set_int() : VInt
  • set_interrupted() : Request
  • set_lang() : Request
  • set_mail() : Request_charsets
  • set_my_variable() : VMethodFrame
  • set_name() : VStateless_class
  • set_pos() : String::Body
  • set_self() : VMethodFrame
  • set_somebody_entered_some_class() : WContext
  • set_source() : Request_charsets
  • set_string() : StringOrValue, VString
  • set_table() : VTable
  • set_time() : VDate
  • set_top_index() : Stack< T >
  • set_tz() : VDate
  • set_url() : SQL_Connection, SQL_Driver_services_impl
  • set_value() : StringOrValue
  • set_xmldoc() : VXdoc
  • SetColorTransparent() : gdImage
  • SetInterlace() : gdImage
  • SetLineStyle() : gdImage
  • SetLineWidth() : gdImage
  • SetPixel() : gdImage
  • setter : Property
  • should_refill_fields_and_tables() : VForm
  • signature : JPG_Exif_segment_begin, GIF_Header, PNG_Header
  • size : apr_finfo_t, gdBuf, Charset::UTF8CaseTable
  • SMTP() : SMTP
  • sort_ToTable() : Charset
  • source : Request_charsets, Parse_control
  • spacebarspace : Font
  • split() : String
  • SQL_Connection : SQL_Connection, SQL_Driver_manager
  • SQL_Driver_manager() : SQL_Driver_manager
  • SQL_Driver_services_impl() : SQL_Driver_services_impl
  • SQL_Error() : SQL_Error
  • Stack() : Stack< T >
  • stack : Request_context_saver, Request
  • StackItem() : Request::StackItem
  • standalone : VXdoc::Output_options
  • start_bits : real_pcre_extra
  • start_match : match_data
  • start_subject : match_data
  • starting_line_of : Dictionary
  • starts_with() : String
  • state : PA_MD5_CTX, refill_data
  • stateless_object__get_element() : VObject
  • stateless_object__put_element() : VObject
  • status : pa_request_rec_tag, PA_exec_result
  • step_width() : Font
  • store_param() : VMethodFrame
  • store_param_index : VMethodFrame
  • str : String::Cm, String::C, File_read_result
  • strdup() : PA_Allocated
  • String() : String
  • string : VString, Request::StackItem, Parse_control, CordRep, Request::Execute_nonvirtual_method_result
  • string_display() : Font
  • String_match_table_template_columns() : String_match_table_template_columns
  • string_start : Parse_control
  • string_width() : Font
  • StringOrValue() : StringOrValue
  • strpart() : VForm
  • StyledLine() : gdImage
  • stylesheet() : Stylesheet_connection
  • Stylesheet_connection : Stylesheet_connection, Stylesheet_manager
  • Stylesheet_connection_ptr : Stylesheet_connection_ptr, Stylesheet_connection
  • Stylesheet_manager() : Stylesheet_manager
  • subprocess_env : pa_request_rec_tag
  • Subst() : Dictionary::Subst
  • substs : Dictionary
  • success : File_read_result
  • SX() : gdImage
  • sx : gdImage
  • SY() : gdImage
  • sy : gdImage
  • sym_prefix : lt_user_dlloader, lt_dlloader
  • syms : lt_dlsymlists_t
  • system : lt_dlhandle_struct

- t -
  • Table() : Table
  • table() : VTable
  • table_first_that() : Table
  • table_for_each() : Table
  • tables : VForm, real_pcre, Charset
  • TableSeparators() : TableSeparators
  • tag : cache_line, JPG_Exif_IFD_entry
  • target : chr_data
  • Temp_client_charset : Temp_client_charset, Request_charsets
  • Temp_connection : Temp_connection, Request
  • Temp_derived() : Temp_derived
  • Temp_hash_value() : Temp_hash_value< K, V >
  • Temp_lang : Temp_lang, Request
  • Temp_method : Temp_method, VStateless_class
  • Temp_method_frame_self() : Temp_method_frame_self
  • Temp_request_self : Request
  • Temp_value_element() : Temp_value_element
  • text : SMTP
  • the_socket : SMTP
  • this_starts() : String
  • threshold : Hash< K, V >
  • THRESHOLD_PERCENT : Hash< K, V >
  • time_hi_and_version : uuid
  • time_low : uuid
  • time_mid : uuid
  • time_to_die : Hashfile_value_serialized_prolog
  • time_used : Stylesheet_connection, SQL_Connection
  • timeout : SMTP
  • to : Dictionary::Subst, Charset::UTF8CaseTable::Rec
  • top_backref : real_pcre
  • top_bracket : real_pcre
  • top_index() : Stack< T >
  • top_value() : Stack< T >
  • toTable : Charset::Tables
  • toTableSize : Charset::Tables
  • Trace() : Request::Trace
  • trace : Request::Exception_details
  • transcode() : VForm, SQL_Driver_services, SQL_Driver_services_impl, Request, Charset
  • transcode_buf2xchar() : Charset
  • transcode_cstr() : Charset
  • transcodeFromUTF8() : Charset
  • transcoder() : Charset
  • transcodeToCharset() : Charset
  • transcodeToUTF8() : Charset
  • transform_and_send_edit_data() : SMTP
  • transparent : gdImage
  • trim() : String, String::Body
  • trim_bof : Parse_control
  • TRIM_BOTH : String
  • TRIM_END : String
  • Trim_kind : String
  • TRIM_START : String
  • type() : WWrapper, WContext, VXnode, VXdoc, VVoid, VTable, VString, VStatus, VStateless_class, VResponse, VRequest, VProperty, VObject, VMethodFrame, VMemory, VMath, VMail, VJunction, VInt, VImage, VHashfile, VHash, VForm, VFile, VEnv, VDouble, VDate, VCookie, VConsole, VCodeFrame, VClass, VBool, Value, SQL_Error, Exception

- u -
  • uncachable() : Stylesheet_connection
  • UnescapeChars() : VForm
  • ungetc() : Parse_control
  • unregister_cleanup() : Pool
  • Untaint_lang_name2enum() : Untaint_lang_name2enum
  • unuse() : Stylesheet_connection
  • uri : pa_request_rec_tag, Request_info
  • url_without_login() : SQL_Driver_services_impl
  • use() : Stylesheet_connection, SQL_Connection
  • use_buf() : Request
  • use_file() : Request
  • used : Stylesheet_connection
  • used_directly() : MXnode, MVoid, MTable, MString, MResponse, MMemory, MMath, MMail, MInt, MImage, MHashfile, MHash, MForm, MFile, MDouble, MDate, Methoded
  • used_files : Request

- v -
  • v() : String, String::Body, String::Languages
  • valid() : Table
  • value : Request::StackItem, SQL_Driver::Placeholder, Operation, Hash< K, V >::Pair
  • value_or_offset_to_it : JPG_Exif_IFD_entry
  • value_ptr() : VFile
  • value_size() : VFile
  • value_type : Hash< K, V >
  • VBool() : VBool
  • VClassMAIN() : VClassMAIN
  • VCodeFrame() : VCodeFrame
  • VConsole() : VConsole
  • VDate() : VDate
  • VDouble() : VDouble
  • VEnv() : VEnv
  • version : VXdoc::Output_options, Hashfile_value_serialized_prolog, GIF_Header
  • VFile::VFile() : VFile
  • VForm() : VForm
  • VHash() : VHash
  • vhash : Request::Exception_details
  • VHash_lock : VHash_lock, VHash
  • VHashfile() : VHashfile
  • VInt() : VInt
  • VJunction() : VJunction
  • VMail() : VMail
  • VMath() : VMath
  • VMemory() : VMemory
  • VMethodFrame() : VMethodFrame
  • VObject() : VObject
  • void_string_value : VVoid
  • vreceived : VMail
  • VRequest() : VRequest
  • VResponse() : VResponse
  • VStateless_class() : VStateless_class
  • VString() : VString
  • VTable() : VTable
  • VXdoc() : VXdoc
  • VXnode() : VXnode

- w -
  • WContext() : WContext
  • wcontext : VCodeFrame, Junction, Request_context_saver, Request
  • WebUse : SMTP
  • week_no() : VDate
  • were_string_writes : WContext
  • were_updated : SQL_Driver::Placeholder
  • Width : gdGifEncoder
  • width : JPG_Size_segment_body, GIF_Header, PNG_Header
  • wipe_unused() : Stack< T >
  • wipe_unused_execution_stack() : Request
  • wrap() : VXdoc
  • Write() : gdGifEncoder
  • write() : WContext, VMethodFrame, VCodeFrame
  • write_assign_lang() : Request
  • write_no_lang() : Request
  • write_pass_lang() : Request
  • WriteOperationCount : _IO_COUNTERS_
  • WriteTransferCount : _IO_COUNTERS_
  • WWrapper() : WWrapper

- x -
  • x : gdImage::Point

- y -
  • y : gdImage::Point

- z -
  • ZeroDataBlock : gdImage

- ~ -
  • ~AutoSYNCHRONIZED() : AutoSYNCHRONIZED
  • ~Cache_manager() : Cache_manager
  • ~Cache_managers() : Cache_managers
  • ~Mutex() : Mutex
  • ~PA_Cleaned() : PA_Cleaned
  • ~Pool() : Pool
  • ~Pooled() : Pooled
  • ~Random_provider() : Random_provider
  • ~Request() : Request
  • ~SMTP() : SMTP
  • ~SQL_Driver_manager() : SQL_Driver_manager
  • ~Stylesheet_connection_ptr() : Stylesheet_connection_ptr
  • ~Stylesheet_manager() : Stylesheet_manager
  • ~Temp_client_charset() : Temp_client_charset
  • ~Temp_connection() : Temp_connection
  • ~Temp_derived() : Temp_derived
  • ~Temp_hash_value() : Temp_hash_value< K, V >
  • ~Temp_lang() : Temp_lang
  • ~Temp_method() : Temp_method
  • ~Temp_method_frame_self() : Temp_method_frame_self
  • ~Temp_value_element() : Temp_value_element
  • ~VHash_lock() : VHash_lock
  • ~VHashfile() : VHashfile
  • ~WContext() : WContext


Namespace Index

Parser3 Source Code Namespace List

Here is a list of all namespaces with brief descriptions:
PCRE


PCRE Namespace Reference

Copyright © 2001–2004 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 29 Dec 2005


Module Index

Parser3 Source Code Modules

Here is a list of all modules:
  • Error Codes
    • Error Values
      • Canonical Errors
  • Stat Functions
  • I/O Handling Functions
    • File Open Flags/Routines
    • File Seek Flags
    • File Lock Types
  • SDBM library
  • String routines
  • APR Utility Functions


Error Codes

Modules

Error Values
 APR ERROR VALUES
 APR_ENOSTAT      APR was unable to perform a stat on the file
 APR_ENOPOOL      APR was not provided a pool with which to allocate memory
 APR_EBADDATE     APR was given an invalid date
 APR_EINVALSOCK   APR was given an invalid socket
 APR_ENOPROC      APR was not given a process structure
 APR_ENOTIME      APR was not given a time structure
 APR_ENODIR       APR was not given a directory structure
 APR_ENOLOCK      APR was not given a lock structure
 APR_ENOPOLL      APR was not given a poll structure
 APR_ENOSOCKET    APR was not given a socket
 APR_ENOTHREAD    APR was not given a thread structure
 APR_ENOTHDKEY    APR was not given a thread key structure
 APR_ENOSHMAVAIL  There is no more shared memory available
 APR_EDSOOPEN     APR was unable to open the dso object.  For more
                  information call apr_dso_error().
 APR_EGENERAL     General failure (specific information not available)
 APR_EBADIP       The specified IP address is invalid
 APR_EBADMASK     The specified netmask is invalid
.

Defines

#define | APR_OS_START_ERROR 20000
APR_OS_START_ERROR is where the APR specific error values start. More...

#define | APR_OS_ERRSPACE_SIZE 50000
APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit into one of the error/status ranges below -- except for APR_OS_START_USERERR, which see. More...

#define | APR_OS_START_STATUS (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE)
APR_OS_START_STATUS is where the APR specific status codes start. More...

#define | APR_OS_START_USERERR (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE)
APR_OS_START_USERERR are reserved for applications that use APR that layer their own error codes along with APR's. More...

#define | APR_OS_START_USEERR APR_OS_START_USERERR
APR_OS_START_USEERR is obsolete, defined for compatibility only. More...

#define | APR_OS_START_CANONERR
APR_OS_START_CANONERR is where APR versions of errno values are defined on systems which don't have the corresponding errno. More...

#define | APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into apr_status_t values. More...

#define | APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)
APR_OS_START_SYSERR folds platform-specific system error values into apr_status_t values. More...

#define | APR_SUCCESS 0
no error. More...

Typedefs

typedef int | apr_status_t
Type for specifying an error or status code. More...

Define Documentation

#define APR_OS_START_ERROR 20000

APR_OS_START_ERROR is where the APR specific error values start.

Definition at line 86 of file apr_errno.h.

#define APR_OS_ERRSPACE_SIZE 50000

APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit into one of the error/status ranges below -- except for APR_OS_START_USERERR, which see.

Definition at line 92 of file apr_errno.h.

#define APR_OS_START_STATUS (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE)

APR_OS_START_STATUS is where the APR specific status codes start.

Definition at line 96 of file apr_errno.h.

#define APR_OS_START_USERERR (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE)

APR_OS_START_USERERR are reserved for applications that use APR that layer their own error codes along with APR's.

Note that the error immediately following this one is set ten times farther away than usual, so that users of apr have a lot of room in which to declare custom error codes.

Definition at line 104 of file apr_errno.h.

#define APR_OS_START_USEERR APR_OS_START_USERERR

APR_OS_START_USEERR is obsolete, defined for compatibility only.

Use APR_OS_START_USERERR instead.

Definition at line 109 of file apr_errno.h.

#define APR_OS_START_CANONERR

Value:

(APR_OS_START_USERERR \
                                 + (APR_OS_ERRSPACE_SIZE * 10))
APR_OS_START_CANONERR is where APR versions of errno values are defined on systems which don't have the corresponding errno.

Definition at line 114 of file apr_errno.h.

#define APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)

APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into apr_status_t values.

Definition at line 120 of file apr_errno.h.

#define APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)

APR_OS_START_SYSERR folds platform-specific system error values into apr_status_t values.

Definition at line 125 of file apr_errno.h.

#define APR_SUCCESS 0

no error.

See also:
APR_STATUS_IS_SUCCESS

Definition at line 128 of file apr_errno.h.

Referenced by check(), database_cleanup(), VHashfile::for_each(), and prep().

Typedef Documentation

typedef int apr_status_t

Type for specifying an error or status code.

Definition at line 81 of file apr_errno.h.

Referenced by check(), database_cleanup(), and prep().


Error Values
[Error Codes]

 APR ERROR VALUES
 APR_ENOSTAT      APR was unable to perform a stat on the file
 APR_ENOPOOL      APR was not provided a pool with which to allocate memory
 APR_EBADDATE     APR was given an invalid date
 APR_EINVALSOCK   APR was given an invalid socket
 APR_ENOPROC      APR was not given a process structure
 APR_ENOTIME      APR was not given a time structure
 APR_ENODIR       APR was not given a directory structure
 APR_ENOLOCK      APR was not given a lock structure
 APR_ENOPOLL      APR was not given a poll structure
 APR_ENOSOCKET    APR was not given a socket
 APR_ENOTHREAD    APR was not given a thread structure
 APR_ENOTHDKEY    APR was not given a thread key structure
 APR_ENOSHMAVAIL  There is no more shared memory available
 APR_EDSOOPEN     APR was unable to open the dso object.  For more
                  information call apr_dso_error().
 APR_EGENERAL     General failure (specific information not available)
 APR_EBADIP       The specified IP address is invalid
 APR_EBADMASK     The specified netmask is invalid
. More...

Modules

Canonical Errors

Defines

#define | APR_ENOSTAT (APR_OS_START_ERROR + 1)
#define | APR_ENOPOOL (APR_OS_START_ERROR + 2)
#define | APR_EBADDATE (APR_OS_START_ERROR + 4)
#define | APR_EINVALSOCK (APR_OS_START_ERROR + 5)
#define | APR_ENOPROC (APR_OS_START_ERROR + 6)
#define | APR_ENOTIME (APR_OS_START_ERROR + 7)
#define | APR_ENODIR (APR_OS_START_ERROR + 8)
#define | APR_ENOLOCK (APR_OS_START_ERROR + 9)
#define | APR_ENOPOLL (APR_OS_START_ERROR + 10)
#define | APR_ENOSOCKET (APR_OS_START_ERROR + 11)
#define | APR_ENOTHREAD (APR_OS_START_ERROR + 12)
#define | APR_ENOTHDKEY (APR_OS_START_ERROR + 13)
#define | APR_EGENERAL (APR_OS_START_ERROR + 14)
#define | APR_ENOSHMAVAIL (APR_OS_START_ERROR + 15)
#define | APR_EBADIP (APR_OS_START_ERROR + 16)
#define | APR_EBADMASK (APR_OS_START_ERROR + 17)
#define | APR_EDSOOPEN (APR_OS_START_ERROR + 19)
#define | APR_EABSOLUTE (APR_OS_START_ERROR + 20)
#define | APR_ERELATIVE (APR_OS_START_ERROR + 21)
#define | APR_EINCOMPLETE (APR_OS_START_ERROR + 22)
#define | APR_EABOVEROOT (APR_OS_START_ERROR + 23)
#define | APR_EBADPATH (APR_OS_START_ERROR + 24)
#define | APR_INCHILD (APR_OS_START_STATUS + 1)
#define | APR_INPARENT (APR_OS_START_STATUS + 2)
#define | APR_DETACH (APR_OS_START_STATUS + 3)
#define | APR_NOTDETACH (APR_OS_START_STATUS + 4)
#define | APR_CHILD_DONE (APR_OS_START_STATUS + 5)
#define | APR_CHILD_NOTDONE (APR_OS_START_STATUS + 6)
#define | APR_TIMEUP (APR_OS_START_STATUS + 7)
#define | APR_INCOMPLETE (APR_OS_START_STATUS + 8)
#define | APR_BADCH (APR_OS_START_STATUS + 12)
#define | APR_BADARG (APR_OS_START_STATUS + 13)
#define | APR_EOF (APR_OS_START_STATUS + 14)
#define | APR_NOTFOUND (APR_OS_START_STATUS + 15)
#define | APR_ANONYMOUS (APR_OS_START_STATUS + 19)
#define | APR_FILEBASED (APR_OS_START_STATUS + 20)
#define | APR_KEYBASED (APR_OS_START_STATUS + 21)
#define | APR_EINIT (APR_OS_START_STATUS + 22)
#define | APR_ENOTIMPL (APR_OS_START_STATUS + 23)
#define | APR_EMISMATCH (APR_OS_START_STATUS + 24)
#define | APR_EBUSY (APR_OS_START_STATUS + 25)

Detailed Description

 APR ERROR VALUES
 APR_ENOSTAT      APR was unable to perform a stat on the file
 APR_ENOPOOL      APR was not provided a pool with which to allocate memory
 APR_EBADDATE     APR was given an invalid date
 APR_EINVALSOCK   APR was given an invalid socket
 APR_ENOPROC      APR was not given a process structure
 APR_ENOTIME      APR was not given a time structure
 APR_ENODIR       APR was not given a directory structure
 APR_ENOLOCK      APR was not given a lock structure
 APR_ENOPOLL      APR was not given a poll structure
 APR_ENOSOCKET    APR was not given a socket
 APR_ENOTHREAD    APR was not given a thread structure
 APR_ENOTHDKEY    APR was not given a thread key structure
 APR_ENOSHMAVAIL  There is no more shared memory available
 APR_EDSOOPEN     APR was unable to open the dso object.  For more
                  information call apr_dso_error().
 APR_EGENERAL     General failure (specific information not available)
 APR_EBADIP       The specified IP address is invalid
 APR_EBADMASK     The specified netmask is invalid
.

 APR STATUS VALUES
 APR_INCHILD        Program is currently executing in the child
 APR_INPARENT       Program is currently executing in the parent
 APR_DETACH         The thread is detached
 APR_NOTDETACH      The thread is not detached
 APR_CHILD_DONE     The child has finished executing
 APR_CHILD_NOTDONE  The child has not finished executing
 APR_TIMEUP         The operation did not finish before the timeout
 APR_INCOMPLETE     The operation was incomplete although some processing
                    was performed and the results are partially valid
 APR_BADCH          Getopt found an option not in the option string
 APR_BADARG         Getopt found an option that is missing an argument
                    and an argument was specified in the option string
 APR_EOF            APR has encountered the end of the file
 APR_NOTFOUND       APR was unable to find the socket in the poll structure
 APR_ANONYMOUS      APR is using anonymous shared memory
 APR_FILEBASED      APR is using a file name as the key to the shared memory
 APR_KEYBASED       APR is using a shared key as the key to the shared memory
 APR_EINIT          Ininitalizer value.  If no option has been found, but
                    the status variable requires a value, this should be used
 APR_ENOTIMPL       The APR function has not been implemented on this
                    platform, either because nobody has gotten to it yet,
                    or the function is impossible on this platform.
 APR_EMISMATCH      Two passwords do not match.
 APR_EABSOLUTE      The given path was absolute.
 APR_ERELATIVE      The given path was relative.
 APR_EINCOMPLETE    The given path was neither relative nor absolute.
 APR_EABOVEROOT     The given path was above the root path.
 APR_EBUSY          The given lock was busy.

Define Documentation

#define APR_ENOSTAT (APR_OS_START_ERROR + 1)

See also:
APR_STATUS_IS_ENOSTAT

Definition at line 189 of file apr_errno.h.

#define APR_ENOPOOL (APR_OS_START_ERROR + 2)

See also:
APR_STATUS_IS_ENOPOOL

Definition at line 191 of file apr_errno.h.

#define APR_EBADDATE (APR_OS_START_ERROR + 4)

See also:
APR_STATUS_IS_EBADDATE

Definition at line 194 of file apr_errno.h.

#define APR_EINVALSOCK (APR_OS_START_ERROR + 5)

See also:
APR_STATUS_IS_EINVALSOCK

Definition at line 196 of file apr_errno.h.

#define APR_ENOPROC (APR_OS_START_ERROR + 6)

See also:
APR_STATUS_IS_ENOPROC

Definition at line 198 of file apr_errno.h.

#define APR_ENOTIME (APR_OS_START_ERROR + 7)

See also:
APR_STATUS_IS_ENOTIME

Definition at line 200 of file apr_errno.h.

#define APR_ENODIR (APR_OS_START_ERROR + 8)

See also:
APR_STATUS_IS_ENODIR

Definition at line 202 of file apr_errno.h.

#define APR_ENOLOCK (APR_OS_START_ERROR + 9)

See also:
APR_STATUS_IS_ENOLOCK

Definition at line 204 of file apr_errno.h.

#define APR_ENOPOLL (APR_OS_START_ERROR + 10)

See also:
APR_STATUS_IS_ENOPOLL

Definition at line 206 of file apr_errno.h.

#define APR_ENOSOCKET (APR_OS_START_ERROR + 11)

See also:
APR_STATUS_IS_ENOSOCKET

Definition at line 208 of file apr_errno.h.

#define APR_ENOTHREAD (APR_OS_START_ERROR + 12)

See also:
APR_STATUS_IS_ENOTHREAD

Definition at line 210 of file apr_errno.h.

#define APR_ENOTHDKEY (APR_OS_START_ERROR + 13)

See also:
APR_STATUS_IS_ENOTHDKEY

Definition at line 212 of file apr_errno.h.

#define APR_EGENERAL (APR_OS_START_ERROR + 14)

See also:
APR_STATUS_IS_EGENERAL

Definition at line 214 of file apr_errno.h.

#define APR_ENOSHMAVAIL (APR_OS_START_ERROR + 15)

See also:
APR_STATUS_IS_ENOSHMAVAIL

Definition at line 216 of file apr_errno.h.

#define APR_EBADIP (APR_OS_START_ERROR + 16)

See also:
APR_STATUS_IS_EBADIP

Definition at line 218 of file apr_errno.h.

#define APR_EBADMASK (APR_OS_START_ERROR + 17)

See also:
APR_STATUS_IS_EBADMASK

Definition at line 220 of file apr_errno.h.

#define APR_EDSOOPEN (APR_OS_START_ERROR + 19)

See also:
APR_STATUS_IS_EDSOPEN

Definition at line 223 of file apr_errno.h.

#define APR_EABSOLUTE (APR_OS_START_ERROR + 20)

See also:
APR_STATUS_IS_EABSOLUTE

Definition at line 225 of file apr_errno.h.

#define APR_ERELATIVE (APR_OS_START_ERROR + 21)

See also:
APR_STATUS_IS_ERELATIVE

Definition at line 227 of file apr_errno.h.

#define APR_EINCOMPLETE (APR_OS_START_ERROR + 22)

See also:
APR_STATUS_IS_EINCOMPLETE

Definition at line 229 of file apr_errno.h.

#define APR_EABOVEROOT (APR_OS_START_ERROR + 23)

See also:
APR_STATUS_IS_EABOVEROOT

Definition at line 231 of file apr_errno.h.

#define APR_EBADPATH (APR_OS_START_ERROR + 24)

See also:
APR_STATUS_IS_EBADPATH

Definition at line 233 of file apr_errno.h.

#define APR_INCHILD (APR_OS_START_STATUS + 1)

See also:
APR_STATUS_IS_INCHILD

Definition at line 237 of file apr_errno.h.

#define APR_INPARENT (APR_OS_START_STATUS + 2)

See also:
APR_STATUS_IS_INPARENT

Definition at line 239 of file apr_errno.h.

#define APR_DETACH (APR_OS_START_STATUS + 3)

See also:
APR_STATUS_IS_DETACH

Definition at line 241 of file apr_errno.h.

#define APR_NOTDETACH (APR_OS_START_STATUS + 4)

See also:
APR_STATUS_IS_NOTDETACH

Definition at line 243 of file apr_errno.h.

#define APR_CHILD_DONE (APR_OS_START_STATUS + 5)

See also:
APR_STATUS_IS_CHILD_DONE

Definition at line 245 of file apr_errno.h.

#define APR_CHILD_NOTDONE (APR_OS_START_STATUS + 6)

See also:
APR_STATUS_IS_CHILD_NOTDONE

Definition at line 247 of file apr_errno.h.

#define APR_TIMEUP (APR_OS_START_STATUS + 7)

See also:
APR_STATUS_IS_TIMEUP

Definition at line 249 of file apr_errno.h.

#define APR_INCOMPLETE (APR_OS_START_STATUS + 8)

See also:
APR_STATUS_IS_INCOMPLETE

Definition at line 251 of file apr_errno.h.

#define APR_BADCH (APR_OS_START_STATUS + 12)

See also:
APR_STATUS_IS_BADCH

Definition at line 256 of file apr_errno.h.

#define APR_BADARG (APR_OS_START_STATUS + 13)

See also:
APR_STATUS_IS_BADARG

Definition at line 258 of file apr_errno.h.

#define APR_EOF (APR_OS_START_STATUS + 14)

See also:
APR_STATUS_IS_EOF

Definition at line 260 of file apr_errno.h.

#define APR_NOTFOUND (APR_OS_START_STATUS + 15)

See also:
APR_STATUS_IS_NOTFOUND

Definition at line 262 of file apr_errno.h.

#define APR_ANONYMOUS (APR_OS_START_STATUS + 19)

See also:
APR_STATUS_IS_ANONYMOUS

Definition at line 267 of file apr_errno.h.

#define APR_FILEBASED (APR_OS_START_STATUS + 20)

See also:
APR_STATUS_IS_FILEBASED

Definition at line 269 of file apr_errno.h.

#define APR_KEYBASED (APR_OS_START_STATUS + 21)

See also:
APR_STATUS_IS_KEYBASED

Definition at line 271 of file apr_errno.h.

#define APR_EINIT (APR_OS_START_STATUS + 22)

See also:
APR_STATUS_IS_EINIT

Definition at line 273 of file apr_errno.h.

#define APR_ENOTIMPL (APR_OS_START_STATUS + 23)

See also:
APR_STATUS_IS_ENOTIMPL

Definition at line 275 of file apr_errno.h.

#define APR_EMISMATCH (APR_OS_START_STATUS + 24)

See also:
APR_STATUS_IS_EMISMATCH

Definition at line 277 of file apr_errno.h.

#define APR_EBUSY (APR_OS_START_STATUS + 25)

See also:
APR_STATUS_IS_EBUSY

Definition at line 279 of file apr_errno.h.


Canonical Errors
[Error Values]

Defines

#define | APR_EACCES (APR_OS_START_CANONERR + 1)
#define | APR_EEXIST (APR_OS_START_CANONERR + 2)
#define | APR_ENAMETOOLONG (APR_OS_START_CANONERR + 3)
#define | APR_ENOENT (APR_OS_START_CANONERR + 4)
#define | APR_ENOTDIR (APR_OS_START_CANONERR + 5)
#define | APR_ENOSPC (APR_OS_START_CANONERR + 6)
#define | APR_ENOMEM (APR_OS_START_CANONERR + 7)
#define | APR_EMFILE (APR_OS_START_CANONERR + 8)
#define | APR_ENFILE (APR_OS_START_CANONERR + 9)
#define | APR_EBADF (APR_OS_START_CANONERR + 10)
#define | APR_EINVAL (APR_OS_START_CANONERR + 11)
#define | APR_ESPIPE (APR_OS_START_CANONERR + 12)
#define | APR_EAGAIN (APR_OS_START_CANONERR + 13)
#define | APR_EINTR (APR_OS_START_CANONERR + 14)
#define | APR_ENOTSOCK (APR_OS_START_CANONERR + 15)
#define | APR_ECONNREFUSED (APR_OS_START_CANONERR + 16)
#define | APR_EINPROGRESS (APR_OS_START_CANONERR + 17)
#define | APR_ECONNABORTED (APR_OS_START_CANONERR + 18)
#define | APR_ECONNRESET (APR_OS_START_CANONERR + 19)
#define | APR_ETIMEDOUT (APR_OS_START_CANONERR + 20)
#define | APR_EHOSTUNREACH (APR_OS_START_CANONERR + 21)
#define | APR_ENETUNREACH (APR_OS_START_CANONERR + 22)
#define | APR_EFTYPE (APR_OS_START_CANONERR + 23)
#define | APR_EPIPE (APR_OS_START_CANONERR + 24)
#define | APR_EXDEV (APR_OS_START_CANONERR + 25)
#define | APR_ENOTEMPTY (APR_OS_START_CANONERR + 26)

Define Documentation

#define APR_EACCES (APR_OS_START_CANONERR + 1)

See also:
APR_STATUS_IS_EACCES

Definition at line 290 of file apr_errno.h.

#define APR_EEXIST (APR_OS_START_CANONERR + 2)

See also:
APR_STATUS_IS_EXIST

Definition at line 297 of file apr_errno.h.

#define APR_ENAMETOOLONG (APR_OS_START_CANONERR + 3)

See also:
APR_STATUS_IS_ENAMETOOLONG

Definition at line 304 of file apr_errno.h.

#define APR_ENOENT (APR_OS_START_CANONERR + 4)

See also:
APR_STATUS_IS_ENOENT

Definition at line 311 of file apr_errno.h.

#define APR_ENOTDIR (APR_OS_START_CANONERR + 5)

See also:
APR_STATUS_IS_ENOTDIR

Definition at line 318 of file apr_errno.h.

#define APR_ENOSPC (APR_OS_START_CANONERR + 6)

See also:
APR_STATUS_IS_ENOSPC

Definition at line 325 of file apr_errno.h.

#define APR_ENOMEM (APR_OS_START_CANONERR + 7)

See also:
APR_STATUS_IS_ENOMEM

Definition at line 332 of file apr_errno.h.

#define APR_EMFILE (APR_OS_START_CANONERR + 8)

See also:
APR_STATUS_IS_EMFILE

Definition at line 339 of file apr_errno.h.

#define APR_ENFILE (APR_OS_START_CANONERR + 9)

See also:
APR_STATUS_IS_ENFILE

Definition at line 346 of file apr_errno.h.

#define APR_EBADF (APR_OS_START_CANONERR + 10)

See also:
APR_STATUS_IS_EBADF

Definition at line 353 of file apr_errno.h.

#define APR_EINVAL (APR_OS_START_CANONERR + 11)

See also:
APR_STATUS_IS_EINVAL

Definition at line 360 of file apr_errno.h.

#define APR_ESPIPE (APR_OS_START_CANONERR + 12)

See also:
APR_STATUS_IS_ESPIPE

Definition at line 367 of file apr_errno.h.

#define APR_EAGAIN (APR_OS_START_CANONERR + 13)

See also:
APR_STATUS_IS_EAGAIN
Warning:
use APR_STATUS_IS_EAGAIN instead of just testing this value

Definition at line 379 of file apr_errno.h.

#define APR_EINTR (APR_OS_START_CANONERR + 14)

See also:
APR_STATUS_IS_EINTR

Definition at line 386 of file apr_errno.h.

#define APR_ENOTSOCK (APR_OS_START_CANONERR + 15)

See also:
APR_STATUS_IS_ENOTSOCK

Definition at line 393 of file apr_errno.h.

#define APR_ECONNREFUSED (APR_OS_START_CANONERR + 16)

See also:
APR_STATUS_IS_ECONNREFUSED

Definition at line 400 of file apr_errno.h.

#define APR_EINPROGRESS (APR_OS_START_CANONERR + 17)

See also:
APR_STATUS_IS_EINPROGRESS

Definition at line 407 of file apr_errno.h.

#define APR_ECONNABORTED (APR_OS_START_CANONERR + 18)

See also:
APR_STATUS_IS_ECONNABORTED
Warning:
use APR_STATUS_IS_ECONNABORTED instead of just testing this value

Definition at line 418 of file apr_errno.h.

#define APR_ECONNRESET (APR_OS_START_CANONERR + 19)

See also:
APR_STATUS_IS_ECONNRESET

Definition at line 425 of file apr_errno.h.

#define APR_ETIMEDOUT (APR_OS_START_CANONERR + 20)

See also:
APR_STATUS_IS_ETIMEDOUT

Definition at line 432 of file apr_errno.h.

#define APR_EHOSTUNREACH (APR_OS_START_CANONERR + 21)

See also:
APR_STATUS_IS_EHOSTUNREACH

Definition at line 439 of file apr_errno.h.

#define APR_ENETUNREACH (APR_OS_START_CANONERR + 22)

See also:
APR_STATUS_IS_ENETUNREACH

Definition at line 446 of file apr_errno.h.

#define APR_EFTYPE (APR_OS_START_CANONERR + 23)

See also:
APR_STATUS_IS_EFTYPE

Definition at line 453 of file apr_errno.h.

#define APR_EPIPE (APR_OS_START_CANONERR + 24)

See also:
APR_STATUS_IS_EPIPE

Definition at line 460 of file apr_errno.h.

#define APR_EXDEV (APR_OS_START_CANONERR + 25)

See also:
APR_STATUS_IS_EXDEV

Definition at line 467 of file apr_errno.h.

#define APR_ENOTEMPTY (APR_OS_START_CANONERR + 26)

See also:
APR_STATUS_IS_ENOTEMPTY

Definition at line 474 of file apr_errno.h.


Stat Functions

Compounds

struct | apr_finfo_t

Defines

#define | APR_FINFO_SIZE 0x00000100
Size of the file. More...

Typedefs

typedef apr_finfo_t | apr_finfo_t
The file information structure. More...

Define Documentation

#define APR_FINFO_SIZE 0x00000100

Size of the file.

Definition at line 84 of file apr_file_info.h.

Typedef Documentation

typedef struct apr_finfo_t apr_finfo_t

The file information structure.

This is analogous to the POSIX stat structure.

Definition at line 111 of file apr_file_info.h.


I/O Handling Functions

Modules

File Open Flags/Routines
File Seek Flags
File Lock Types

Typedefs

typedef int | apr_seek_where_t
should be same as whence type in lseek, POSIX defines this as int. More...

typedef apr_file_t | apr_file_t
Structure for referencing files. More...

Variables

const char * | fname
const char apr_int32_t | flag
const char apr_int32_t apr_fileperms_t | perm
const char apr_int32_t apr_fileperms_t
apr_pool_t * 		cont
int | type
apr_int32_t wanted
apr_int32_t apr_file_t * thefile
apr_seek_where_t where
apr_seek_where_t apr_off_t * offset
void * | buf
void apr_size_t | nbytes
void apr_size_t apr_size_t * | bytes_read
const void apr_size_t apr_size_t * | bytes_written

Typedef Documentation

typedef int apr_seek_where_t

should be same as whence type in lseek, POSIX defines this as int.

Definition at line 114 of file apr_file_io.h.

typedef struct apr_file_t apr_file_t

Structure for referencing files.

@defvar apr_file_t

Definition at line 120 of file apr_file_io.h.

Variable Documentation

const char* fname

Definition at line 177 of file apr_file_io.h.

const char apr_int32_t flag

Definition at line 177 of file apr_file_io.h.

const char apr_int32_t apr_fileperms_t perm

Definition at line 177 of file apr_file_io.h.

const char apr_int32_t apr_fileperms_t apr_pool_t* cont

Definition at line 177 of file apr_file_io.h.

int type

Definition at line 199 of file apr_file_io.h.

apr_int32_t wanted

Definition at line 215 of file apr_file_io.h.

apr_int32_t apr_file_t* thefile

Definition at line 215 of file apr_file_io.h.

apr_seek_where_t where

Definition at line 232 of file apr_file_io.h.

apr_seek_where_t apr_off_t* offset

Definition at line 232 of file apr_file_io.h.

Referenced by _load(), _offset(), _roll(), _sql(), Array< Operation >::append(), compile_branch(), file_read(), LA2S(), LA2V(), match(), match_ref(), Table::offset(), output_pieces(), P(), String::Body::pos(), SQL_Connection::query(), and sql_result_string().

const void* buf

Definition at line 277 of file apr_file_io.h.

const void apr_size_t nbytes

Definition at line 277 of file apr_file_io.h.

void apr_size_t apr_size_t* bytes_read

Definition at line 255 of file apr_file_io.h.

Referenced by SMTP::GetBuffer().

const void apr_size_t apr_size_t* bytes_written

Definition at line 277 of file apr_file_io.h.


File Open Flags/Routines
[I/O Handling Functions]

Defines

#define | APR_READ 1
Open the file for reading. More...

#define | APR_WRITE 2
Open the file for writing. More...

#define | APR_CREATE 4
Create the file if not there. More...

#define | APR_APPEND 8
Append to the end of the file. More...

#define | APR_TRUNCATE 16
Open the file and truncate to 0 length. More...

#define | APR_BINARY 32
Open the file in binary mode. More...

#define | APR_EXCL 64
Open should fail if APR_CREATE and file exists. More...

#define | APR_BUFFERED 128
Open the file for buffered I/O. More...

#define | APR_DELONCLOSE 256
Delete the file after close. More...

#define | APR_XTHREAD 512
Platform dependent tag to open the file for use across multiple threads. More...

#define | APR_SHARELOCK 1024
Platform dependent support for higher level locked read/write access to support writes across process/machines. More...

#define | APR_FILE_NOCLEANUP 2048
Do not register a cleanup when the file is opened. More...

Functions

APR_DECLARE (apr_status_t) apr_file_open(apr_file_t **new_file
Open the specified file. More...

Define Documentation

#define APR_READ 1

Open the file for reading.

Definition at line 82 of file apr_file_io.h.

Referenced by VHashfile::open(), and prep().

#define APR_WRITE 2

Open the file for writing.

Definition at line 83 of file apr_file_io.h.

Referenced by VHashfile::get_db_for_writing(), and prep().

#define APR_CREATE 4

Create the file if not there.

Definition at line 84 of file apr_file_io.h.

Referenced by VHashfile::open().

#define APR_APPEND 8

Append to the end of the file.

Definition at line 85 of file apr_file_io.h.

#define APR_TRUNCATE 16

Open the file and truncate to 0 length.

Definition at line 86 of file apr_file_io.h.

#define APR_BINARY 32

Open the file in binary mode.

Definition at line 87 of file apr_file_io.h.

Referenced by prep().

#define APR_EXCL 64

Open should fail if APR_CREATE and file exists.

Definition at line 88 of file apr_file_io.h.

#define APR_BUFFERED 128

Open the file for buffered I/O.

Definition at line 90 of file apr_file_io.h.

#define APR_DELONCLOSE 256

Delete the file after close.

Definition at line 91 of file apr_file_io.h.

#define APR_XTHREAD 512

Platform dependent tag to open the file for use across multiple threads.

Definition at line 92 of file apr_file_io.h.

#define APR_SHARELOCK 1024

Platform dependent support for higher level locked read/write access to support writes across process/machines.

Definition at line 94 of file apr_file_io.h.

Referenced by VHashfile::open(), and prep().

#define APR_FILE_NOCLEANUP 2048

Do not register a cleanup when the file is opened.

Definition at line 97 of file apr_file_io.h.

Function Documentation

APR_DECLARE ( apr_status_t )

Open the specified file.

Parameters:
new_file | The opened file descriptor.
fname | The full path to the file (using / on all systems)
flag Or'ed value of:
           APR_READ             open for reading
           APR_WRITE            open for writing
           APR_CREATE           create the file if not there
           APR_APPEND           file ptr is set to end prior to all writes
           APR_TRUNCATE         set length to zero if file exists
           APR_BINARY           not a text file (This flag is ignored on
                                UNIX because it has no meaning)
           APR_BUFFERED         buffer the data.  Default is non-buffered
           APR_EXCL             return error if APR_CREATE and file exists
           APR_DELONCLOSE       delete the file after closing.
           APR_XTHREAD          Platform dependent tag to open the file
                                for use across multiple threads
           APR_SHARELOCK        Platform dependent support for higher
                                level locked read/write access to support
                                writes across process/machines
           APR_FILE_NOCLEANUP   Do not register a cleanup with the pool
                                passed in on the cont argument (see below).
                                The apr_os_file_t handle in apr_file_t will not
 &                                be closed when the pool is destroyed.
perm | Access permissions for file.
cont | The pool to use.
Remarks:
If perm is APR_OS_DEFAULT and the file is being created, appropriate default permissions will be used. *arg1 must point to a valid file_t, or NULL (in which case it will be allocated)


File Seek Flags
[I/O Handling Functions]

Defines

#define | APR_SET SEEK_SET
#define | APR_CUR SEEK_CUR
#define | APR_END SEEK_END

Define Documentation

#define APR_SET SEEK_SET

Definition at line 108 of file apr_file_io.h.

#define APR_CUR SEEK_CUR

Definition at line 109 of file apr_file_io.h.

#define APR_END SEEK_END

Definition at line 110 of file apr_file_io.h.


File Lock Types
[I/O Handling Functions]

Defines

#define | APR_FLOCK_SHARED 1
Shared lock. More...

#define | APR_FLOCK_EXCLUSIVE 2
Exclusive lock. More...

#define | APR_FLOCK_TYPEMASK 0x000F
mask to extract lock type. More...

#define | APR_FLOCK_NONBLOCK 0x0010
do not block while acquiring the file lock. More...

Define Documentation

#define APR_FLOCK_SHARED 1

Shared lock.

More than one process or thread can hold a shared lock at any given time. Essentially, this is a "read lock", preventing writers from establishing an exclusive lock.

Definition at line 128 of file apr_file_io.h.

Referenced by VHashfile::for_each(), and prep().

#define APR_FLOCK_EXCLUSIVE 2

Exclusive lock.

Only one process may hold an exclusive lock at any given time. This is analogous to a "write lock".

Definition at line 134 of file apr_file_io.h.

Referenced by prep().

#define APR_FLOCK_TYPEMASK 0x000F

mask to extract lock type.

Definition at line 139 of file apr_file_io.h.

#define APR_FLOCK_NONBLOCK 0x0010

do not block while acquiring the file lock.

Definition at line 140 of file apr_file_io.h.


SDBM library

Compounds

struct | apr_sdbm_datum_t
Structure for referencing the datum record within an sdbm. More...

Defines

#define | APR_SDBM_DIRFEXT ".dir"
#define | APR_SDBM_PAGFEXT ".pag"
#define | APR_SDBM_INSERT 0
#define | APR_SDBM_REPLACE 1
#define | APR_SDBM_INSERTDUP 2

Typedefs

typedef apr_sdbm_t | apr_sdbm_t
Structure for referencing an sdbm. More...

Functions

APU_DECLARE (apr_status_t) apr_sdbm_open(apr_sdbm_t **db
Open an sdbm database by file name. More...

APU_DECLARE (int) apr_sdbm_rdonly(apr_sdbm_t *db)
Returns true if the sdbm database opened for read-only access. More...

Variables

const char * | name
const char apr_int32_t | mode
const char apr_int32_t apr_fileperms_t | perms
const char apr_int32_t apr_fileperms_t
apr_pool_t * 		p
int | type
apr_sdbm_datum_t * value
apr_sdbm_datum_t apr_sdbm_datum_t key
apr_sdbm_datum_t apr_sdbm_datum_t
int 		opt

Define Documentation

#define APR_SDBM_DIRFEXT ".dir"

Definition at line 100 of file apr_sdbm.h.

Referenced by VHashfile::delete_files().

#define APR_SDBM_PAGFEXT ".pag"

Definition at line 101 of file apr_sdbm.h.

Referenced by VHashfile::delete_files().

#define APR_SDBM_INSERT 0

Definition at line 104 of file apr_sdbm.h.

#define APR_SDBM_REPLACE 1

Definition at line 105 of file apr_sdbm.h.

Referenced by VHashfile::put_field().

#define APR_SDBM_INSERTDUP 2

Definition at line 106 of file apr_sdbm.h.

Typedef Documentation

typedef struct apr_sdbm_t apr_sdbm_t

Structure for referencing an sdbm.

Definition at line 87 of file apr_sdbm.h.

Function Documentation

APU_DECLARE ( apr_status_t )

Open an sdbm database by file name.

Parameters:
db | The newly opened database
name | The sdbm file to open
mode The flag values (APR_READ and APR_BINARY flags are implicit)
           APR_WRITE          open for read-write access
           APR_CREATE         create the sdbm if it does not exist
           APR_TRUNCATE       empty the contents of the sdbm
           APR_EXCL           fail for APR_CREATE if the file exists
           APR_DELONCLOSE     delete the sdbm when closed
           APR_SHARELOCK      support locking across process/machines
perm | Permissions to apply to if created
pool | The pool to use when creating the sdbm
Remarks:
The sdbm name is not a true file name, as sdbm appends suffixes for seperate data and index files.

APU_DECLARE ( int )

Returns true if the sdbm database opened for read-only access.

Parameters:
db The database to test

Variable Documentation

const char* name

Definition at line 126 of file apr_sdbm.h.

const char apr_int32_t mode

Definition at line 126 of file apr_sdbm.h.

Referenced by _save(), and is_text_mode().

const char apr_int32_t apr_fileperms_t perms

Definition at line 126 of file apr_sdbm.h.

const char apr_int32_t apr_fileperms_t apr_pool_t* p

Definition at line 126 of file apr_sdbm.h.

Referenced by gdImage::CopyResampled(), CORD__extend_path(), CORD__next(), CORD__pos_fetch(), CORD__prev(), CORD_block_iter(), CORD_iter5(), CORD_next(), CORD_pos_fetch(), CORD_pos_to_cord(), CORD_pos_to_index(), CORD_pos_valid(), CORD_prev(), CORD_riter4(), CORD_set_pos(), CORD_substr_checked(), gdImage::FilledPolygon(), gdImage::FilledPolygonReplaceColor(), find_headers_end(), is_counted_repeat(), match_ref(), pa_ap_pstrdup(), pa_tolower(), parse_range(), parser_create_dir_config(), parser_create_server_config(), parser_merge_dir_config(), parser_merge_server_config(), parser_module_done(), parser_module_init(), pcre_exec(), pcre_get_substring_list(), pcre_maketables(), gdImage::Polygon(), prep(), read_repeat_counts(), and remove_crlf().

int type

Definition at line 151 of file apr_sdbm.h.

Referenced by Value::bark().

apr_sdbm_datum_t apr_sdbm_datum_t value

Definition at line 180 of file apr_sdbm.h.

Referenced by _case(), _load_pass_param(), _locate_name_value(), _sort(), _throw_operator(), VClass::add_property(), append_attrib_pair(), append_attribute_meaning(), append_env_pair(), VForm::AppendFormEntry(), MethodParams::as_bool(), MethodParams::as_double(), as_image(), MethodParams::as_int(), MethodParams::as_junction(), MethodParams::as_no_junction(), attributed_meaning_to_string(), MForm::configure_admin(), copy_all_dontoverwrite_to(), copy_all_overwrite_to(), copy_intersection_to(), Request::core(), VHashfile::deserialize_value(), Request::execute(), Request::execute_virtual_method(), form_string_value2string(), form_value2string(), String::Body::Format(), format(), MethodParams::get_as(), Request::get_element(), VHashfile::get_field(), get_hash__put(), MethodParams::get_processed(), VForm::getAttributeValue(), http_pass_header(), LA2S(), Table::locate(), Hash< const String::Body, void * >::maybe_put_replaced(), Hash< const String::Body, void * >::maybe_replace_maybe_append(), Hash< const String::Body, void * >::maybe_replace_never_append(), mk_env_pair(), one_foreach_cycle(), parse_IFD_entry(), parse_IFD_entry_formatted_one_value(), parse_IFD_entry_formatted_value(), parse_IFD_entry_value(), VForm::ParseFormInput(), pass_cgi_header_attribute(), VClass::prevent_append_if_exists_in_base(), VObject::prevent_append_if_exists_in_static_or_base(), VClass::prevent_overwrite_property(), Hash< const String::Body, void * >::put(), Hash< const String::Body, void * >::put_dont_replace(), Request::put_element(), VHashfile::put_field(), Hash< const String::Body, void * >::put_replaced(), Hash< const String::Body, void * >::replace_maybe_append(), VMethodFrame::set_my_variable(), sort_cmp_string(), store_column_item_to_hash(), VMethodFrame::store_param(), unmarshal_bind_updates(), and VL().

register char * key

Definition at line 275 of file sdbm_pair.c.

apr_sdbm_datum_t apr_sdbm_datum_t int opt

Definition at line 180 of file apr_sdbm.h.


String routines

Functions

APR_DECLARE_NONSTD (char *) apr_pstrcat(apr_pool_t *p
Concatenate multiple strings, allocating memory out a pool. More...

Function Documentation

APR_DECLARE_NONSTD ( char * )

Concatenate multiple strings, allocating memory out a pool.

Parameters:
p The pool to allocate out of
... The strings to concatenate. The final string must be NULL
Returns:
The new string


APR Utility Functions

Defines

#define | APU_DECLARE(type) type
The public APR-UTIL functions are declared with APU_DECLARE(), so they may use the most appropriate calling convention. More...

#define | APU_DECLARE_NONSTD(type) type
The public APR-UTIL functions using variable arguments are declared with APU_DECLARE_NONSTD(), as they must use the C language calling convention. More...

#define | APU_DECLARE_DATA
The public APR-UTIL variables are declared with APU_DECLARE_DATA. More...

#define | APU_HAVE_SDBM

Define Documentation

#define APU_DECLARE ( type ) type

The public APR-UTIL functions are declared with APU_DECLARE(), so they may use the most appropriate calling convention.

Public APR functions with variable arguments must use APU_DECLARE_NONSTD().

@deffunc APU_DECLARE(rettype) apr_func(args);

Definition at line 90 of file apu.h.

#define APU_DECLARE_NONSTD ( type ) type

The public APR-UTIL functions using variable arguments are declared with APU_DECLARE_NONSTD(), as they must use the C language calling convention.

@deffunc APU_DECLARE_NONSTD(rettype) apr_func(args, ...);

Definition at line 97 of file apu.h.

#define APU_DECLARE_DATA

The public APR-UTIL variables are declared with APU_DECLARE_DATA.

This assures the appropriate indirection is invoked at compile time.

@deffunc APU_DECLARE_DATA type apr_variable; @tip APU_DECLARE_DATA extern type apr_variable; syntax is required for declarations within headers to properly import the variable.

Definition at line 106 of file apu.h.

#define APU_HAVE_SDBM

Definition at line 110 of file apu.h.


File Member Index

Parser3 Source Code File Members

_ | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | r | s | t | u | v | w | x | y

Here is a list of all file members with links to the files they belong to:

- _ -

  • __dec() : int.C, double.C
  • __div() : int.C, double.C
  • __GC : gc.h
  • __inc() : int.C, double.C
  • __mod() : int.C, double.C
  • __mul() : int.C, double.C
  • __snprintf() : pa_common.C, smtp.C, pa_common.h
  • __STDC__ : config_fixed.h
  • __vsnprintf() : pa_common.C, pa_common.h
  • __WINDOWS__ : ltdl.h
  • _append() : table.C, string.C
  • _arc() : image.C
  • _bar() : image.C
  • _base64() : string.C, file.C
  • _basename() : file.C
  • _cache() : op.C
  • _calendar() : date.C
  • _case() : op.C
  • _cgi() : file.C
  • _circle() : image.C
  • _clear() : response.C, hashfile.C
  • _columns() : table.C
  • _compact() : memory.C
  • _connect() : op.C
  • _copy() : image.C
  • _count() : table.C, hash.C
  • _create() : table.C, image.C, file.C, date.C
  • _create_or_add() : hash.C
  • _crypt() : math.C
  • _dec() : int.C, double.C
  • _default : untaint.C
  • _delete() : hashfile.C, hash.C, file.C
  • _dirname() : file.C
  • _div() : int.C, double.C
  • _double() : void.C, string.C, int.C, double.C
  • _eval() : op.C
  • _exec() : file.C
  • _exec_cgi() : file.C
  • _fill() : image.C
  • _find() : file.C
  • _flip() : table.C
  • _font() : image.C
  • _for() : op.C
  • _foreach() : hashfile.C, hash.C
  • _fullpath() : file.C
  • _gif() : image.C
  • _hash() : table.C, hashfile.C
  • _html() : image.C
  • _if() : op.C
  • _inc() : int.C, double.C
  • _int() : void.C, string.C, int.C, double.C
  • _intersection() : hash.C
  • _intersects() : hash.C
  • _join() : table.C
  • _justext() : file.C
  • _justname() : file.C
  • _keys() : hash.C
  • _left() : string.C
  • _left_right() : void.C
  • _length() : void.C, string.C, image.C
  • _line() : table.C, image.C
  • _list() : file.C
  • _load() : table.C, image.C, file.C
  • _load_pass_param() : file.C
  • _locate() : table.C
  • _locate_expression() : table.C
  • _locate_name_value() : table.C
  • _lock() : file.C
  • _lower() : string.C
  • _lsplit() : string.C
  • _match() : string.C
  • _md5() : math.C
  • _measure() : image.C
  • _menu() : table.C
  • _mid() : void.C, string.C
  • _mod() : int.C, double.C
  • _move() : file.C
  • _mul() : int.C, double.C
  • _normalize() : string.C
  • _now() : date.C
  • _O_BINARY : pa_common.C
  • _O_TEXT : pa_common.C
  • _offset() : table.C
  • _open() : hashfile.C
  • _pixel() : image.C
  • _polybar() : image.C
  • _polygon() : image.C
  • _polyline() : image.C
  • _pos() : void.C, string.C
  • _process() : op.C
  • _qsort : pa_common.h
  • _random() : math.C
  • _rectangle() : image.C
  • _rem() : op.C
  • _replace() : string.C, image.C
  • _right() : string.C
  • _roll() : date.C
  • _rsplit() : string.C
  • _save() : table.C, string.C, file.C
  • _sector() : image.C
  • _select() : table.C
  • _send() : mail.C
  • _sleep_operator() : op.C
  • _sort() : table.C
  • _split() : string.C
  • _sql() : void.C, table.C, string.C, int.C, hash.C, file.C, double.C
  • _sql_string() : file.C, date.C
  • _stat() : file.C
  • _string_format() : string.C, int.C, double.C
  • _sub() : hash.C
  • _switch() : op.C
  • _taint() : op.C
  • _text() : image.C
  • _throw_operator() : op.C
  • _trim() : string.C
  • _try_operator() : op.C
  • _uid64() : math.C
  • _union() : hash.C
  • _unix_timestamp() : date.C
  • _untaint() : op.C
  • _upper() : string.C
  • _use() : op.C
  • _uuid() : math.C
  • _while() : op.C
  • _WIN32_WINNT : math.C

- a -
  • abort() : parser3isapi.C
  • ABORT : cordxtra.c, cordbscs.c
  • access : config_fixed.h
  • adate_name() : file.C
  • ADD0 : math.C
  • ADD1 : math.C
  • ADD2 : math.C
  • add_connection_to_status_cache_table() : pa_sql_driver_manager.C
  • add_connections_to_status_cache_table() : pa_sql_driver_manager.C
  • add_header_attribute() : pa_request.C
  • addr_spec_soon() : untaint.C
  • ADDX : math.C
  • ANTI_ENDLESS_EXECUTE_RECOURSION : pa_request.h
  • append_attrib_pair() : image.C
  • append_attribute_meaning() : pa_value.C
  • append_attribute_subattribute() : pa_value.C
  • append_env_pair() : pa_exec.C, file.C
  • append_fragment_nonoptimizing() : untaint.C
  • append_fragment_optimizing() : untaint.C
  • APR_ANONYMOUS : apr_errno.h
  • APR_APPEND : apr_file_io.h
  • APR_BADARG : apr_errno.h
  • APR_BADCH : apr_errno.h
  • APR_BINARY : apr_file_io.h
  • APR_BUFFERED : apr_file_io.h
  • APR_CHILD_DONE : apr_errno.h
  • APR_CHILD_NOTDONE : apr_errno.h
  • APR_CREATE : apr_file_io.h
  • APR_CUR : apr_file_io.h
  • APR_DECLARE : apr_file_io.C, apr_file_io.h, apr.h
  • APR_DECLARE_DATA : apr.h
  • APR_DECLARE_NONSTD : apr_strings.C, apr_strings.h, apr.h
  • APR_DELONCLOSE : apr_file_io.h
  • APR_DETACH : apr_errno.h
  • APR_EABOVEROOT : apr_errno.h
  • APR_EABSOLUTE : apr_errno.h
  • APR_EACCES : apr_errno.h
  • APR_EAGAIN : apr_errno.h
  • APR_EBADDATE : apr_errno.h
  • APR_EBADF : apr_errno.h
  • APR_EBADIP : apr_errno.h
  • APR_EBADMASK : apr_errno.h
  • APR_EBADPATH : apr_errno.h
  • APR_EBUSY : apr_errno.h
  • APR_ECONNABORTED : apr_errno.h
  • APR_ECONNREFUSED : apr_errno.h
  • APR_ECONNRESET : apr_errno.h
  • APR_EDSOOPEN : apr_errno.h
  • APR_EEXIST : apr_errno.h
  • APR_EFTYPE : apr_errno.h
  • APR_EGENERAL : apr_errno.h
  • APR_EHOSTUNREACH : apr_errno.h
  • APR_EINCOMPLETE : apr_errno.h
  • APR_EINIT : apr_errno.h
  • APR_EINPROGRESS : apr_errno.h
  • APR_EINTR : apr_errno.h
  • APR_EINVAL : apr_errno.h
  • APR_EINVALSOCK : apr_errno.h
  • APR_EMFILE : apr_errno.h
  • APR_EMISMATCH : apr_errno.h
  • APR_ENAMETOOLONG : apr_errno.h
  • APR_END : apr_file_io.h
  • APR_ENETUNREACH : apr_errno.h
  • APR_ENFILE : apr_errno.h
  • APR_ENODIR : apr_errno.h
  • APR_ENOENT : apr_errno.h
  • APR_ENOLOCK : apr_errno.h
  • APR_ENOMEM : apr_errno.h
  • APR_ENOPOLL : apr_errno.h
  • APR_ENOPOOL : apr_errno.h
  • APR_ENOPROC : apr_errno.h
  • APR_ENOSHMAVAIL : apr_errno.h
  • APR_ENOSOCKET : apr_errno.h
  • APR_ENOSPC : apr_errno.h
  • APR_ENOSTAT : apr_errno.h
  • APR_ENOTDIR : apr_errno.h
  • APR_ENOTEMPTY : apr_errno.h
  • APR_ENOTHDKEY : apr_errno.h
  • APR_ENOTHREAD : apr_errno.h
  • APR_ENOTIME : apr_errno.h
  • APR_ENOTIMPL : apr_errno.h
  • APR_ENOTSOCK : apr_errno.h
  • APR_EOF : apr_errno.h
  • APR_EPIPE : apr_errno.h
  • APR_ERELATIVE : apr_errno.h
  • APR_ESPIPE : apr_errno.h
  • APR_ETIMEDOUT : apr_errno.h
  • APR_EXCL : apr_file_io.h
  • APR_EXDEV : apr_errno.h
  • APR_FILE_NOCLEANUP : apr_file_io.h
  • apr_file_t : apr_file_io.h
  • APR_FILEBASED : apr_errno.h
  • apr_fileperms_t : apr_file_info.h
  • APR_FINFO_SIZE : apr_file_info.h
  • apr_finfo_t : apr_file_info.h
  • APR_FLOCK_EXCLUSIVE : apr_file_io.h
  • APR_FLOCK_NONBLOCK : apr_file_io.h
  • APR_FLOCK_SHARED : apr_file_io.h
  • APR_FLOCK_TYPEMASK : apr_file_io.h
  • APR_INCHILD : apr_errno.h
  • APR_INCOMPLETE : apr_errno.h
  • APR_INPARENT : apr_errno.h
  • apr_int32_t : apr.h
  • APR_KEYBASED : apr_errno.h
  • APR_NOTDETACH : apr_errno.h
  • APR_NOTFOUND : apr_errno.h
  • apr_off_t : apr.h
  • APR_OS_ERRSPACE_SIZE : apr_errno.h
  • APR_OS_START_CANONERR : apr_errno.h
  • APR_OS_START_EAIERR : apr_errno.h
  • APR_OS_START_ERROR : apr_errno.h
  • APR_OS_START_STATUS : apr_errno.h
  • APR_OS_START_SYSERR : apr_errno.h
  • APR_OS_START_USEERR : apr_errno.h
  • APR_OS_START_USERERR : apr_errno.h
  • apr_pool_t : apr_pools.h
  • APR_READ : apr_file_io.h
  • APR_SDBM_DIRFEXT : apr_sdbm.h
  • APR_SDBM_INSERT : apr_sdbm.h
  • APR_SDBM_INSERTDUP : apr_sdbm.h
  • APR_SDBM_PAGFEXT : apr_sdbm.h
  • APR_SDBM_REPLACE : apr_sdbm.h
  • apr_sdbm_t : apr_sdbm.h
  • apr_seek_where_t : apr_file_io.h
  • APR_SET : apr_file_io.h
  • APR_SHARELOCK : apr_file_io.h
  • apr_size_t : apr.h
  • apr_status_t : apr_errno.h
  • APR_SUCCESS : apr_errno.h
  • APR_TIMEUP : apr_errno.h
  • APR_TRUNCATE : apr_file_io.h
  • APR_WRITE : apr_file_io.h
  • APR_XTHREAD : apr_file_io.h
  • APU_DECLARE : sdbm_lock.c, sdbm.c, apr_sdbm.h, apu.h
  • APU_DECLARE_DATA : apu.h
  • APU_DECLARE_NONSTD : apu.h
  • APU_HAVE_SDBM : apu.h
  • archive_ext : ltdl.c
  • argv0 : parser3isapi.C, parser3.C
  • argz_append : ltdl.c
  • argz_create_sep : ltdl.c
  • argz_insert : ltdl.c
  • argz_len : ltdl.c
  • argz_next : ltdl.c
  • argz_stringify : ltdl.c
  • ARRAY_OPTION_LIMIT_ALL : pa_array.h
  • ArrayOperation : pa_operation.h
  • ArrayString : pa_string.h
  • ArrayValue : pa_value.h
  • as_expires() : op.C
  • as_file_spec() : op.C
  • as_image() : image.C
  • as_node() : xnode.h
  • as_xmlchar() : xnode.h
  • assert : ltdl.c
  • ASSERT_STRING_INVARIANT : pa_string.h
  • atoi() : pa_vform.C
  • ATOMIC_READ : cordxtra.c
  • ATOMIC_WRITE : cordxtra.c
  • ATTACHMENT_WEIGHT : mail.C
  • attributed_meaning_to_string() : pa_value.h, pa_value.C
  • AUTO_FILE_NAME : pa_request.h
  • AUTO_METHOD_NAME : pa_request.C
  • auto_method_name : pa_request.C, pa_request.h

- b -
  • back_slashes_to_slashes() : pa_common.C, pa_common.h
  • bad : sdbm.c
  • base64_alphabet : pa_common.C
  • BASE_NAME : pa_vobject.h
  • base_name : ltdl.c
  • basic_authorization_field() : pa_http.C
  • before : ltdl.c
  • BINARY_MODE_NAME : file.C
  • BitSet : gifio.C
  • BODY_NAME : pa_request.C
  • body_name : pa_request.C, pa_request.h
  • BOOL : internal.h
  • BRASTACK_SIZE : pcre.c
  • buf : apr_file_io.h, ltdl.c
  • buf_len : ltdl.c
  • BUFSZ : cordxtra.c
  • buildCommand() : pa_exec.C
  • bytes_read : apr_file_io.h
  • bytes_written : apr_file_io.h
  • BYTESIZ : sdbm_tune.h

- c -
  • CACHE_DATA_NAME : op.C
  • cache_data_name() : op.C
  • cache_delete() : op.C
  • CACHE_EXCEPTION_HANDLED_CACHE_NAME : op.C
  • cache_get() : op.C
  • cache_managers : pa_cache_managers.C, pa_cache_managers.h
  • CACHE_SZ : cordxtra.c
  • calc_prefix_size() : math.C
  • CALLER_ELEMENT_NAME : pa_vmethod_frame.h
  • CASE_DEFAULT_VALUE : op.C
  • cbit_digit : internal.h
  • cbit_length : internal.h
  • cbit_space : internal.h
  • cbit_word : internal.h
  • cbits_offset : internal.h
  • cdate_name() : file.C
  • cgi : parser3.C
  • change_case() : string.C
  • change_case_UTF8() : pa_charset.C, pa_charset.h
  • change_string_literal_to_write_string_literal() : compile_tools.h
  • change_string_literal_value() : compile_tools.h, compile_tools.C
  • changetail_or_append() : compile_tools.h, compile_tools.C
  • char_type : gifio.C
  • CHARSET_EXEC_PARAM_NAME : file.C
  • CHARSET_NAME : pa_vmail.C, pa_value.h
  • charset_name() : pa_vmail.C
  • CHARSET_UTF8_NAME : pa_charsets.C
  • charsets : pa_charsets.C, pa_charsets.h
  • CHARSETS_NAME : pa_request.C
  • charsets_name() : pa_request.C
  • check() : pa_vhashfile.C
  • check_escape() : pcre.c
  • CHECK_EXPIRED_CONNECTIONS_SECONDS : pa_sql_driver_manager.C
  • check_option_param() : table.C
  • chkpage : sdbm_pair.h
  • CLASS_NAME : pa_vstateless_class.h
  • CLASS_PATH_NAME : pa_request.C
  • class_path_name() : pa_request.C
  • cleanup() : pa_pool.C
  • clear_delete_key() : pa_vhashfile.C
  • closedir : config_fixed.h
  • CM_BLUE : gifio.C
  • CM_GREEN : gifio.C
  • CM_RED : gifio.C
  • cmd_parser_config() : mod_parser3.c
  • cmd_parser_status_allowed() : mod_parser3.c
  • CodeTabOf : gifio.C
  • colorstobpp() : gifio.C
  • compile_branch() : pcre.c
  • compile_data : internal.h
  • compile_regex() : pcre.c
  • CONCAT_HDR : cordbscs.c
  • CONF_METHOD_NAME : pa_request.C
  • conf_method_name() : pa_request.C
  • config_filespec_cstr : parser3.C
  • configure_admin_one() : classes.C
  • configure_user_one() : classes.C
  • CONSOLE_CLASS_NAME : pa_vconsole.h
  • CONSOLE_LINE_NAME : pa_vconsole.h
  • cont : apr_file_io.h
  • content_disposition_filename_name : pa_request.C, pa_request.h
  • CONTENT_DISPOSITION_FILENAME_NAME : pa_request.h
  • content_disposition_name : pa_request.C, pa_request.h
  • CONTENT_DISPOSITION_NAME : pa_request.h
  • content_disposition_value : pa_request.C, pa_request.h
  • CONTENT_DISPOSITION_VALUE : pa_request.h
  • content_type_name : pa_value.C, pa_value.h
  • CONTENT_TYPE_NAME : pa_value.h
  • context : pa_md5.h
  • CONV_RESULT_LEN : cordprnt.c
  • CONV_SPEC_LEN : cordprnt.c
  • COOKIE_CLASS_NAME : pa_vcookie.h
  • copy_all_dontoverwrite_to() : hash.C
  • copy_all_overwrite_to() : hash.C
  • copy_intersection_to() : hash.C
  • CORD : cord.h
  • CORD__extend_path() : cordbscs.c
  • CORD__next() : cord_pos.h, cordbscs.c
  • CORD__pos_fetch() : cord_pos.h, cordbscs.c
  • CORD__prev() : cord_pos.h, cordbscs.c
  • CORD_add_forest() : cordbscs.c
  • CORD_apply_access_fn() : cordbscs.c
  • CORD_balance() : cord.h, cordbscs.c
  • CORD_balance_insert() : cordbscs.c
  • CORD_batched_chr_proc() : cordxtra.c
  • CORD_batched_fill_proc() : cordxtra.c
  • CORD_batched_iter_fn : cord.h
  • CORD_batched_iter_fn_generic_hash_code() : pa_string.C
  • CORD_batched_put_proc() : cordxtra.c
  • CORD_block_count() : pa_string.C, pa_string.h
  • CORD_block_count_proc() : pa_string.C
  • CORD_block_iter() : cord.h, cordbscs.c
  • CORD_block_iter_fn : cord.h
  • CORD_BUFSZ : ec.h
  • CORD_cat() : cord.h, cordbscs.c
  • CORD_cat_char() : cord.h, cordxtra.c
  • CORD_cat_char_star() : cord.h, cordbscs.c
  • CORD_catn() : cord.h, cordxtra.c
  • CORD_chars() : cord.h, cordxtra.c
  • CORD_chr() : cord.h, cordxtra.c
  • CORD_chr_proc() : cordxtra.c
  • CORD_cmp() : cord.h, cordxtra.c
  • CORD_concat_forest() : cordbscs.c
  • CORD_dump() : cord.h, cordbscs.c
  • CORD_dump_inner() : cordbscs.c
  • CORD_ec : ec.h
  • CORD_ec_append : untaint.C, ec.h
  • CORD_ec_append_cord() : ec.h, cordxtra.c
  • CORD_ec_flush_buf() : ec.h, cordxtra.c
  • CORD_ec_init : ec.h
  • CORD_ec_to_cord : ec.h
  • CORD_EMPTY : cord.h
  • CORD_fetch() : cord.h, cordxtra.c
  • CORD_fill_buf() : cordxtra.c
  • CORD_fill_proc() : cordxtra.c
  • CORD_fn : cord.h
  • CORD_FOR : cord.h
  • CORD_fprintf() : cord.h, cordprnt.c
  • CORD_from_char_star() : cord.h, cordxtra.c
  • CORD_from_file() : cord.h
  • CORD_from_file_eager() : cord.h, cordxtra.c
  • CORD_from_file_lazy() : cord.h
  • CORD_from_fn() : cord.h, cordbscs.c
  • CORD_from_fn_gen() : cord.h
  • CORD_index_access_fn() : cordbscs.c
  • CORD_init_forest() : cordbscs.c
  • CORD_init_min_len() : cordbscs.c
  • CORD_IS_STRING : cord.h
  • CORD_iter : cord.h, cordbscs.c, cord.h
  • CORD_iter5() : cord.h, cordbscs.c
  • CORD_iter_fn : cord.h
  • CORD_len() : cord.h, cordbscs.c
  • CORD_max_len : cordbscs.c
  • CORD_ncmp() : cord.h, cordxtra.c
  • CORD_next : cord_pos.h, cordbscs.c, cord_pos.h
  • CORD_NO_FN : cord.h
  • CORD_NO_IO : pa_string.h
  • CORD_NOT_FOUND : cord.h
  • CORD_nul : cord.h
  • CORD_nul_func() : cordxtra.c, cordbscs.c
  • CORD_oom_fn : cord.h, cordbscs.c
  • CORD_pos : cord_pos.h
  • CORD_pos_advance : cord_pos.h
  • CORD_pos_chars_left : cord_pos.h
  • CORD_pos_cur_char_addr : cord_pos.h
  • CORD_pos_fetch : cord_pos.h, cordbscs.c, cord_pos.h
  • CORD_POS_INVALID : cord_pos.h
  • CORD_pos_to_cord : cord_pos.h, cordbscs.c, cord_pos.h
  • CORD_pos_to_index : cord_pos.h, cordbscs.c, cord_pos.h
  • CORD_pos_valid : cord_pos.h, cordbscs.c, cord_pos.h
  • CORD_prev : cord_pos.h, cordbscs.c, cord_pos.h
  • CORD_printf() : cord.h, cordprnt.c
  • CORD_put() : cord.h, cordxtra.c
  • CORD_put_proc() : cordxtra.c
  • CORD_range_contains_chr_greater_then() : pa_string.C, pa_string.h
  • CORD_range_contains_chr_greater_then_proc() : pa_string.C
  • CORD_rchr() : cord.h, cordxtra.c
  • CORD_rchr_proc() : cordxtra.c
  • CORD_riter() : cord.h, cordbscs.c
  • CORD_riter4() : cord.h, cordbscs.c
  • CORD_set_pos() : cord_pos.h, cordbscs.c
  • CORD_sprintf() : cord.h, cordprnt.c
  • CORD_str() : cord.h, cordxtra.c
  • CORD_substr() : cord.h, cordbscs.c
  • CORD_substr_checked() : cordbscs.c
  • CORD_substr_closure() : cordbscs.c
  • CORD_to_char_star() : cord.h, cordxtra.c
  • CORD_to_const_char_star() : cord.h, cordxtra.c
  • CORD_vfprintf() : cord.h, cordprnt.c
  • CORD_vprintf() : cord.h, cordprnt.c
  • CORD_vsprintf() : cord.h, cordprnt.c
  • cost : mtables.h
  • costScale : mtables.h
  • create_dir_for_file() : pa_common.C, pa_common.h
  • CreateHiddenConsoleProcess() : pa_exec.C
  • CRLF : pa_http.C
  • crypt() : math.C
  • cstr2ctypes() : pa_charset.C
  • cstr_to_string_body_block() : untaint.C
  • cstr_to_time_t() : image.C, date.C
  • ctype_digit : internal.h
  • ctype_letter : internal.h
  • ctype_meta : internal.h
  • ctype_space : internal.h
  • ctype_word : internal.h
  • ctype_xdigit : internal.h
  • ctypes_offset : internal.h

- d -
  • data : ltdl.c
  • data1 : ltdl.c
  • data2 : ltdl.c
  • DATA_STRING_SERIALIZED_VERSION : op.C
  • database_cleanup() : sdbm.c
  • date_attribute() : pa_value.C
  • date_calendar_table_template() : date.C
  • date_class : pa_vdate.h
  • DBLKSIZ : sdbm_private.h
  • de_stack : gifio.C
  • debug : sdbm_tune.h
  • DECLARE_CLASS_VAR : xnode.C, xdoc.C, void.C, table.C, string.C, response.C, memory.C, math.C, mail.C, int.C, image.C, hashfile.C, hash.C, form.C, file.C, double.C, date.C, classes.h
  • Decode() : pa_md5c.c
  • DEFAULT_CONTENT_TYPE : pa_request.C
  • DEFAULT_EXPIRES_DAYS : pa_vcookie.C
  • default_preloaded_symbols : ltdl.c
  • DEFAULT_USER_AGENT : pa_http.C
  • DEFINE_DUAL : pa_request.h
  • degrees() : math.C
  • delete_file() : pa_vhashfile.C
  • delete_one() : pa_cache_managers.C
  • delim : ltdl.c
  • delpair : sdbm_pair.h
  • deplibs : ltdl.c
  • DEPTH : cordbscs.c
  • detect_charset() : pa_http.C
  • DFTABLES : pcre_parser_ctype.c, dftables.c
  • die_or_abort() : parser3.C, mod_parser3_core.C
  • DIR : config_fixed.h
  • dir : ltdl.c
  • dir_exists() : pa_common.C, pa_common.h
  • dirnam : ltdl.c
  • dirname : ltdl.c
  • DIV_CACHE_SZ : cordxtra.c
  • DIV_LINE_SZ : cordxtra.c
  • DllMain() : parser3isapi.C
  • dlloader : ltdl.c
  • dlname : ltdl.c
  • DOCUMENT_ROOT_NAME : pa_vrequest.C
  • double_class : pa_vdouble.h
  • DOWNLOAD_NAME : pa_request.C
  • download_name() : pa_request.C
  • dp : ltdl.c
  • DPRINTF : pcre.c
  • DUFF : sdbm_hash.c
  • duppair : sdbm_pair.h

- e -
  • ec_append() : untaint.C
  • ec_len() : cordprnt.c
  • ECSTR : file.C
  • element2case() : pa_charset.C
  • element2ctypes() : pa_charset.C
  • encode : untaint.C
  • Encode() : pa_md5c.c
  • endian_to_uint() : image.C
  • endian_to_ushort() : image.C
  • entry : ltdl.c
  • entry_exists() : pa_common.C, pa_common.h
  • entry_readable() : pa_common.C
  • ENV_CLASS_NAME : pa_venv.h
  • EPOCH_BIAS : pa_vstatus.C
  • ERR1 : internal.h
  • ERR10 : internal.h
  • ERR11 : internal.h
  • ERR12 : internal.h
  • ERR13 : internal.h
  • ERR14 : internal.h
  • ERR15 : internal.h
  • ERR16 : internal.h
  • ERR17 : internal.h
  • ERR18 : internal.h
  • ERR19 : internal.h
  • ERR2 : internal.h
  • ERR20 : internal.h
  • ERR21 : internal.h
  • ERR22 : internal.h
  • ERR23 : internal.h
  • ERR24 : internal.h
  • ERR25 : internal.h
  • ERR26 : internal.h
  • ERR27 : internal.h
  • ERR28 : internal.h
  • ERR3 : internal.h
  • ERR4 : internal.h
  • ERR5 : internal.h
  • ERR6 : internal.h
  • ERR7 : internal.h
  • ERR8 : internal.h
  • ERR9 : internal.h
  • ERR_CLOSING : smtp.h
  • ERR_NOT_A_SOCKET : smtp.h
  • ERR_SENDING_DATA : smtp.h
  • error_t : config_fixed.h
  • errorcount : ltdl.c
  • ESC_A : internal.h
  • ESC_B : internal.h
  • ESC_b : internal.h
  • ESC_D : internal.h
  • ESC_d : internal.h
  • ESC_REF : internal.h
  • ESC_S : internal.h
  • ESC_s : internal.h
  • ESC_W : internal.h
  • ESC_w : internal.h
  • ESC_Z : internal.h
  • ESC_z : internal.h
  • escape : untaint.C
  • escapes : pcre.c
  • EXCEPTION_COMMENT_PART_NAME : pa_request.C
  • exception_comment_part_name : pa_request.C, pa_request.h
  • exception_handled_part_name : pa_request.C, pa_request.h
  • EXCEPTION_HANDLED_PART_NAME : pa_request.h
  • EXCEPTION_SOURCE_PART_NAME : pa_request.C
  • exception_source_part_name : pa_request.C, pa_request.h
  • EXCEPTION_TYPE_PART_NAME : pa_request.C
  • exception_type_part_name : pa_request.C, pa_request.h
  • EXCEPTION_VAR_NAME : op.C
  • exception_var_name() : op.C
  • execution_canceled : parser3.C
  • exhash : sdbm_pair.c, sdbm.c
  • EXIF_ELEMENT_NAME : pa_vimage.h
  • EXIF_TAG : image.C
  • exif_tag_value2name : image.C
  • expire_connection() : pa_sql_driver_manager.C
  • expire_connections() : pa_sql_driver_manager.C
  • EXPIRE_UNUSED_CONNECTION_SECONDS : pa_sql_driver_manager.C
  • expires_name : pa_value.C, pa_value.h
  • EXPIRES_NAME : pa_value.h
  • expires_vdate() : pa_vcookie.C
  • expression_is_true() : table.C
  • extract_conv_spec() : cordprnt.c
  • EXTRACT_MAX : internal.h
  • extractEmail() : pa_vmail.C
  • extractEmails() : pa_vmail.C

- f -
  • F : pa_md5c.c
  • FA_DIREC : pa_dir.h
  • fail_on_config_read_problem : parser3.C
  • FALSE : internal.h, gifio.C
  • fcc_offset : internal.h
  • FF : pa_md5c.c
  • file : sdbm.c
  • file_class : pa_vfile.C
  • file_delete() : pa_common.C, pa_common.h
  • file_executable() : pa_common.C, pa_common.h
  • file_exist() : pa_common.C, pa_common.h
  • file_measure_action() : image.C
  • file_move() : pa_common.C, pa_common.h
  • file_read() : pa_common.C, pa_common.h
  • File_read_action : pa_common.h
  • file_read_action() : pa_common.C
  • file_read_action_under_lock() : pa_common.C, pa_common.h
  • file_read_text() : pa_common.C, pa_common.h
  • file_stat() : pa_common.C, pa_common.h
  • FILE_STATUS_NAME : pa_common.C
  • file_status_name : pa_common.C, pa_common.h
  • file_value_to_string() : pa_vmail.C
  • file_write() : pa_common.C, pa_common.h
  • File_write_action : pa_common.h
  • file_write_action() : pa_common.C
  • file_write_action_under_lock() : pa_common.C, pa_common.h
  • filename : ltdl.c
  • fill_month_days() : date.C
  • fill_week_days() : date.C
  • find_firstchar() : pcre.c
  • find_fixedlength() : pcre.c
  • find_headers_end() : pa_http.C
  • findclose() : pa_dir.C, pa_dir.h
  • findfirst() : pa_dir.C, pa_dir.h
  • findnext() : pa_dir.C, pa_dir.h
  • first_significant_code() : pcre.c
  • fitpair : sdbm_pair.h, sdbm_pair.c, sdbm_pair.h
  • fix_line_breaks() : pa_common.C, pa_common.h
  • flag : apr_file_io.C, apr_file_io.h
  • flags : sdbm.c
  • FN_HDR : cordbscs.c
  • fname : apr_file_io.C, apr_file_io.h
  • for_each_string_callback() : pa_vhashfile.C
  • Forest : cordbscs.c
  • form_base_class : pa_vform.C
  • FORM_FIELDS_ELEMENT_NAME : pa_vform.h
  • FORM_IMAP_ELEMENT_NAME : pa_vform.h
  • form_string_value2string() : pa_http.C
  • form_table_value2string() : pa_http.C
  • FORM_TABLES_ELEMENT_NAME : pa_vform.h
  • form_value2string() : pa_http.C
  • format() : pa_common.C, pa_common.h
  • FORMAT_NAME : pa_vmail.C
  • format_name() : pa_vmail.C
  • frac() : math.C
  • full_file_spec() : parser3.C
  • func : ltdl.c
  • FUNCTION_BUF_SZ : cord_pos.h

- g -
  • G : pa_md5c.c
  • g_mime_utils_base64_decode_step() : pa_common.C
  • g_mime_utils_base64_encode_close() : pa_common.C
  • g_mime_utils_base64_encode_step() : pa_common.C
  • GC_all_interior_pointers : gc.h
  • GC_API : gc.h
  • GC_CHANGE_STUBBORN : gc.h
  • GC_CONST : gc.h
  • GC_dont_expand : gc.h
  • GC_dont_gc : gc.h
  • GC_dont_precollect : gc.h
  • GC_END_STUBBORN_CHANGE : gc.h
  • GC_EXTRA_PARAMS : gc.h
  • GC_EXTRAS : gc.h
  • GC_finalize_on_demand : gc.h
  • GC_finalizer_notifier : gc.h
  • GC_find_leak : gc.h
  • GC_FREE : gc.h
  • GC_free_space_divisor : gc.h
  • GC_full_freq : gc.h
  • GC_gc_no : gc.h
  • GC_GENERAL_REGISTER_DISAPPEARING_LINK : gc.h
  • GC_INIT : gc.h
  • GC_java_finalization : gc.h
  • GC_MALLOC : gc.h
  • GC_MALLOC_ATOMIC : gc.h
  • GC_MALLOC_STUBBORN : gc.h
  • GC_MALLOC_UNCOLLECTABLE : gc.h
  • GC_max_retries : gc.h
  • GC_NEW : gc.h
  • GC_NEW_ATOMIC : gc.h
  • GC_NEW_STUBBORN : gc.h
  • GC_NEW_UNCOLLECTABLE : gc.h
  • GC_no_dls : gc.h
  • GC_non_gc_bytes : gc.h
  • GC_parallel : gc.h
  • GC_POST_INCR : gc.h
  • GC_POST_INCR2 : gc.h
  • GC_PRE_INCR : gc.h
  • GC_PRE_INCR3 : gc.h
  • GC_PROTECTS_NONE : gc.h
  • GC_PROTECTS_POINTER_HEAP : gc.h
  • GC_PROTECTS_PTRFREE_HEAP : gc.h
  • GC_PROTECTS_STACK : gc.h
  • GC_PROTECTS_STATIC_DATA : gc.h
  • GC_PROTO : gc.h
  • GC_PTR : gc.h
  • GC_PTR_ADD : gc.h
  • GC_PTR_ADD3 : gc.h
  • GC_PTR_STORE : gc.h
  • GC_quiet : gc.h
  • GC_REALLOC : gc.h
  • GC_REGISTER_DISPLACEMENT : gc.h
  • GC_REGISTER_FINALIZER : gc.h
  • GC_REGISTER_FINALIZER_IGNORE_SELF : gc.h
  • GC_REGISTER_FINALIZER_NO_ORDER : gc.h
  • GC_signed_word : gc.h
  • GC_stackbottom : gc.h
  • gc_substitute_memory_management_functions() : pa_globals.C
  • GC_time_limit : gc.h
  • GC_TIME_UNLIMITED : gc.h
  • GC_use_entire_heap : gc.h
  • GC_word : gc.h
  • gdCompareInt() : gif.C
  • gdMaxColors : gif.h
  • GEN_LEN : cordbscs.c
  • generic_hash_code() : pa_hash.h
  • get_action_options() : table.C
  • get_hash__put() : pa_vhashfile.C
  • get_length() : pa_string.h
  • get_length< String::Body >() : pa_string.h
  • GET_SELF : pa_request.h
  • getdbit() : sdbm.c
  • geterror : ltdl.c
  • GetExtensionVersion() : parser3isapi.C
  • getHeader() : pa_vform.C
  • getMonthDays() : pa_common.C, pa_common.h
  • getnext() : sdbm.c
  • getnkey : sdbm_pair.h
  • getopt() : getopt.h, getopt.c
  • getpage() : sdbm.c
  • getpair : sdbm_pair.h
  • GETPROCESSIOCOUNTERS : pa_vstatus.C
  • getrow() : pa_common.C, pa_common.h
  • gFirstByteMark : pa_charset.C
  • GG : pa_md5c.c
  • GIFBITS : gifio.C
  • global_mutex : isapi/pa_threads.C, cgi/pa_threads.C, apache13core/pa_threads.C, pa_threads.h
  • gmime_base64_rank : pa_common.C
  • grep_char() : parser3isapi.C
  • guess_content_length() : pa_http.C
  • gUTFBytes : pa_charset.C
  • gUTFOffsets : pa_charset.C

- h -
  • H : pa_md5c.c
  • handle : ltdl.c
  • handles : ltdl.c
  • Hash_allocates : pa_hash.h
  • HASH_ALLOCATES_COUNT : pa_hash.h
  • hash_class : pa_vhash.h
  • hash_code() : pa_string.h, pa_hash.h
  • HASH_DEFAULT_ELEMENT_NAME : pa_vhash.h
  • HASH_FIELDS_NAME : pa_vhash.h
  • HASHC : sdbm_hash.c
  • hashfile_class : pa_vhashfile.h
  • HASHFILE_VALUE_SERIALIZED_VERSION : pa_vhashfile.C
  • HashStringBool : pa_xml_io.h, hashfile.C
  • HashStringObject : pa_value.h
  • HashStringString : pa_charset.h
  • HashStringValue : pa_value.h, pa_common.h
  • HashTabOf : gifio.C
  • HAVE__LOCKING : pa_config_fixed.h
  • HAVE_ASSERT_H : pa_config_fixed.h
  • HAVE_CTYPE_H : config_fixed.h, pa_config_fixed.h
  • HAVE_DAYLIGHT : pa_config_fixed.h
  • HAVE_DIRECT_H : pa_config_fixed.h
  • HAVE_ERRNO_H : config_fixed.h, pa_config_fixed.h
  • HAVE_FCNTL_H : pa_config_fixed.h
  • HAVE_IO_H : pa_config_fixed.h
  • HAVE_MATH_H : pa_config_fixed.h
  • HAVE_MEMCPY : config_fixed.h
  • HAVE_MEMMOVE : config_fixed.h
  • HAVE_MEMORY_H : config_fixed.h, pa_config_fixed.h
  • HAVE_PROCESS_H : pa_config_fixed.h
  • HAVE_SETJMP_H : pa_config_fixed.h
  • HAVE_STDARG_H : pa_config_fixed.h
  • HAVE_STDDEF_H : pa_config_fixed.h
  • HAVE_STDIO_H : config_fixed.h, pa_config_fixed.h
  • HAVE_STDLIB_H : config_fixed.h
  • HAVE_STRCHR : config_fixed.h
  • HAVE_STRCMP : config_fixed.h
  • HAVE_STRING_H : config_fixed.h, pa_config_fixed.h
  • HAVE_STRINGS_H : config_fixed.h
  • HAVE_STRRCHR : config_fixed.h
  • HAVE_SYS_LOCKING_H : pa_config_fixed.h
  • HAVE_SYS_STAT_H : config_fixed.h, pa_config_fixed.h
  • HAVE_SYS_TYPES_H : config_fixed.h, pa_config_fixed.h
  • HAVE_TIME_H : pa_config_fixed.h
  • HAVE_TIMEZONE : pa_config_fixed.h
  • HAVE_WINSOCK_H : pa_config_fixed.h
  • hex_string() : math.C
  • hex_value : pa_globals.C, pa_globals.h
  • HH : pa_md5c.c
  • HSIZE : gif.h
  • HTTP_ANY_STATUS_NAME : pa_http.C
  • HTTP_BODY_NAME : pa_http.C
  • HTTP_CHARSET_NAME : pa_http.C
  • HTTP_FORM_NAME : pa_http.C
  • HTTP_HEADERS_NAME : pa_http.C
  • HTTP_METHOD_NAME : pa_http.C
  • http_pass_header() : pa_http.C
  • HTTP_PASSWORD : pa_http.C
  • http_read_response() : pa_http.C
  • http_request() : pa_http.C
  • HTTP_TABLES_NAME : pa_http.C
  • HTTP_TIMEOUT_NAME : pa_http.C
  • HTTP_USER : pa_http.C
  • HttpExtensionProc() : parser3isapi.C

- i -
  • I : pa_md5c.c
  • I_HIDE_POINTERS : cordxtra.c
  • IDENT : pa_vvoid.C, pa_vhashfile.C, pa_vhash.C, pa_venv.C, apr_strings.C, apr_file_io.C, hashfile.C
  • IDENT_ARRAY_Y : pa_array.h
  • IDENT_CACHE_MANAGERS_C : pa_cache_managers.C
  • IDENT_CACHE_MANAGERS_H : pa_cache_managers.h
  • IDENT_CHARSET_C : pa_charset.C
  • IDENT_CHARSET_H : pa_charset.h
  • IDENT_CHARSETS_C : pa_charsets.C
  • IDENT_CHARSETS_H : pa_charsets.h
  • IDENT_CLASSES_C : classes.C
  • IDENT_CLASSES_H : classes.h
  • IDENT_COMMON_C : pa_os.C, pa_common.C
  • IDENT_COMMON_H : pa_common.h
  • IDENT_COMMS_C : comms.C
  • IDENT_COMPILE_C : compile.C
  • IDENT_COMPILE_TOOLS_C : compile_tools.C
  • IDENT_COMPILE_TOOLS_H : compile_tools.h
  • IDENT_CONFIG_FIXED_H : pa_config_fixed.h
  • IDENT_DATE_C : date.C
  • IDENT_DICTIONARY_C : pa_dictionary.C
  • IDENT_DICTIONARY_H : pa_dictionary.h
  • IDENT_DIR_C : pa_dir.C
  • IDENT_DIR_H : pa_dir.h
  • IDENT_DOUBLE_C : double.C
  • IDENT_EXCEPTION_C : pa_exception.C
  • IDENT_EXCEPTION_H : pa_exception.h
  • IDENT_EXEC_C : pa_exec.C
  • IDENT_EXEC_H : pa_exec.h
  • IDENT_EXECUTE_C : execute.C
  • IDENT_FILE_C : file.C
  • IDENT_FORM_C : form.C
  • IDENT_GIF_C : gif.C
  • IDENT_GIF_H : gif.h
  • IDENT_GIFIO_C : gifio.C
  • IDENT_GLOBALS_C : pa_globals.C
  • IDENT_GLOBALS_H : pa_globals.h
  • IDENT_HASH_C : hash.C
  • IDENT_HASH_H : pa_hash.h
  • IDENT_HTTP_C : pa_http.C
  • IDENT_HTTP_H : pa_http.h
  • IDENT_HTTPD_H : pa_httpd.h
  • IDENT_IMAGE_C : image.C
  • IDENT_INT_C : int.C
  • IDENT_JUNCTION_H : pa_junction.h
  • IDENT_MAIL_C : mail.C
  • IDENT_MATH_C : memory.C, math.C
  • IDENT_MD5_C : pa_md5c.c
  • IDENT_MD5_H : pa_md5.h
  • IDENT_MEMORY_C : pa_memory.C
  • IDENT_MEMORY_H : pa_memory.h
  • IDENT_METHOD_H : pa_method.h
  • IDENT_MOD_PARSER3_C : mod_parser3.c
  • IDENT_MOD_PARSER3_MAIN_C : mod_parser3_core.C
  • IDENT_OP_C : op.C
  • IDENT_OPCODE_H : pa_opcode.h
  • IDENT_OPERATION_H : pa_operation.h
  • IDENT_OS_H : pa_os.h
  • IDENT_PARSER3_C : parser3.C
  • IDENT_PARSER3ISAPI_C : parser3isapi.C
  • IDENT_POOL_C : pa_pool.C
  • IDENT_POOL_H : pa_pool.h
  • IDENT_PROPERTY_H : pa_property.h
  • IDENT_REQUEST_C : pa_request.C
  • IDENT_REQUEST_CHARSETS_H : pa_request_charsets.h
  • IDENT_REQUEST_H : pa_request.h
  • IDENT_REQUEST_INFO_H : pa_request_info.h
  • IDENT_RESPONSE_C : response.C
  • IDENT_SAPI_H : pa_sapi.h
  • IDENT_SMTP_C : smtp.C
  • IDENT_SMTP_H : smtp.h
  • IDENT_SOCKS_C : pa_socks.C
  • IDENT_SOCKS_H : pa_socks.h
  • IDENT_SQL_CONNECTION_H : pa_sql_connection.h
  • IDENT_SQL_DRIVER_H : pa_sql_driver.h
  • IDENT_SQL_DRIVER_MANAGER_C : pa_sql_driver_manager.C
  • IDENT_SQL_DRIVER_MANAGER_H : pa_sql_driver_manager.h
  • IDENT_STACK_H : pa_stack.h
  • IDENT_STRING_C : pa_string.C, string.C
  • IDENT_STRING_H : pa_string.h
  • IDENT_STYLESHEET_CONNECTION_H : pa_stylesheet_connection.h
  • IDENT_STYLESHEET_MANAGER_H : pa_stylesheet_manager.h
  • IDENT_TABLE_C : pa_table.C, table.C
  • IDENT_TABLE_H : pa_table.h
  • IDENT_THREADS_C : isapi/pa_threads.C, cgi/pa_threads.C, apache13core/pa_threads.C
  • IDENT_THREADS_H : pa_threads.h
  • IDENT_TYPES_H : pa_types.h
  • IDENT_UNTAINT_C : untaint.C
  • IDENT_UUE_C : pa_uue.C
  • IDENT_UUE_H : pa_uue.h
  • IDENT_VALUE_C : pa_value.C
  • IDENT_VALUE_H : pa_value.h
  • IDENT_VBOOL_H : pa_vbool.h
  • IDENT_VCLASS_C : pa_vclass.C
  • IDENT_VCLASS_H : pa_vclass.h
  • IDENT_VCODE_FRAME_H : pa_vcode_frame.h
  • IDENT_VCONSOLE_H : pa_vconsole.h
  • IDENT_VCOOKIE_C : pa_vcookie.C
  • IDENT_VCOOKIE_H : pa_vcookie.h
  • IDENT_VDATE_H : pa_vdate.h
  • IDENT_VDOUBLE_H : pa_vdouble.h
  • IDENT_VENV_H : pa_venv.h
  • IDENT_VFILE_C : pa_vfile.C
  • IDENT_VFILE_H : pa_vfile.h
  • IDENT_VFORM_C : pa_vform.C
  • IDENT_VFORM_H : pa_vform.h
  • IDENT_VHASH_H : pa_vhash.h
  • IDENT_VHASHFILE_H : pa_vhashfile.h
  • IDENT_VIMAGE_C : pa_vimage.C
  • IDENT_VIMAGE_H : pa_vimage.h
  • IDENT_VINT_H : pa_vint.h
  • IDENT_VJUNCTION_H : pa_vjunction.h
  • IDENT_VMAIL_C : pa_vmail.C
  • IDENT_VMAIL_H : pa_vmail.h
  • IDENT_VMATH_C : pa_vmath.C
  • IDENT_VMATH_H : pa_vmath.h
  • IDENT_VMEMORY_H : pa_vmemory.h
  • IDENT_VMETHOD_FRAME_H : pa_vmethod_frame.h
  • IDENT_VOBJECT_C : pa_vobject.C
  • IDENT_VOBJECT_H : pa_vobject.h
  • IDENT_VOID_C : void.C
  • IDENT_VPROPERTY_H : pa_vproperty.h
  • IDENT_VREQUEST_C : pa_vrequest.C
  • IDENT_VREQUEST_H : pa_vrequest.h
  • IDENT_VRESPONSE_C : pa_vresponse.C
  • IDENT_VRESPONSE_H : pa_vresponse.h
  • IDENT_VSTATELESS_CLASS_C : pa_vstateless_class.C, pa_vmethod_frame.C
  • IDENT_VSTATELESS_CLASS_H : pa_vstateless_class.h
  • IDENT_VSTATELESS_OBJECT_H : pa_vstateless_object.h
  • IDENT_VSTATUS_C : pa_vstatus.C
  • IDENT_VSTATUS_H : pa_vstatus.h
  • IDENT_VSTRING_C : pa_vstring.C
  • IDENT_VSTRING_H : pa_vstring.h
  • IDENT_VTABLE_C : pa_vtable.C
  • IDENT_VTABLE_H : pa_vtable.h
  • IDENT_VVOID_H : pa_vvoid.h
  • IDENT_VXDOC_H : pa_vxdoc.h
  • IDENT_VXNODE_H : pa_vxnode.h
  • IDENT_WCONTEXT_C : pa_wcontext.C
  • IDENT_WCONTEXT_H : pa_wcontext.h
  • IDENT_WWRAPPER_H : pa_wwrapper.h
  • IDENT_XML_IO_H : pa_xml_io.h
  • IDENT_XNODE_H : xnode.h
  • ignored : ltdl.c
  • II : pa_md5c.c
  • IIS51var_count : parser3isapi.C
  • IIS51vars : parser3isapi.C
  • image_class : pa_vimage.h
  • INADDR_NONE : pa_http.C
  • initialized : ltdl.c
  • inline : config_fixed.h, pa_config_fixed.h
  • input : pa_md5c.c, pa_md5.h
  • inputLen : pa_md5.h
  • installed : ltdl.c
  • int_class : pa_vint.h
  • INTERLACE : gifio.C
  • intersects() : hash.C
  • IO_COUNTERS_ : pa_vstatus.C
  • is_anchored() : pcre.c
  • IS_CONCATENATION : cordbscs.c
  • is_counted_repeat() : pcre.c
  • IS_FUNCTION : cordbscs.c
  • is_safe_env_key() : file.C
  • is_salt_body_char() : math.C
  • is_startline() : pcre.c
  • IS_SUBSTR : cordbscs.c
  • is_text_mode() : file.C
  • isLeap() : pa_common.C

- j -
  • join_named_row() : table.C
  • join_nameless_row() : table.C
  • JPEG_EXIF_DATE_CHARS : image.C
  • JPG_IFD_TAG_EXIF_OFFSET : image.C

- k -
  • key : sdbm_pair.c, apr_sdbm.h
  • keys_collector() : hash.C

- l -
  • LA2S() : compile_tools.h
  • LA2V() : compile_tools.h, compile_tools.C
  • lastposafter() : file.C
  • LAZY_THRESHOLD : cordxtra.c
  • lcc_offset : internal.h
  • LEFT_LEN : cordbscs.c
  • LEN : cordbscs.c
  • lexical_brackets_nestage : compile.y
  • lexical_state : compile_tools.h
  • libdir : ltdl.c
  • LIMITS_NAME : form.C
  • limits_name() : form.C
  • LINE_START : cordxtra.c
  • LINE_SZ : cordxtra.c
  • LM_to_uint : gifio.C
  • load() : image.C
  • load_charset() : pa_request.C
  • LOAD_DIR : pa_dir.h
  • loader_name : ltdl.c
  • loaders : ltdl.c
  • LOCALCOLORMAP : gifio.C
  • locate_int_string() : pa_table.C
  • lock_execute_body() : file.C
  • locked_process_and_cache_put() : op.C
  • locked_process_and_cache_put_action() : op.C
  • log() : parser3.C
  • LOG_CACHE_SZ : cordxtra.c
  • LOG_LINE_SZ : cordxtra.c
  • log_signal() : parser3.C
  • LS_DEF_COMMENT : compile_tools.h
  • LS_DEF_LOCALS : compile_tools.h
  • LS_DEF_NAME : compile_tools.h
  • LS_DEF_PARAMS : compile_tools.h
  • LS_DEF_SPECIAL_BODY : compile_tools.h
  • LS_EXPRESSION_COMMENT : compile_tools.h
  • LS_EXPRESSION_STRING_APOSTROFED : compile_tools.h
  • LS_EXPRESSION_STRING_QUOTED : compile_tools.h
  • LS_EXPRESSION_VAR_NAME_WITH_COLON : compile_tools.h
  • LS_EXPRESSION_VAR_NAME_WITHOUT_COLON : compile_tools.h
  • LS_METHOD_AFTER : compile_tools.h
  • LS_METHOD_CURLY : compile_tools.h
  • LS_METHOD_NAME : compile_tools.h
  • LS_METHOD_ROUND : compile_tools.h
  • LS_METHOD_SQUARE : compile_tools.h
  • LS_NAME_SQUARE_PART : compile_tools.h
  • LS_USER : compile_tools.h
  • LS_USER_COMMENT : compile_tools.h
  • LS_VAR_CURLY : compile_tools.h
  • LS_VAR_NAME_CURLY : compile_tools.h
  • LS_VAR_NAME_SIMPLE_WITH_COLON : compile_tools.h
  • LS_VAR_NAME_SIMPLE_WITHOUT_COLON : compile_tools.h
  • LS_VAR_ROUND : compile_tools.h
  • LS_VAR_SQUARE : compile_tools.h
  • lsplit() : pa_common.C, pa_common.h, table.C
  • LT_BEGIN_C_DECLS : ltdl.h
  • LT_CONC : ltdl.h
  • LT_D_NAMLEN : config_fixed.h
  • LT_DIRSEP_CHAR : ltdl.h
  • lt_dladderror() : ltdl.c
  • lt_dlcaller_id : ltdl.h
  • lt_dlerror_strings : ltdl.c
  • lt_dlerror_table : ltdl.h
  • LT_DLFREE : ltdl.c
  • LT_DLGET_FLAG : ltdl.c
  • lt_dlhandle : ltdl.h
  • lt_dlinit() : ltdl.c
  • LT_DLIS_RESIDENT : ltdl.c
  • lt_dllast_error : ltdl.c
  • lt_dlloader : ltdl.h
  • LT_DLMALLOC : ltdl.c
  • LT_DLMEM_REASSIGN : ltdl.c
  • LT_DLMUTEX_GETERROR : ltdl.c
  • lt_dlmutex_geterror_func : ltdl.c
  • LT_DLMUTEX_LOCK : ltdl.c
  • lt_dlmutex_lock_func : ltdl.c
  • lt_dlmutex_register() : ltdl.c
  • LT_DLMUTEX_SETERROR : ltdl.c
  • lt_dlmutex_seterror_func : ltdl.c
  • LT_DLMUTEX_UNLOCK : ltdl.c
  • lt_dlmutex_unlock_func : ltdl.c
  • lt_dlpreload() : ltdl.c
  • LT_DLREALLOC : ltdl.c
  • LT_DLRESIDENT_FLAG : ltdl.c
  • LT_DLSET_FLAG : ltdl.c
  • LT_DLSTRERROR : ltdl.c
  • lt_dlsymlists_t : ltdl.c
  • LT_EMALLOC : ltdl.c
  • LT_END_C_DECLS : ltdl.h
  • LT_EOS_CHAR : ltdl.h
  • LT_EREALLOC : ltdl.c
  • LT_ERROR : ltdl.h, ltdl.c
  • LT_ERROR_MAX : ltdl.h
  • LT_FILENAME_MAX : ltdl.c
  • LT_GLOBAL_DATA : ltdl.c
  • lt_module : ltdl.h
  • LT_PARAMS : ltdl.h, ltdl.c, ltdl.h, ltdl.c, ltdl.h
  • LT_PATHSEP_CHAR : ltdl.h
  • lt_ptr : ltdl.h
  • LT_READTEXT_MODE : ltdl.c
  • LT_SCOPE : ltdl.h
  • LT_STMT_END : ltdl.h
  • LT_STMT_START : ltdl.h
  • LT_STRLEN : ltdl.h
  • LT_SYMBOL_LENGTH : ltdl.c
  • LT_SYMBOL_OVERHEAD : ltdl.c
  • lt_user_data : ltdl.h
  • LTDL_ARCHIVE_EXT : ltdl.c
  • LTDL_H : ltdl.h
  • LTDL_OBJDIR : config_fixed.h
  • LTDL_SEARCHPATH_VAR : ltdl.c
  • LTDL_SET_PRELOADED_SYMBOLS : ltdl.h
  • LTDL_SHLIB_EXT : config_fixed.h

- m -
  • MAGIC_NUMBER : internal.h
  • mail_base_class : pa_vmail.C
  • MAIL_CLASS_NAME : mail.C
  • mail_header_char_valid_within_Qencoded() : untaint.C
  • mail_header_nonspace_char() : untaint.C
  • MAIL_NAME : mail.C
  • mail_name() : mail.C
  • MAIL_OPTIONS_NAME : pa_vmail.h
  • mail_received : parser3.C
  • MAIL_RECEIVED_ELEMENT_NAME : pa_vmail.h
  • mail_sendmail_name() : mail.C
  • main() : parser3.C, pcre_parser_ctype.c, dftables.c
  • main_class_name() : pa_request.C
  • MAIN_CLASS_NAME : pa_request.h
  • MAIN_METHOD_NAME : pa_request.C
  • main_method_name : pa_request.C, pa_request.h
  • MAIN_SQL_DRIVERS_NAME : pa_sql_driver_manager.h
  • MAIN_SQL_NAME : pa_sql_driver_manager.h
  • makroom() : sdbm.c
  • marshal_bind() : table.C
  • marshal_binds() : void.C, table.C, string.C, hash.C
  • masks : sdbm.c, gifio.C
  • match() : pcre.c
  • match_data : internal.h
  • match_ref() : pcre.c
  • MATCH_VAR_NAME : string.C
  • match_var_name() : string.C
  • math1() : math.C
  • MATH1 : math.C
  • math1_func_ptr : math.C
  • MATH1P : math.C
  • MATH2 : math.C
  • math2() : math.C
  • math2_func_ptr : math.C
  • math_base_class : pa_vmath.C
  • MAX_BOOL_AS_STRING : pa_vbool.h
  • MAX_CHARS_IN_HEADER_LINE : pa_vmail.C
  • MAX_CHARSET_UNI_CODES : pa_charset.h
  • MAX_CHARSETS : pa_charset.h
  • MAX_DEPTH : cord_pos.h
  • max_integral : pa_types.h
  • MAX_LEFT_LEN : cordbscs.c
  • MAX_LEXICAL_STATES : compile_tools.h
  • MAX_LOOPS : op.C
  • MAX_LWZ_BITS : gifio.C
  • MAX_MATCH_GROUPS : pa_string.C
  • MAX_NUMBER : pa_types.h
  • MAX_POST_SIZE_DEFAULT : form.C
  • MAX_POST_SIZE_NAME : form.C
  • max_post_size_name() : form.C
  • MAX_SALT : math.C
  • MAX_SAVED_LENGTHS : apr_strings.C
  • MAX_STATUS_LENGTH : parser3isapi.C
  • MAX_STRING : pa_types.h
  • MAX_UCM : pcre_parser_ctype.c
  • MAX_UINT : math.C
  • MAXCODE : gifio.C
  • MAXCOLORMAPSIZE : gifio.C
  • MAXOUTLINE : smtp.h
  • MAXPATH : pa_dir.h
  • maybe_change_string_literal_to_double_literal() : compile_tools.h, compile_tools.C
  • maybe_enclose() : table.C
  • maybe_expire_one() : pa_cache_managers.C
  • maybe_reconstruct_IIS_status_in_qs() : parser3.C
  • MD5_DIGESTSIZE : pa_md5.h
  • MD5Transform() : pa_md5c.c
  • mdate_name() : file.C
  • measure() : image.C
  • measure_gif() : image.C
  • measure_jpeg() : image.C
  • measure_png() : image.C
  • memory_base_class : pa_vmemory.h
  • memory_element() : pa_vstatus.C
  • methoded_array() : classes.h, classes.C
  • MIME_TYPES_NAME : pa_request.C
  • mime_types_name() : pa_request.C
  • min_len : cordbscs.c
  • min_len_init : cordbscs.c
  • mk_env_pair() : parser3isapi.C, mod_parser3_core.C
  • MOD_CACHE_SZ : cordxtra.c
  • MOD_LINE_SZ : cordxtra.c
  • mode : apr_sdbm.h
  • module : ltdl.c
  • MTABLES_H : mtables.h

- n -
  • N() : compile_tools.h
  • n : sdbm_pair.c, pa_md5.h
  • name : ltdl.h, apr_sdbm.h
  • name_name : pa_value.C, pa_value.h
  • NAME_NAME : pa_value.h, file.C
  • NativeCodePtr : pa_method.h
  • nbytes : apr_file_io.h, pa_md5.h
  • need : sdbm_pair.c
  • need_file_encode() : untaint.C
  • need_http_header_encode() : untaint.C
  • need_quote_http_header() : untaint.C
  • need_regex_escape() : untaint.C
  • need_uri_encode() : untaint.C
  • new : sdbm_pair.c
  • NO_UNISTD_H : pa_socks.C
  • NONAME_DAT : pa_vfile.h
  • NONE : cordprnt.c
  • num : sdbm_pair.c

- o -
  • O() : compile_tools.h
  • OA() : compile_tools.h
  • objdir : ltdl.c
  • OFF_DIR : sdbm.c
  • OFF_PAG : sdbm.c
  • off_t : pa_config_fixed.h
  • offset : apr_file_io.h
  • offsetof : internal.h
  • old_name : ltdl.c
  • oldname : ltdl.c
  • one_foreach_cycle() : hashfile.C, hash.C
  • oom_fn : cordxtra.c, cordbscs.c
  • OP_ADD : pa_opcode.h
  • OP_ALT : internal.h
  • OP_ANY : internal.h
  • OP_ASSERT : internal.h
  • OP_ASSERT_NOT : internal.h
  • OP_ASSERTBACK : internal.h
  • OP_ASSERTBACK_NOT : internal.h
  • OP_BIN_AND : pa_opcode.h
  • OP_BIN_OR : pa_opcode.h
  • OP_BIN_SL : pa_opcode.h
  • OP_BIN_SR : pa_opcode.h
  • OP_BIN_XOR : pa_opcode.h
  • OP_BRA : internal.h
  • OP_BRAMINZERO : internal.h
  • OP_BRAZERO : internal.h
  • OP_CALL : pa_opcode.h
  • OP_CALL__WRITE : pa_opcode.h
  • OP_CHARS : internal.h
  • OP_CIRC : internal.h
  • OP_CLASS : internal.h
  • OP_COND : internal.h
  • OP_CONSTRUCT_EXPR : pa_opcode.h
  • OP_CONSTRUCT_VALUE : pa_opcode.h
  • OP_CREF : internal.h
  • OP_CRMINPLUS : internal.h
  • OP_CRMINQUERY : internal.h
  • OP_CRMINRANGE : internal.h
  • OP_CRMINSTAR : internal.h
  • OP_CRPLUS : internal.h
  • OP_CRQUERY : internal.h
  • OP_CRRANGE : internal.h
  • OP_CRSTAR : internal.h
  • OP_CURLY_CODE__CONSTRUCT : pa_opcode.h
  • OP_CURLY_CODE__STORE_PARAM : pa_opcode.h
  • OP_DEF : pa_opcode.h
  • OP_DEXISTS : pa_opcode.h
  • OP_DIGIT : internal.h
  • OP_DIV : pa_opcode.h
  • OP_DOLL : internal.h
  • OP_END : internal.h
  • OP_EOD : internal.h
  • OP_EODN : internal.h
  • OP_EXACT : internal.h
  • OP_EXPR_CODE__STORE_PARAM : pa_opcode.h
  • OP_FEXISTS : pa_opcode.h
  • OP_GET_CLASS : pa_opcode.h
  • OP_GET_ELEMENT : pa_opcode.h
  • OP_GET_ELEMENT__WRITE : pa_opcode.h
  • OP_GET_ELEMENT_OR_OPERATOR : pa_opcode.h
  • OP_IN : pa_opcode.h
  • OP_INTDIV : pa_opcode.h
  • OP_INV : pa_opcode.h
  • OP_IS : pa_opcode.h
  • OP_KET : internal.h
  • OP_KETRMAX : internal.h
  • OP_KETRMIN : internal.h
  • OP_LOG_AND : pa_opcode.h
  • OP_LOG_OR : pa_opcode.h
  • OP_LOG_XOR : pa_opcode.h
  • OP_MINPLUS : internal.h
  • OP_MINQUERY : internal.h
  • OP_MINSTAR : internal.h
  • OP_MINUPTO : internal.h
  • OP_MOD : pa_opcode.h
  • OP_MUL : pa_opcode.h
  • OP_NEG : pa_opcode.h
  • OP_NESTED_CODE : pa_opcode.h
  • OP_NOT : internal.h, pa_opcode.h
  • OP_NOT_DIGIT : internal.h
  • OP_NOT_WHITESPACE : internal.h
  • OP_NOT_WORD_BOUNDARY : internal.h
  • OP_NOT_WORDCHAR : internal.h
  • OP_NOTEXACT : internal.h
  • OP_NOTMINPLUS : internal.h
  • OP_NOTMINQUERY : internal.h
  • OP_NOTMINSTAR : internal.h
  • OP_NOTMINUPTO : internal.h
  • OP_NOTPLUS : internal.h
  • OP_NOTQUERY : internal.h
  • OP_NOTSTAR : internal.h
  • OP_NOTUPTO : internal.h
  • OP_NUM_EQ : pa_opcode.h
  • OP_NUM_GE : pa_opcode.h
  • OP_NUM_GT : pa_opcode.h
  • OP_NUM_LE : pa_opcode.h
  • OP_NUM_LT : pa_opcode.h
  • OP_NUM_NE : pa_opcode.h
  • OP_OBJECT_POOL : pa_opcode.h
  • OP_ONCE : internal.h
  • OP_OPT : internal.h
  • OP_PLUS : internal.h
  • OP_PREPARE_TO_CONSTRUCT_OBJECT : pa_opcode.h
  • OP_PREPARE_TO_EXPRESSION : pa_opcode.h
  • OP_QUERY : internal.h
  • OP_REF : internal.h
  • OP_REVERSE : internal.h
  • OP_SOD : internal.h
  • OP_STAR : internal.h
  • OP_STORE_PARAM : pa_opcode.h
  • OP_STR_EQ : pa_opcode.h
  • OP_STR_GE : pa_opcode.h
  • OP_STR_GT : pa_opcode.h
  • OP_STR_LE : pa_opcode.h
  • OP_STR_LT : pa_opcode.h
  • OP_STR_NE : pa_opcode.h
  • OP_STRING__WRITE : pa_opcode.h
  • OP_STRING_POOL : pa_opcode.h
  • OP_SUB : pa_opcode.h
  • OP_TYPEEXACT : internal.h
  • OP_TYPEMINPLUS : internal.h
  • OP_TYPEMINQUERY : internal.h
  • OP_TYPEMINSTAR : internal.h
  • OP_TYPEMINUPTO : internal.h
  • OP_TYPEPLUS : internal.h
  • OP_TYPEQUERY : internal.h
  • OP_TYPESTAR : internal.h
  • OP_TYPEUPTO : internal.h
  • OP_UPTO : internal.h
  • OP_VALUE : pa_opcode.h
  • OP_WHITESPACE : internal.h
  • OP_WITH_READ : pa_opcode.h
  • OP_WITH_ROOT : pa_opcode.h
  • OP_WITH_SELF : pa_opcode.h
  • OP_WITH_WRITE : pa_opcode.h
  • OP_WORD_BOUNDARY : internal.h
  • OP_WORDCHAR : internal.h
  • OP_WRITE_EXPR_RESULT : pa_opcode.h
  • OP_WRITE_VALUE : pa_opcode.h
  • OPCODE : pa_opcode.h
  • OPEN_DATA_NAME : hashfile.C
  • opendir : config_fixed.h
  • OPERATIONS_PER_OPVALUE : pa_operation.h
  • operator delete() : pa_memory.h
  • operator delete[]() : pa_memory.h
  • operator new() : pa_memory.h
  • operator new[]() : pa_memory.h
  • opt : apr_sdbm.h
  • optarg : getopt.h, getopt.c
  • opterr : getopt.h, getopt.c
  • OPTERRARG : getopt.c
  • OPTERRCOLON : getopt.c
  • OPTERRNF : getopt.c
  • optind : getopt.h, getopt.c
  • optiserr() : getopt.c
  • optopt : getopt.h, getopt.c
  • ORIGINS_CONTENT_TYPE : pa_request.C
  • ORIGINS_MODE_NAME : pa_request.C
  • origins_mode_name() : pa_request.C
  • our_dconfig() : mod_parser3.c
  • out_c() : pcre_parser_ctype.c
  • OUT_OF_MEMORY : cordxtra.c, cordbscs.c
  • output_after() : pa_vcookie.C
  • output_deleted() : pa_vcookie.C
  • output_pieces() : pa_request.C
  • output_set_cookie_header() : pa_vcookie.C
  • output_sole_piece() : pa_request.C
  • override : pa_memory.h

- p -
  • P() : compile_tools.h
  • p : apr_sdbm.h
  • P_FILE : pa_vmail.C
  • P_HTML : pa_vmail.C
  • P_MESSAGE : pa_vmail.C
  • P_TEXT : pa_vmail.C
  • P_TYPES_COUNT : pa_vmail.C
  • pa_ap_add_cgi_vars() : pa_httpd.h, mod_parser3.c
  • pa_ap_add_common_vars() : pa_httpd.h, mod_parser3.c
  • pa_ap_get_client_block() : pa_httpd.h, mod_parser3.c
  • pa_ap_hard_timeout() : pa_httpd.h, mod_parser3.c
  • pa_ap_kill_timeout() : pa_httpd.h, mod_parser3.c
  • pa_ap_log_error() : pa_httpd.h, mod_parser3.c
  • pa_ap_log_rerror() : pa_httpd.h, mod_parser3.c
  • pa_ap_pstrdup() : pa_httpd.h, mod_parser3.c
  • pa_ap_reset_timeout() : pa_httpd.h, mod_parser3.c
  • pa_ap_rwrite() : pa_httpd.h, mod_parser3.c
  • pa_ap_send_http_header() : pa_httpd.h, mod_parser3.c
  • pa_ap_setup_client_block() : pa_httpd.h, mod_parser3.c
  • pa_ap_should_client_block() : pa_httpd.h, mod_parser3.c
  • pa_ap_table_addn() : pa_httpd.h, mod_parser3.c
  • pa_ap_table_do() : pa_httpd.h, mod_parser3.c
  • pa_ap_table_get() : pa_httpd.h, mod_parser3.c
  • pa_ap_table_size() : pa_httpd.h, mod_parser3.c
  • PA_API_EXPORT : pa_md5c.c, pa_md5.h
  • PA_APLOG_ALERT : pa_httpd.h, mod_parser3.c
  • PA_APLOG_CRIT : pa_httpd.h, mod_parser3.c
  • PA_APLOG_DEBUG : pa_httpd.h, mod_parser3.c
  • PA_APLOG_EMERG : pa_httpd.h, mod_parser3.c
  • PA_APLOG_ERR : pa_httpd.h, mod_parser3.c
  • PA_APLOG_INFO : pa_httpd.h, mod_parser3.c
  • PA_APLOG_LEVELMASK : pa_httpd.h, mod_parser3.c
  • PA_APLOG_MARK : pa_httpd.h, mod_parser3.c
  • PA_APLOG_NOERRNO : pa_httpd.h, mod_parser3.c
  • PA_APLOG_NOTICE : pa_httpd.h, mod_parser3.c
  • PA_APLOG_WARNING : pa_httpd.h, mod_parser3.c
  • pa_atod() : pa_string.C, pa_string.h
  • pa_atoi() : pa_string.C, pa_string.h
  • pa_base64_decode() : pa_common.C, pa_common.h
  • pa_base64_encode() : pa_common.C, pa_common.h
  • PA_COLUMN_ENCLOSER_NAME : pa_common.h
  • PA_COLUMN_SEPARATOR_NAME : pa_common.h
  • PA_COMMENT_TYPE_FORMAT : pa_request.C
  • pa_CORD_oom_fn() : pa_globals.C
  • pa_CORD_pos_advance() : untaint.C
  • pa_destroy_module_cells() : mod_parser3_core.C, pa_httpd.h
  • pa_dictionary_add_first() : pa_dictionary.C
  • pa_exec() : pa_exec.C, pa_exec.h
  • pa_fail_alloc() : pa_memory.C, pa_memory.h
  • pa_form2string() : pa_http.C, pa_http.h
  • pa_free() : pa_memory.h
  • pa_gc_free() : pa_memory.h
  • pa_gc_malloc() : pa_memory.h
  • pa_gc_malloc_atomic() : pa_memory.h
  • pa_gc_realloc() : pa_memory.h
  • pa_get_thread_id() : isapi/pa_threads.C, cgi/pa_threads.C, apache13core/pa_threads.C, pa_threads.h
  • pa_get_valid_file_options_count() : pa_common.C, pa_common.h
  • pa_globals_destroy() : pa_globals.C
  • pa_globals_done() : pa_globals.C, pa_globals.h
  • pa_globals_init() : pa_globals.C, pa_globals.h
  • PA_HTTP_NOT_FOUND : pa_httpd.h
  • pa_internal_file_read_http() : pa_http.C, pa_http.h
  • PA_LITTLE_ENDIAN : pa_config_fixed.h
  • pa_lock_exclusive_blocking() : pa_os.h, pa_common.h
  • pa_lock_exclusive_nonblocking() : pa_os.h, pa_common.h
  • pa_lock_shared_blocking() : pa_os.h, pa_common.h
  • pa_malloc() : pa_memory.h
  • pa_malloc_atomic() : pa_memory.h
  • PA_MD5_CTX : pa_httpd.h
  • PA_MD5_DIGESTSIZE : pa_httpd.h
  • pa_MD5Encode() : pa_httpd.h, mod_parser3.c
  • pa_MD5Final() : pa_httpd.h, mod_parser3.c
  • pa_MD5Init() : pa_httpd.h, mod_parser3.c
  • PA_MD5PW_ID : pa_md5.h
  • PA_MD5PW_IDLEN : pa_md5.h
  • pa_MD5Update() : pa_httpd.h, mod_parser3.c
  • PA_Object : pa_memory.h
  • PA_OK : pa_httpd.h
  • PA_ORIGIN_FILE_POS_FORMAT : pa_request.C
  • pa_pa_cpystrn : pa_md5c.c
  • pa_parser_handler() : mod_parser3_core.C, pa_httpd.h
  • pa_pool : pa_httpd.h
  • pa_realloc() : pa_memory.h
  • pa_register_thread_request() : pa_globals.C, pa_globals.h
  • PA_REQUEST_CHUNKED_DECHUNK : pa_httpd.h
  • PA_REQUEST_CHUNKED_ERROR : pa_httpd.h
  • PA_REQUEST_CHUNKED_PASS : pa_httpd.h
  • PA_REQUEST_NO_BODY : pa_httpd.h
  • pa_request_rec : pa_httpd.h
  • pa_server_rec : pa_httpd.h
  • pa_setup_module_cells() : mod_parser3_core.C, pa_httpd.h
  • PA_SIG_IGN : pa_httpd.h
  • pa_signal : mod_parser3.c, pa_httpd.h
  • PA_SIGPIPE : pa_httpd.h
  • pa_sleep() : pa_os.C, pa_os.h
  • pa_socks_done() : pa_socks.C, pa_socks.h
  • pa_socks_errno() : pa_socks.C, pa_socks.h
  • pa_socks_init() : pa_socks.C, pa_socks.h
  • pa_socks_strerr() : pa_socks.C, pa_socks.h
  • PA_SOURCE_FORMAT : pa_request.C
  • PA_SQL_LIMIT_NAME : pa_common.h
  • PA_SQL_OFFSET_NAME : pa_common.h
  • pa_strdup() : pa_memory.h
  • pa_table : pa_httpd.h
  • pa_thread_request() : pa_globals.C, pa_globals.h
  • pa_thread_t : pa_threads.h
  • pa_to64() : pa_httpd.h, mod_parser3.c
  • pa_tolower() : pa_vform.C
  • pa_unlock() : pa_os.h, pa_common.h
  • PA_URI_FORMAT : pa_request.C
  • pa_uuencode() : pa_uue.C, pa_uue.h
  • pa_version() : mod_parser3_core.C, pa_httpd.h
  • PA_WITH_SJLJ_EXCEPTIONS : pa_config_fixed.h
  • pa_xml_io_init() : pa_xml_io.h
  • pa_xmlGetDependencies() : pa_xml_io.h
  • pa_xmlMapNs() : xnode.h
  • pa_xmlStartMonitoringDependencies() : pa_xml_io.h
  • PADDING : pa_md5c.c
  • PAIRMAX : sdbm_private.h
  • pargz : ltdl.c
  • pargz_len : ltdl.c
  • parse_exif() : image.C
  • parse_IFD() : image.C
  • parse_IFD_entry() : image.C
  • parse_IFD_entry_formatted_one_value() : image.C
  • parse_IFD_entry_formatted_value() : image.C
  • parse_IFD_entry_value() : image.C
  • parse_range() : pa_request.C
  • parser3_module : mod_parser3.c
  • parser_access_checker() : mod_parser3.c
  • parser_auth_checker() : mod_parser3.c
  • parser_check_user_id() : mod_parser3.c
  • parser_cmds : mod_parser3.c
  • PARSER_CONFIG_ENV_NAME : parser3.C
  • parser_create_dir_config() : mod_parser3.c
  • parser_create_server_config() : mod_parser3.c
  • parser_done() : parser3isapi.C
  • parser_handler() : mod_parser3.c
  • parser_handlers : mod_parser3.c
  • parser_init() : parser3isapi.C
  • PARSER_LOG_ENV_NAME : parser3.C
  • parser_merge_dir_config() : mod_parser3.c
  • parser_merge_server_config() : mod_parser3.c
  • Parser_module_config : pa_httpd.h
  • parser_module_done() : mod_parser3.c
  • parser_module_init() : mod_parser3.c
  • parser_multithreaded : isapi/pa_threads.C, cgi/pa_threads.C, apache13core/pa_threads.C, pa_threads.h
  • parser_translate_handler() : mod_parser3.c
  • PARSER_VERSION : pa_version.h
  • parser_version() : pa_venv.C
  • part_name_begins : pa_vmail.C
  • PartType : pa_vmail.C
  • pass_cgi_header_attribute() : file.C
  • path_name() : pa_vcookie.C
  • PATH_NAME : pa_vcookie.C
  • path_value_default() : pa_vcookie.C
  • PATH_VALUE_DEFAULT : pa_vcookie.C
  • PBLKSIZ : sdbm_private.h
  • PC : compile.y
  • pcanonical : ltdl.c
  • pcre : pcre.h
  • PCRE_ANCHORED : pcre.h
  • PCRE_CASELESS : pcre.h
  • pcre_compile() : pcre.h, pcre.c
  • pcre_copy_substring() : pcre.h, get.c
  • PCRE_DATE : pcre.h
  • pcre_default_tables : pa_charset.C, chartables.c
  • PCRE_DL_IMPORT : pcre.h
  • PCRE_DOLLAR_ENDONLY : pcre.h
  • PCRE_DOTALL : pcre.h
  • PCRE_ERROR_BADMAGIC : pcre.h
  • PCRE_ERROR_BADOPTION : pcre.h
  • PCRE_ERROR_NOMATCH : pcre.h
  • PCRE_ERROR_NOMEMORY : pcre.h
  • PCRE_ERROR_NOSUBSTRING : pcre.h
  • PCRE_ERROR_NULL : pcre.h
  • PCRE_ERROR_UNKNOWN_NODE : pcre.h
  • pcre_exec() : pcre.h, pcre.c
  • PCRE_EXTENDED : pcre.h
  • pcre_extra : pcre.h
  • PCRE_EXTRA : pcre.h
  • PCRE_FIRSTSET : internal.h
  • pcre_free : pcre.h, pcre.c
  • pcre_get_substring() : pcre.h, get.c
  • pcre_get_substring_list() : pcre.h, get.c
  • PCRE_ICHANGED : internal.h
  • PCRE_IMS : internal.h
  • pcre_info() : pcre.h, pcre.c
  • PCRE_INGROUP : internal.h
  • PCRE_MAJOR : pcre.h
  • pcre_maketables() : pcre.h, maketables.c
  • pcre_malloc : pcre.h, pcre.c
  • PCRE_MAX_POS : internal.h
  • PCRE_MINOR : pcre.h
  • PCRE_MULTILINE : pcre.h
  • PCRE_NOTBOL : pcre.h
  • PCRE_NOTEMPTY : pcre.h
  • PCRE_NOTEOL : pcre.h
  • PCRE_REQCHSET : internal.h
  • PCRE_STARTLINE : internal.h
  • pcre_study() : study.c, pcre.h
  • PCRE_STUDY_MAPPED : internal.h
  • PCRE_UNGREEDY : pcre.h
  • pcre_version() : pcre.h, pcre.c
  • pdir : ltdl.c
  • perm : apr_file_io.C, apr_file_io.h
  • perms : sdbm.c, apr_sdbm.h
  • PGETPROCESSMEMORYINFO : pa_vstatus.C
  • PGETPROCESSTIMES : pa_vstatus.C
  • PI : pa_vmath.h
  • PIO_COUNTERS_ : pa_vstatus.C
  • PointerFreeGC : pa_memory.h
  • POOL : compile.y
  • pop_LS() : compile_tools.h, compile_tools.C
  • POST_PROCESS_METHOD_NAME : pa_request.C
  • post_process_method_name() : pa_request.C
  • prefix : ltdl.c
  • preloaded_symbols : ltdl.c
  • prep() : sdbm.c
  • prepare_case_tables() : pa_charset.C
  • presym_init() : ltdl.c
  • process_cache_body_code() : op.C
  • PROCESS_FILE_OPTION_NAME : op.C
  • PROCESS_LINENO_OPTION_NAME : op.C
  • PROCESS_MAIN_OPTION_NAME : op.C
  • process_try_body_code() : op.C
  • PROPERTY_BUT_NO_SETTER_IN_SELF : pa_vclass.C
  • pseudo_file_no__process : pa_request.h
  • PUBLIC_EXEC_OPTIONS : internal.h
  • PUBLIC_OPTIONS : internal.h
  • PUBLIC_STUDY_OPTIONS : internal.h
  • push_LS() : compile_tools.h, compile_tools.C
  • PUT_ELEMENT_REPLACED_ELEMENT : pa_value.h
  • putpair : sdbm_pair.h

- r -
  • R_OK : config_fixed.h
  • radians() : math.C
  • random() : math.C
  • random_provider : math.C
  • RAW_NAME : pa_vmail.C
  • RC : compile.y
  • RCSId : pcre_parser_ctype.c
  • read_pipe() : pa_exec.C
  • READ_POST_CHUNK_SIZE : parser3.C
  • read_repeat_counts() : pcre.c
  • read_ucm() : pcre_parser_ctype.c
  • ReadColorMap() : gifio.C
  • readdir : config_fixed.h
  • ReadOK : gifio.C
  • real_parser_handler() : parser3isapi.C, parser3.C, mod_parser3_core.C
  • real_pcre : internal.h
  • real_pcre_extra : internal.h
  • realloc : ltdl.c
  • REDIRECT_PREFIX : parser3.C
  • refill_cache() : cordxtra.c
  • regex_options() : pa_string.C
  • register_one() : classes.C
  • remove_crlf() : pa_common.C, pa_common.h
  • remove_key_from() : hash.C
  • rep_max : pcre.c
  • rep_min : pcre.c
  • replace_action() : string.C
  • request : parser3.C
  • REQUEST_CLASS_NAME : pa_vrequest.h
  • REQUEST_HEADERS_ELEMENT_NAME : pa_vresponse.C
  • request_info : parser3.C
  • RESPONSE_BODY_FILE_NAME : pa_request.C
  • response_body_file_name() : pa_request.C
  • response_class : pa_vresponse.h
  • result : pa_md5.h
  • result_var_name() : pa_vmethod_frame.C
  • RESULT_VAR_NAME : pa_vmethod_frame.h
  • rethrow : pa_memory.h
  • rmdir() : pa_common.C
  • ROTATE_LEFT : pa_md5c.c
  • rpl_realloc : ltdl.c
  • rsplit() : pa_common.C, pa_common.h
  • rusage_element() : pa_vstatus.C

- s -
  • S11 : pa_md5c.c
  • S12 : pa_md5c.c
  • S13 : pa_md5c.c
  • S14 : pa_md5c.c
  • S21 : pa_md5c.c
  • S22 : pa_md5c.c
  • S23 : pa_md5c.c
  • S24 : pa_md5c.c
  • S31 : pa_md5c.c
  • S32 : pa_md5c.c
  • S33 : pa_md5c.c
  • S34 : pa_md5c.c
  • S41 : pa_md5c.c
  • S42 : pa_md5c.c
  • S43 : pa_md5c.c
  • S44 : pa_md5c.c
  • salt : pa_md5.h
  • SAPI_environment_append() : mod_parser3_core.C
  • SAPI_info : parser3.C
  • sbit : sdbm_pair.c
  • sdbm_dirfno : sdbm.c
  • SDBM_EXCLUSIVE_LOCK : sdbm_private.h
  • sdbm_hash() : sdbm_private.h, sdbm_hash.c
  • SDBM_INVALIDATE_CACHE : sdbm_private.h
  • sdbm_nullitem : sdbm_private.h, sdbm.c
  • sdbm_pagfno : sdbm.c
  • SDBM_RDONLY : sdbm_private.h
  • SDBM_SHARED : sdbm_private.h
  • SDBM_SHARED_LOCK : sdbm_private.h
  • search_action() : string.C
  • search_dir : ltdl.c
  • search_stop() : pa_vcookie.C
  • searchAttribute() : pa_vform.C
  • SECS_PER_DAY : pa_common.h
  • SEEK_END : cordxtra.c
  • SEEK_SET : cordxtra.c
  • seepair() : sdbm_pair.c
  • SELF_ELEMENT_NAME : pa_vmethod_frame.h
  • sendmail() : mail.C
  • SENDMAIL_NAME : mail.C
  • sep : ltdl.c
  • serialize_body_char() : pa_string.C
  • serialize_body_piece() : pa_string.C
  • serialize_lang_piece() : pa_string.C
  • SESSION_NAME : pa_vcookie.C
  • set_addr() : pa_http.C
  • set_bit() : study.c
  • set_start_bits() : study.c
  • set_tz() : pa_vdate.h
  • setdbit() : sdbm.c
  • seterror : ltdl.c
  • setup_hex_value() : pa_globals.C
  • shlib_ext : ltdl.c
  • SHORT_LIMIT : cordbscs.c
  • sint : mtables.h
  • sintScale : mtables.h
  • siz : sdbm_pair.c
  • size : ltdl.c
  • size_name() : pa_vfile.C
  • SIZE_NAME : pa_vfile.C
  • skip_empty_and_comment_lines() : table.C
  • snprintf : smtp.C, pa_common.h
  • SOCKET_BUFFER_SIZE : smtp.h
  • sort_cmp_double() : table.C
  • sort_cmp_string() : table.C
  • sort_cmp_Trans_rec_intCh() : pa_charset.C
  • SPLIT_HORIZONTAL : string.C
  • split_horizontal() : string.C
  • SPLIT_LEFT : string.C
  • split_list() : string.C
  • split_options() : string.C
  • SPLIT_RIGHT : string.C
  • SPLIT_VERTICAL : string.C
  • split_vertical() : string.C
  • split_with_options() : string.C
  • splpage : sdbm_pair.h
  • SPLTMAX : sdbm_private.h
  • SQL_BIND_NAME : table.C
  • sql_bind_name : table.C, void.C, string.C, hash.C
  • SQL_CONNECTION_SERVICED_FUNC_GUARDED : pa_sql_connection.h
  • sql_default_name : table.C, string.C, hash.C
  • SQL_DEFAULT_NAME : table.C
  • sql_distinct_name : table.C, string.C, hash.C
  • SQL_DISTINCT_NAME : table.C
  • SQL_DRIVER_API_VERSION : pa_sql_driver.h
  • SQL_DRIVER_CREATE : pa_sql_driver.h
  • SQL_Driver_create_func : pa_sql_driver.h
  • SQL_DRIVER_CREATE_NAME : pa_sql_driver.h
  • SQL_driver_manager : pa_sql_driver_manager.C, pa_sql_driver_manager.h
  • sql_limit_name : table.C, string.C, hash.C, file.C
  • sql_offset_name : table.C, string.C, hash.C, file.C
  • sql_result_string() : string.C, int.C, double.C
  • ssize_t : pa_config_fixed.h
  • starts() : pa_dictionary.C
  • STATUS_CLASS_NAME : pa_vstatus.h
  • STDIN_EXEC_PARAM_NAME : file.C
  • stdout_write() : pa_common.C, pa_common.h
  • store_column_item_to_hash() : pa_vtable.C
  • store_message_element() : pa_vmail.C
  • store_UTF8() : pa_charset.C
  • str : ltdl.c
  • STR_DL_DEPLIBS : ltdl.c
  • STR_DLNAME : ltdl.c
  • STR_LIBDIR : ltdl.c
  • STR_LIBRARY_NAMES : ltdl.c
  • STR_OLD_LIBRARY : ltdl.c
  • strdup : ltdl.c
  • StrEqNc() : pa_common.C, pa_common.h
  • STRING : pcre.c
  • string_class : pa_vstring.h
  • string_contains_char_which() : pa_vmail.C
  • string_contains_char_which_check : pa_vmail.C
  • string_match_table_template() : pa_string.C
  • STRING_NOT_FOUND : pa_string.h
  • styledSet : gif.C
  • stylesheet_manager : pa_stylesheet_manager.h
  • SUBSTR_HDR : cordbscs.c
  • SUBSTR_LIMIT : cordbscs.c
  • suexec_safe_env_lst : file.C
  • SWITCH_DATA_NAME : op.C
  • switch_data_name() : op.C
  • symbol : ltdl.c
  • SYNCHRONIZED : pa_threads.h
  • sys_wll_open() : ltdl.c

- t -
  • tab_prefixof : gifio.C
  • TAB_SIZE : compile_tools.h
  • tab_suffixof : gifio.C
  • table_class : pa_vtable.h
  • TABLE_FIELDS_ELEMENT_NAME : pa_vtable.h
  • TABLE_REVERSE_NAME : table.C
  • table_reverse_name() : table.C
  • table_row_to_hash() : table.C
  • TABLE_WRAP_COL : pcre_parser_ctype.c
  • tables_length : internal.h
  • TerminateExtension() : parser3isapi.C
  • TEXT_MODE_NAME : file.C
  • text_name() : pa_vfile.C
  • TEXT_NAME : pa_vfile.C
  • text_value_to_string() : pa_vmail.C
  • thefile : apr_file_io.h
  • thread_request : pa_globals.C
  • to_bool() : pa_charset.C
  • to_char : untaint.C
  • to_string : untaint.C
  • to_tm_year() : date.C
  • to_wchar_code() : pa_charset.C
  • transcode_pair() : pa_charset.C
  • transcodeFromUTF8() : pa_charset.C
  • transcodeToUTF8() : pa_charset.C
  • TRIM_BOTH_OPTION : string.C
  • TRIM_END_OPTION : string.C
  • TRIM_START_OPTION : string.C
  • trimBoth() : pa_vmail.C
  • TRUE : internal.h, gifio.C
  • try_catch() : op.C
  • type : apr_sdbm.h, apr_file_io.h

- u -
  • uchar : pa_types.h
  • ucm : pcre_parser_ctype.c
  • ui64 : pa_vstatus.C
  • uint : pa_types.h
  • UINT4 : pa_md5.h
  • ULN : op.C
  • ulong : pa_types.h
  • unescape_chars() : pa_common.C, pa_common.h
  • UNHANDLED_EXCEPTION_CONTENT_TYPE : pa_request.C
  • UNHANDLED_EXCEPTION_METHOD_NAME : pa_request.C
  • unlock : ltdl.c
  • unmarshal_bind_updates() : void.C, table.C, string.C, hash.C
  • unregister_cleanup() : pa_pool.C
  • untaint_lang_name2enum : op.C
  • usage() : parser3.C
  • uschar : internal.h
  • USE_CONTROL_METHOD_NAME : compile.y
  • USE_SMTP : pa_config_fixed.h
  • UseGC : pa_memory.h
  • user_search_path : ltdl.c
  • ushort : pa_types.h
  • UTF8_charset : pa_charsets.C, pa_charsets.h
  • UTF8CaseToLower : pa_charset.C, pa_charset.h
  • UTF8CaseToLowerRecords : pa_charset.C
  • UTF8CaseToUpper : pa_charset.C, pa_charset.h
  • UTF8CaseToUpperRecords : pa_charset.C
  • uue_table : pa_uue.C

- v -
  • v : pa_md5.h
  • val : sdbm_pair.c
  • value : apr_sdbm.h
  • value_name : pa_value.C, pa_value.h
  • VALUE_NAME : pa_value.h
  • VARIABLE : cordprnt.c
  • VClassMAIN_create() : pa_request.C, op.C
  • VDATE_TYPE : pa_vdate.h
  • vdouble_op() : double.C
  • vdouble_op_func_ptr : double.C
  • VHASH_TYPE : pa_vhash.h
  • VHASHFILE_TYPE : pa_vhashfile.h
  • VIMAGE_TYPE : pa_vimage.h
  • vint_op() : int.C
  • vint_op_func_ptr : int.C
  • VL() : compile_tools.h
  • void_class : pa_vvoid.h
  • vsnprintf : pa_common.h
  • VTABLE_TYPE : pa_vtable.h
  • VXDOC_TYPE : pa_vxdoc.h
  • VXNODE_TYPE : pa_vxnode.h

- w -
  • WAIT_A_BIT : smtp.h
  • wanted : apr_file_io.h
  • WDFILL : date.C
  • where : apr_file_io.h
  • word : cordbscs.c
  • wsaData : pa_socks.C

- x -
  • x_endian_to_uint() : image.C
  • x_endian_to_ushort() : image.C
  • xdoc_class : pa_vxdoc.h
  • xlatOneTo() : pa_charset.C
  • XML : pa_config_fixed.h
  • XMLByte : pa_charset.h
  • XMLCh : pa_charset.h
  • xnode_class : pa_vxnode.h
  • XSTRING : pcre.c

- y -
  • Y : image.C
  • YYDEBUG : compile.y
  • yydebug : compile.C
  • yyerror : compile.y
  • YYERROR_VERBOSE : compile.y
  • YYLEX_PARAM : compile.y
  • yyparse() : compile.C
  • YYPARSE_PARAM : compile.y
  • YYPRINT : compile.y
  • YYSTYPE : compile.y


Page Index

Parser3 Source Code Related Pages

Here is a list of all related documentation pages:
  • Class: parent+methods+fields
  • Example of creating simple class (with methods only)
  • Sample of creating simple class (with fields only)
  • Sample of creating class (methods and fields)
  • Compiler
  • Exceptions: work with errors
  • Executor
  • Memory: work with memory
  • Methoded: configurable class
  • Object: class+fields
  • Pooled: ðàáîòà ñ ïàìÿòüþ
  • String
  • Build targets
  • Value
  • Todo List
  • Test List
  • Bug List


Class: parent+methods+fields

 Class holds
  • parent: VStateless_class::base();
  • bunch of methods: VStateless_class::fmethods, Method.
  • fields: VClass::ffields
VStateless_class::get_element returns method+self[VJunction]. VClass_class::get_element returns static fields


Example of creating simple class (with methods only)

 To create the class of your own, consisting only of methods[like, for "random" class], one need to put to classes/ directory module in C++ language with .C file name extension, in which...

1. Define a descendant of Methoded, declaring Methoded::used_directly as true.

2. Code methods of objects like this[ Native_code_ptr ]:

static void _test(Request& r, const String& method_name, MethodParams *params) {
    Pool& pool=r.pool();

    ...

    // generate exceptions like this:
    if(error_code)
        throw Exception("exception class",
            &method_name, // address of String, containing text/source of error
            "problem %d", error_code);

    // output text like this:
    if(text_result)
        r.write_assign_lang(*new(pool) String(pool, "òåñò"));

    // output objects like this:
    if(object_result)
        r.write_no_lang(*new(pool) VInt(pool, 48));
}

3. In constructor one must set class name and register it's methods:

MExample1::MExample1(Pool& apool) : Methoded(apool, "example1") {
    // ^example1:test[]
    add_native_method("test", Method::CT_STATIC, _test, 0, 0);
}

See also:
VStateless_class::add_native_method
4. And, finally, define constricting function, with name M{name_of_file_with_first_letter_Capital}_create:
Methoded *MExample1_create(Pool& pool) {
    return new(pool) MExample1(pool);
}

5. If for class to work it need any options, they could be read from variables assigned in @conf, by overriding Methoded::configure_admin and/or Methoded::configure_user.

User then could call that method like:

^example1:test[]


Sample of creating simple class (with fields only)

 To create the class of your own, which does not contain methods [like 'env', see VEnv], one need to create a derivate from Value, where override Value::type, and also Value::get_element and/or Value::put_element.

File pa_vexample2.h in types/ directory:

#define EXAMPLE2_CLASS_NAME "example2"

class VExample2 : public Value {
public: // Value

    const char *type() const { return "example2"; }

    Value *get_element(const String& aname) {
        // device information
        double temperature=25;
        return NEW VDouble(temperature);
    }

public: // usage

    VExample2(Pool& apool) : Value(apool) {
    }

};

Register your class in Request::classes(), by adding it to Request constructor [in pa_request.C file]:

    // example2 class
    classes().put(*NEW String(pool(), EXAMPLE2_CLASS_NAME), &example2);

User could then read temperature like:

$example2:test


Sample of creating class (methods and fields)

 To create a class of your own, which
  • could be constructed by users,
  • has methods
  • AND fields [like 'image' class], one need to create simple class, see Example of creating simple class (with methods only), and override Methoded::create_new_value to
class MExample3 : public Methoded {
public: // VStateless_class

    Value *create_new_value(Pool& pool) { return new(pool) VExample3(pool); }

This methods would be called when user would creates values of your type:

$variable[^example3::create[]]

Here "VExample3", is value class, see ClassExample2. It need not be registered, because it has Methoded::used_directly set to true. But it should override: VStateless_class *get_class() { return example_class3; } where example_class3 is global instance of MExample3.


Compiler

 Source code is compiled to internal form. This happens with each request, result of compilation is not cached. After compilation we have class, which got registered in Hash Request::classes().

See also:
compile.y, compile.C, compile_tools.h, compile_tools.C


Exceptions: work with errors

 All exceptions in Parser have type Exception. If a problem arises, one should throw C++ exception of that type
    throw Exception("exception class",
        &string, // address of String, containing text/source of error
        "problem %d", error_code);

"exception class" should be one of system, or your own (invent a good one!), or 0.


Executor

 Code in internal form then got executed.

Methods[Method] can be

  • native: registered by VStateless_class::add_native_method, and nave nonempty Method::native_code
  • parser: registered by VStateless_class::add_method, and nave nonempty Method::parser_code
See also:
execute.C


Memory: work with memory

 Parser in it's work with memory relies on garbage collection. See http://www.hpl.hp.com/personal/Hans_Boehm/gc

Work with memory goes like this: all allocations are in the end get to pa_malloc pa_malloc_atomic, pa_realloc, pa_free functions; For C++ corresponding new operators are overloaded. To allocate a memory in C++ style not for objects one should specify, will the block to-be-allocated contain pointers, new(UseGC) when "it will". new(PointerFreeGC) when "it will not".

For convinient memory allocation for objects there is root class PA_Object, overriding new operator, implementing it with pa_malloc, and providing wrappers for malloc/malloc_atomic/realloc/free. It is recommended, where it is possible, to allocate memory in C++ style [using new operator], exception can be made for a case where realloc is needed: on many platforms new-operator changes the pointer, returned by new-operator-implementation allocator. that is new+realloc / realloc+delete are not allowed.


Methoded: configurable class

 Classes[mail, string, ...], are direct and indirect decendants of Methoded.

Methoded can be used directly [Methoded::used_directly()=true], then at the request processing stat method Methoded_array::register_directly_used whould register them in Request::classes(). Example: class mail [MMail].

Or indirectly, then they[global instance] are used in Value::get_class to specify a class of Value descendant. Excample: class string [instance of MString in VString::get_class].

Any class can also can parameters defined in @conf in global auto.p file, to work with those one should override Methoded::configure_admin. Class can also can user-defined parameters: Methoded::configure_user.


Object: class+fields

 Object[VObject], is an instance of Class. Stores fields: VObject::ffields (dynamic, not static - those are stored in Class).


Pooled: работа с памятью

 Работа с памятью происходит так: все выделения происходят через Pool::malloc и Pool::calloc, для удобства имеется Pooled родитель, инкапсулирующий класс Pool, и имеющий одноимённые обёртки: Pooled::malloc и Pooled::calloc, а также функцию Pooled::pool() для доступа к самому pool'у. Когда освобождается память зависит от варианта сборки:
  • Apache: делает это сам;
  • CGI: вообще ничего не освобождает, смерть процесса всё списывает;
  • ISAPI extension: освобождается в Pooled:~Pooled().
Все исключения в Parser имеют тип Exception, если возникает проблема, следует бросить C++ исключение этого типа
    throw Exception("класс ошибки",
        &method_name, // адрес String, содержащей текст/место ошибки
        "проблема %d", error_code);

"Класс ошибки" следует задать один из системных, придумать хороших свой, или не задавать вовсе.


String

 In memory strings[String] are stored as letters[actually, cord objects from libgd cord library, see cord.h file] plus list of fragments[String::Fragment] which contain language of fragment+it's length.

Fragments that are received from stdout of scripts are considered clean(String::Language ::L_CLEAN), but those from visitor - from stderr of scripts, from environment, from form, from dist[table:load] or from sql server[table:sql] are considered tainted(String::Language ::UL_TAINTED), when string involved in different operations, it can be split, but all resulting parts still remember languages of their fragments. String can be written to Request::wcontext, then part of fragments can change their language. Language is set to those fragments, which were not in particular language, but just tainted[L_TAINTED], they become "dirty, but we need what to do to make them clean, that is we know their language". Say,

^void:sql{insert into news (title) values ('$form:title')]
when parameter of sql is processed, with help of Temp_lang we set "current language"[Request::flang], and when string got written[Request::write_assign_lang] L_TAINTED string from $form:title part of parameter of sql-method, the one in apostrophes, got assigned an L_SQL language.

String can be converted to normal Ñ-string by String::cstr(). If it is called with this parameter String::cstr(String::L_UNSPECIFIED) then when it will be converted, fragment languages would be taken into consideration, and corresponding cleansing performed. Particular language can also be specified String::cstr(String::Language) [by default =L_AS_IS], then all string fragments would forcibly considered to be in that language, regardles of the language inside fragment.

This is used, for instance, in work with file names [ATTENTION: never ever use this construction if you care about your secret files, it is used only as an example]:

$file[^table::load[$form:file_name]]
here with normal $form:file_name processing would be L_HTML|L_OPTIMIZE_BIT, while we need L_FILE_SPEC, and it would be stupid everywhere to do like we do in table:sql, insisting on {} parameters.

Usual language of output is String::Language::L_HTML|String::Language::L_OPTIMIZE_BIT, exception is CGI script, which got started outside of web-server, in that case language String::Language::L_AS_IS is used.

In fragments where language is marked as OPTIMIZED (String::Language::L_OPTIMIZE_BIT), when they are converted into string String::cstr white spaces would be optimized: out of several consequent characters would be left only first, others would be wiped off the result.

When code works with char* it is assumed it is can never be 0. k


Build targets

 Parser is build as [/targets]:
  • Apache 1.3 module [apache13/];
  • CGI script [cgi/];
  • ISAPI extension [isapi/].
Each target implements pure virtual static SAPI class - an interface of Parser with web-server.

At the very beginning an instance of Request object is created, which is passed an Request::Info object with request parameters. After that Request::core method is called, which does all request processing.


Value

 All values, with which Parser operates, are instances of classes, derived from Value. Value knows it's type [Value::type], which is used in error messages. Type can also be checked like this:
^if($variable is hash){when there is hash in variable}{when not hash}

Value can store elements [Value::get_element, Value::put_element]. Simplest example - hash[VHash].


Todo List
Member Charset::transcodeToUTF8(const String::C src) const
not so memory-hungry with prescan

Member Hash::merge_dont_replace(const Hash &src)
optimize this.allocated==src.allocated case

Member Request::get_element(Value &ncontext, const String &name, bool can_call_operator)
cache|prepare junctions

Member SAPI::send_header(SAPI_Info &info)
intelligent cache-control

Member SQL_Driver::operator new(size_t size)
never freed

Class SQL_Driver::Placeholder
can be optimized to contain type information,

Member SQL_Driver_manager::get_connection_from_cache(connection_cache_type::key_type url)
get rid of memory spending Stack [zeros deep inside got accumulated]

Member String::mid(size_t substr_begin, size_t substr_end) const
check in doc: whether it documents NOW bad situation "abc".mid(-1, 3) =were?="ab"

Member String::Languages::count() const
currently there can be adjucent blocks of same language. someday merge them

Member VMail::message_hash_to_string(Request &r, HashStringValue *message_hash, int level, const String *&from, bool extract_to, String *&to)
files and messages in order (file, file2, ...)

Member _exec_cgi(Request &r, MethodParams &params, bool cgi)
fix `` in perl - they produced flipping consoles and no output to perl

Member real_parser_handler(SAPI_Info &SAPI_info, Parser_module_config *dcfg)
intelligent cache-control

Member transcodeFromUTF8(const XMLByte *srcData, size_t &srcLen, XMLByte *toFill, size_t &toFillLen, const Charset::Tables &tables)
digital entites only when xml/html output [at output in html/xml mode, in html part of a letter]

Member format(double value, char *fmt)
less stupid type detection

File pa_exec.C
setrlimit

Member gc_substitute_memory_management_functions()
gc: libltdl: substitute lt_dlmalloc & co

Member pa_internal_file_read_http(Request_charsets &charsets, const String &file_spec, bool as_text, HashStringValue *options)
build .cookies field. use ^file.tables.SET-COOKIES.menu{ for now

File pa_uue.C
setrlimit

Member real_parser_handler(const char *filespec_to_process, const char *request_method, bool header_only)
IIS: remove trailing default-document[index.html] from $request.uri. to do that we need to consult metabase, wich is tested but seems slow.

Member abort(const char *fmt, va_list args)
event log

Member real_parser_handler(SAPI_Info &SAPI_info, bool header_only)
IIS: remove trailing default-document[index.html] from $request.uri. to do that we need to consult metabase, wich is tested&works but seems slow runtime and not could-be-quickly-implemented if prepared.

Member replace_action(Table &table, ArrayString *row, int prestart, int prefinish, int poststart, int postfinish, void *info)
they can do $global[$result] there, getting pointer to later-invalid local var, kill this

Member _match(Request &r, MethodParams &params)
use pcre:study somehow


Test List
Member Request::core(const char *config_filespec, bool config_fail_on_read_problem, bool header_only)
log stack trace

Member SAPI::add_header_attribute(SAPI_Info &info, const char *dont_store_key, const char *dont_store_value)
location provide with protocol. think about internal redirects

Member load(Request &r, const String &file_name)
wrap FILE to auto-object

Member pa_parser_handler(pa_request_rec *r, Parser_module_config *dcfg)
r->finfo.st_mode check seems to work only on win32

Member append_env_pair(HashStringString::key_type key, HashStringString::value_type value, Append_env_pair_info *info)
maybe here and at argv construction --- cstr(String::L_UNSPECIFIED

Member pa_globals_init()
hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);

Member real_parser_handler(SAPI_Info &SAPI_info, bool header_only)
PARSER_VERSION from outside


Bug List
Member Request::get_element(Value &ncontext, const String &name, bool can_call_operator)
^superbase:method would dynamically call ^base:method if there is any

Member SMTP::ResolveService(const char *, u_short *)
getservbyname is not reenterant

Member SMTP::ResolveHostname(const char *, struct sockaddr_in *)
gethostbyname is not reenterant


Graphical Class Hierarchy

Parser3 Source Code Graphical Class Hierarchy

Go to the textual class hierarchy


Alphabetical index

Parser3 Source Code Compound Index

_
Font MHash Request_charsets
V
_IO_COUNTERS_ ForestElement MHashfile Request_context_saver Value
A
FT MImage Request_info VBool
apr_file_t
G
MInt
S
VClass
apr_finfo_t gdBuf MMail SAPI VClass::Prevent_info
apr_sdbm_datum_t gdGifEncoder MMath SAPI_Info VClassMAIN
apr_sdbm_t gdGrowingBuf MMemory SMTP VCodeFrame
Array gdImage MResponse SQL_Connection VConsole
Array::Action_options gdImage::Point MString SQL_Driver VCookie
Array_iterator GIF_Header MTable SQL_Driver::Placeholder VDate
AutoSYNCHRONIZED
H
Mutex SQL_Driver_manager VDouble
C
Hash MVoid SQL_Driver_query_event_handlers VEnv
cache_line Hash::Pair MXnode SQL_Driver_services VFile
Cache_manager Hashfile_value_serialized_prolog
O
SQL_Driver_services_impl VForm
Cache_managers
J
Operation SQL_Error VHash
Charset JPG_Exif_IFD_begin Operation::Origin Stack VHash_lock
Charset::Tables JPG_Exif_IFD_entry
P
String VHashfile
Charset::Tables::Rec JPG_Exif_segment_begin PA_Allocated String::Body VImage
Charset::UTF8CaseTable JPG_Exif_TIFF_header PA_Cleaned String::C VInt
Charset::UTF8CaseTable::Rec JPG_Segment_head PA_exec_result String::Cm VJunction
Charsets JPG_Size_segment_body PA_MD5_CTX String::Languages VMail
chr_data Junction pa_request_rec_tag String_match_table_template_columns VMath
compile_data
L
Parse_control StringOrValue VMemory
CORD_ec_struct lf_state Parser_module_config_tag Stylesheet_connection VMethodFrame
CORD_fill_data lsplit_result PNG_Header Stylesheet_connection_ptr VObject
CORD_pe lt_dlhandle_struct Pool Stylesheet_manager VObject::Prevent_append_if_exists_in_static_or_base_info
CORD_Pos lt_dlinfo Pool::Cleanup substr_args VProperty
CordRep lt_dlloader Pooled
T
VRequest
CordRep::Concatenation lt_dlsymlist Pos Table VResponse
CordRep::Function lt_dlsymlists_t Property TableSeparators VStateless_class
CordRep::Generic lt_user_dlloader
R
Temp_client_charset VStateless_object
D
M
Random_provider Temp_connection VStatus
Date_calendar_table_template_columns match_data real_pcre Temp_derived VString
Dictionary MDate real_pcre_extra Temp_hash_value VTable
Dictionary::Subst MDouble refill_data Temp_lang VVoid
dirent Method Request Temp_method VXdoc
E
Methoded Request::Exception_details Temp_method_frame_self VXdoc::Output_options
Exception Methoded_array Request::Exception_trace Temp_value_element VXnode
EXIF_tag_value2name MethodParams Request::Execute_nonvirtual_method_result
U
W
F
MFile Request::StackItem Untaint_lang_name2enum WContext
ffblk MForm Request::Trace uuid WWrapper
File_read_result


Graph Legend

This page explains how to interpret the graphs that are generated by doxygen.

Consider the following example:

/*! Invisible class because of truncation */
class Invisible { };

/*! Truncated class, inheritance relation is hidden */
class Truncated : public Invisible { };

/* Class not documented with doxygen comments */
class Undocumented { };

/*! Class that is inherited using public inheritance */
class PublicBase : public Truncated { };

/*! A template class */
template<class T> class Templ { };

/*! Class that is inherited using protected inheritance */
class ProtectedBase { };

/*! Class that is inherited using private inheritance */
class PrivateBase { };

/*! Class that is used by the Inherited class */
class Used { };

/*! Super class that inherits a number of other classes */
class Inherited : public PublicBase,
                  protected ProtectedBase,
                  private PrivateBase,
                  public Undocumented
                  public Templ<int>
{
  private:
    Used *m_usedClass;
};
If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:

The boxes in the above graph have the following meaning:

  • A filled black box represents the struct or class for which the graph is generated.
  • A box with a black border denotes a documented struct or class.
  • A box with a grey border denotes an undocumented struct or class.
  • A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
The arrows have the following meaning:
  • A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • A dark green arrow is used for protected inheritance.
  • A dark red arrow is used for private inheritance.
  • A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.